Merge "improvement and fixes for bindings test"
diff --git a/res/layout/browser_subwindow.xml b/res/layout/browser_subwindow.xml
index 76d72d5..adf3284 100644
--- a/res/layout/browser_subwindow.xml
+++ b/res/layout/browser_subwindow.xml
@@ -23,6 +23,7 @@
android:layout_height="match_parent"
android:padding="10dip" >
<LinearLayout
+ android:id="@+id/inner_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 4779aa1..2e8510a 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -30,11 +30,6 @@
<item name="android:windowContentOverlay">@null</item>
</style>
- <style name="FindDialog">
- <item name="android:windowEnterAnimation">@anim/find_dialog_enter</item>
- <item name="android:windowExitAnimation">@anim/find_dialog_exit</item>
- </style>
-
<style name="TitleBar">
<item name="android:windowEnterAnimation">@anim/title_bar_enter</item>
<item name="android:windowExitAnimation">@anim/title_bar_exit</item>
diff --git a/res/values/themes.xml b/res/values/themes.xml
deleted file mode 100644
index bb922dd..0000000
--- a/res/values/themes.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<resources>
- <style name="FindDialogTheme">
- <item name="android:windowFrame">@null</item>
- <item name="android:windowIsFloating">true</item>
- <item name="android:windowIsTranslucent">true</item>
- <item name="android:windowNoTitle">true</item>
- <item name="android:background">@null</item>
- <item name="android:windowBackground">@null</item>
- <item name="android:windowAnimationStyle">@style/FindDialog</item>
- <item name="android:backgroundDimEnabled">false</item>
- </style>
-</resources>
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 5e55789..8efb18a 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -1367,9 +1367,8 @@
if (null == mFindDialog) {
mFindDialog = new FindDialog(this);
}
- mFindDialog.setWebView(getTopWindow());
- mFindDialog.show();
- getTopWindow().setFindIsUp(true);
+ // Need to do something special for Tablet
+ mTabControl.getCurrentTab().showFind(mFindDialog);
mMenuState = EMPTY_MENU;
break;
@@ -1450,7 +1449,14 @@
return true;
}
+ /*
+ * Remove the FindDialog.
+ */
public void closeFind() {
+ if (mFindDialog != null) {
+ mTabControl.getCurrentTab().closeFind(mFindDialog);
+ mFindDialog.dismiss();
+ }
mMenuState = R.id.MAIN_MENU;
}
@@ -2462,7 +2468,9 @@
onProgressChanged(view, INITIAL_PROGRESS);
mDidStopLoad = false;
if (!mIsNetworkUp) createAndShowNetworkDialog();
-
+ if (view.getFindIsUp()) {
+ closeFind();
+ }
if (mSettings.isTracing()) {
String host;
try {
diff --git a/src/com/android/browser/BrowserBackupAgent.java b/src/com/android/browser/BrowserBackupAgent.java
index 6f6e829..c968ce5 100644
--- a/src/com/android/browser/BrowserBackupAgent.java
+++ b/src/com/android/browser/BrowserBackupAgent.java
@@ -84,6 +84,10 @@
savedVersion = in.readInt();
} catch (EOFException e) {
// It means we had no previous state; that's fine
+ } finally {
+ if (in != null) {
+ in.close();
+ }
}
// Build a flattened representation of the bookmarks table
@@ -174,6 +178,10 @@
} catch (IOException ioe) {
Log.w(TAG, "Bad backup data; not restoring");
crc = -1;
+ } finally {
+ if (in != null) {
+ in.close();
+ }
}
}
@@ -187,7 +195,7 @@
}
}
- class Bookmark {
+ static class Bookmark {
public String url;
public int visits;
public long date;
@@ -258,13 +266,18 @@
data.writeEntityHeader(key, toCopy);
FileInputStream in = new FileInputStream(file);
- int nRead;
- while (toCopy > 0) {
- nRead = in.read(buf, 0, CHUNK);
- data.writeEntityData(buf, nRead);
- toCopy -= nRead;
+ try {
+ int nRead;
+ while (toCopy > 0) {
+ nRead = in.read(buf, 0, CHUNK);
+ data.writeEntityData(buf, nRead);
+ toCopy -= nRead;
+ }
+ } finally {
+ if (in != null) {
+ in.close();
+ }
}
- in.close();
}
// Read the given file from backup to a file, calculating a CRC32 along the way
@@ -275,14 +288,18 @@
CRC32 crc = new CRC32();
FileOutputStream out = new FileOutputStream(file);
- while (toRead > 0) {
- int numRead = data.readEntityData(buf, 0, CHUNK);
- crc.update(buf, 0, numRead);
- out.write(buf, 0, numRead);
- toRead -= numRead;
+ try {
+ while (toRead > 0) {
+ int numRead = data.readEntityData(buf, 0, CHUNK);
+ crc.update(buf, 0, numRead);
+ out.write(buf, 0, numRead);
+ toRead -= numRead;
+ }
+ } finally {
+ if (out != null) {
+ out.close();
+ }
}
-
- out.close();
return crc.getValue();
}
@@ -291,8 +308,14 @@
throws IOException {
DataOutputStream out = new DataOutputStream(
new FileOutputStream(stateFile.getFileDescriptor()));
- out.writeLong(fileSize);
- out.writeLong(crc);
- out.writeInt(BACKUP_AGENT_VERSION);
+ try {
+ out.writeLong(fileSize);
+ out.writeLong(crc);
+ out.writeInt(BACKUP_AGENT_VERSION);
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
}
}
diff --git a/src/com/android/browser/ErrorConsoleView.java b/src/com/android/browser/ErrorConsoleView.java
index 0f87cb5..ca5fed4 100644
--- a/src/com/android/browser/ErrorConsoleView.java
+++ b/src/com/android/browser/ErrorConsoleView.java
@@ -230,7 +230,7 @@
* This class is an adapter for ErrorConsoleListView that contains the error console
* message data.
*/
- private class ErrorConsoleMessageList extends android.widget.BaseAdapter
+ private static class ErrorConsoleMessageList extends android.widget.BaseAdapter
implements android.widget.ListAdapter {
private Vector<ConsoleMessage> mMessages;
diff --git a/src/com/android/browser/FindDialog.java b/src/com/android/browser/FindDialog.java
index 45c8016..caff852 100644
--- a/src/com/android/browser/FindDialog.java
+++ b/src/com/android/browser/FindDialog.java
@@ -16,24 +16,23 @@
package com.android.browser;
-import android.app.Dialog;
import android.content.Context;
-import android.os.Bundle;
import android.text.Editable;
import android.text.Spannable;
import android.text.TextWatcher;
import android.view.Gravity;
import android.view.KeyEvent;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
+import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebView;
import android.widget.EditText;
+import android.widget.LinearLayout;
import android.widget.TextView;
-/* package */ class FindDialog extends Dialog implements TextWatcher {
+/* package */ class FindDialog extends LinearLayout implements TextWatcher {
private WebView mWebView;
private TextView mMatches;
private BrowserActivity mBrowserActivity;
@@ -53,7 +52,7 @@
private View.OnClickListener mFindCancelListener =
new View.OnClickListener() {
public void onClick(View v) {
- dismiss();
+ mBrowserActivity.closeFind();
}
};
@@ -89,22 +88,11 @@
}
/* package */ FindDialog(BrowserActivity context) {
- super(context, R.style.FindDialogTheme);
+ super(context);
mBrowserActivity = context;
- setCanceledOnTouchOutside(true);
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- Window theWindow = getWindow();
- theWindow.setGravity(Gravity.BOTTOM|Gravity.FILL_HORIZONTAL);
-
- setContentView(R.layout.browser_find);
-
- theWindow.setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
+ LayoutInflater factory = LayoutInflater.from(context);
+ factory.inflate(R.layout.browser_find, this);
mEditText = (EditText) findViewById(R.id.edit);
@@ -122,23 +110,38 @@
mMatches = (TextView) findViewById(R.id.matches);
mMatchesView = findViewById(R.id.matches_view);
disableButtons();
- theWindow.setSoftInputMode(
- WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+
}
-
+
+ /**
+ * Called by BrowserActivity.closeFind. Start the animation to hide
+ * the dialog, inform the WebView that the dialog is being dismissed,
+ * and hide the soft keyboard.
+ */
public void dismiss() {
- super.dismiss();
- mBrowserActivity.closeFind();
mWebView.notifyFindDialogDismissed();
+ startAnimation(AnimationUtils.loadAnimation(mBrowserActivity,
+ R.anim.find_dialog_exit));
+ InputMethodManager imm = (InputMethodManager)
+ getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ imm.hideSoftInputFromWindow(this.getWindowToken(), 0);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER
- && event.getAction() == KeyEvent.ACTION_UP
- && mEditText.hasFocus()) {
- findNext();
- return true;
+ int keyCode = event.getKeyCode();
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ if (event.getAction() == KeyEvent.ACTION_UP) {
+ mBrowserActivity.closeFind();
+ return true;
+ }
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ if (keyCode == KeyEvent.KEYCODE_ENTER
+ && mEditText.hasFocus()) {
+ findNext();
+ return true;
+ }
}
return super.dispatchKeyEvent(event);
}
@@ -152,7 +155,6 @@
}
public void show() {
- super.show();
mEditText.requestFocus();
mEditText.setText("");
Spannable span = (Spannable) mEditText.getText();
@@ -160,6 +162,11 @@
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
setMatchesFound(0);
disableButtons();
+ startAnimation(AnimationUtils.loadAnimation(mBrowserActivity,
+ R.anim.find_dialog_enter));
+ InputMethodManager imm = (InputMethodManager)
+ mBrowserActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showSoftInput(mEditText, 0);
}
// TextWatcher methods
@@ -184,8 +191,6 @@
mMatchesView.setVisibility(View.INVISIBLE);
} else {
mMatchesView.setVisibility(View.VISIBLE);
- mWebView.setFindDialogHeight(
- getWindow().getDecorView().getHeight());
int found = mWebView.findAll(find.toString());
setMatchesFound(found);
if (found < 2) {
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 2dac050..12f0cf6 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -87,7 +87,7 @@
// The Geolocation permissions prompt
private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt;
// Main WebView wrapper
- private View mContainer;
+ private LinearLayout mContainer;
// Main WebView
private WebView mMainView;
// Subwindow container
@@ -1205,9 +1205,18 @@
private static class SubWindowClient extends WebViewClient {
// The main WebViewClient.
private final WebViewClient mClient;
+ private final BrowserActivity mBrowserActivity;
- SubWindowClient(WebViewClient client) {
+ SubWindowClient(WebViewClient client, BrowserActivity activity) {
mClient = client;
+ mBrowserActivity = activity;
+ }
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ // Unlike the others, do not call mClient's version, which would
+ // change the progress bar. However, we do want to remove the
+ // find dialog.
+ if (view.getFindIsUp()) mBrowserActivity.closeFind();
}
@Override
public void doUpdateVisitedHistory(WebView view, String url,
@@ -1297,7 +1306,7 @@
// The tab consists of a container view, which contains the main
// WebView, as well as any other UI elements associated with the tab.
- mContainer = mInflateService.inflate(R.layout.tab, null);
+ mContainer = (LinearLayout) mInflateService.inflate(R.layout.tab, null);
mDownloadListener = new DownloadListener() {
public void onDownloadStart(String url, String userAgent,
@@ -1408,6 +1417,7 @@
*/
boolean createSubWindow() {
if (mSubView == null) {
+ if (mMainView.getFindIsUp()) mActivity.closeFind();
mSubViewContainer = mInflateService.inflate(
R.layout.browser_subwindow, null);
mSubView = (WebView) mSubViewContainer.findViewById(R.id.webview);
@@ -1416,7 +1426,8 @@
mSubView.setMapTrackballToArrowKeys(false);
// Enable the built-in zoom
mSubView.getSettings().setBuiltInZoomControls(true);
- mSubView.setWebViewClient(new SubWindowClient(mWebViewClient));
+ mSubView.setWebViewClient(new SubWindowClient(mWebViewClient,
+ mActivity));
mSubView.setWebChromeClient(new SubWindowChromeClient(
mWebChromeClient));
// Set a different DownloadListener for the mSubView, since it will
@@ -1454,6 +1465,9 @@
*/
void dismissSubWindow() {
if (mSubView != null) {
+ if (mSubView.getFindIsUp()) {
+ mActivity.closeFind();
+ }
BrowserSettings.getInstance().deleteObserver(
mSubView.getSettings());
mSubView.destroy();
@@ -1478,6 +1492,7 @@
void removeSubWindow(ViewGroup content) {
if (mSubView != null) {
content.removeView(mSubViewContainer);
+ if (mSubView.getFindIsUp()) mActivity.closeFind();
}
}
@@ -1536,6 +1551,7 @@
(FrameLayout) mContainer.findViewById(R.id.webview_wrapper);
wrapper.removeView(mMainView);
content.removeView(mContainer);
+ if (mMainView.getFindIsUp()) mActivity.closeFind();
removeSubWindow(content);
}
@@ -1931,4 +1947,36 @@
}
return true;
}
+
+ /*
+ * Open the find dialog. Called by BrowserActivity.
+ */
+ void showFind(FindDialog dialog) {
+ LinearLayout container;
+ WebView view;
+ if (mSubView != null) {
+ view = mSubView;
+ container = (LinearLayout) mSubViewContainer.findViewById(
+ R.id.inner_container);
+ } else {
+ view = mMainView;
+ container = mContainer;
+ }
+ dialog.show();
+ container.addView(dialog, new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ dialog.setWebView(view);
+ view.setFindIsUp(true);
+ }
+
+ /*
+ * Close the find dialog. Called by BrowserActivity.closeFind.
+ */
+ void closeFind(FindDialog dialog) {
+ // The dialog may be attached to the subwindow. Ensure that the
+ // correct parent has it removed.
+ LinearLayout parent = (LinearLayout) dialog.getParent();
+ if (parent != null) parent.removeView(dialog);
+ }
}
diff --git a/src/com/android/browser/WebsiteSettingsActivity.java b/src/com/android/browser/WebsiteSettingsActivity.java
index 430286f..1e27092 100644
--- a/src/com/android/browser/WebsiteSettingsActivity.java
+++ b/src/com/android/browser/WebsiteSettingsActivity.java
@@ -62,7 +62,7 @@
private static String sMBStored = null;
private SiteAdapter mAdapter = null;
- class Site {
+ static class Site {
private String mOrigin;
private String mTitle;
private Bitmap mIcon;
@@ -190,7 +190,7 @@
* Adds the specified feature to the site corresponding to supplied
* origin in the map. Creates the site if it does not already exist.
*/
- private void addFeatureToSite(Map sites, String origin, int feature) {
+ private void addFeatureToSite(Map<String, Site> sites, String origin, int feature) {
Site site = null;
if (sites.containsKey(origin)) {
site = (Site) sites.get(origin);
@@ -213,7 +213,7 @@
WebStorage.getInstance().getOrigins(new ValueCallback<Map>() {
public void onReceiveValue(Map origins) {
- Map sites = new HashMap<String, Site>();
+ Map<String, Site> sites = new HashMap<String, Site>();
if (origins != null) {
Iterator<String> iter = origins.keySet().iterator();
while (iter.hasNext()) {
@@ -225,7 +225,7 @@
});
}
- public void askForGeolocation(final Map sites) {
+ public void askForGeolocation(final Map<String, Site> sites) {
GeolocationPermissions.getInstance().getOrigins(new ValueCallback<Set<String> >() {
public void onReceiveValue(Set<String> origins) {
if (origins != null) {
@@ -240,19 +240,19 @@
});
}
- public void populateIcons(Map sites) {
+ public void populateIcons(Map<String, Site> sites) {
// Create a map from host to origin. This is used to add metadata
// (title, icon) for this origin from the bookmarks DB.
- HashMap hosts = new HashMap<String, Set<Site> >();
- Set keys = sites.keySet();
- Iterator<String> originIter = keys.iterator();
+ HashMap<String, Set<Site>> hosts = new HashMap<String, Set<Site>>();
+ Set<Map.Entry<String, Site>> elements = sites.entrySet();
+ Iterator<Map.Entry<String, Site>> originIter = elements.iterator();
while (originIter.hasNext()) {
- String origin = originIter.next();
- Site site = (Site) sites.get(origin);
- String host = Uri.parse(origin).getHost();
- Set hostSites = null;
+ Map.Entry<String, Site> entry = originIter.next();
+ Site site = entry.getValue();
+ String host = Uri.parse(entry.getKey()).getHost();
+ Set<Site> hostSites = null;
if (hosts.containsKey(host)) {
- hostSites = (Set) hosts.get(host);
+ hostSites = (Set<Site>)hosts.get(host);
} else {
hostSites = new HashSet<Site>();
hosts.put(host, hostSites);
@@ -266,55 +266,56 @@
new String[] { Browser.BookmarkColumns.URL, Browser.BookmarkColumns.TITLE,
Browser.BookmarkColumns.FAVICON }, "bookmark = 1", null, null);
- if ((c != null) && c.moveToFirst()) {
- int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
- int titleIndex = c.getColumnIndex(Browser.BookmarkColumns.TITLE);
- int faviconIndex = c.getColumnIndex(Browser.BookmarkColumns.FAVICON);
- do {
- String url = c.getString(urlIndex);
- String host = Uri.parse(url).getHost();
- if (hosts.containsKey(host)) {
- String title = c.getString(titleIndex);
- Bitmap bmp = null;
- byte[] data = c.getBlob(faviconIndex);
- if (data != null) {
- bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
- }
- Set matchingSites = (Set) hosts.get(host);
- Iterator<Site> sitesIter = matchingSites.iterator();
- while (sitesIter.hasNext()) {
- Site site = sitesIter.next();
- // We should only set the title if the bookmark is for the root
- // (i.e. www.google.com), as website settings act on the origin
- // as a whole rather than a single page under that origin. If the
- // user has bookmarked a page under the root but *not* the root,
- // then we risk displaying the title of that page which may or
- // may not have any relevance to the origin.
- if (url.equals(site.getOrigin()) ||
- (new String(site.getOrigin()+"/")).equals(url)) {
- site.setTitle(title);
+ if (c != null) {
+ if (c.moveToFirst()) {
+ int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
+ int titleIndex = c.getColumnIndex(Browser.BookmarkColumns.TITLE);
+ int faviconIndex = c.getColumnIndex(Browser.BookmarkColumns.FAVICON);
+ do {
+ String url = c.getString(urlIndex);
+ String host = Uri.parse(url).getHost();
+ if (hosts.containsKey(host)) {
+ String title = c.getString(titleIndex);
+ Bitmap bmp = null;
+ byte[] data = c.getBlob(faviconIndex);
+ if (data != null) {
+ bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
}
- if (bmp != null) {
- site.setIcon(bmp);
+ Set matchingSites = (Set) hosts.get(host);
+ Iterator<Site> sitesIter = matchingSites.iterator();
+ while (sitesIter.hasNext()) {
+ Site site = sitesIter.next();
+ // We should only set the title if the bookmark is for the root
+ // (i.e. www.google.com), as website settings act on the origin
+ // as a whole rather than a single page under that origin. If the
+ // user has bookmarked a page under the root but *not* the root,
+ // then we risk displaying the title of that page which may or
+ // may not have any relevance to the origin.
+ if (url.equals(site.getOrigin()) ||
+ (new String(site.getOrigin()+"/")).equals(url)) {
+ site.setTitle(title);
+ }
+ if (bmp != null) {
+ site.setIcon(bmp);
+ }
}
}
- }
- } while (c.moveToNext());
+ } while (c.moveToNext());
+ }
+ c.close();
}
-
- c.close();
}
- public void populateOrigins(Map sites) {
+ public void populateOrigins(Map<String, Site> sites) {
clear();
// We can now simply populate our array with Site instances
- Set keys = sites.keySet();
- Iterator<String> originIter = keys.iterator();
- while (originIter.hasNext()) {
- String origin = originIter.next();
- Site site = (Site) sites.get(origin);
+ Set<Map.Entry<String, Site>> elements = sites.entrySet();
+ Iterator<Map.Entry<String, Site>> entryIterator = elements.iterator();
+ while (entryIterator.hasNext()) {
+ Map.Entry<String, Site> entry = entryIterator.next();
+ Site site = entry.getValue();
add(site);
}