Merge "Implement the psychic search engine."
diff --git a/res/drawable-mdpi/qc_background_normal.png b/res/drawable-mdpi/qc_background_normal.png
new file mode 100644
index 0000000..539b45d
--- /dev/null
+++ b/res/drawable-mdpi/qc_background_normal.png
Binary files differ
diff --git a/res/drawable-mdpi/qc_background_selected.png b/res/drawable-mdpi/qc_background_selected.png
new file mode 100644
index 0000000..c0a6efc
--- /dev/null
+++ b/res/drawable-mdpi/qc_background_selected.png
Binary files differ
diff --git a/res/layout-land/http_authentication.xml b/res/layout-land/http_authentication.xml
deleted file mode 100644
index 3fa7e4f..0000000
--- a/res/layout-land/http_authentication.xml
+++ /dev/null
@@ -1,65 +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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:orientation="vertical" >
-
- <TableLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="12dip"
- android:gravity="center_horizontal" >
-
- <TableRow>
- <TextView android:id="@+id/username_view"
- android:text="@string/username"
- android:gravity="right"
- android:layout_marginLeft="20dip" />
-
- <EditText android:id="@+id/username_edit"
- android:scrollHorizontally="true"
- android:autoText="false"
- android:capitalize="none"
- android:gravity="fill_horizontal"
- android:layout_weight="1"
- android:layout_marginLeft="10dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="12dip" />
- </TableRow>
-
- <TableRow>
- <TextView android:id="@+id/password_view"
- android:text="@string/password"
- android:gravity="right"
- android:layout_marginLeft="20dip" />
-
- <EditText android:id="@+id/password_edit"
- android:scrollHorizontally="true"
- android:autoText="false"
- android:capitalize="none"
- android:gravity="fill_horizontal"
- android:layout_weight="1"
- android:layout_marginLeft="10dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="12dip"
- android:password="true" />
- </TableRow>
- </TableLayout>
-
-</LinearLayout>
diff --git a/res/layout/http_authentication.xml b/res/layout/http_authentication.xml
index cee3a42..856c45c 100644
--- a/res/layout/http_authentication.xml
+++ b/res/layout/http_authentication.xml
@@ -14,49 +14,48 @@
limitations under the License.
-->
-<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:gravity="center_horizontal"
android:orientation="vertical"
>
<TextView
- android:id="@+id/username_view"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/username"
- android:gravity="left"
android:layout_marginTop="12dip"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip" />
<EditText
android:id="@+id/username_edit"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:scrollHorizontally="true"
android:inputType="text"
- android:gravity="fill_horizontal"
- android:layout_weight="1"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
- android:layout_marginBottom="12dip" />
+ android:layout_marginBottom="12dip"
+ android:singleLine="true"
+ android:imeOptions="actionNext" />
<TextView
- android:id="@+id/password_view"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/password"
- android:gravity="left"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip" />
<EditText
android:id="@+id/password_edit"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:scrollHorizontally="true"
android:inputType="textPassword"
- android:gravity="fill_horizontal"
- android:layout_weight="1"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
- android:layout_marginBottom="12dip" />
-</TableLayout>
+ android:layout_marginBottom="12dip"
+ android:singleLine="true"
+ android:imeOptions="actionDone" />
+</LinearLayout>
diff --git a/res/layout/url_bar.xml b/res/layout/url_bar.xml
index 4d8efdd..f2b32c4 100644
--- a/res/layout/url_bar.xml
+++ b/res/layout/url_bar.xml
@@ -51,19 +51,12 @@
android:orientation="horizontal"
android:background="@drawable/url_background">
<ImageView
- android:id="@+id/web_icon"
+ android:id="@+id/url_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_web_holo_dark"
style="@style/HoloIcon" />
<ImageView
- android:id="@+id/voice_icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:src="@drawable/ic_voice_search_holo_dark"
- style="@style/HoloIcon"
- android:visibility="gone" />
- <ImageView
android:id="@+id/lock"
android:layout_width="wrap_content"
android:layout_height="match_parent"
diff --git a/res/menu-xlarge/browser.xml b/res/menu-xlarge/browser.xml
index a791cdd..be4a521 100644
--- a/res/menu-xlarge/browser.xml
+++ b/res/menu-xlarge/browser.xml
@@ -32,6 +32,8 @@
android:title="@string/share_page"
android:icon="@drawable/ic_share_holo_dark"
android:alphabeticShortcut="s" />
+ <item android:id="@+id/save_webarchive_menu_id"
+ android:title="@string/menu_save_webarchive" />
<item android:id="@+id/page_info_menu_id"
android:title="@string/page_info"
android:icon="@drawable/ic_pageinfo_holo_dark"
@@ -44,8 +46,6 @@
android:title="@string/menu_preferences"
android:icon="@drawable/ic_settings_holo_dark"
android:alphabeticShortcut="p" />
- <item android:id="@+id/save_webarchive_menu_id"
- android:title="@string/menu_save_webarchive" />
<!-- followings are debug only -->
<item android:id="@+id/dump_nav_menu_id"
android:title="@string/dump_nav"
diff --git a/res/menu/browser.xml b/res/menu/browser.xml
index 7a59ffd..abe3716 100644
--- a/res/menu/browser.xml
+++ b/res/menu/browser.xml
@@ -45,6 +45,8 @@
android:title="@string/share_page"
android:icon="@drawable/ic_share_holo_dark"
android:alphabeticShortcut="s" />
+ <item android:id="@+id/save_webarchive_menu_id"
+ android:title="@string/menu_save_webarchive" />
<item android:id="@+id/page_info_menu_id"
android:title="@string/page_info"
android:icon="@drawable/ic_pageinfo_holo_dark"
@@ -57,8 +59,6 @@
android:title="@string/menu_preferences"
android:icon="@drawable/ic_settings_holo_dark"
android:alphabeticShortcut="p" />
- <item android:id="@+id/save_webarchive_menu_id"
- android:title="@string/menu_save_webarchive" />
<!-- followings are debug only -->
<item android:id="@+id/dump_nav_menu_id"
android:title="@string/dump_nav"
diff --git a/res/values/dimensions.xml b/res/values/dimensions.xml
index f0230bd..5054254 100644
--- a/res/values/dimensions.xml
+++ b/res/values/dimensions.xml
@@ -45,7 +45,6 @@
<dimen name="list_favicon_padding">5dip</dimen>
<dimen name="list_favicon_corner_radius">3dip</dimen>
<dimen name="tab_favicon_corner_radius">2dip</dimen>
- <dimen name="dropdown_offset">8dip</dimen>
<dimen name="widgetThumbnailHeight">104dip</dimen>
<dimen name="widgetHorizontalSpacing">14dip</dimen>
<dimen name="widgetVerticalSpacing">12dip</dimen>
diff --git a/res/values/integers.xml b/res/values/integers.xml
index a899a14..ad0ed90 100644
--- a/res/values/integers.xml
+++ b/res/values/integers.xml
@@ -25,4 +25,6 @@
<integer name="most_visits_limit">10</integer>
<!-- Animation durations -->
<integer name="comboViewFadeInDuration">400</integer>
+ <!-- fade between tabs duration -->
+ <integer name="tabFadeDuration">300</integer>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 321da95..893f02e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -235,12 +235,12 @@
<string name="copy_page_url">Copy page url</string>
<!-- Menu item -->
<string name="share_page">Share page</string>
- <!-- Menu item for saving a page as a web archive. -->
- <string name="menu_save_webarchive">Save as Web Archive</string>
- <!-- Toast informing the user that the page has been saved. -->
- <string name="webarchive_saved">Web archive saved.</string>
- <!-- Toast informing the user that saving the page has failed. -->
- <string name="webarchive_failed">Failed to save web archive.</string>
+ <!-- Menu item for saving a page. [CHAR LIMIT=30] -->
+ <string name="menu_save_webarchive">Save page</string>
+ <!-- Toast informing the user that the page has been saved. [CHAR LIMIT=50] -->
+ <string name="webarchive_saved">Page saved.</string>
+ <!-- Toast informing the user that saving the page has failed. [CHAR LIMIT=50] -->
+ <string name="webarchive_failed">Failed to save page.</string>
<!-- The number of bookmarks in a folder [CHAR LIMT=50] -->
<string name="contextheader_folder_bookmarkcount"><xliff:g id="bookmark_count">%d</xliff:g> bookmarks</string>
<!-- No bookmarks in the folder [CHAR LIMIT=50] -->
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index 15f07c6..c01ec06 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -19,6 +19,8 @@
import com.android.browser.Tab.LockIcon;
import com.android.browser.UI.DropdownChangeListener;
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.res.Configuration;
@@ -68,7 +70,7 @@
Activity mActivity;
UiController mUiController;
TabControl mTabControl;
- private Tab mActiveTab;
+ protected Tab mActiveTab;
private InputMethodManager mInputManager;
private Drawable mSecLockIcon;
@@ -221,12 +223,18 @@
}
@Override
- public void setActiveTab(Tab tab) {
+ public void setActiveTab(final Tab tab) {
+ setActiveTab(tab, true);
+ }
+
+ void setActiveTab(Tab tab, boolean needsAttaching) {
if ((tab != mActiveTab) && (mActiveTab != null)) {
removeTabFromContentView(mActiveTab);
}
mActiveTab = tab;
- attachTabToContentView(tab);
+ if (needsAttaching) {
+ attachTabToContentView(tab);
+ }
setShouldShowErrorConsole(tab, mUiController.shouldShowErrorConsole());
onTabDataChanged(tab);
onProgressChanged(tab);
@@ -260,7 +268,7 @@
attachTabToContentView(tab);
}
- private void attachTabToContentView(Tab tab) {
+ protected void attachTabToContentView(Tab tab) {
if ((tab == null) || (tab.getWebView() == null)) {
return;
}
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 5b655c4..e4b0a0c 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -489,7 +489,8 @@
case R.id.save_link_context_menu_id:
case R.id.download_context_menu_id:
DownloadHandler.onDownloadStartNoStream(
- mActivity, url, null, null, null);
+ mActivity, url, null, null, null,
+ view.isPrivateBrowsingEnabled());
break;
}
break;
@@ -963,9 +964,10 @@
@Override
public void onDownloadStart(Tab tab, String url, String userAgent,
String contentDisposition, String mimetype, long contentLength) {
+ WebView w = tab.getWebView();
DownloadHandler.onDownloadStart(mActivity, url, userAgent,
- contentDisposition, mimetype);
- if (tab.getWebView().copyBackForwardList().getSize() == 0) {
+ contentDisposition, mimetype, w.isPrivateBrowsingEnabled());
+ if (w.copyBackForwardList().getSize() == 0) {
// This Tab was opened for the sole purpose of downloading a
// file. Remove it.
if (tab == mTabControl.getCurrentTab()) {
@@ -1372,7 +1374,8 @@
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).
- setOnMenuItemClickListener(new Download(mActivity, extra));
+ setOnMenuItemClickListener(
+ new Download(mActivity, extra, webview.isPrivateBrowsingEnabled()));
menu.findItem(R.id.set_wallpaper_context_menu_id).
setOnMenuItemClickListener(new WallpaperHandler(mActivity,
extra));
@@ -1469,8 +1472,10 @@
newtab.setEnabled(getTabControl().canCreateNewTab());
MenuItem archive = menu.findItem(R.id.save_webarchive_menu_id);
- String url = w != null ? w.getUrl() : null;
- archive.setVisible(url != null && !url.endsWith(".webarchivexml"));
+ Tab tab = getTabControl().getCurrentTab();
+ String url = tab != null ? tab.getUrl() : null;
+ archive.setVisible(!TextUtils.isEmpty(url)
+ && !url.endsWith(".webarchivexml"));
break;
}
mCurrentMenuState = mMenuState;
@@ -1590,8 +1595,9 @@
Toast.LENGTH_SHORT).show();
break;
}
- WebView topWebView = getCurrentTopWebView();
+ final WebView topWebView = getCurrentTopWebView();
final String title = topWebView.getTitle();
+ final String url = topWebView.getUrl();
topWebView.saveWebArchive(directory, true,
new ValueCallback<String>() {
@Override
@@ -1615,8 +1621,8 @@
return;
}
}
- Toast.makeText(mActivity,
- R.string.webarchive_failed, Toast.LENGTH_SHORT).show();
+ DownloadHandler.onDownloadStartNoStream(mActivity,
+ url, null, null, null, topWebView.isPrivateBrowsingEnabled());
}
});
break;
@@ -2044,16 +2050,18 @@
private static class Download implements OnMenuItemClickListener {
private Activity mActivity;
private String mText;
+ private boolean mPrivateBrowsing;
public boolean onMenuItemClick(MenuItem item) {
DownloadHandler.onDownloadStartNoStream(mActivity, mText, null,
- null, null);
+ null, null, mPrivateBrowsing);
return true;
}
- public Download(Activity activity, String toDownload) {
+ public Download(Activity activity, String toDownload, boolean privateBrowsing) {
mActivity = activity;
mText = toDownload;
+ mPrivateBrowsing = privateBrowsing;
}
}
diff --git a/src/com/android/browser/DownloadHandler.java b/src/com/android/browser/DownloadHandler.java
index 4903a41..17ad320 100644
--- a/src/com/android/browser/DownloadHandler.java
+++ b/src/com/android/browser/DownloadHandler.java
@@ -53,9 +53,11 @@
* @param userAgent User agent of the downloading application.
* @param contentDisposition Content-disposition http header, if present.
* @param mimetype The mimetype of the content reported by the server
+ * @param privateBrowsing If the request is coming from a private browsing tab.
*/
public static void onDownloadStart(Activity activity, String url,
- String userAgent, String contentDisposition, String mimetype) {
+ String userAgent, String contentDisposition, String mimetype,
+ boolean privateBrowsing) {
// if we're dealing wih A/V content that's not explicitly marked
// for download, check if it's streamable.
if (contentDisposition == null
@@ -93,7 +95,7 @@
}
}
onDownloadStartNoStream(activity, url, userAgent, contentDisposition,
- mimetype);
+ mimetype, privateBrowsing);
}
// This is to work around the fact that java.net.URI throws Exceptions
@@ -134,10 +136,11 @@
* @param userAgent User agent of the downloading application.
* @param contentDisposition Content-disposition http header, if present.
* @param mimetype The mimetype of the content reported by the server
+ * @param privateBrowsing If the request is coming from a private browsing tab.
*/
/*package */ static void onDownloadStartNoStream(Activity activity,
String url, String userAgent, String contentDisposition,
- String mimetype) {
+ String mimetype, boolean privateBrowsing) {
String filename = URLUtil.guessFileName(url,
contentDisposition, mimetype);
@@ -198,7 +201,7 @@
request.setDescription(webAddress.getHost());
// XXX: Have to use the old url since the cookies were stored using the
// old percent-encoded url.
- String cookies = CookieManager.getInstance().getCookie(url);
+ String cookies = CookieManager.getInstance().getCookie(url, privateBrowsing);
request.addRequestHeader("cookie", cookies);
request.setNotificationVisibility(
DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
diff --git a/src/com/android/browser/HttpAuthenticationDialog.java b/src/com/android/browser/HttpAuthenticationDialog.java
index a9ba332..ac4119c 100644
--- a/src/com/android/browser/HttpAuthenticationDialog.java
+++ b/src/com/android/browser/HttpAuthenticationDialog.java
@@ -18,10 +18,13 @@
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
+import android.view.inputmethod.EditorInfo;
import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
/**
* HTTP authentication dialog.
@@ -109,6 +112,16 @@
View v = factory.inflate(R.layout.http_authentication, null);
mUsernameView = (TextView) v.findViewById(R.id.username_edit);
mPasswordView = (TextView) v.findViewById(R.id.password_edit);
+ mPasswordView.setOnEditorActionListener(new OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ mDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick();
+ return true;
+ }
+ return false;
+ }
+ });
String title = mContext.getText(R.string.sign_in_to).toString().replace(
"%s1", mHost).replace("%s2", mRealm);
diff --git a/src/com/android/browser/PieControl.java b/src/com/android/browser/PieControl.java
index 23dcced..2e2eba4 100644
--- a/src/com/android/browser/PieControl.java
+++ b/src/com/android/browser/PieControl.java
@@ -64,22 +64,22 @@
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
mPie.setLayoutParams(lp);
- mForward = makeMenuView(R.drawable.ic_pie_forward);
- mPie.addItem(mForward);
- mRefresh = makeMenuView(R.drawable.ic_pie_refresh);
- mPie.addItem(mRefresh);
+ mNewTab = makeMenuView(R.drawable.ic_pie_new_tab);
+ mPie.addItem(mNewTab);
mBack = makeMenuView(R.drawable.ic_pie_back);
mPie.addItem(mBack);
mUrl = makeMenuView(R.drawable.ic_pie_web);
mPie.addItem(mUrl);
mBookmarks = makeMenuView(R.drawable.ic_pie_bookmarks);
mPie.addItem(mBookmarks);
- mNewTab = makeMenuView(R.drawable.ic_pie_new_tab);
- mPie.addItem(mNewTab);
mOptions = makeMenuView(R.drawable.ic_pie_more);
mPie.addItem(mOptions);
- setClickListener(mBack, mForward, mRefresh, mUrl, mOptions,
- mBookmarks, mNewTab);
+ setClickListener(mBack,
+ mUrl,
+ mOptions,
+ mBookmarks,
+ mNewTab
+ );
mPie.setController(this);
}
container.addView(mPie);
diff --git a/src/com/android/browser/ScrollWebView.java b/src/com/android/browser/ScrollWebView.java
index 2bf07e1..d1dc25b 100644
--- a/src/com/android/browser/ScrollWebView.java
+++ b/src/com/android/browser/ScrollWebView.java
@@ -1,22 +1,24 @@
/*
* 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
+ * 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
+ * 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.
+ * 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.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
@@ -25,7 +27,7 @@
import java.util.Map;
/**
- * Manage WebView scroll events
+ * Manage WebView scroll events
*/
public class ScrollWebView extends WebView implements Runnable {
@@ -34,6 +36,9 @@
private boolean mBackgroundRemoved = false;
private boolean mUserInitiated = false;
private TitleBarBase mTitleBar;
+ private boolean mDrawCached = false;
+ private Bitmap mBitmap;
+ private Paint mCachePaint = new Paint();
/**
* @param context
@@ -51,8 +56,8 @@
* @param attrs
* @param defStyle
*/
- public ScrollWebView(Context context, AttributeSet attrs, int defStyle,
- boolean privateBrowsing) {
+ public ScrollWebView(
+ Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) {
super(context, attrs, defStyle, privateBrowsing);
}
@@ -97,6 +102,10 @@
}
}
+ public boolean hasTitleBar() {
+ return (mTitleBar != null);
+ }
+
@Override
public boolean onTouchEvent(MotionEvent evt) {
if (MotionEvent.ACTION_DOWN == evt.getActionMasked()) {
@@ -128,22 +137,46 @@
mScrollListener = l;
}
+ @Override
+ public void invalidate() {
+ if (!mDrawCached) {
+ super.invalidate();
+ }
+ }
+
// callback for scroll events
interface ScrollListener {
public void onScroll(int visibleTitleHeight, boolean userInitiated);
}
- @Override
- protected void onDraw(android.graphics.Canvas c) {
- super.onDraw(c);
- if (!mBackgroundRemoved && getRootView().getBackground() != null) {
- mBackgroundRemoved = true;
- post(new Runnable() {
- public void run() {
- getRootView().setBackgroundDrawable(null);
- }
- });
+ void setDrawCached(boolean cached) {
+ if (cached) {
+ buildDrawingCache();
+ mBitmap = getDrawingCache(false);
+ mDrawCached = (mBitmap != null);
+ } else {
+ mBitmap = null;
+ destroyDrawingCache();
+ mDrawCached = false;
}
}
+
+ @Override
+ protected void onDraw(android.graphics.Canvas c) {
+ if (mDrawCached) {
+ c.drawBitmap(mBitmap, getScrollX(), getScrollY(), mCachePaint);
+ } else {
+ super.onDraw(c);
+ if (!mBackgroundRemoved && getRootView().getBackground() != null) {
+ mBackgroundRemoved = true;
+ post(new Runnable() {
+ public void run() {
+ getRootView().setBackgroundDrawable(null);
+ }
+ });
+ }
+ }
+ }
+
}
diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java
index f4ba9db..8a715b1 100644
--- a/src/com/android/browser/TitleBarXLarge.java
+++ b/src/com/android/browser/TitleBarXLarge.java
@@ -58,15 +58,14 @@
private ImageButton mBackButton;
private ImageButton mForwardButton;
private ImageView mStar;
- private ImageView mWebIcon;
- private View mSearchButton;
+ private ImageView mUrlIcon;
+ private ImageView mSearchButton;
private View mUrlContainer;
private View mGoButton;
private ImageView mStopButton;
private View mAllButton;
private View mClearButton;
- private View mVoiceSearch;
- private View mVoiceSearchIndicator;
+ private ImageView mVoiceSearch;
private PageProgressView mProgressView;
private Drawable mFocusDrawable;
private Drawable mUnfocusDrawable;
@@ -112,17 +111,16 @@
// back/forward. Probably should be done inside onPageStarted.
mBackButton = (ImageButton) findViewById(R.id.back);
mForwardButton = (ImageButton) findViewById(R.id.forward);
- mWebIcon = (ImageView) findViewById(R.id.web_icon);
+ mUrlIcon = (ImageView) findViewById(R.id.url_icon);
mStar = (ImageView) findViewById(R.id.star);
mStopButton = (ImageView) findViewById(R.id.stop);
- mSearchButton = findViewById(R.id.search);
+ mSearchButton = (ImageView) findViewById(R.id.search);
mLockIcon = (ImageView) findViewById(R.id.lock);
mGoButton = findViewById(R.id.go);
mClearButton = findViewById(R.id.clear);
- mVoiceSearch = findViewById(R.id.voicesearch);
+ mVoiceSearch = (ImageView) findViewById(R.id.voicesearch);
mProgressView = (PageProgressView) findViewById(R.id.progress);
mUrlContainer = findViewById(R.id.urlbar_focused);
- mVoiceSearchIndicator = findViewById(R.id.voice_icon);
mBackButton.setOnClickListener(this);
mForwardButton.setOnClickListener(this);
mStar.setOnClickListener(this);
@@ -173,17 +171,6 @@
mUseQuickControls = useQuickControls;
mUrlInput.setUseQuickControls(mUseQuickControls);
setLayoutParams(makeLayoutParams());
- if (mUseQuickControls) {
- mBackButton.setVisibility(View.GONE);
- mForwardButton.setVisibility(View.GONE);
- mStopButton.setVisibility(View.GONE);
- mAllButton.setVisibility(View.GONE);
- } else {
- mBackButton.setVisibility(View.VISIBLE);
- mForwardButton.setVisibility(View.VISIBLE);
- mStopButton.setVisibility(View.VISIBLE);
- mAllButton.setVisibility(View.VISIBLE);
- }
}
void setShowProgressOnly(boolean progress) {
@@ -210,6 +197,9 @@
} else if (!mUrlInput.needsUpdate()) {
mUrlInput.dismissDropDown();
mUrlInput.hideIME();
+ if (mUseQuickControls) {
+ mUi.hideTitleBar();
+ }
}
mUrlInput.clearNeedsUpdate();
}
@@ -294,23 +284,21 @@
mSearchButton.setVisibility(View.GONE);
mStar.setVisibility(View.GONE);
mClearButton.setVisibility(View.VISIBLE);
- if (mInVoiceMode) {
- mVoiceSearchIndicator.setVisibility(View.VISIBLE);
- }
- mWebIcon.setImageResource(R.drawable.ic_search_holo_dark);
+ mUrlIcon.setImageResource(R.drawable.ic_search_holo_dark);
updateSearchMode(false);
} else {
mGoButton.setVisibility(View.GONE);
mVoiceSearch.setVisibility(View.GONE);
mStar.setVisibility(View.VISIBLE);
mClearButton.setVisibility(View.GONE);
- mVoiceSearchIndicator.setVisibility(View.GONE);
if (mUseQuickControls) {
mSearchButton.setVisibility(View.GONE);
} else {
mSearchButton.setVisibility(View.VISIBLE);
}
- mWebIcon.setImageResource(R.drawable.ic_web_holo_dark);
+ mUrlIcon.setImageResource(mInVoiceMode ?
+ R.drawable.ic_search_holo_dark
+ : R.drawable.ic_web_holo_dark);
}
}
@@ -392,9 +380,7 @@
public void setInVoiceMode(boolean voicemode, List<String> voiceResults) {
mInVoiceMode = voicemode;
mUrlInput.setVoiceResults(voiceResults);
- mVoiceSearchIndicator.setVisibility(mInVoiceMode
- ? View.VISIBLE : View.GONE);
- mWebIcon.setVisibility(mInVoiceMode ? View.GONE : View.VISIBLE);
+ mUrlIcon.setImageDrawable(mSearchButton.getDrawable());
}
@Override
diff --git a/src/com/android/browser/UrlInputView.java b/src/com/android/browser/UrlInputView.java
index 5e6684d..b7f2bff 100644
--- a/src/com/android/browser/UrlInputView.java
+++ b/src/com/android/browser/UrlInputView.java
@@ -61,7 +61,6 @@
private View mContainer;
private boolean mLandscape;
private boolean mIncognitoMode;
- private int mVOffset;
private boolean mNeedsUpdate;
private DropdownChangeListener mDropdownListener;
@@ -89,7 +88,6 @@
onConfigurationChanged(ctx.getResources().getConfiguration());
setThreshold(1);
setOnItemClickListener(this);
- mVOffset = 0;
mNeedsUpdate = false;
mDropdownListener = null;
@@ -130,9 +128,6 @@
}
void setUseQuickControls(boolean useQuickControls) {
- mVOffset = (useQuickControls
- ? (int) getResources().getDimension(R.dimen.dropdown_offset)
- : 0);
mAdapter.setReverseResults(useQuickControls);
}
@@ -180,7 +175,6 @@
if (getLeft() != -getDropDownHorizontalOffset()) {
setDropDownHorizontalOffset(-getLeft());
}
- setDropDownVerticalOffset(mVOffset);
}
@Override
diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java
index 5127ff3..33151f7 100644
--- a/src/com/android/browser/XLargeUi.java
+++ b/src/com/android/browser/XLargeUi.java
@@ -19,6 +19,9 @@
import com.android.browser.ScrollWebView.ScrollListener;
import com.android.browser.UI.DropdownChangeListener;
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.ObjectAnimator;
import android.app.ActionBar;
import android.app.Activity;
import android.content.pm.PackageManager;
@@ -30,6 +33,7 @@
import android.view.View;
import android.webkit.WebChromeClient.CustomViewCallback;
import android.webkit.WebView;
+import android.widget.FrameLayout;
import java.util.List;
@@ -205,11 +209,57 @@
}
@Override
- public void setActiveTab(Tab tab) {
- if (mTitleBar.isEditingUrl()) {
- mTitleBar.stopEditingUrl();
+ public void setActiveTab(final Tab tab) {
+ if ((tab != mActiveTab) && (mActiveTab != null)) {
+ // animate between the two
+ final ScrollWebView fromWV = (ScrollWebView) mActiveTab.getWebView();
+ fromWV.setDrawCached(true);
+ fromWV.setEmbeddedTitleBar(null);
+ final ScrollWebView toWV = (ScrollWebView) tab.getWebView();
+ if (!mUseQuickControls) {
+ if (mTitleBar.getParent() == null) {
+ toWV.setEmbeddedTitleBar(mTitleBar);
+ }
+ }
+ toWV.setDrawCached(true);
+ attachTabToContentView(tab);
+ super.setActiveTab(tab, false);
+ ObjectAnimator transition = ObjectAnimator.ofFloat(
+ toWV, "alpha", 0f, 1f);
+ transition.setDuration(mActivity.getResources()
+ .getInteger(R.integer.tabFadeDuration));
+ transition.addListener(new AnimatorListener() {
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ fromWV.setDrawCached(false);
+ toWV.setDrawCached(false);
+ setActiveTab(tab, false);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ fromWV.setDrawCached(false);
+ toWV.setDrawCached(false);
+ setActiveTab(tab, false);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ }
+ });
+ transition.start();
+ } else {
+ super.setActiveTab(tab, true);
+ setActiveTab(tab, true);
}
- super.setActiveTab(tab);
+ }
+
+ @Override
+ void setActiveTab(Tab tab, boolean needsAttaching) {
ScrollWebView view = (ScrollWebView) tab.getWebView();
// TabControl.setCurrentTab has been called before this,
// so the tab is guaranteed to have a webview
@@ -223,7 +273,10 @@
view.setScrollListener(null);
mTabBar.showTitleBarIndicator(false);
} else {
- view.setEmbeddedTitleBar(mTitleBar);
+ // check if title bar is already attached by animation
+ if (mTitleBar.getParent() == null) {
+ view.setEmbeddedTitleBar(mTitleBar);
+ }
view.setScrollListener(this);
}
mTabBar.onSetActiveTab(tab);
@@ -282,7 +335,6 @@
protected void showTitleBar() {
if (canShowTitleBar()) {
if (mUseQuickControls) {
- setTitleGravity(Gravity.BOTTOM);
mContentView.addView(mTitleBar);
} else {
setTitleGravity(Gravity.TOP);
@@ -296,9 +348,10 @@
protected void hideTitleBar() {
if (isTitleBarShowing()) {
mTabBar.onHideTitleBar();
- setTitleGravity(Gravity.NO_GRAVITY);
if (mUseQuickControls) {
mContentView.removeView(mTitleBar);
+ } else {
+ setTitleGravity(Gravity.NO_GRAVITY);
}
super.hideTitleBar();
}
@@ -313,6 +366,18 @@
return mTitleBar;
}
+ @Override
+ protected void setTitleGravity(int gravity) {
+ if (mUseQuickControls) {
+ FrameLayout.LayoutParams lp =
+ (FrameLayout.LayoutParams) mTitleBar.getLayoutParams();
+ lp.gravity = gravity;
+ mTitleBar.setLayoutParams(lp);
+ } else {
+ super.setTitleGravity(gravity);
+ }
+ }
+
// action mode callbacks
@Override
diff --git a/src/com/android/browser/preferences/GeneralPreferencesFragment.java b/src/com/android/browser/preferences/GeneralPreferencesFragment.java
index 1c82e1c..9c763e9 100644
--- a/src/com/android/browser/preferences/GeneralPreferencesFragment.java
+++ b/src/com/android/browser/preferences/GeneralPreferencesFragment.java
@@ -426,7 +426,8 @@
// Re-parent the existing bookmarks to the newly create bookmarks bar folder
ops.add(ContentProviderOperation.newUpdate(Bookmarks.CONTENT_URI)
.withValueBackReference(Bookmarks.PARENT, 2)
- .withSelection(Bookmarks.PARENT + "=?",
+ .withSelection(Bookmarks.ACCOUNT_NAME + " IS NULL AND " +
+ Bookmarks.PARENT + "=?",
new String[] { Integer.toString(1) })
.build());
diff --git a/src/com/android/browser/view/PieMenu.java b/src/com/android/browser/view/PieMenu.java
index 5185adb..080c257 100644
--- a/src/com/android/browser/view/PieMenu.java
+++ b/src/com/android/browser/view/PieMenu.java
@@ -20,15 +20,21 @@
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
import android.graphics.Canvas;
+import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.graphics.Shader;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -64,6 +70,17 @@
private boolean mDirty;
+ private Drawable mActiveDrawable;
+ private Drawable mInactiveDrawable;
+ private final Paint mActiveShaderPaint = new Paint();
+ private final Paint mInactiveShaderPaint = new Paint();
+ private final Matrix mActiveMatrix = new Matrix();
+ private final Matrix mInactiveMatrix = new Matrix();
+
+ private BitmapShader mActiveShader;
+ private BitmapShader mInactiveShader;
+
+
/**
* @param context
* @param attrs
@@ -111,6 +128,37 @@
setDrawingCacheEnabled(false);
mCenter = new Point(0,0);
mDirty = true;
+ mActiveShaderPaint.setStyle(Paint.Style.FILL);
+ mActiveShaderPaint.setAntiAlias(true);
+
+ mInactiveShaderPaint.setStyle(Paint.Style.FILL);
+ mInactiveShaderPaint.setAntiAlias(true);
+ mActiveDrawable = res.getDrawable(R.drawable.qc_background_selected);
+ mInactiveDrawable = res.getDrawable(R.drawable.qc_background_normal);
+
+ Bitmap activeTexture = getDrawableAsBitmap(mActiveDrawable,
+ mActiveDrawable.getIntrinsicWidth(),
+ mActiveDrawable.getIntrinsicHeight());
+ Bitmap inactiveTexture = getDrawableAsBitmap(mInactiveDrawable,
+ mInactiveDrawable.getIntrinsicWidth(),
+ mInactiveDrawable.getIntrinsicHeight());
+
+ mActiveShader = new BitmapShader(activeTexture,
+ Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+ mActiveShaderPaint.setShader(mActiveShader);
+
+ mInactiveShader = new BitmapShader(inactiveTexture,
+ Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+ mInactiveShaderPaint.setShader(mInactiveShader);
+
+ }
+
+ private static Bitmap getDrawableAsBitmap(Drawable drawable, int width, int height) {
+ Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(b);
+ drawable.setBounds(0, 0, width, height);
+ drawable.draw(c);
+ return b;
}
public void setController(PieController ctl) {
@@ -268,10 +316,15 @@
tag.sweep = sweep;
tag.inner = inner;
tag.outer = outer;
-
- Paint p = item.isPressed() ? mSelectedPaint : mPaint;
- canvas.drawPath(slice, p);
int state = canvas.save();
+ int[] topLeft = new int[2];
+ getLocationInWindow(topLeft);
+ topLeft[0] = mCenter.x - outer;
+ topLeft[1] = mCenter.y - outer;
+ Paint paint = item.isPressed() ? mActiveShaderPaint : mInactiveShaderPaint;
+ drawClipped(canvas, paint, slice, topLeft, item.isPressed());
+ canvas.restoreToCount(state);
+ state = canvas.save();
if (onTheLeft()) {
canvas.scale(-1, 1);
}
@@ -287,6 +340,16 @@
return newanchor;
}
+ private void drawClipped(Canvas canvas, Paint paint, Path clipPath, int[] pos,
+ boolean selected) {
+ // TODO: We should change the matrix/shader only when needed
+ final Matrix matrix = selected ? mActiveMatrix : mInactiveMatrix;
+ matrix.setTranslate(pos[0], pos[1]);
+ (selected ? mActiveShader : mInactiveShader).setLocalMatrix(matrix);
+ canvas.drawPath(clipPath, paint);
+ }
+
+
/**
* converts a
* @param angle from 0..PI to Android degrees (clockwise starting at 3 o'clock)
@@ -391,6 +454,7 @@
}
if (view != null) {
// clear up stack
+ playSoundEffect(SoundEffectConstants.CLICK);
MenuTag tag = (MenuTag) view.getTag();
int i = mStack.size() - 1;
while (i > 0) {