blob: d83d81dba7d75bd601639aed641cf3af95d14232 [file] [log] [blame]
Michael Kolb66706532010-12-12 19:50:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Bijan Amirzada41242f22014-03-21 12:12:18 -070017package com.android.browser;
Michael Kolb66706532010-12-12 19:50:22 -080018
Michael Kolbc3af0672011-08-09 10:24:41 -070019import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
21import android.animation.AnimatorSet;
22import android.animation.ObjectAnimator;
Michael Kolb66706532010-12-12 19:50:22 -080023import android.app.Activity;
Michael Kolbc3af0672011-08-09 10:24:41 -070024import android.content.Context;
25import android.graphics.Bitmap;
26import android.graphics.Canvas;
27import android.graphics.Matrix;
Axesh R. Ajmera2e241242014-05-19 15:53:38 -070028import android.os.Handler;
John Reck9c5004e2011-10-07 16:00:12 -070029import android.os.Message;
Michael Kolb376b5412010-12-15 11:52:57 -080030import android.util.Log;
John Reckaae029c2011-09-16 14:36:39 -070031import android.util.TypedValue;
Michael Kolb66706532010-12-12 19:50:22 -080032import android.view.ActionMode;
Michael Kolba4183062011-01-16 10:43:21 -080033import android.view.KeyEvent;
Michael Kolbc3af0672011-08-09 10:24:41 -070034import android.view.LayoutInflater;
Michael Kolb66706532010-12-12 19:50:22 -080035import android.view.Menu;
Michael Kolb3ca12752011-07-20 13:52:25 -070036import android.view.MenuItem;
Michael Kolb66706532010-12-12 19:50:22 -080037import android.view.View;
Michael Kolb30adae62011-07-29 13:37:05 -070038import android.view.accessibility.AccessibilityEvent;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080039import org.codeaurora.swe.WebView;
Michael Kolbc3af0672011-08-09 10:24:41 -070040import android.widget.ImageView;
Michael Kolb66706532010-12-12 19:50:22 -080041
Bijan Amirzada41242f22014-03-21 12:12:18 -070042import com.android.browser.R;
43import com.android.browser.UrlInputView.StateListener;
Michael Kolb629b22c2011-07-13 16:26:47 -070044
Michael Kolb66706532010-12-12 19:50:22 -080045/**
46 * Ui for regular phone screen sizes
47 */
48public class PhoneUi extends BaseUi {
49
50 private static final String LOGTAG = "PhoneUi";
John Reck9c5004e2011-10-07 16:00:12 -070051 private static final int MSG_INIT_NAVSCREEN = 100;
Michael Kolb66706532010-12-12 19:50:22 -080052
Michael Kolbf2055602011-04-09 17:20:03 -070053 private NavScreen mNavScreen;
John Reckcc0059c2011-10-07 13:53:13 -070054 private AnimScreen mAnimScreen;
John Reck0f602f32011-07-07 15:38:43 -070055 private NavigationBarPhone mNavigationBar;
John Reckaae029c2011-09-16 14:36:39 -070056 private int mActionBarHeight;
Michael Kolb66706532010-12-12 19:50:22 -080057
Michael Kolb08a687a2011-04-22 16:13:02 -070058 boolean mAnimating;
yijunx.zhu2230a312012-07-27 13:37:00 -040059 boolean mShowNav = false;
Michael Kolb66706532010-12-12 19:50:22 -080060
Axesh R. Ajmera2e241242014-05-19 15:53:38 -070061 static final int POST_DELAY = 300;
62
Michael Kolb66706532010-12-12 19:50:22 -080063 /**
64 * @param browser
65 * @param controller
66 */
67 public PhoneUi(Activity browser, UiController controller) {
68 super(browser, controller);
Michael Kolbfdb70242011-03-24 09:41:11 -070069 setUseQuickControls(BrowserSettings.getInstance().useQuickControls());
John Reck0f602f32011-07-07 15:38:43 -070070 mNavigationBar = (NavigationBarPhone) mTitleBar.getNavigationBar();
John Reckaae029c2011-09-16 14:36:39 -070071 TypedValue heightValue = new TypedValue();
72 browser.getTheme().resolveAttribute(
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080073 android.R.attr.actionBarSize, heightValue, true);
John Reckaae029c2011-09-16 14:36:39 -070074 mActionBarHeight = TypedValue.complexToDimensionPixelSize(heightValue.data,
75 browser.getResources().getDisplayMetrics());
John Reck285ef042011-02-11 15:44:17 -080076 }
Michael Kolb66706532010-12-12 19:50:22 -080077
John Reck285ef042011-02-11 15:44:17 -080078 @Override
Michael Kolb66706532010-12-12 19:50:22 -080079 public void onDestroy() {
Michael Kolb7cdc4902011-02-03 17:54:40 -080080 hideTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -080081 }
82
83 @Override
Michael Kolb1f9b3562012-04-24 14:38:34 -070084 public void editUrl(boolean clearInput, boolean forceIME) {
Michael Kolb46f987e2011-04-05 10:39:10 -070085 if (mUseQuickControls) {
John Reck0f602f32011-07-07 15:38:43 -070086 mTitleBar.setShowProgressOnly(false);
Michael Kolb46f987e2011-04-05 10:39:10 -070087 }
yijunx.zhu2230a312012-07-27 13:37:00 -040088 //Do nothing while at Nav show screen.
89 if (mShowNav) return;
Michael Kolb1f9b3562012-04-24 14:38:34 -070090 super.editUrl(clearInput, forceIME);
Michael Kolbdc2ee1b2011-02-14 14:34:40 -080091 }
92
93 @Override
Michael Kolb66706532010-12-12 19:50:22 -080094 public boolean onBackKey() {
John Reckcc0059c2011-10-07 13:53:13 -070095 if (showingNavScreen()) {
Michael Kolba3194d02011-09-07 11:23:51 -070096 mNavScreen.close(mUiController.getTabControl().getCurrentPosition());
Michael Kolbf2055602011-04-09 17:20:03 -070097 return true;
Michael Kolb66706532010-12-12 19:50:22 -080098 }
99 return super.onBackKey();
100 }
101
John Reckcc0059c2011-10-07 13:53:13 -0700102 private boolean showingNavScreen() {
103 return mNavScreen != null && mNavScreen.getVisibility() == View.VISIBLE;
104 }
105
Michael Kolb66706532010-12-12 19:50:22 -0800106 @Override
Michael Kolbf2055602011-04-09 17:20:03 -0700107 public boolean dispatchKey(int code, KeyEvent event) {
Michael Kolbf2055602011-04-09 17:20:03 -0700108 return false;
109 }
110
111 @Override
John Reck30c714c2010-12-16 17:30:34 -0800112 public void onProgressChanged(Tab tab) {
Michael Kolbe8a82332012-04-25 14:14:26 -0700113 super.onProgressChanged(tab);
John Reck9c5004e2011-10-07 16:00:12 -0700114 if (mNavScreen == null && getTitleBar().getHeight() > 0) {
115 mHandler.sendEmptyMessage(MSG_INIT_NAVSCREEN);
116 }
117 }
118
119 @Override
120 protected void handleMessage(Message msg) {
121 super.handleMessage(msg);
122 if (msg.what == MSG_INIT_NAVSCREEN) {
123 if (mNavScreen == null) {
124 mNavScreen = new NavScreen(mActivity, mUiController, this);
125 mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
126 mNavScreen.setVisibility(View.GONE);
127 }
128 if (mAnimScreen == null) {
129 mAnimScreen = new AnimScreen(mActivity);
130 // initialize bitmaps
131 mAnimScreen.set(getTitleBar(), getWebView());
132 }
133 }
Michael Kolb66706532010-12-12 19:50:22 -0800134 }
135
136 @Override
Michael Kolbfdb70242011-03-24 09:41:11 -0700137 public void setActiveTab(final Tab tab) {
John Reck8ee633f2011-08-09 16:00:35 -0700138 mTitleBar.cancelTitleBarAnimation(true);
139 mTitleBar.setSkipTitleBarAnimations(true);
John Reck5d43ce82011-06-21 17:16:51 -0700140 super.setActiveTab(tab);
yijunx.zhu2230a312012-07-27 13:37:00 -0400141
142 //if at Nav screen show, detach tab like what showNavScreen() do.
143 if (mShowNav) {
144 detachTab(mActiveTab);
145 }
146
Michael Kolbfdb70242011-03-24 09:41:11 -0700147 BrowserWebView view = (BrowserWebView) tab.getWebView();
Michael Kolb376b5412010-12-15 11:52:57 -0800148 // TabControl.setCurrentTab has been called before this,
149 // so the tab is guaranteed to have a webview
150 if (view == null) {
151 Log.e(LOGTAG, "active tab with no webview detected");
152 return;
153 }
Michael Kolbfdb70242011-03-24 09:41:11 -0700154 // Request focus on the top window.
155 if (mUseQuickControls) {
156 mPieControl.forceToTop(mContentView);
Michael Kolb4923c222012-04-02 16:18:36 -0700157 view.setTitleBar(null);
Michael Kolbe8a82332012-04-25 14:14:26 -0700158 mTitleBar.setShowProgressOnly(true);
Michael Kolbfdb70242011-03-24 09:41:11 -0700159 } else {
Michael Kolb4923c222012-04-02 16:18:36 -0700160 view.setTitleBar(mTitleBar);
Michael Kolbfdb70242011-03-24 09:41:11 -0700161 }
Michael Kolb629b22c2011-07-13 16:26:47 -0700162 // update nav bar state
163 mNavigationBar.onStateChanged(StateListener.STATE_NORMAL);
Michael Kolbfdb70242011-03-24 09:41:11 -0700164 updateLockIconToLatest(tab);
John Reck8ee633f2011-08-09 16:00:35 -0700165 mTitleBar.setSkipTitleBarAnimations(false);
Michael Kolb376b5412010-12-15 11:52:57 -0800166 }
167
Michael Kolb66706532010-12-12 19:50:22 -0800168 // menu handling callbacks
169
170 @Override
Michael Kolb3ca12752011-07-20 13:52:25 -0700171 public boolean onPrepareOptionsMenu(Menu menu) {
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700172 updateMenuState(mActiveTab, menu);
Michael Kolb3ca12752011-07-20 13:52:25 -0700173 return true;
174 }
175
176 @Override
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700177 public void updateMenuState(Tab tab, Menu menu) {
Michael Kolb0d0245f2011-12-05 16:36:05 -0800178 MenuItem bm = menu.findItem(R.id.bookmarks_menu_id);
179 if (bm != null) {
180 bm.setVisible(!showingNavScreen());
181 }
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700182 MenuItem abm = menu.findItem(R.id.add_bookmark_menu_id);
183 if (abm != null) {
John Reckcc0059c2011-10-07 13:53:13 -0700184 abm.setVisible((tab != null) && !tab.isSnapshot() && !showingNavScreen());
John Recke1a03a32011-09-14 17:04:16 -0700185 }
Michael Kolb315d5022011-10-13 12:47:11 -0700186 MenuItem info = menu.findItem(R.id.page_info_menu_id);
187 if (info != null) {
188 info.setVisible(false);
189 }
190 MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
191 if (newtab != null && !mUseQuickControls) {
192 newtab.setVisible(false);
193 }
194 MenuItem incognito = menu.findItem(R.id.incognito_menu_id);
195 if (incognito != null) {
196 incognito.setVisible(showingNavScreen() || mUseQuickControls);
197 }
Afzal Najamd4e33312012-04-26 01:54:01 -0400198 MenuItem closeOthers = menu.findItem(R.id.close_other_tabs_id);
199 if (closeOthers != null) {
200 boolean isLastTab = true;
201 if (tab != null) {
202 isLastTab = (mTabControl.getTabCount() <= 1);
203 }
204 closeOthers.setEnabled(!isLastTab);
205 }
John Reckcc0059c2011-10-07 13:53:13 -0700206 if (showingNavScreen()) {
John Recke1a03a32011-09-14 17:04:16 -0700207 menu.setGroupVisible(R.id.LIVE_MENU, false);
208 menu.setGroupVisible(R.id.SNAPSHOT_MENU, false);
John Recke1a03a32011-09-14 17:04:16 -0700209 menu.setGroupVisible(R.id.NAV_MENU, false);
Michael Kolb315d5022011-10-13 12:47:11 -0700210 menu.setGroupVisible(R.id.COMBO_MENU, true);
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700211 }
212 }
213
214 @Override
Michael Kolb3ca12752011-07-20 13:52:25 -0700215 public boolean onOptionsItemSelected(MenuItem item) {
Michael Kolb315d5022011-10-13 12:47:11 -0700216 if (showingNavScreen()
217 && (item.getItemId() != R.id.history_menu_id)
218 && (item.getItemId() != R.id.snapshots_menu_id)) {
Michael Kolba3194d02011-09-07 11:23:51 -0700219 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
Michael Kolb3ca12752011-07-20 13:52:25 -0700220 }
221 return false;
222 }
223
224 @Override
Michael Kolb66706532010-12-12 19:50:22 -0800225 public void onContextMenuCreated(Menu menu) {
Michael Kolb7cdc4902011-02-03 17:54:40 -0800226 hideTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -0800227 }
228
229 @Override
230 public void onContextMenuClosed(Menu menu, boolean inLoad) {
231 if (inLoad) {
Michael Kolb7cdc4902011-02-03 17:54:40 -0800232 showTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -0800233 }
234 }
235
236 // action mode callbacks
237
238 @Override
239 public void onActionModeStarted(ActionMode mode) {
Bijan Amirzada357ec8a2014-04-08 14:19:10 -0700240 super.onActionModeStarted(mode);
Michael Kolb42c0c062011-08-02 12:56:06 -0700241 if (!isEditingUrl()) {
242 hideTitleBar();
243 }
Michael Kolb66706532010-12-12 19:50:22 -0800244 }
245
Michael Kolba4183062011-01-16 10:43:21 -0800246 @Override
John Reck6cda7b12011-03-18 15:57:13 -0700247 public void onActionModeFinished(boolean inLoad) {
Bijan Amirzada357ec8a2014-04-08 14:19:10 -0700248 super.onActionModeFinished(inLoad);
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700249 mTitleBar.animate().translationY(0);
250 stopEditingUrl();
251 Handler handler = new Handler();
252 handler.postDelayed(new Runnable() {
253 public void run() {
254 mNavigationBar.onStateChanged(StateListener.STATE_NORMAL);
255 }}, POST_DELAY);
256
Michael Kolbc16c5952011-03-29 15:37:03 -0700257 if (inLoad) {
258 if (mUseQuickControls) {
259 mTitleBar.setShowProgressOnly(true);
John Reck6cda7b12011-03-18 15:57:13 -0700260 }
Michael Kolbc16c5952011-03-29 15:37:03 -0700261 showTitleBar();
262 }
John Reck6cda7b12011-03-18 15:57:13 -0700263 }
264
265 @Override
Michael Kolbc3af0672011-08-09 10:24:41 -0700266 public boolean isWebShowing() {
John Reckcc0059c2011-10-07 13:53:13 -0700267 return super.isWebShowing() && !showingNavScreen();
Michael Kolbc3af0672011-08-09 10:24:41 -0700268 }
269
270 @Override
271 public void showWeb(boolean animate) {
272 super.showWeb(animate);
Michael Kolba3194d02011-09-07 11:23:51 -0700273 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), animate);
Michael Kolbc3af0672011-08-09 10:24:41 -0700274 }
275
Michael Kolbf2055602011-04-09 17:20:03 -0700276 void showNavScreen() {
yijunx.zhu2230a312012-07-27 13:37:00 -0400277 mShowNav = true;
Michael Kolbc3af0672011-08-09 10:24:41 -0700278 mUiController.setBlockEvents(true);
John Reckcc0059c2011-10-07 13:53:13 -0700279 if (mNavScreen == null) {
280 mNavScreen = new NavScreen(mActivity, mUiController, this);
281 mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
282 } else {
283 mNavScreen.setVisibility(View.VISIBLE);
284 mNavScreen.setAlpha(1f);
John Reck9c5004e2011-10-07 16:00:12 -0700285 mNavScreen.refreshAdapter();
John Reckcc0059c2011-10-07 13:53:13 -0700286 }
Michael Kolbc3af0672011-08-09 10:24:41 -0700287 mActiveTab.capture();
John Reckcc0059c2011-10-07 13:53:13 -0700288 if (mAnimScreen == null) {
289 mAnimScreen = new AnimScreen(mActivity);
John Reckce8bcb02011-10-11 13:45:29 -0700290 } else {
291 mAnimScreen.mMain.setAlpha(1f);
292 mAnimScreen.mTitle.setAlpha(1f);
293 mAnimScreen.setScaleFactor(1f);
John Reckcc0059c2011-10-07 13:53:13 -0700294 }
295 mAnimScreen.set(getTitleBar(), getWebView());
Michael Kolba30e4fb2011-11-07 17:32:01 -0800296 if (mAnimScreen.mMain.getParent() == null) {
297 mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
298 }
Michael Kolbf2055602011-04-09 17:20:03 -0700299 mCustomViewContainer.setVisibility(View.VISIBLE);
300 mCustomViewContainer.bringToFront();
John Reckce8bcb02011-10-11 13:45:29 -0700301 mAnimScreen.mMain.layout(0, 0, mContentView.getWidth(),
302 mContentView.getHeight());
Michael Kolbc3af0672011-08-09 10:24:41 -0700303 int fromLeft = 0;
304 int fromTop = getTitleBar().getHeight();
305 int fromRight = mContentView.getWidth();
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800306 int fixedTbarHeight = mTitleBar.isFixed() ? mTitleBar.calculateEmbeddedHeight() : 0;
307 int fromBottom = mContentView.getHeight() + fixedTbarHeight;
Michael Kolba3194d02011-09-07 11:23:51 -0700308 int width = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_width);
309 int height = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_height);
Michael Kolb7a321d62011-09-23 15:54:22 -0700310 int ntth = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_titleheight);
Michael Kolbc3af0672011-08-09 10:24:41 -0700311 int toLeft = (mContentView.getWidth() - width) / 2;
Michael Kolb7a321d62011-09-23 15:54:22 -0700312 int toTop = ((fromBottom - (ntth + height)) / 2 + ntth);
Michael Kolbc3af0672011-08-09 10:24:41 -0700313 int toRight = toLeft + width;
314 int toBottom = toTop + height;
315 float scaleFactor = width / (float) mContentView.getWidth();
Michael Kolbc3af0672011-08-09 10:24:41 -0700316 mContentView.setVisibility(View.GONE);
Michael Kolba3194d02011-09-07 11:23:51 -0700317 AnimatorSet set1 = new AnimatorSet();
Michael Kolbc3af0672011-08-09 10:24:41 -0700318 AnimatorSet inanim = new AnimatorSet();
John Reckcc0059c2011-10-07 13:53:13 -0700319 ObjectAnimator tx = ObjectAnimator.ofInt(mAnimScreen.mContent, "left",
Michael Kolbc3af0672011-08-09 10:24:41 -0700320 fromLeft, toLeft);
John Reckcc0059c2011-10-07 13:53:13 -0700321 ObjectAnimator ty = ObjectAnimator.ofInt(mAnimScreen.mContent, "top",
Michael Kolbc3af0672011-08-09 10:24:41 -0700322 fromTop, toTop);
John Reckcc0059c2011-10-07 13:53:13 -0700323 ObjectAnimator tr = ObjectAnimator.ofInt(mAnimScreen.mContent, "right",
Michael Kolbc3af0672011-08-09 10:24:41 -0700324 fromRight, toRight);
John Reckcc0059c2011-10-07 13:53:13 -0700325 ObjectAnimator tb = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom",
Michael Kolbc3af0672011-08-09 10:24:41 -0700326 fromBottom, toBottom);
John Reckcc0059c2011-10-07 13:53:13 -0700327 ObjectAnimator title = ObjectAnimator.ofFloat(mAnimScreen.mTitle, "alpha",
Michael Kolbc3af0672011-08-09 10:24:41 -0700328 1f, 0f);
John Reckcc0059c2011-10-07 13:53:13 -0700329 ObjectAnimator sx = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor",
Michael Kolbc3af0672011-08-09 10:24:41 -0700330 1f, scaleFactor);
John Reck1adf0302011-10-11 10:58:12 -0700331 ObjectAnimator blend1 = ObjectAnimator.ofFloat(mAnimScreen.mMain,
332 "alpha", 1f, 0f);
Michael Kolba3194d02011-09-07 11:23:51 -0700333 blend1.setDuration(100);
334
335 inanim.playTogether(tx, ty, tr, tb, sx, title);
336 inanim.setDuration(200);
337 set1.addListener(new AnimatorListenerAdapter() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700338 @Override
339 public void onAnimationEnd(Animator anim) {
John Reck1adf0302011-10-11 10:58:12 -0700340 mCustomViewContainer.removeView(mAnimScreen.mMain);
Michael Kolbc3af0672011-08-09 10:24:41 -0700341 finishAnimationIn();
342 mUiController.setBlockEvents(false);
343 }
344 });
Michael Kolba3194d02011-09-07 11:23:51 -0700345 set1.playSequentially(inanim, blend1);
346 set1.start();
Bijan Amirzadafd75eae2014-04-17 17:09:12 -0700347 mUiController.setBlockEvents(false);
Michael Kolbc3af0672011-08-09 10:24:41 -0700348 }
349
350 private void finishAnimationIn() {
John Reckcc0059c2011-10-07 13:53:13 -0700351 if (showingNavScreen()) {
Michael Kolbb43f2f62011-08-17 10:39:31 -0700352 // notify accessibility manager about the screen change
353 mNavScreen.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
354 mTabControl.setOnThumbnailUpdatedListener(mNavScreen);
355 }
Michael Kolbf2055602011-04-09 17:20:03 -0700356 }
357
Michael Kolba3194d02011-09-07 11:23:51 -0700358 void hideNavScreen(int position, boolean animate) {
yijunx.zhu2230a312012-07-27 13:37:00 -0400359 mShowNav = false;
John Reckcc0059c2011-10-07 13:53:13 -0700360 if (!showingNavScreen()) return;
Michael Kolba3194d02011-09-07 11:23:51 -0700361 final Tab tab = mUiController.getTabControl().getTab(position);
Michael Kolbbf32cd02011-08-16 15:07:04 -0700362 if ((tab == null) || !animate) {
Michael Kolb365561d2011-08-18 09:56:25 -0700363 if (tab != null) {
364 setActiveTab(tab);
365 } else if (mTabControl.getTabCount() > 0) {
366 // use a fallback tab
367 setActiveTab(mTabControl.getCurrentTab());
368 }
Michael Kolbbf32cd02011-08-16 15:07:04 -0700369 mContentView.setVisibility(View.VISIBLE);
370 finishAnimateOut();
Michael Kolb8a009492011-08-15 15:37:30 -0700371 return;
Michael Kolbc3af0672011-08-09 10:24:41 -0700372 }
Michael Kolba3194d02011-09-07 11:23:51 -0700373 NavTabView tabview = (NavTabView) mNavScreen.getTabView(position);
Michael Kolbc3af0672011-08-09 10:24:41 -0700374 if (tabview == null) {
Michael Kolb365561d2011-08-18 09:56:25 -0700375 if (mTabControl.getTabCount() > 0) {
376 // use a fallback tab
377 setActiveTab(mTabControl.getCurrentTab());
378 }
Michael Kolbbf32cd02011-08-16 15:07:04 -0700379 mContentView.setVisibility(View.VISIBLE);
380 finishAnimateOut();
Michael Kolb8a009492011-08-15 15:37:30 -0700381 return;
Michael Kolbc3af0672011-08-09 10:24:41 -0700382 }
383 mUiController.setBlockEvents(true);
384 mUiController.setActiveTab(tab);
385 mContentView.setVisibility(View.VISIBLE);
John Reckcc0059c2011-10-07 13:53:13 -0700386 if (mAnimScreen == null) {
387 mAnimScreen = new AnimScreen(mActivity);
388 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700389 mAnimScreen.set(tab.getFullScreenshot());
Michael Kolb0755fcd2012-01-10 10:19:50 -0800390 if (mAnimScreen.mMain.getParent() == null) {
391 mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
392 }
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800393 int fixedTbarHeight = mTitleBar.isFixed() ? mTitleBar.calculateEmbeddedHeight() : 0;
John Reckcc0059c2011-10-07 13:53:13 -0700394 mAnimScreen.mMain.layout(0, 0, mContentView.getWidth(),
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800395 mContentView.getHeight() + fixedTbarHeight);
Michael Kolba3194d02011-09-07 11:23:51 -0700396 mNavScreen.mScroller.finishScroller();
397 ImageView target = tabview.mImage;
Michael Kolbc3af0672011-08-09 10:24:41 -0700398 int toLeft = 0;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800399 int toTop = 0;
400 if (mTitleBar.isFixed()) {
401 toTop = fixedTbarHeight;
402 } else {
403 toTop = (tab.getWebView() != null) ? tab.getWebView().getVisibleTitleHeight() : 0;
404 }
Michael Kolbc3af0672011-08-09 10:24:41 -0700405 int toRight = mContentView.getWidth();
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700406 int width = mContentView.getWidth();
407 int height = mContentView.getHeight();
Michael Kolba3194d02011-09-07 11:23:51 -0700408 int fromLeft = tabview.getLeft() + target.getLeft() - mNavScreen.mScroller.getScrollX();
409 int fromTop = tabview.getTop() + target.getTop() - mNavScreen.mScroller.getScrollY();
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700410 int fromRight = fromLeft + target.getDrawable().getIntrinsicWidth();
411 int fromBottom = fromTop + target.getDrawable().getIntrinsicHeight();
Michael Kolbc3af0672011-08-09 10:24:41 -0700412 float scaleFactor = mContentView.getWidth() / (float) width;
Michael Kolba3194d02011-09-07 11:23:51 -0700413 int toBottom = toTop + (int) (height * scaleFactor);
John Reck9c5004e2011-10-07 16:00:12 -0700414 mAnimScreen.mContent.setLeft(fromLeft);
415 mAnimScreen.mContent.setTop(fromTop);
416 mAnimScreen.mContent.setRight(fromRight);
417 mAnimScreen.mContent.setBottom(fromBottom);
418 mAnimScreen.setScaleFactor(1f);
Michael Kolba3194d02011-09-07 11:23:51 -0700419 AnimatorSet set1 = new AnimatorSet();
John Reckcc0059c2011-10-07 13:53:13 -0700420 ObjectAnimator fade2 = ObjectAnimator.ofFloat(mAnimScreen.mMain, "alpha", 0f, 1f);
Michael Kolba3194d02011-09-07 11:23:51 -0700421 ObjectAnimator fade1 = ObjectAnimator.ofFloat(mNavScreen, "alpha", 1f, 0f);
John Reck9c5004e2011-10-07 16:00:12 -0700422 set1.playTogether(fade1, fade2);
Michael Kolba3194d02011-09-07 11:23:51 -0700423 set1.setDuration(100);
424 AnimatorSet set2 = new AnimatorSet();
John Reckcc0059c2011-10-07 13:53:13 -0700425 ObjectAnimator l = ObjectAnimator.ofInt(mAnimScreen.mContent, "left",
Michael Kolbc3af0672011-08-09 10:24:41 -0700426 fromLeft, toLeft);
John Reckcc0059c2011-10-07 13:53:13 -0700427 ObjectAnimator t = ObjectAnimator.ofInt(mAnimScreen.mContent, "top",
Michael Kolbc3af0672011-08-09 10:24:41 -0700428 fromTop, toTop);
John Reckcc0059c2011-10-07 13:53:13 -0700429 ObjectAnimator r = ObjectAnimator.ofInt(mAnimScreen.mContent, "right",
Michael Kolbc3af0672011-08-09 10:24:41 -0700430 fromRight, toRight);
John Reckcc0059c2011-10-07 13:53:13 -0700431 ObjectAnimator b = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom",
Michael Kolbc3af0672011-08-09 10:24:41 -0700432 fromBottom, toBottom);
John Reckcc0059c2011-10-07 13:53:13 -0700433 ObjectAnimator scale = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor",
Michael Kolbc3af0672011-08-09 10:24:41 -0700434 1f, scaleFactor);
Michael Kolba3194d02011-09-07 11:23:51 -0700435 set2.playTogether(l, t, r, b, scale);
436 set2.setDuration(200);
437 AnimatorSet combo = new AnimatorSet();
Matthew Hui1eb7a832014-04-15 12:20:58 -0400438 combo.playSequentially(set1, set2);
Michael Kolba3194d02011-09-07 11:23:51 -0700439 combo.addListener(new AnimatorListenerAdapter() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700440 @Override
441 public void onAnimationEnd(Animator anim) {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400442 checkTabReady();
443 }
444 });
445 combo.start();
446 }
447
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700448
449 private int mNumTries = 0;
Matthew Hui1eb7a832014-04-15 12:20:58 -0400450 private void checkTabReady() {
451 boolean isready = true;
452 Tab tab = mUiController.getTabControl().getCurrentTab();
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700453 BrowserWebView webview = null;
Matthew Hui1eb7a832014-04-15 12:20:58 -0400454 if (tab == null)
455 isready = false;
456 else {
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700457 webview = (BrowserWebView)tab.getWebView();
458 if (webview == null) {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400459 isready = false;
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700460 }
461 else if (webview.hasCrashed()) {
462 webview.reload();
463 isready = true;
464 } else {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400465 isready = webview.isReady();
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700466 }
Matthew Hui1eb7a832014-04-15 12:20:58 -0400467 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700468 // Post only when not ready and not crashed
469 if (!isready && mNumTries++ < 150) {
470 mCustomViewContainer.postDelayed(new Runnable() {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400471 public void run() {
472 checkTabReady();
473 }
474 }, 17); //WebView is not ready. check again in for next frame.
475 return;
476 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700477 mNumTries = 0;
478 final boolean hasCrashed = (webview == null) ? false : webview.hasCrashed();
479 mCustomViewContainer.postDelayed(new Runnable() {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400480 public void run() {
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700481 fadeOutCustomViewContainer(hasCrashed);
Matthew Hui1eb7a832014-04-15 12:20:58 -0400482 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700483 }, 33); //WebView is ready, but give it extra 2 frame's time to display and finish the swaps
Matthew Hui1eb7a832014-04-15 12:20:58 -0400484 }
485
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700486 private void fadeOutCustomViewContainer(boolean hasCrashed) {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400487 ObjectAnimator otheralpha = ObjectAnimator.ofFloat(mCustomViewContainer, "alpha", 1f, 0f);
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700488 if (hasCrashed)
489 otheralpha.setDuration(300);
490 else
491 otheralpha.setDuration(100);
Matthew Hui1eb7a832014-04-15 12:20:58 -0400492 otheralpha.addListener(new AnimatorListenerAdapter() {
493 @Override
494 public void onAnimationEnd(Animator anim) {
John Reckcc0059c2011-10-07 13:53:13 -0700495 mCustomViewContainer.removeView(mAnimScreen.mMain);
Michael Kolbbf32cd02011-08-16 15:07:04 -0700496 finishAnimateOut();
Michael Kolbc3af0672011-08-09 10:24:41 -0700497 mUiController.setBlockEvents(false);
498 }
499 });
Matthew Hui1eb7a832014-04-15 12:20:58 -0400500 otheralpha.start();
Michael Kolbc3af0672011-08-09 10:24:41 -0700501 }
502
Michael Kolbbf32cd02011-08-16 15:07:04 -0700503 private void finishAnimateOut() {
John Reck8ee633f2011-08-09 16:00:35 -0700504 mTabControl.setOnThumbnailUpdatedListener(null);
John Reckcc0059c2011-10-07 13:53:13 -0700505 mNavScreen.setVisibility(View.GONE);
Michael Kolbc3af0672011-08-09 10:24:41 -0700506 mCustomViewContainer.setAlpha(1f);
Michael Kolbf2055602011-04-09 17:20:03 -0700507 mCustomViewContainer.setVisibility(View.GONE);
Michael Kolbf2055602011-04-09 17:20:03 -0700508 }
509
John Reck6b4bd5f2011-07-12 10:14:38 -0700510 @Override
511 public boolean needsRestoreAllTabs() {
512 return false;
513 }
514
Michael Kolb20be26d2011-07-18 16:38:02 -0700515 public void toggleNavScreen() {
John Reckcc0059c2011-10-07 13:53:13 -0700516 if (!showingNavScreen()) {
Michael Kolb20be26d2011-07-18 16:38:02 -0700517 showNavScreen();
518 } else {
Michael Kolba3194d02011-09-07 11:23:51 -0700519 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
Michael Kolb20be26d2011-07-18 16:38:02 -0700520 }
521 }
522
John Reck1cf4b792011-07-26 10:22:22 -0700523 @Override
524 public boolean shouldCaptureThumbnails() {
525 return true;
526 }
527
Michael Kolbc3af0672011-08-09 10:24:41 -0700528 static class AnimScreen {
John Reck3ba45532011-08-11 16:26:53 -0700529
Michael Kolbc3af0672011-08-09 10:24:41 -0700530 private View mMain;
531 private ImageView mTitle;
532 private ImageView mContent;
533 private float mScale;
John Reckcc0059c2011-10-07 13:53:13 -0700534 private Bitmap mTitleBarBitmap;
535 private Bitmap mContentBitmap;
Michael Kolbc3af0672011-08-09 10:24:41 -0700536
John Reckcc0059c2011-10-07 13:53:13 -0700537 public AnimScreen(Context ctx) {
Michael Kolbc3af0672011-08-09 10:24:41 -0700538 mMain = LayoutInflater.from(ctx).inflate(R.layout.anim_screen,
539 null);
Michael Kolbc3af0672011-08-09 10:24:41 -0700540 mTitle = (ImageView) mMain.findViewById(R.id.title);
John Reckcc0059c2011-10-07 13:53:13 -0700541 mContent = (ImageView) mMain.findViewById(R.id.content);
542 mContent.setScaleType(ImageView.ScaleType.MATRIX);
543 mContent.setImageMatrix(new Matrix());
544 mScale = 1.0f;
545 setScaleFactor(getScaleFactor());
546 }
547
548 public void set(TitleBar tbar, WebView web) {
John Reck62077d82011-10-13 15:17:50 -0700549 if (tbar == null || web == null) {
550 return;
551 }
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800552 int embTbarHeight = tbar.getEmbeddedHeight();
553 int tbarHeight = tbar.isFixed() ? tbar.calculateEmbeddedHeight() : embTbarHeight;
554 if (tbar.getWidth() > 0 && tbarHeight > 0) {
John Reck1adf0302011-10-11 10:58:12 -0700555 if (mTitleBarBitmap == null
556 || mTitleBarBitmap.getWidth() != tbar.getWidth()
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800557 || mTitleBarBitmap.getHeight() != tbarHeight) {
John Recka98c83b2011-10-31 12:31:58 -0700558 mTitleBarBitmap = safeCreateBitmap(tbar.getWidth(),
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800559 tbarHeight);
John Reck1adf0302011-10-11 10:58:12 -0700560 }
John Recka98c83b2011-10-31 12:31:58 -0700561 if (mTitleBarBitmap != null) {
562 Canvas c = new Canvas(mTitleBarBitmap);
563 tbar.draw(c);
564 c.setBitmap(null);
565 }
John Reck1adf0302011-10-11 10:58:12 -0700566 } else {
567 mTitleBarBitmap = null;
John Reckcc0059c2011-10-07 13:53:13 -0700568 }
John Reckcc0059c2011-10-07 13:53:13 -0700569 mTitle.setImageBitmap(mTitleBarBitmap);
570 mTitle.setVisibility(View.VISIBLE);
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800571 // SWE: WebView.draw() wouldn't draw anything if SurfaceView is enabled.
572 mContentBitmap = web.getViewportBitmap();
573 if (mContentBitmap == null) {
574 int h = web.getHeight() - embTbarHeight;
575 if (mContentBitmap == null
576 || mContentBitmap.getWidth() != web.getWidth()
577 || mContentBitmap.getHeight() != h) {
578 mContentBitmap = safeCreateBitmap(web.getWidth(), h);
579 }
580 if (mContentBitmap != null) {
581 Canvas c = new Canvas(mContentBitmap);
582 int tx = web.getScrollX();
583 int ty = web.getScrollY();
584 c.translate(-tx, -ty - embTbarHeight);
585 web.draw(c);
586 c.setBitmap(null);
587 }
John Recka98c83b2011-10-31 12:31:58 -0700588 }
John Reckcc0059c2011-10-07 13:53:13 -0700589 mContent.setImageBitmap(mContentBitmap);
Michael Kolbc3af0672011-08-09 10:24:41 -0700590 }
591
John Recka98c83b2011-10-31 12:31:58 -0700592 private Bitmap safeCreateBitmap(int width, int height) {
593 if (width <= 0 || height <= 0) {
594 Log.w(LOGTAG, "safeCreateBitmap failed! width: " + width
595 + ", height: " + height);
596 return null;
597 }
598 return Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
599 }
600
John Reckcc0059c2011-10-07 13:53:13 -0700601 public void set(Bitmap image) {
Michael Kolba3194d02011-09-07 11:23:51 -0700602 mTitle.setVisibility(View.GONE);
Michael Kolbc3af0672011-08-09 10:24:41 -0700603 mContent.setImageBitmap(image);
Michael Kolbc3af0672011-08-09 10:24:41 -0700604 }
605
John Reckcc0059c2011-10-07 13:53:13 -0700606 private void setScaleFactor(float sf) {
Michael Kolbc3af0672011-08-09 10:24:41 -0700607 mScale = sf;
608 Matrix m = new Matrix();
609 m.postScale(sf,sf);
610 mContent.setImageMatrix(m);
611 }
612
John Reckcc0059c2011-10-07 13:53:13 -0700613 private float getScaleFactor() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700614 return mScale;
615 }
616
John Reck3ba45532011-08-11 16:26:53 -0700617 }
618
Michael Kolb66706532010-12-12 19:50:22 -0800619}