Merge "Update homescreen icon generator to look better on xlarge devices."
diff --git a/Android.mk b/Android.mk
index 2abde9b..a5a47b3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -4,7 +4,8 @@
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-common
+ android-common \
+ guava
LOCAL_SRC_FILES := \
$(call all-java-files-under, src) \
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b653461..955687b 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -41,7 +41,7 @@
android:label="@string/application_name"
android:icon="@mipmap/ic_launcher_browser"
android:backupAgent=".BrowserBackupAgent"
- android:hardwareAccelerated="false"
+ android:hardwareAccelerated="true"
android:taskAffinity="android.task.browser" >
<provider android:name="BrowserProvider"
@@ -66,6 +66,7 @@
android:alwaysRetainTaskState="true"
android:configChanges="orientation|keyboardHidden"
android:theme="@style/BrowserTheme"
+ android:hardwareAccelerated="false"
android:windowSoftInputMode="adjustResize" >
<intent-filter>
<action android:name="android.speech.action.VOICE_SEARCH_RESULTS" />
@@ -160,18 +161,13 @@
android:configChanges="orientation|keyboardHidden">
</activity>
- <activity android:name="BrowserPreferencesPage" android:label="@string/menu_preferences"
- android:configChanges="orientation|keyboardHidden">
+ <activity android:name="BrowserPreferencesPage" android:label="@string/menu_preferences">
</activity>
<activity android:name="BrowserHistoryPage" android:label=""
android:configChanges="orientation|keyboardHidden">
</activity>
- <activity android:name="WebsiteSettingsActivity" android:label=""
- android:configChanges="orientation|keyboardHidden">
- </activity>
-
<activity android:name="BookmarkSearch"
android:label="@string/bookmarks_search"
android:stateNotNeeded="true"
diff --git a/res/drawable-hdpi/frame_bookmark_thumb_pressed.9.png b/res/drawable-hdpi/frame_bookmark_thumb_pressed.9.png
new file mode 100644
index 0000000..95f3ab5
--- /dev/null
+++ b/res/drawable-hdpi/frame_bookmark_thumb_pressed.9.png
Binary files differ
diff --git a/res/drawable-mdpi/frame_bookmark_thumb_pressed.9.png b/res/drawable-mdpi/frame_bookmark_thumb_pressed.9.png
new file mode 100755
index 0000000..8bae932
--- /dev/null
+++ b/res/drawable-mdpi/frame_bookmark_thumb_pressed.9.png
Binary files differ
diff --git a/res/menu/websitesettings.xml b/res/drawable/bookmark_thumb_selector.xml
similarity index 62%
copy from res/menu/websitesettings.xml
copy to res/drawable/bookmark_thumb_selector.xml
index 5acc8a5..5219d90 100644
--- a/res/menu/websitesettings.xml
+++ b/res/drawable/bookmark_thumb_selector.xml
@@ -1,4 +1,5 @@
-<!-- Copyright (C) 2009 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,9 +14,8 @@
limitations under the License.
-->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:id="@+id/website_settings_menu_clear_all"
- android:title="@string/website_settings_clear_all"
- android:icon="@android:drawable/ic_menu_close_clear_cancel" />
-</menu>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@drawable/frame_bookmark_thumb_pressed" />
+ <item android:drawable="@android:color/transparent" />
+</selector>
diff --git a/res/layout/autofill_settings_fragment.xml b/res/layout/autofill_settings_fragment.xml
index bdffebb..b0e0f53 100644
--- a/res/layout/autofill_settings_fragment.xml
+++ b/res/layout/autofill_settings_fragment.xml
@@ -38,6 +38,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
+ android:shrinkColumns="1"
android:stretchColumns="1">
<TableRow
android:layout_height="match_parent"
diff --git a/res/layout/bookmarks.xml b/res/layout/bookmarks.xml
index 7a0aa23..28f83e4 100644
--- a/res/layout/bookmarks.xml
+++ b/res/layout/bookmarks.xml
@@ -37,7 +37,7 @@
android:verticalSpacing="16dip"
android:stretchMode="spacingWidth"
android:scrollbarStyle="insideInset"
- android:listSelector="@android:drawable/gallery_thumb"
+ android:listSelector="@drawable/bookmark_thumb_selector"
android:drawSelectorOnTop="true"
android:focusable="true"
android:focusableInTouchMode="true"
diff --git a/res/layout/browser_add_bookmark.xml b/res/layout/browser_add_bookmark.xml
index 0eaf526..c547389 100644
--- a/res/layout/browser_add_bookmark.xml
+++ b/res/layout/browser_add_bookmark.xml
@@ -69,6 +69,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:stretchColumns="1"
+ android:shrinkColumns="1"
android:paddingTop="20dip"
android:paddingLeft="20dip"
android:paddingRight="20dip" >
diff --git a/res/layout/url_bar.xml b/res/layout/url_bar.xml
index 2a67c72..ba93d1b 100644
--- a/res/layout/url_bar.xml
+++ b/res/layout/url_bar.xml
@@ -63,7 +63,7 @@
android:layout_height="match_parent"
style="@style/HoloIcon"
android:visibility="gone" />
- <EditText
+ <TextView
android:id="@+id/url_unfocused"
android:layout_width="0dip"
android:layout_weight="1.0"
@@ -76,9 +76,7 @@
android:singleLine="true"
android:ellipsize="end"
android:lines="1"
- android:scrollHorizontally="true"
- android:inputType="textUri"
- android:imeOptions="actionGo" />
+ android:scrollHorizontally="true" />
<ImageButton
android:id="@+id/star"
android:src="@drawable/ic_favorite_off_normal"
diff --git a/res/layout/website_settings.xml b/res/layout/website_settings.xml
new file mode 100644
index 0000000..ed95148
--- /dev/null
+++ b/res/layout/website_settings.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:background="@android:color/transparent">
+
+ <ListView android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1"
+ android:clipToPadding="false"
+ android:drawSelectorOnTop="false"
+ android:cacheColorHint="@android:color/transparent"
+ android:scrollbarAlwaysDrawVerticalTrack="true" />
+
+ <Button android:id="@+id/clear_all_button"
+ android:layout_width="150dip"
+ android:layout_height="wrap_content"
+ android:layout_margin="5dip"
+ android:text="@string/website_settings_clear_all"
+ android:visibility="gone" />
+</LinearLayout>
diff --git a/res/menu/websitesettings.xml b/res/menu/url_selection.xml
similarity index 69%
rename from res/menu/websitesettings.xml
rename to res/menu/url_selection.xml
index 5acc8a5..1bb6d0e 100644
--- a/res/menu/websitesettings.xml
+++ b/res/menu/url_selection.xml
@@ -1,4 +1,5 @@
-<!-- Copyright (C) 2009 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,8 +15,10 @@
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:id="@+id/website_settings_menu_clear_all"
- android:title="@string/website_settings_clear_all"
- android:icon="@android:drawable/ic_menu_close_clear_cancel" />
+ <item android:id="@+id/share"
+ android:icon="@drawable/ic_menu_share_normal"
+ android:title="@string/menu_share_url"
+ android:showAsAction="always|withText"
+ />
</menu>
diff --git a/res/values-id/strings.xml b/res/values-in/strings.xml
similarity index 100%
rename from res/values-id/strings.xml
rename to res/values-in/strings.xml
diff --git a/res/values-he/strings.xml b/res/values-iw/strings.xml
similarity index 100%
rename from res/values-he/strings.xml
rename to res/values-iw/strings.xml
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e98d9d5..ece6ffa 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -871,4 +871,10 @@
<!-- Button allowing users to import all of their existing bookmarks into an account when setting up syncing with their bookmarks stored in Google Chrome [CHAR-LIMIT=64] -->
<string name="import_bookmarks_dialog_import">Add your Android bookmarks to bookmarks for <xliff:g id="Google account" example="account@example.com">%s</xliff:g></string>
+
+ <!-- Url Selection Action Mode -->
+
+ <!-- Menu item to share URL selection [CHAR LIMIT=30] -->
+ <string name="menu_share_url">Share</string>
+
</resources>
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index 5f8944f..79c3327 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -201,6 +201,9 @@
if (mActiveTabsPage != null) {
mUiController.removeActiveTabsPage(true);
}
+ if (isCustomViewShowing()) {
+ onHideCustomView();
+ }
cancelStopToast();
mActivityPaused = true;
}
@@ -427,6 +430,24 @@
mainView.setEmbeddedTitleBar(null);
}
+ @Override
+ public void onSetWebView(Tab tab, WebView webView) {
+ View container = tab.getViewContainer();
+ if (container == null) {
+ // The tab consists of a container view, which contains the main
+ // WebView, as well as any other UI elements associated with the tab.
+ container = mActivity.getLayoutInflater().inflate(R.layout.tab,
+ null);
+ tab.setViewContainer(container);
+ }
+ if (tab.getWebView() != webView) {
+ // Just remove the old one.
+ FrameLayout wrapper =
+ (FrameLayout) container.findViewById(R.id.webview_wrapper);
+ wrapper.removeView(tab.getWebView());
+ }
+ }
+
/**
* create a sub window container and webview for the tab
* Note: this methods operates through side-effects for now
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 9844547..a8c393a 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -16,6 +16,8 @@
package com.android.browser;
+import com.google.common.annotations.VisibleForTesting;
+
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
@@ -95,16 +97,11 @@
mController.start(icicle, getIntent());
}
+ @VisibleForTesting
Controller getController() {
return mController;
}
- // TODO: this is here for the test classes
- // remove once tests are fixed
- TabControl getTabControl() {
- return mController.getTabControl();
- }
-
@Override
protected void onNewIntent(Intent intent) {
mController.handleNewIntent(intent);
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index 4887f3f..74385f9 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -357,8 +357,6 @@
}
BookmarkItem header = new BookmarkItem(activity);
populateBookmarkItem(cursor, header, isFolder);
- new LookupBookmarkCount(getActivity(), header)
- .execute(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
menu.setHeaderView(header);
int count = menu.size();
@@ -374,6 +372,8 @@
Bitmap bitmap =
BitmapFactory.decodeResource(getResources(), R.drawable.ic_folder);
item.setFavicon(bitmap);
+ new LookupBookmarkCount(getActivity(), item)
+ .execute(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
} else {
String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
item.setUrl(url);
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index a3ce0b4..5cd9545 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -366,7 +366,10 @@
mMostVisited.close();
}
mMostVisited = cursor;
- mMostVisited.registerDataSetObserver(mDataSetObserver);
+ if (mMostVisited != null) {
+ mMostVisited.registerDataSetObserver(mDataSetObserver);
+ }
+ notifyDataSetChanged();
}
@Override
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index acd76dd..75dd913 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -317,6 +317,11 @@
}
@Override
+ public void onSetWebView(Tab tab, WebView view) {
+ mUi.onSetWebView(tab, view);
+ }
+
+ @Override
public void createSubWindow(Tab tab) {
endActionMode();
WebView mainView = tab.getWebView();
@@ -488,6 +493,22 @@
}
+ @Override
+ public void shareCurrentPage() {
+ shareCurrentPage(mTabControl.getCurrentTab());
+ }
+
+ private void shareCurrentPage(Tab tab) {
+ if (tab != null) {
+ tab.populatePickerData();
+ sharePage(mActivity, tab.getTitle(),
+ tab.getUrl(), tab.getFavicon(),
+ createScreenshot(tab.getWebView(),
+ getDesiredThumbnailWidth(mActivity),
+ getDesiredThumbnailHeight(mActivity)));
+ }
+ }
+
/**
* Share a page, providing the title, url, favicon, and a screenshot. Uses
* an {@link Intent} to launch the Activity chooser.
@@ -543,13 +564,16 @@
Log.e(LOGTAG, "BrowserActivity is already paused.");
return;
}
- mTabControl.pauseCurrentTab();
+ CookieManager.getInstance().flushCookieStore();
mActivityPaused = true;
- if (mTabControl.getCurrentIndex() >= 0 &&
- !pauseWebViewTimers(mActivityPaused)) {
- mWakeLock.acquire();
- mHandler.sendMessageDelayed(mHandler
- .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
+ Tab tab = mTabControl.getCurrentTab();
+ if (tab != null) {
+ tab.pause();
+ if (!pauseWebViewTimers(tab)) {
+ mWakeLock.acquire();
+ mHandler.sendMessageDelayed(mHandler
+ .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
+ }
}
mUi.onPause();
mNetworkHandler.onPause();
@@ -575,10 +599,12 @@
Log.e(LOGTAG, "BrowserActivity is already resumed.");
return;
}
- mTabControl.resumeCurrentTab();
mActivityPaused = false;
- resumeWebViewTimers();
-
+ Tab current = mTabControl.getCurrentTab();
+ if (current != null) {
+ current.resume();
+ resumeWebViewTimers(current);
+ }
if (mWakeLock.isHeld()) {
mHandler.removeMessages(RELEASE_WAKELOCK);
mWakeLock.release();
@@ -588,9 +614,11 @@
WebView.enablePlatformNotifications();
}
- private void resumeWebViewTimers() {
- Tab tab = mTabControl.getCurrentTab();
- if (tab == null) return; // monkey can trigger this
+ /**
+ * resume all WebView timers using the WebView instance of the given tab
+ * @param tab guaranteed non-null
+ */
+ private void resumeWebViewTimers(Tab tab) {
boolean inLoad = tab.inPageLoad();
if ((!mActivityPaused && !inLoad) || (mActivityPaused && inLoad)) {
CookieSyncManager.getInstance().startSync();
@@ -601,19 +629,23 @@
}
}
- private boolean pauseWebViewTimers(boolean activityPaused) {
- Tab tab = mTabControl.getCurrentTab();
- boolean inLoad = tab.inPageLoad();
- if (activityPaused && !inLoad) {
+ /**
+ * Pause all WebView timers using the WebView of the given tab
+ * @param tab
+ * @return true if the timers are paused or tab is null
+ */
+ private boolean pauseWebViewTimers(Tab tab) {
+ if (tab == null) {
+ return true;
+ } else if (!tab.inPageLoad()) {
CookieSyncManager.getInstance().stopSync();
WebView w = getCurrentWebView();
if (w != null) {
w.pauseTimers();
}
return true;
- } else {
- return false;
}
+ return false;
}
void onDestroy() {
@@ -708,7 +740,7 @@
// to start the timer. As we won't switch tabs while an activity is in
// pause state, we can ensure calling resume and pause in pair.
if (mActivityPaused) {
- resumeWebViewTimers();
+ resumeWebViewTimers(tab);
}
mLoadStopped = false;
if (!mNetworkHandler.isNetworkUp()) {
@@ -749,7 +781,7 @@
}
// pause the WebView timer and release the wake lock if it is finished
// while BrowserActivity is in pause state.
- if (mActivityPaused && pauseWebViewTimers(mActivityPaused)) {
+ if (mActivityPaused && pauseWebViewTimers(tab)) {
if (mWakeLock.isHeld()) {
mHandler.removeMessages(RELEASE_WAKELOCK);
mWakeLock.release();
@@ -1565,12 +1597,7 @@
mCanChord = false;
return false;
}
- currentTab.populatePickerData();
- sharePage(mActivity, currentTab.getTitle(),
- currentTab.getUrl(), currentTab.getFavicon(),
- createScreenshot(currentTab.getWebView(),
- getDesiredThumbnailWidth(mActivity),
- getDesiredThumbnailHeight(mActivity)));
+ shareCurrentPage(currentTab);
break;
case R.id.dump_nav_menu_id:
@@ -2312,7 +2339,7 @@
// force the tab's inLoad() to be false as we are going to
// either finish the activity or remove the tab. This will
// ensure pauseWebViewTimers() taking action.
- mTabControl.getCurrentTab().clearInPageLoad();
+ current.clearInPageLoad();
if (mTabControl.getTabCount() == 1) {
mActivity.finish();
return;
@@ -2321,7 +2348,7 @@
Log.e(LOGTAG, "BrowserActivity is already paused "
+ "while handing goBackOnePageOrQuit.");
}
- pauseWebViewTimers(true);
+ pauseWebViewTimers(current);
removeTab(current);
}
/*
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index a048c2d..8a3bc27 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -85,7 +85,7 @@
// The Geolocation permissions prompt
private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt;
// Main WebView wrapper
- private LinearLayout mContainer;
+ private View mContainer;
// Main WebView
private WebView mMainView;
// Subwindow container
@@ -128,8 +128,6 @@
// the lock icon type and previous lock icon type for the tab
private int mLockIconType;
private int mPrevLockIconType;
- // Inflation service for making subwindows.
- private final LayoutInflater mInflateService;
// The listener that gets invoked when a download is started from the
// mMainView
private final DownloadListener mDownloadListener;
@@ -497,8 +495,10 @@
@Override
public void onPageFinished(WebView view, String url) {
- LogTag.logPageFinishedLoading(
- url, SystemClock.uptimeMillis() - mLoadStartTime);
+ if (!isPrivateBrowsingEnabled()) {
+ LogTag.logPageFinishedLoading(
+ url, SystemClock.uptimeMillis() - mLoadStartTime);
+ }
mInPageLoad = false;
mWebViewController.onPageFinished(Tab.this, url);
@@ -1203,11 +1203,6 @@
mInPageLoad = false;
mInForeground = false;
- mInflateService = LayoutInflater.from(mActivity);
-
- // The tab consists of a container view, which contains the main
- // WebView, as well as any other UI elements associated with the tab.
- mContainer = (LinearLayout) mInflateService.inflate(R.layout.tab, null);
mDownloadListener = new DownloadListener() {
public void onDownloadStart(String url, String userAgent,
@@ -1244,16 +1239,14 @@
if (mMainView == w) {
return;
}
+
// If the WebView is changing, the page will be reloaded, so any ongoing
// Geolocation permission requests are void.
if (mGeolocationPermissionsPrompt != null) {
mGeolocationPermissionsPrompt.hide();
}
- // Just remove the old one.
- FrameLayout wrapper =
- (FrameLayout) mContainer.findViewById(R.id.webview_wrapper);
- wrapper.removeView(mMainView);
+ mWebViewController.onSetWebView(this, w);
// set the new one
mMainView = w;
@@ -1449,6 +1442,10 @@
return mMainView;
}
+ void setViewContainer(View container) {
+ mContainer = container;
+ }
+
View getViewContainer() {
return mContainer;
}
diff --git a/src/com/android/browser/TabControl.java b/src/com/android/browser/TabControl.java
index 2d90d23..9e669ce 100644
--- a/src/com/android/browser/TabControl.java
+++ b/src/com/android/browser/TabControl.java
@@ -600,20 +600,6 @@
return setCurrentTab(newTab, false);
}
- void pauseCurrentTab() {
- Tab t = getCurrentTab();
- if (t != null) {
- t.pause();
- }
- }
-
- void resumeCurrentTab() {
- Tab t = getCurrentTab();
- if (t != null) {
- t.resume();
- }
- }
-
/**
* If force is true, this method skips the check for newTab == current.
*/
diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java
index 7e54710..0aa09db 100644
--- a/src/com/android/browser/TitleBarXLarge.java
+++ b/src/com/android/browser/TitleBarXLarge.java
@@ -26,12 +26,9 @@
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
-import android.view.ContextMenu;
import android.view.LayoutInflater;
-import android.view.MenuInflater;
import android.view.View;
import android.view.View.OnClickListener;
-import android.view.View.OnFocusChangeListener;
import android.widget.ImageView;
import android.widget.TextView;
@@ -39,11 +36,10 @@
* tabbed title bar for xlarge screen browser
*/
public class TitleBarXLarge extends TitleBarBase
- implements UrlInputListener, OnClickListener, OnFocusChangeListener {
+ implements UrlInputListener, OnClickListener {
private static final int PROGRESS_MAX = 100;
- private Activity mActivity;
private UiController mUiController;
private Drawable mStopDrawable;
@@ -67,7 +63,6 @@
public TitleBarXLarge(Activity activity, UiController controller) {
super(activity);
- mActivity = activity;
mUiController = controller;
Resources resources = activity.getResources();
mStopDrawable = resources.getDrawable(R.drawable.ic_stop_normal);
@@ -106,25 +101,15 @@
mGoButton.setOnClickListener(this);
mClearButton.setOnClickListener(this);
mUrlFocused.setUrlInputListener(this);
- mUrlUnfocused.setOnFocusChangeListener(this);
mUrlFocused.setContainer(mFocusContainer);
+ mUrlFocused.setController(mUiController);
mUnfocusContainer.setOnClickListener(this);
}
- public void onFocusChange(View v, boolean hasFocus) {
- if (hasFocus) {
- setUrlMode(true);
- mUrlFocused.selectAll();
- mUrlFocused.requestFocus();
- mUrlFocused.setDropDownWidth(mUnfocusContainer.getWidth());
- mUrlFocused.setDropDownHorizontalOffset(-mUrlFocused.getLeft());
- }
- }
-
@Override
public void onClick(View v) {
if (mUnfocusContainer == v) {
- mUrlUnfocused.requestFocus();
+ setUrlMode(true);
} else if (mBackButton == v) {
mUiController.getCurrentTopWebView().goBack();
} else if (mForwardButton == v) {
@@ -190,6 +175,10 @@
private void setUrlMode(boolean focused) {
swapUrlContainer(focused);
if (focused) {
+ mUrlFocused.selectAll();
+ mUrlFocused.requestFocus();
+ mUrlFocused.setDropDownWidth(mUnfocusContainer.getWidth());
+ mUrlFocused.setDropDownHorizontalOffset(-mUrlFocused.getLeft());
mSearchButton.setVisibility(View.GONE);
mGoButton.setVisibility(View.VISIBLE);
} else {
@@ -203,13 +192,6 @@
mFocusContainer.setVisibility(focus ? View.VISIBLE : View.GONE);
}
- @Override
- public void createContextMenu(ContextMenu menu) {
- MenuInflater inflater = mActivity.getMenuInflater();
- inflater.inflate(R.menu.title_context, menu);
- mActivity.onCreateContextMenu(menu, this, null);
- }
-
private void search() {
setDisplayTitle("");
mUrlUnfocused.requestFocus();
diff --git a/src/com/android/browser/UI.java b/src/com/android/browser/UI.java
index 3a8a5cd..e7f67f2 100644
--- a/src/com/android/browser/UI.java
+++ b/src/com/android/browser/UI.java
@@ -58,6 +58,8 @@
public void attachTab(Tab tab);
+ public void onSetWebView(Tab tab, WebView view);
+
public void createSubWindow(Tab tab, WebView subWebView);
public void attachSubWindow(View subContainer);
diff --git a/src/com/android/browser/UiController.java b/src/com/android/browser/UiController.java
index dffebba..c74d74e 100644
--- a/src/com/android/browser/UiController.java
+++ b/src/com/android/browser/UiController.java
@@ -75,4 +75,6 @@
void endActionMode();
+ void shareCurrentPage();
+
}
diff --git a/src/com/android/browser/UrlInputView.java b/src/com/android/browser/UrlInputView.java
index 2e29f26..a4c2be3 100644
--- a/src/com/android/browser/UrlInputView.java
+++ b/src/com/android/browser/UrlInputView.java
@@ -20,8 +20,8 @@
import android.content.Context;
import android.content.res.Configuration;
+import android.text.TextUtils;
import android.util.AttributeSet;
-import android.view.ActionMode;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnFocusChangeListener;
@@ -35,7 +35,8 @@
* handling suggestions
*/
public class UrlInputView extends AutoCompleteTextView
- implements OnFocusChangeListener, OnEditorActionListener, CompletionListener {
+ implements OnFocusChangeListener, OnEditorActionListener,
+ CompletionListener {
private UrlInputListener mListener;
private InputMethodManager mInputManager;
@@ -65,11 +66,17 @@
super.setOnFocusChangeListener(this);
mAdapter = new SuggestionsAdapter(ctx, this);
setAdapter(mAdapter);
- setSelectAllOnFocus(false);
+ setSelectAllOnFocus(true);
onConfigurationChanged(ctx.getResources().getConfiguration());
setThreshold(1);
}
+ void setController(UiController controller) {
+ UrlSelectionActionMode urlSelectionMode
+ = new UrlSelectionActionMode(controller);
+ setCustomSelectionActionModeCallback(urlSelectionMode);
+ }
+
void setContainer(View container) {
mContainer = container;
}
@@ -108,12 +115,6 @@
}
@Override
- public ActionMode startActionMode(ActionMode.Callback callback) {
- // suppress selection action mode
- return null;
- }
-
- @Override
public void setOnFocusChangeListener(OnFocusChangeListener focusListener) {
mWrappedFocusListener = focusListener;
}
@@ -148,7 +149,7 @@
this.dismissDropDown();
this.setSelection(0,0);
mInputManager.hideSoftInputFromWindow(getWindowToken(), 0);
- if (url == null) {
+ if (TextUtils.isEmpty(url)) {
mListener.onDismiss();
} else {
mListener.onAction(url, extra);
diff --git a/src/com/android/browser/UrlSelectionActionMode.java b/src/com/android/browser/UrlSelectionActionMode.java
new file mode 100644
index 0000000..5636388
--- /dev/null
+++ b/src/com/android/browser/UrlSelectionActionMode.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.browser;
+
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuItem;
+
+public class UrlSelectionActionMode implements ActionMode.Callback {
+
+ private UiController mUiController;
+
+ public UrlSelectionActionMode(UiController controller) {
+ mUiController = controller;
+ }
+
+ // ActionMode.Callback implementation
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ mode.getMenuInflater().inflate(R.menu.url_selection, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.share:
+ mUiController.shareCurrentPage();
+ mode.finish();
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return true;
+ }
+
+}
diff --git a/src/com/android/browser/WebStorageSizeManager.java b/src/com/android/browser/WebStorageSizeManager.java
index dcf2f8b..5f76f72 100644
--- a/src/com/android/browser/WebStorageSizeManager.java
+++ b/src/com/android/browser/WebStorageSizeManager.java
@@ -16,17 +16,19 @@
package com.android.browser;
+import com.android.browser.preferences.WebsiteSettingsFragment;
+
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.StatFs;
+import android.preference.PreferenceActivity;
import android.util.Log;
import android.webkit.WebStorage;
import java.io.File;
-import java.util.Set;
/**
@@ -82,7 +84,7 @@
* the user can free some of the Web storage space by deleting all the data used
* by an origin.
*/
-class WebStorageSizeManager {
+public class WebStorageSizeManager {
// Logging flags.
private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
@@ -346,7 +348,7 @@
// Reset the notification time; we use this iff the user
// use clear all; we reset it to some time in the future instead
// of just setting it to -1, as the clear all method is asynchronous
- static void resetLastOutOfSpaceNotificationTime() {
+ public static void resetLastOutOfSpaceNotificationTime() {
mLastOutOfSpaceNotificationTime = System.currentTimeMillis() -
NOTIFICATION_INTERVAL + RESET_NOTIFICATION_INTERVAL;
}
@@ -403,7 +405,9 @@
CharSequence text = mContext.getString(
R.string.webstorage_outofspace_notification_text);
long when = System.currentTimeMillis();
- Intent intent = new Intent(mContext, WebsiteSettingsActivity.class);
+ Intent intent = new Intent(mContext, BrowserPreferencesPage.class);
+ intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT,
+ WebsiteSettingsFragment.class.getName());
PendingIntent contentIntent =
PendingIntent.getActivity(mContext, 0, intent, 0);
Notification notification = new Notification(icon, title, when);
diff --git a/src/com/android/browser/WebViewController.java b/src/com/android/browser/WebViewController.java
index eeeee18..11a6959 100644
--- a/src/com/android/browser/WebViewController.java
+++ b/src/com/android/browser/WebViewController.java
@@ -42,6 +42,8 @@
WebViewFactory getWebViewFactory();
+ void onSetWebView(Tab tab, WebView view);
+
void createSubWindow(Tab tab);
void onPageStarted(Tab tab, WebView view, String url, Bitmap favicon);
diff --git a/src/com/android/browser/preferences/AdvancedPreferencesFragment.java b/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
index 59b6ce1..952e04a 100644
--- a/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
+++ b/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
@@ -18,9 +18,7 @@
import com.android.browser.BrowserSettings;
import com.android.browser.R;
-import com.android.browser.WebsiteSettingsActivity;
-import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
@@ -44,8 +42,7 @@
PreferenceScreen websiteSettings = (PreferenceScreen) findPreference(
BrowserSettings.PREF_WEBSITE_SETTINGS);
- Intent intent = new Intent(getActivity(), WebsiteSettingsActivity.class);
- websiteSettings.setIntent(intent);
+ websiteSettings.setFragment(WebsiteSettingsFragment.class.getName());
}
/*
diff --git a/src/com/android/browser/preferences/PersonalPreferencesFragment.java b/src/com/android/browser/preferences/PersonalPreferencesFragment.java
index a0c8ea0..0620df2 100644
--- a/src/com/android/browser/preferences/PersonalPreferencesFragment.java
+++ b/src/com/android/browser/preferences/PersonalPreferencesFragment.java
@@ -81,14 +81,14 @@
refreshUi(context);
}
- private class GetAccountsTask extends AsyncTask<Void, Void, Void> {
+ private class GetAccountsTask extends AsyncTask<Void, Void, String> {
private Context mContext;
GetAccountsTask(Context ctx) {
mContext = ctx;
}
- protected Void doInBackground(Void... unused) {
+ protected String doInBackground(Void... unused) {
AccountManager am = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
Account[] accounts = am.getAccountsByType("com.google");
if (accounts == null || accounts.length == 0) {
@@ -97,26 +97,34 @@
getPreferenceScreen().removePreference(mChromeSync);
}
} else {
+ // Google accounts are present.
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
Bundle args = mChromeSync.getExtras();
args.putParcelableArray("accounts", accounts);
mEnabled = BrowserContract.Settings.isSyncEnabled(mContext);
+ mChromeSync.setOnPreferenceClickListener(PersonalPreferencesFragment.this);
+
if (!mEnabled) {
- // Google accounts are present, but Chrome sync isn't enabled yet.
// Setup a link to the enable wizard
- mChromeSync.setSummary(R.string.pref_personal_sync_with_chrome_summary);
+ return mContext.getResources().getString(
+ R.string.pref_personal_sync_with_chrome_summary);
} else {
// Chrome sync is enabled, setup a link to account switcher
- String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME,
- null);
- mChromeSync.setSummary(accountName);
+ String accountName = prefs.getString(
+ BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
args.putString("curAccount", accountName);
+ return accountName;
}
- mChromeSync.setOnPreferenceClickListener(PersonalPreferencesFragment.this);
}
return null;
}
+
+ protected void onPostExecute(String summary) {
+ if (summary != null) {
+ mChromeSync.setSummary(summary);
+ }
+ }
}
void refreshUi(Context context) {
diff --git a/src/com/android/browser/WebsiteSettingsActivity.java b/src/com/android/browser/preferences/WebsiteSettingsFragment.java
similarity index 86%
rename from src/com/android/browser/WebsiteSettingsActivity.java
rename to src/com/android/browser/preferences/WebsiteSettingsFragment.java
index 95f8fb0..1965ffe 100644
--- a/src/com/android/browser/WebsiteSettingsActivity.java
+++ b/src/com/android/browser/preferences/WebsiteSettingsFragment.java
@@ -14,56 +14,62 @@
* limitations under the License.
*/
-package com.android.browser;
+package com.android.browser.preferences;
+
+import com.android.browser.R;
+import com.android.browser.WebStorageSizeManager;
import android.app.AlertDialog;
-import android.app.ListActivity;
+import android.app.FragmentTransaction;
+import android.app.ListFragment;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
import android.provider.BrowserContract.Bookmarks;
import android.util.Log;
-import android.view.KeyEvent;
import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.webkit.GeolocationPermissions;
import android.webkit.ValueCallback;
-import android.webkit.WebIconDatabase;
import android.webkit.WebStorage;
-import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
+import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
-import java.util.Vector;
/**
* Manage the settings for an origin.
* We use it to keep track of the 'HTML5' settings, i.e. database (webstorage)
* and Geolocation.
*/
-public class WebsiteSettingsActivity extends ListActivity {
+public class WebsiteSettingsFragment extends ListFragment implements OnClickListener {
+ private static final String EXTRA_SITE = "site";
private String LOGTAG = "WebsiteSettingsActivity";
private static String sMBStored = null;
private SiteAdapter mAdapter = null;
+ private Site mSite = null;
- static class Site {
+ static class Site implements Serializable {
private String mOrigin;
private String mTitle;
private Bitmap mIcon;
@@ -169,6 +175,10 @@
private Site mCurrentSite;
public SiteAdapter(Context context, int rsc) {
+ this(context, rsc, null);
+ }
+
+ public SiteAdapter(Context context, int rsc, Site site) {
super(context, rsc);
mResource = rsc;
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -184,7 +194,10 @@
R.drawable.ic_list_gps_on);
mLocationDisallowedIcon = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_list_gps_denied);
- askForOrigins();
+ mCurrentSite = site;
+ if (mCurrentSite == null) {
+ askForOrigins();
+ }
}
/**
@@ -409,6 +422,7 @@
}
}
+ @Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
final TextView title;
@@ -434,7 +448,6 @@
locationIcon.setVisibility(View.GONE);
if (mCurrentSite == null) {
- setTitle(getString(R.string.pref_extras_website_settings));
Site site = getItem(position);
title.setText(site.getPrettyTitle());
@@ -494,7 +507,6 @@
locationIcon.setVisibility(View.GONE);
usageIcon.setVisibility(View.GONE);
featureIcon.setVisibility(View.VISIBLE);
- setTitle(mCurrentSite.getPrettyTitle());
String origin = mCurrentSite.getOrigin();
switch (mCurrentSite.getFeatureByIndex(position)) {
case Site.FEATURE_WEB_STORAGE:
@@ -551,7 +563,7 @@
// origins list.
mCurrentSite.removeFeature(Site.FEATURE_WEB_STORAGE);
if (mCurrentSite.getFeatureCount() == 0) {
- mCurrentSite = null;
+ finish();
}
askForOrigins();
notifyDataSetChanged();
@@ -570,7 +582,7 @@
GeolocationPermissions.getInstance().clear(mCurrentSite.getOrigin());
mCurrentSite.removeFeature(Site.FEATURE_GEOLOCATION);
if (mCurrentSite.getFeatureCount() == 0) {
- mCurrentSite = null;
+ finish();
}
askForOrigins();
notifyDataSetChanged();
@@ -581,8 +593,14 @@
break;
}
} else {
- mCurrentSite = (Site) view.getTag();
- notifyDataSetChanged();
+ Site site = (Site) view.getTag();
+ PreferenceActivity activity = (PreferenceActivity) getActivity();
+ if (activity != null) {
+ Bundle args = new Bundle();
+ args.putSerializable(EXTRA_SITE, site);
+ activity.startPreferencePanel(WebsiteSettingsFragment.class.getName(), args, 0,
+ site.getPrettyTitle(), null, 0);
+ }
}
}
@@ -591,67 +609,64 @@
}
}
- /**
- * Intercepts the back key to immediately notify
- * NativeDialog that we are done.
- */
- public boolean dispatchKeyEvent(KeyEvent event) {
- if ((event.getKeyCode() == KeyEvent.KEYCODE_BACK)
- && (event.getAction() == KeyEvent.ACTION_DOWN)) {
- if ((mAdapter != null) && (mAdapter.backKeyPressed())){
- return true; // event consumed
- }
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.website_settings, container, false);
+ Bundle args = getArguments();
+ if (args != null) {
+ mSite = (Site) args.getSerializable(EXTRA_SITE);
}
- return super.dispatchKeyEvent(event);
+ if (mSite == null) {
+ View clear = view.findViewById(R.id.clear_all_button);
+ clear.setVisibility(View.VISIBLE);
+ clear.setOnClickListener(this);
+ }
+ return view;
}
@Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
if (sMBStored == null) {
sMBStored = getString(R.string.webstorage_origin_summary_mb_stored);
}
- mAdapter = new SiteAdapter(this, R.layout.website_settings_row);
- setListAdapter(mAdapter);
+ mAdapter = new SiteAdapter(getActivity(), R.layout.website_settings_row);
+ if (mSite != null) {
+ mAdapter.mCurrentSite = mSite;
+ }
+ getListView().setAdapter(mAdapter);
getListView().setOnItemClickListener(mAdapter);
}
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.websitesettings, menu);
- return true;
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- // If we are not on the sites list (rather on the page for a specific site) or
- // we aren't listing any sites hide the clear all button (and hence the menu).
- return mAdapter.currentSite() == null && mAdapter.getCount() > 0;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.website_settings_menu_clear_all:
- // Show the prompt to clear all origins of their data and geolocation permissions.
- new AlertDialog.Builder(this)
- .setTitle(R.string.website_settings_clear_all_dialog_title)
- .setMessage(R.string.website_settings_clear_all_dialog_message)
- .setPositiveButton(R.string.website_settings_clear_all_dialog_ok_button,
- new AlertDialog.OnClickListener() {
- public void onClick(DialogInterface dlg, int which) {
- WebStorage.getInstance().deleteAllData();
- GeolocationPermissions.getInstance().clearAll();
- WebStorageSizeManager.resetLastOutOfSpaceNotificationTime();
- mAdapter.askForOrigins();
- finish();
- }})
- .setNegativeButton(R.string.website_settings_clear_all_dialog_cancel_button, null)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .show();
- return true;
+ private void finish() {
+ PreferenceActivity activity = (PreferenceActivity) getActivity();
+ if (activity != null) {
+ activity.finishPreferencePanel(this, 0, null);
}
- return false;
+ }
+
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.clear_all_button:
+ // Show the prompt to clear all origins of their data and geolocation permissions.
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.website_settings_clear_all_dialog_title)
+ .setMessage(R.string.website_settings_clear_all_dialog_message)
+ .setPositiveButton(R.string.website_settings_clear_all_dialog_ok_button,
+ new AlertDialog.OnClickListener() {
+ public void onClick(DialogInterface dlg, int which) {
+ WebStorage.getInstance().deleteAllData();
+ GeolocationPermissions.getInstance().clearAll();
+ WebStorageSizeManager.resetLastOutOfSpaceNotificationTime();
+ mAdapter.askForOrigins();
+ finish();
+ }})
+ .setNegativeButton(R.string.website_settings_clear_all_dialog_cancel_button, null)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .show();
+ break;
+ }
}
}
diff --git a/src/com/android/browser/widget/BookmarkListWidgetProvider.java b/src/com/android/browser/widget/BookmarkListWidgetProvider.java
index 04f7b07..2196ae0 100644
--- a/src/com/android/browser/widget/BookmarkListWidgetProvider.java
+++ b/src/com/android/browser/widget/BookmarkListWidgetProvider.java
@@ -26,7 +26,6 @@
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
-import android.util.Log;
import android.widget.RemoteViews;
/**
diff --git a/src/com/android/browser/widget/BookmarkListWidgetService.java b/src/com/android/browser/widget/BookmarkListWidgetService.java
index 14b52b7..8fbe807 100644
--- a/src/com/android/browser/widget/BookmarkListWidgetService.java
+++ b/src/com/android/browser/widget/BookmarkListWidgetService.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.Bitmap;
@@ -31,9 +32,8 @@
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.net.Uri;
-import android.os.Binder;
+import android.os.AsyncTask;
import android.os.Handler;
-import android.os.HandlerThread;
import android.preference.PreferenceManager;
import android.provider.BrowserContract;
import android.provider.BrowserContract.Bookmarks;
@@ -101,7 +101,6 @@
BookmarkFactory fac = mFactories.get(widgetId);
if (fac != null && folderId >= 0) {
fac.changeFolder(folderId);
- AppWidgetManager.getInstance(this).notifyAppWidgetViewDataChanged(widgetId, R.id.bookmarks_list);
}
}
return START_STICKY;
@@ -123,10 +122,11 @@
super.onChange(selfChange);
// Update all the bookmark widgets
- sendBroadcast(new Intent(
- BookmarkListWidgetProvider.ACTION_BOOKMARK_APPWIDGET_UPDATE,
- null, BookmarkListWidgetService.this,
- BookmarkListWidgetProvider.class));
+ if (mFactories != null) {
+ for (BookmarkFactory fac : mFactories.values()) {
+ fac.loadData();
+ }
+ }
}
}
@@ -137,7 +137,10 @@
Log.w(TAG, "Missing EXTRA_APPWIDGET_ID!");
return null;
} else {
- BookmarkFactory fac = new BookmarkFactory(this, widgetId);
+ BookmarkFactory fac = mFactories.get(widgetId);
+ if (fac == null) {
+ fac = new BookmarkFactory(getApplicationContext(), widgetId);
+ }
mFactories.put(widgetId, fac);
return fac;
}
@@ -152,13 +155,15 @@
}
}
- static class BookmarkFactory implements RemoteViewsService.RemoteViewsFactory {
+ static class BookmarkFactory implements RemoteViewsService.RemoteViewsFactory,
+ OnSharedPreferenceChangeListener {
private List<RenderResult> mBookmarks;
private Context mContext;
private int mWidgetId;
private String mAccountType;
private String mAccountName;
private Stack<Breadcrumb> mBreadcrumbs;
+ private LoadBookmarksTask mLoadTask;
public BookmarkFactory(Context context, int widgetId) {
mBreadcrumbs = new Stack<Breadcrumb>();
@@ -171,12 +176,14 @@
if (!mBreadcrumbs.empty() && mBreadcrumbs.peek().mId == folderId) {
mBreadcrumbs.pop();
+ loadData();
return;
}
for (RenderResult res : mBookmarks) {
if (res.mId == folderId) {
mBreadcrumbs.push(new Breadcrumb(res.mId, res.mTitle));
+ loadData();
break;
}
}
@@ -264,30 +271,55 @@
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
mAccountType = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null);
mAccountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
+ prefs.registerOnSharedPreferenceChangeListener(this);
loadData();
}
@Override
public void onDestroy() {
recycleBitmaps();
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ prefs.unregisterOnSharedPreferenceChangeListener(this);
}
@Override
public void onDataSetChanged() {
- loadData();
}
void loadData() {
- // Reset identity since this could be an IPC call
- long token = Binder.clearCallingIdentity();
- update();
- Binder.restoreCallingIdentity(token);
+ if (mLoadTask != null) {
+ mLoadTask.cancel(false);
+ }
+ mLoadTask = new LoadBookmarksTask();
+ mLoadTask.execute();
}
- void update() {
- recycleBitmaps();
+ class LoadBookmarksTask extends AsyncTask<Void, Void, List<RenderResult>> {
+ private Breadcrumb mFolder;
+
+ @Override
+ protected void onPreExecute() {
+ mFolder = mBreadcrumbs.empty() ? null : mBreadcrumbs.peek();
+ }
+
+ @Override
+ protected List<RenderResult> doInBackground(Void... params) {
+ return loadBookmarks(mFolder);
+ }
+
+ @Override
+ protected void onPostExecute(List<RenderResult> result) {
+ if (!isCancelled() && result != null) {
+ recycleBitmaps();
+ mBookmarks = result;
+ AppWidgetManager.getInstance(mContext)
+ .notifyAppWidgetViewDataChanged(mWidgetId, R.id.bookmarks_list);
+ }
+ }
+ }
+
+ List<RenderResult> loadBookmarks(Breadcrumb folder) {
String where = null;
- Breadcrumb folder = mBreadcrumbs.empty() ? null : mBreadcrumbs.peek();
Uri uri;
if (USE_FOLDERS) {
uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER;
@@ -301,18 +333,21 @@
if (!TextUtils.isEmpty(mAccountType) && !TextUtils.isEmpty(mAccountName)) {
uri = uri.buildUpon()
.appendQueryParameter(Bookmarks.PARAM_ACCOUNT_TYPE, mAccountType)
- .appendQueryParameter(Bookmarks.PARAM_ACCOUNT_NAME, mAccountName).build();
+ .appendQueryParameter(Bookmarks.PARAM_ACCOUNT_NAME, mAccountName)
+ .build();
}
Cursor c = null;
try {
c = mContext.getContentResolver().query(uri, PROJECTION,
where, null, null);
if (c != null) {
- mBookmarks = new ArrayList<RenderResult>(c.getCount() + 1);
+ ArrayList<RenderResult> bookmarks
+ = new ArrayList<RenderResult>(c.getCount() + 1);
if (folder != null) {
- RenderResult res = new RenderResult(folder.mId, folder.mTitle, null);
+ RenderResult res = new RenderResult(
+ folder.mId, folder.mTitle, null);
res.mIsFolder = true;
- mBookmarks.add(res);
+ bookmarks.add(res);
}
while (c.moveToNext()) {
long id = c.getLong(0);
@@ -328,8 +363,9 @@
blob, 0, blob.length, options);
}
res.mIsFolder = c.getInt(4) != 0;
- mBookmarks.add(res);
+ bookmarks.add(res);
}
+ return bookmarks;
}
} catch (IllegalStateException e) {
Log.e(TAG, "update bookmark widget", e);
@@ -338,6 +374,7 @@
c.close();
}
}
+ return null;
}
private void recycleBitmaps() {
@@ -351,6 +388,21 @@
}
}
}
+
+ @Override
+ public void onSharedPreferenceChanged(
+ SharedPreferences prefs, String key) {
+ if (BrowserBookmarksPage.PREF_ACCOUNT_TYPE.equals(key)) {
+ mAccountType = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null);
+ mBreadcrumbs.clear();
+ loadData();
+ }
+ if (BrowserBookmarksPage.PREF_ACCOUNT_NAME.equals(key)) {
+ mAccountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
+ mBreadcrumbs.clear();
+ loadData();
+ }
+ }
}
// Class containing the rendering information for a specific bookmark.
diff --git a/tests/assets/popular_urls.txt b/tests/assets/popular_urls.txt
new file mode 100644
index 0000000..70d0997
--- /dev/null
+++ b/tests/assets/popular_urls.txt
@@ -0,0 +1,4 @@
+http://google.com
+http://nytimes.com
+http://slashdot.org
+
diff --git a/tests/src/com/android/browser/JNIBindingsTestApp.java b/tests/src/com/android/browser/JNIBindingsTestApp.java
index 4c8802a..f4efa2c 100644
--- a/tests/src/com/android/browser/JNIBindingsTestApp.java
+++ b/tests/src/com/android/browser/JNIBindingsTestApp.java
@@ -50,6 +50,7 @@
private static final int MSG_WEBKIT_DATA_READY = 101;
private BrowserActivity mActivity = null;
+ private Controller mController = null;
private Instrumentation mInst = null;
private boolean mTestDone = false;
@@ -111,6 +112,7 @@
super.setUp();
mActivity = getActivity();
+ mController = mActivity.getController();
mInst = getInstrumentation();
mInst.waitForIdleSync();
@@ -147,7 +149,7 @@
* and wrapping the WebView's helper clients.
*/
void setUpBrowser() {
- Tab tab = mActivity.getTabControl().getCurrentTab();
+ Tab tab = mController.getTabControl().getCurrentTab();
WebView webView = tab.getWebView();
webView.addJavascriptInterface(new JNIBindingsTest(this), "JNIBindingsTest");
@@ -229,7 +231,7 @@
public void testJNIBindings() {
setUpBrowser();
- Tab tab = mActivity.getTabControl().getCurrentTab();
+ Tab tab = mController.getTabControl().getCurrentTab();
WebView webView = tab.getWebView();
webView.loadUrl("file://" + SDCARD_BINDINGS_TEST_HTML);
synchronized(this) {
diff --git a/tests/src/com/android/browser/PopularUrlsTest.java b/tests/src/com/android/browser/PopularUrlsTest.java
index 98a0e9f..ad1fe4f 100644
--- a/tests/src/com/android/browser/PopularUrlsTest.java
+++ b/tests/src/com/android/browser/PopularUrlsTest.java
@@ -17,11 +17,13 @@
package com.android.browser;
import android.app.Instrumentation;
+import android.content.Context;
import android.content.Intent;
+import android.content.res.AssetManager;
import android.net.Uri;
import android.net.http.SslError;
-import android.os.Environment;
import android.test.ActivityInstrumentationTestCase2;
+import android.text.TextUtils;
import android.util.Log;
import android.webkit.HttpAuthHandler;
import android.webkit.JsPromptResult;
@@ -35,6 +37,7 @@
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Iterator;
import java.util.LinkedList;
@@ -53,13 +56,13 @@
private final static String sInputFile = "popular_urls.txt";
private final static String sOutputFile = "test_output.txt";
private final static String sStatusFile = "test_status.txt";
- private final static File sExternalStorage = Environment.getExternalStorageDirectory();
private final static int PERF_LOOPCOUNT = 10;
private final static int STABILITY_LOOPCOUNT = 1;
private final static int PAGE_LOAD_TIMEOUT = 120000; // 2 minutes
private BrowserActivity mActivity = null;
+ private Controller mController = null;
private Instrumentation mInst = null;
private CountDownLatch mLatch = new CountDownLatch(1);
private RunStatus mStatus;
@@ -76,10 +79,11 @@
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("about:blank"));
setActivityIntent(i);
mActivity = getActivity();
+ mController = mActivity.getController();
mInst = getInstrumentation();
mInst.waitForIdleSync();
- mStatus = RunStatus.load();
+ mStatus = RunStatus.load(getInstrumentation().getContext());
}
@Override
@@ -91,16 +95,10 @@
super.tearDown();
}
- static BufferedReader getInputStream() throws FileNotFoundException {
- return getInputStream(sInputFile);
- }
-
- static BufferedReader getInputStream(String inputFile) throws FileNotFoundException {
- String path = sExternalStorage + File.separator + inputFile;
- FileReader fileReader = new FileReader(path);
- BufferedReader bufferedReader = new BufferedReader(fileReader);
-
- return bufferedReader;
+ BufferedReader getInputStream() throws IOException {
+ AssetManager assets = getInstrumentation().getContext().getAssets();
+ return new BufferedReader(
+ new InputStreamReader(assets.open(sInputFile)));
}
OutputStreamWriter getOutputStream() throws IOException {
@@ -108,10 +106,8 @@
}
OutputStreamWriter getOutputStream(String outputFile) throws IOException {
- String path = sExternalStorage + File.separator + outputFile;
-
- File file = new File(path);
-
+ File file = new File(getInstrumentation().getContext()
+ .getExternalFilesDir(null), outputFile);
return new FileWriter(file, mStatus.getIsRecovery());
}
@@ -120,7 +116,16 @@
* and wrapping the WebView's helper clients.
*/
void setUpBrowser() {
- Tab tab = mActivity.getTabControl().getCurrentTab();
+ mInst.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ setupBrowserInternal();
+ }
+ });
+ }
+
+ void setupBrowserInternal() {
+ Tab tab = mController.getTabControl().getCurrentTab();
WebView webView = tab.getWebView();
webView.setWebChromeClient(new TestWebChromeClient(webView.getWebChromeClient()) {
@@ -219,6 +224,7 @@
*/
@Override
public void onPageFinished(WebView view, String url) {
+ super.onPageFinished(view, url);
if (!pageLoadFinishCalled) {
pageLoadFinishCalled = true;
if (pageProgressFull) {
@@ -252,7 +258,7 @@
// try to stop page load
mInst.runOnMainSync(new Runnable(){
public void run() {
- mActivity.getTabControl().getCurrentTab().getWebView().stopLoading();
+ mController.getTabControl().getCurrentTab().getWebView().stopLoading();
}
});
// try to wait for count down latch again
@@ -270,8 +276,8 @@
private String url;
private boolean isRecovery;
- private RunStatus(String file) throws IOException {
- mFile = new File(file);
+ private RunStatus(File file) throws IOException {
+ mFile = file;
FileReader input = null;
BufferedReader reader = null;
isRecovery = false;
@@ -307,12 +313,13 @@
}
}
- public static RunStatus load() throws IOException {
- return load(sStatusFile);
+ public static RunStatus load(Context context) throws IOException {
+ return load(context, sStatusFile);
}
- public static RunStatus load(String file) throws IOException {
- return new RunStatus(sExternalStorage + File.separator + file);
+ public static RunStatus load(Context context, String file) throws IOException {
+ return new RunStatus(new File(
+ context.getExternalFilesDir(null), file));
}
public void write() throws IOException {
@@ -380,14 +387,16 @@
void loopUrls(BufferedReader input, OutputStreamWriter writer,
boolean clearCache, int loopCount)
throws IOException, InterruptedException {
- Tab tab = mActivity.getTabControl().getCurrentTab();
+ Tab tab = mController.getTabControl().getCurrentTab();
WebView webView = tab.getWebView();
List<String> pages = new LinkedList<String>();
String page;
while (null != (page = input.readLine())) {
- pages.add(page);
+ if (!TextUtils.isEmpty(page)) {
+ pages.add(page);
+ }
}
Iterator<String> iterator = pages.iterator();