Merge "Refactor generation of SSL certificate dialogs"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d4d6467..bfed543 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -632,7 +632,7 @@
<string name="pref_lab_title">Labs</string>
<!-- Title for lab quick controls feature [CHAR LIMIT=40] -->
<string name="pref_lab_quick_controls">Quick controls</string>
- <!-- Summary for lab quick controls feature [CHAR LIMIT=80] -->
+ <!-- Summary for lab quick controls feature [CHAR LIMIT=120] -->
<string name="pref_lab_quick_controls_summary">
Slide thumb from the left or right edge to open quick controls and hide app and URL bars</string>
<!-- Title for the "Instant search" lab feature [CHAR LIMIT=40] -->
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index 3128934..ed21b20 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -34,10 +34,10 @@
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
-import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
@@ -89,8 +89,9 @@
protected FrameLayout mContentView;
protected FrameLayout mCustomViewContainer;
+ protected FrameLayout mFullscreenContainer;
- private CustomViewHolder mCustomView;
+ private View mCustomView;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
private int mOriginalOrientation;
@@ -119,7 +120,6 @@
browser.getSystemService(Activity.INPUT_METHOD_SERVICE);
mLockIconSecure = res.getDrawable(R.drawable.ic_secure_holo_dark);
mLockIconMixed = res.getDrawable(R.drawable.ic_secure_partial_holo_dark);
-
FrameLayout frameLayout = (FrameLayout) mActivity.getWindow()
.getDecorView().findViewById(android.R.id.content);
LayoutInflater.from(mActivity)
@@ -505,8 +505,6 @@
if (t != null) {
intent.putExtra(ComboViewActivity.EXTRA_CURRENT_URL, t.getUrl());
}
- intent.putExtra(ComboViewActivity.EXTRA_BOOKMARK_PAGE,
- mUiController.createBookmarkCurrentPageIntent(false));
mActivity.startActivityForResult(intent, Controller.COMBO_VIEW);
}
@@ -520,21 +518,11 @@
}
mOriginalOrientation = mActivity.getRequestedOrientation();
- WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
- WindowManager.LayoutParams params = new WindowManager.LayoutParams(
- WindowManager.LayoutParams.TYPE_APPLICATION,
- 0);
- params.x = 0;
- params.y = 0;
- params.width = LayoutParams.MATCH_PARENT;
- params.height = LayoutParams.MATCH_PARENT;
- params.systemUiVisibility = View.STATUS_BAR_HIDDEN;
- mCustomView = new CustomViewHolder(mActivity);
- view.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT));
- mCustomView.addView(view);
- wm.addView(mCustomView, params);
-
+ FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView();
+ mFullscreenContainer = new FullscreenHolder(mActivity);
+ mFullscreenContainer.addView(view, COVER_SCREEN_PARAMS);
+ decor.addView(mFullscreenContainer, COVER_SCREEN_PARAMS);
+ mCustomView = view;
mCustomViewCallback = callback;
mActivity.setRequestedOrientation(requestedOrientation);
}
@@ -543,10 +531,9 @@
public void onHideCustomView() {
if (mCustomView == null)
return;
-
- WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
- wm.removeView(mCustomView);
-
+ FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView();
+ decor.removeView(mFullscreenContainer);
+ mFullscreenContainer = null;
mCustomView = null;
mCustomViewCallback.onCustomViewHidden();
// Show the content view.
@@ -605,7 +592,10 @@
Drawable d = null;
if (securityState == SecurityState.SECURITY_STATE_SECURE) {
d = mLockIconSecure;
- } else if (securityState == SecurityState.SECURITY_STATE_MIXED) {
+ } else if (securityState == SecurityState.SECURITY_STATE_MIXED
+ || securityState == SecurityState.SECURITY_STATE_BAD_CERTIFICATE) {
+ // TODO: It would be good to have different icons for insecure vs mixed content.
+ // See http://b/5403800
d = mLockIconMixed;
}
mNavigationBar.setLock(d);
@@ -826,18 +816,17 @@
mUiController.hideCustomView();
}
- // custom FrameLayout to forward key events
- static class CustomViewHolder extends FrameLayout {
- Activity mActivity;
+ static class FullscreenHolder extends FrameLayout {
- public CustomViewHolder(Activity act) {
- super(act);
- mActivity = act;
+ public FullscreenHolder(Context ctx) {
+ super(ctx);
+ setBackgroundColor(ctx.getResources().getColor(R.color.black));
}
- public boolean dispatchKeyEvent(KeyEvent event) {
- return mActivity.dispatchKeyEvent(event);
+ @Override
+ public boolean onTouchEvent(MotionEvent evt) {
+ return true;
}
+
}
-
}
diff --git a/src/com/android/browser/ComboViewActivity.java b/src/com/android/browser/ComboViewActivity.java
index 9bdce18..ae49898 100644
--- a/src/com/android/browser/ComboViewActivity.java
+++ b/src/com/android/browser/ComboViewActivity.java
@@ -41,7 +41,6 @@
public static final String EXTRA_OPEN_SNAPSHOT = "snapshot_id";
public static final String EXTRA_OPEN_ALL = "open_all";
public static final String EXTRA_CURRENT_URL = "url";
- public static final String EXTRA_BOOKMARK_PAGE = "create_bookmark";
private ViewPager mViewPager;
private TabsAdapter mTabsAdapter;
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index 25a7d4a..906a246 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -51,6 +51,7 @@
private PieControlPhone mPieControl;
private NavScreen mNavScreen;
+ private AnimScreen mAnimScreen;
private NavigationBarPhone mNavigationBar;
private int mActionBarHeight;
@@ -88,13 +89,17 @@
@Override
public boolean onBackKey() {
- if (mNavScreen != null) {
+ if (showingNavScreen()) {
mNavScreen.close(mUiController.getTabControl().getCurrentPosition());
return true;
}
return super.onBackKey();
}
+ private boolean showingNavScreen() {
+ return mNavScreen != null && mNavScreen.getVisibility() == View.VISIBLE;
+ }
+
@Override
public boolean dispatchKey(int code, KeyEvent event) {
return false;
@@ -169,17 +174,17 @@
public void updateMenuState(Tab tab, Menu menu) {
MenuItem bm = menu.findItem(R.id.bookmarks_menu_id);
if (bm != null) {
- bm.setVisible(mNavScreen == null);
+ bm.setVisible(!showingNavScreen());
}
MenuItem nt = menu.findItem(R.id.new_tab_menu_id);
if (nt != null) {
- nt.setVisible(mNavScreen == null);
+ nt.setVisible(!showingNavScreen());
}
MenuItem abm = menu.findItem(R.id.add_bookmark_menu_id);
if (abm != null) {
- abm.setVisible((tab != null) && !tab.isSnapshot() && mNavScreen == null);
+ abm.setVisible((tab != null) && !tab.isSnapshot() && !showingNavScreen());
}
- if (mNavScreen != null) {
+ if (showingNavScreen()) {
menu.setGroupVisible(R.id.LIVE_MENU, false);
menu.setGroupVisible(R.id.SNAPSHOT_MENU, false);
menu.findItem(R.id.page_info_menu_id).setVisible(false);
@@ -189,7 +194,7 @@
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- if (mNavScreen != null) {
+ if (showingNavScreen()) {
hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
}
return false;
@@ -271,7 +276,7 @@
@Override
public boolean isWebShowing() {
- return super.isWebShowing() && mNavScreen == null;
+ return super.isWebShowing() && !showingNavScreen();
}
@Override
@@ -282,12 +287,19 @@
void showNavScreen() {
mUiController.setBlockEvents(true);
- mNavScreen = new NavScreen(mActivity, mUiController, this);
+ if (mNavScreen == null) {
+ mNavScreen = new NavScreen(mActivity, mUiController, this);
+ mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
+ } else {
+ mNavScreen.setVisibility(View.VISIBLE);
+ mNavScreen.setAlpha(1f);
+ }
mActiveTab.capture();
- // Add the custom view to its container
- mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
- AnimScreen ascreen = new AnimScreen(mActivity, getTitleBar(), getWebView());
- final View animView = ascreen.mMain;
+ if (mAnimScreen == null) {
+ mAnimScreen = new AnimScreen(mActivity);
+ }
+ mAnimScreen.set(getTitleBar(), getWebView());
+ final View animView = mAnimScreen.mMain;
mCustomViewContainer.addView(animView, COVER_SCREEN_PARAMS);
mCustomViewContainer.setVisibility(View.VISIBLE);
mCustomViewContainer.bringToFront();
@@ -307,19 +319,19 @@
mContentView.setVisibility(View.GONE);
AnimatorSet set1 = new AnimatorSet();
AnimatorSet inanim = new AnimatorSet();
- ObjectAnimator tx = ObjectAnimator.ofInt(ascreen.mContent, "left",
+ ObjectAnimator tx = ObjectAnimator.ofInt(mAnimScreen.mContent, "left",
fromLeft, toLeft);
- ObjectAnimator ty = ObjectAnimator.ofInt(ascreen.mContent, "top",
+ ObjectAnimator ty = ObjectAnimator.ofInt(mAnimScreen.mContent, "top",
fromTop, toTop);
- ObjectAnimator tr = ObjectAnimator.ofInt(ascreen.mContent, "right",
+ ObjectAnimator tr = ObjectAnimator.ofInt(mAnimScreen.mContent, "right",
fromRight, toRight);
- ObjectAnimator tb = ObjectAnimator.ofInt(ascreen.mContent, "bottom",
+ ObjectAnimator tb = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom",
fromBottom, toBottom);
- ObjectAnimator title = ObjectAnimator.ofFloat(ascreen.mTitle, "alpha",
+ ObjectAnimator title = ObjectAnimator.ofFloat(mAnimScreen.mTitle, "alpha",
1f, 0f);
- ObjectAnimator sx = ObjectAnimator.ofFloat(ascreen, "scaleFactor",
+ ObjectAnimator sx = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor",
1f, scaleFactor);
- ObjectAnimator blend1 = ObjectAnimator.ofFloat(ascreen.mMain, "alpha", 1, 0);
+ ObjectAnimator blend1 = ObjectAnimator.ofFloat(mAnimScreen.mMain, "alpha", 1, 0);
blend1.setDuration(100);
inanim.playTogether(tx, ty, tr, tb, sx, title);
@@ -337,7 +349,7 @@
}
private void finishAnimationIn() {
- if (mNavScreen != null) {
+ if (showingNavScreen()) {
// notify accessibility manager about the screen change
mNavScreen.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
mTabControl.setOnThumbnailUpdatedListener(mNavScreen);
@@ -345,7 +357,7 @@
}
void hideNavScreen(int position, boolean animate) {
- if (mNavScreen == null) return;
+ if (!showingNavScreen()) return;
final Tab tab = mUiController.getTabControl().getTab(position);
if ((tab == null) || !animate) {
if (tab != null) {
@@ -371,9 +383,12 @@
mUiController.setBlockEvents(true);
mUiController.setActiveTab(tab);
mContentView.setVisibility(View.VISIBLE);
- final AnimScreen screen = new AnimScreen(mActivity, tab.getScreenshot());
- mCustomViewContainer.addView(screen.mMain, COVER_SCREEN_PARAMS);
- screen.mMain.layout(0, 0, mContentView.getWidth(),
+ if (mAnimScreen == null) {
+ mAnimScreen = new AnimScreen(mActivity);
+ }
+ mAnimScreen.set(tab.getScreenshot());
+ mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
+ mAnimScreen.mMain.layout(0, 0, mContentView.getWidth(),
mContentView.getHeight());
mNavScreen.mScroller.finishScroller();
ImageView target = tabview.mImage;
@@ -388,29 +403,29 @@
int fromBottom = fromTop + height;
float scaleFactor = mContentView.getWidth() / (float) width;
int toBottom = toTop + (int) (height * scaleFactor);
- ObjectAnimator l1 = ObjectAnimator.ofInt(screen.mContent, "left",
+ ObjectAnimator l1 = ObjectAnimator.ofInt(mAnimScreen.mContent, "left",
fromLeft, fromLeft);
- ObjectAnimator t1 = ObjectAnimator.ofInt(screen.mContent, "top",
+ ObjectAnimator t1 = ObjectAnimator.ofInt(mAnimScreen.mContent, "top",
fromTop, fromTop);
- ObjectAnimator r1 = ObjectAnimator.ofInt(screen.mContent, "right",
+ ObjectAnimator r1 = ObjectAnimator.ofInt(mAnimScreen.mContent, "right",
fromRight, fromRight);
- ObjectAnimator b1 = ObjectAnimator.ofInt(screen.mContent, "bottom",
+ ObjectAnimator b1 = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom",
fromBottom, fromBottom);
AnimatorSet set1 = new AnimatorSet();
- ObjectAnimator fade2 = ObjectAnimator.ofFloat(screen.mMain, "alpha", 0f, 1f);
+ ObjectAnimator fade2 = ObjectAnimator.ofFloat(mAnimScreen.mMain, "alpha", 0f, 1f);
ObjectAnimator fade1 = ObjectAnimator.ofFloat(mNavScreen, "alpha", 1f, 0f);
set1.playTogether(l1, t1, r1, b1, fade1, fade2);
set1.setDuration(100);
AnimatorSet set2 = new AnimatorSet();
- ObjectAnimator l = ObjectAnimator.ofInt(screen.mContent, "left",
+ ObjectAnimator l = ObjectAnimator.ofInt(mAnimScreen.mContent, "left",
fromLeft, toLeft);
- ObjectAnimator t = ObjectAnimator.ofInt(screen.mContent, "top",
+ ObjectAnimator t = ObjectAnimator.ofInt(mAnimScreen.mContent, "top",
fromTop, toTop);
- ObjectAnimator r = ObjectAnimator.ofInt(screen.mContent, "right",
+ ObjectAnimator r = ObjectAnimator.ofInt(mAnimScreen.mContent, "right",
fromRight, toRight);
- ObjectAnimator b = ObjectAnimator.ofInt(screen.mContent, "bottom",
+ ObjectAnimator b = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom",
fromBottom, toBottom);
- ObjectAnimator scale = ObjectAnimator.ofFloat(screen, "scaleFactor",
+ ObjectAnimator scale = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor",
1f, scaleFactor);
ObjectAnimator otheralpha = ObjectAnimator.ofFloat(mCustomViewContainer, "alpha", 1f, 0f);
otheralpha.setDuration(100);
@@ -421,7 +436,7 @@
combo.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator anim) {
- mCustomViewContainer.removeView(screen.mMain);
+ mCustomViewContainer.removeView(mAnimScreen.mMain);
finishAnimateOut();
mUiController.setBlockEvents(false);
}
@@ -431,9 +446,8 @@
private void finishAnimateOut() {
mTabControl.setOnThumbnailUpdatedListener(null);
- mCustomViewContainer.removeView(mNavScreen);
+ mNavScreen.setVisibility(View.GONE);
mCustomViewContainer.setAlpha(1f);
- mNavScreen = null;
mCustomViewContainer.setVisibility(View.GONE);
}
@@ -443,7 +457,7 @@
}
public void toggleNavScreen() {
- if (mNavScreen == null) {
+ if (!showingNavScreen()) {
showNavScreen();
} else {
hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
@@ -461,55 +475,61 @@
private ImageView mTitle;
private ImageView mContent;
private float mScale;
+ private Bitmap mTitleBarBitmap;
+ private Bitmap mContentBitmap;
- public AnimScreen(Context ctx, TitleBar tbar, WebView web) {
+ public AnimScreen(Context ctx) {
mMain = LayoutInflater.from(ctx).inflate(R.layout.anim_screen,
null);
- mContent = (ImageView) mMain.findViewById(R.id.content);
- mContent.setTop(tbar.getHeight());
-
mTitle = (ImageView) mMain.findViewById(R.id.title);
- Bitmap bm1 = Bitmap.createBitmap(tbar.getWidth(), tbar.getHeight(),
- Bitmap.Config.RGB_565);
- Canvas c1 = new Canvas(bm1);
- tbar.draw(c1);
- mTitle.setImageBitmap(bm1);
+ mContent = (ImageView) mMain.findViewById(R.id.content);
+ mContent.setScaleType(ImageView.ScaleType.MATRIX);
+ mContent.setImageMatrix(new Matrix());
+ mScale = 1.0f;
+ setScaleFactor(getScaleFactor());
+ }
+
+ public void set(TitleBar tbar, WebView web) {
+ if (mTitleBarBitmap == null
+ || mTitleBarBitmap.getWidth() != tbar.getWidth()
+ || mTitleBarBitmap.getHeight() != tbar.getHeight()) {
+ mTitleBarBitmap = Bitmap.createBitmap(tbar.getWidth(),
+ tbar.getHeight(), Bitmap.Config.RGB_565);
+ }
+ Canvas c = new Canvas(mTitleBarBitmap);
+ tbar.draw(c);
+ c.setBitmap(null);
+ mTitle.setImageBitmap(mTitleBarBitmap);
+ mTitle.setVisibility(View.VISIBLE);
int h = web.getHeight() - tbar.getHeight();
- Bitmap bm2 = Bitmap.createBitmap(web.getWidth(), h,
- Bitmap.Config.RGB_565);
- Canvas c2 = new Canvas(bm2);
+ if (mContentBitmap == null
+ || mContentBitmap.getWidth() != web.getWidth()
+ || mContentBitmap.getHeight() != h) {
+ mContentBitmap = Bitmap.createBitmap(web.getWidth(), h,
+ Bitmap.Config.RGB_565);
+ }
+ c.setBitmap(mContentBitmap);
int tx = web.getScrollX();
int ty = web.getScrollY();
- c2.translate(-tx, -ty - tbar.getHeight());
- web.draw(c2);
- mContent.setImageBitmap(bm2);
- mContent.setScaleType(ImageView.ScaleType.MATRIX);
- mContent.setImageMatrix(new Matrix());
- mScale = 1.0f;
- setScaleFactor(getScaleFactor());
+ c.translate(-tx, -ty - tbar.getHeight());
+ web.draw(c);
+ c.setBitmap(null);
+ mContent.setImageBitmap(mContentBitmap);
}
- public AnimScreen(Context ctx, Bitmap image) {
- mMain = LayoutInflater.from(ctx).inflate(R.layout.anim_screen,
- null);
- mTitle = (ImageView) mMain.findViewById(R.id.title);
+ public void set(Bitmap image) {
mTitle.setVisibility(View.GONE);
- mContent = (ImageView) mMain.findViewById(R.id.content);
mContent.setImageBitmap(image);
- mContent.setScaleType(ImageView.ScaleType.MATRIX);
- mContent.setImageMatrix(new Matrix());
- mScale = 1.0f;
- setScaleFactor(getScaleFactor());
}
- public void setScaleFactor(float sf) {
+ private void setScaleFactor(float sf) {
mScale = sf;
Matrix m = new Matrix();
m.postScale(sf,sf);
mContent.setImageMatrix(m);
}
- public float getScaleFactor() {
+ private float getScaleFactor() {
return mScale;
}
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 936aca9..f2aa529 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -114,16 +114,19 @@
}
public enum SecurityState {
- // The page does not use SSL.
+ // The page's main resource does not use SSL. Note that we use this
+ // state irrespective of the SSL authentication state of sub-resources.
SECURITY_STATE_NOT_SECURE,
- // The page uses SSL, the certificate is good and all elements are secure.
+ // The page's main resource uses SSL and the certificate is good. The
+ // same is true of all sub-resources.
SECURITY_STATE_SECURE,
- // The page uses SSL and the certificate is good, but some elements are insecure.
+ // The page's main resource uses SSL and the certificate is good, but
+ // some sub-resources either do not use SSL or have problems with their
+ // certificates.
SECURITY_STATE_MIXED,
- // TODO: Add SECURITY_STATE_BAD_CERTIFICATE
- // See http://b/5403366
- // The page uses SSL but there is a problem with the certificate.
- //SECURITY_STATE_BAD_CERTIFICATE,
+ // The page's main resource uses SSL but there is a problem with its
+ // certificate.
+ SECURITY_STATE_BAD_CERTIFICATE,
}
Context mContext;
@@ -778,6 +781,7 @@
public void onClick(DialogInterface dialog,
int whichButton) {
handler.proceed();
+ handleProceededAfterSslError(error);
}
})
.setNeutralButton(R.string.view_certificate,
@@ -813,6 +817,17 @@
}
/**
+ * Called when an SSL error occurred while loading a resource, but the
+ * WebView but chose to proceed anyway based on a decision retained
+ * from a previous response to onReceivedSslError(). We update our
+ * security state to reflect this.
+ */
+ @Override
+ public void onProceededAfterSslError(WebView view, SslError error) {
+ handleProceededAfterSslError(error);
+ }
+
+ /**
* Displays client certificate request to the user.
*/
@Override
@@ -2252,4 +2267,12 @@
return builder.toString();
}
+ private void handleProceededAfterSslError(SslError error) {
+ if (error.getUrl().equals(mCurrentState.mUrl)) {
+ // The security state should currently be SECURITY_STATE_SECURE.
+ setSecurityState(SecurityState.SECURITY_STATE_BAD_CERTIFICATE);
+ } else if (getSecurityState() == SecurityState.SECURITY_STATE_SECURE) {
+ setSecurityState(SecurityState.SECURITY_STATE_MIXED);
+ }
+ }
}
diff --git a/src/com/android/browser/preferences/WebsiteSettingsFragment.java b/src/com/android/browser/preferences/WebsiteSettingsFragment.java
index a2ccca1..91c66a0 100644
--- a/src/com/android/browser/preferences/WebsiteSettingsFragment.java
+++ b/src/com/android/browser/preferences/WebsiteSettingsFragment.java
@@ -667,6 +667,12 @@
getListView().setOnItemClickListener(mAdapter);
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ mAdapter.askForOrigins();
+ }
+
private void finish() {
PreferenceActivity activity = (PreferenceActivity) getActivity();
if (activity != null) {