blob: a1cb7b318b91a1829297759e1be16fc6c9518296 [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;
Sudheer Koganti06cd42f2015-01-30 15:35:12 -080026import android.graphics.Canvas;
Michael Kolbc3af0672011-08-09 10:24:41 -070027import android.graphics.Matrix;
Sudheer Koganti06cd42f2015-01-30 15:35:12 -080028import android.graphics.Paint;
Tarun Nainaniea28dde2014-08-27 17:25:09 -070029import android.graphics.Rect;
John Reck9c5004e2011-10-07 16:00:12 -070030import android.os.Message;
Michael Kolb376b5412010-12-15 11:52:57 -080031import android.util.Log;
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;
Enrico Ros1f5a0952014-11-18 20:15:48 -080039import android.view.animation.DecelerateInterpolator;
Tarun Nainaniea28dde2014-08-27 17:25:09 -070040import android.webkit.ValueCallback;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080041import org.codeaurora.swe.WebView;
Michael Kolbc3af0672011-08-09 10:24:41 -070042import android.widget.ImageView;
Michael Kolb66706532010-12-12 19:50:22 -080043
Bijan Amirzada41242f22014-03-21 12:12:18 -070044import com.android.browser.UrlInputView.StateListener;
Michael Kolb629b22c2011-07-13 16:26:47 -070045
Michael Kolb66706532010-12-12 19:50:22 -080046/**
47 * Ui for regular phone screen sizes
48 */
49public class PhoneUi extends BaseUi {
50
51 private static final String LOGTAG = "PhoneUi";
John Reck9c5004e2011-10-07 16:00:12 -070052 private static final int MSG_INIT_NAVSCREEN = 100;
Michael Kolb66706532010-12-12 19:50:22 -080053
Michael Kolbf2055602011-04-09 17:20:03 -070054 private NavScreen mNavScreen;
John Reckcc0059c2011-10-07 13:53:13 -070055 private AnimScreen mAnimScreen;
John Reck0f602f32011-07-07 15:38:43 -070056 private NavigationBarPhone mNavigationBar;
Vivek Sekhar60eb9802014-07-21 19:13:33 -070057 private Activity mBrowser;
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -080058 private boolean mNavScreenRequested = false;
Michael Kolb66706532010-12-12 19:50:22 -080059
Michael Kolb08a687a2011-04-22 16:13:02 -070060 boolean mAnimating;
yijunx.zhu2230a312012-07-27 13:37:00 -040061 boolean mShowNav = false;
Michael Kolb66706532010-12-12 19:50:22 -080062
Vivek Sekhar60eb9802014-07-21 19:13:33 -070063
Michael Kolb66706532010-12-12 19:50:22 -080064 /**
65 * @param browser
66 * @param controller
67 */
68 public PhoneUi(Activity browser, UiController controller) {
69 super(browser, controller);
John Reck0f602f32011-07-07 15:38:43 -070070 mNavigationBar = (NavigationBarPhone) mTitleBar.getNavigationBar();
Vivek Sekhar60eb9802014-07-21 19:13:33 -070071 mBrowser = browser;
John Reck285ef042011-02-11 15:44:17 -080072 }
Michael Kolb66706532010-12-12 19:50:22 -080073
John Reck285ef042011-02-11 15:44:17 -080074 @Override
Michael Kolb66706532010-12-12 19:50:22 -080075 public void onDestroy() {
Michael Kolb7cdc4902011-02-03 17:54:40 -080076 hideTitleBar();
Karthikeyan Periasamy5b8f5752015-01-13 16:00:27 -080077 // Free the allocated memory for GC to clear it from the heap.
78 mAnimScreen = null;
Michael Kolb66706532010-12-12 19:50:22 -080079 }
80
81 @Override
Michael Kolb1f9b3562012-04-24 14:38:34 -070082 public void editUrl(boolean clearInput, boolean forceIME) {
yijunx.zhu2230a312012-07-27 13:37:00 -040083 //Do nothing while at Nav show screen.
84 if (mShowNav) return;
Michael Kolb1f9b3562012-04-24 14:38:34 -070085 super.editUrl(clearInput, forceIME);
Michael Kolbdc2ee1b2011-02-14 14:34:40 -080086 }
87
88 @Override
Michael Kolb66706532010-12-12 19:50:22 -080089 public boolean onBackKey() {
John Reckcc0059c2011-10-07 13:53:13 -070090 if (showingNavScreen()) {
Michael Kolba3194d02011-09-07 11:23:51 -070091 mNavScreen.close(mUiController.getTabControl().getCurrentPosition());
Michael Kolbf2055602011-04-09 17:20:03 -070092 return true;
Michael Kolb66706532010-12-12 19:50:22 -080093 }
94 return super.onBackKey();
95 }
96
John Reckcc0059c2011-10-07 13:53:13 -070097 private boolean showingNavScreen() {
98 return mNavScreen != null && mNavScreen.getVisibility() == View.VISIBLE;
99 }
100
Michael Kolb66706532010-12-12 19:50:22 -0800101 @Override
Michael Kolbf2055602011-04-09 17:20:03 -0700102 public boolean dispatchKey(int code, KeyEvent event) {
Michael Kolbf2055602011-04-09 17:20:03 -0700103 return false;
104 }
105
106 @Override
John Reck30c714c2010-12-16 17:30:34 -0800107 public void onProgressChanged(Tab tab) {
Michael Kolbe8a82332012-04-25 14:14:26 -0700108 super.onProgressChanged(tab);
John Reck9c5004e2011-10-07 16:00:12 -0700109 if (mNavScreen == null && getTitleBar().getHeight() > 0) {
110 mHandler.sendEmptyMessage(MSG_INIT_NAVSCREEN);
111 }
112 }
113
114 @Override
115 protected void handleMessage(Message msg) {
116 super.handleMessage(msg);
117 if (msg.what == MSG_INIT_NAVSCREEN) {
118 if (mNavScreen == null) {
119 mNavScreen = new NavScreen(mActivity, mUiController, this);
120 mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
121 mNavScreen.setVisibility(View.GONE);
122 }
123 if (mAnimScreen == null) {
124 mAnimScreen = new AnimScreen(mActivity);
125 // initialize bitmaps
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700126 //mAnimScreen.set(getTitleBar(), getWebView());
John Reck9c5004e2011-10-07 16:00:12 -0700127 }
128 }
Michael Kolb66706532010-12-12 19:50:22 -0800129 }
130
131 @Override
Michael Kolbfdb70242011-03-24 09:41:11 -0700132 public void setActiveTab(final Tab tab) {
John Reck8ee633f2011-08-09 16:00:35 -0700133 mTitleBar.cancelTitleBarAnimation(true);
134 mTitleBar.setSkipTitleBarAnimations(true);
John Reck5d43ce82011-06-21 17:16:51 -0700135 super.setActiveTab(tab);
yijunx.zhu2230a312012-07-27 13:37:00 -0400136
137 //if at Nav screen show, detach tab like what showNavScreen() do.
138 if (mShowNav) {
139 detachTab(mActiveTab);
140 }
141
Michael Kolbfdb70242011-03-24 09:41:11 -0700142 BrowserWebView view = (BrowserWebView) tab.getWebView();
Michael Kolb376b5412010-12-15 11:52:57 -0800143 // TabControl.setCurrentTab has been called before this,
144 // so the tab is guaranteed to have a webview
145 if (view == null) {
146 Log.e(LOGTAG, "active tab with no webview detected");
147 return;
148 }
Michael Kolbfdb70242011-03-24 09:41:11 -0700149 // Request focus on the top window.
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700150 view.setTitleBar(mTitleBar);
151
Michael Kolb629b22c2011-07-13 16:26:47 -0700152 // update nav bar state
153 mNavigationBar.onStateChanged(StateListener.STATE_NORMAL);
Michael Kolbfdb70242011-03-24 09:41:11 -0700154 updateLockIconToLatest(tab);
John Reck8ee633f2011-08-09 16:00:35 -0700155 mTitleBar.setSkipTitleBarAnimations(false);
Michael Kolb376b5412010-12-15 11:52:57 -0800156 }
157
Michael Kolb66706532010-12-12 19:50:22 -0800158 // menu handling callbacks
159
160 @Override
Michael Kolb3ca12752011-07-20 13:52:25 -0700161 public boolean onPrepareOptionsMenu(Menu menu) {
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700162 updateMenuState(mActiveTab, menu);
Michael Kolb3ca12752011-07-20 13:52:25 -0700163 return true;
164 }
165
166 @Override
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700167 public void updateMenuState(Tab tab, Menu menu) {
Michael Kolb0d0245f2011-12-05 16:36:05 -0800168 MenuItem bm = menu.findItem(R.id.bookmarks_menu_id);
169 if (bm != null) {
170 bm.setVisible(!showingNavScreen());
171 }
Michael Kolb315d5022011-10-13 12:47:11 -0700172 MenuItem info = menu.findItem(R.id.page_info_menu_id);
173 if (info != null) {
174 info.setVisible(false);
175 }
Pankaj Garg49b79252014-11-07 17:33:41 -0800176
John Reckcc0059c2011-10-07 13:53:13 -0700177 if (showingNavScreen()) {
Pankaj Garg49b79252014-11-07 17:33:41 -0800178 setMenuItemVisibility(menu, R.id.history_menu_id, false);
179 setMenuItemVisibility(menu, R.id.find_menu_id, false);
John Recke1a03a32011-09-14 17:04:16 -0700180 menu.setGroupVisible(R.id.LIVE_MENU, false);
Pankaj Garg49b79252014-11-07 17:33:41 -0800181 setMenuItemVisibility(menu, R.id.save_snapshot_menu_id, false);
John Recke1a03a32011-09-14 17:04:16 -0700182 menu.setGroupVisible(R.id.SNAPSHOT_MENU, false);
John Recke1a03a32011-09-14 17:04:16 -0700183 menu.setGroupVisible(R.id.NAV_MENU, false);
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700184 }
185 }
186
187 @Override
Michael Kolb3ca12752011-07-20 13:52:25 -0700188 public boolean onOptionsItemSelected(MenuItem item) {
Michael Kolb315d5022011-10-13 12:47:11 -0700189 if (showingNavScreen()
190 && (item.getItemId() != R.id.history_menu_id)
191 && (item.getItemId() != R.id.snapshots_menu_id)) {
Michael Kolba3194d02011-09-07 11:23:51 -0700192 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
Michael Kolb3ca12752011-07-20 13:52:25 -0700193 }
194 return false;
195 }
196
197 @Override
Michael Kolb66706532010-12-12 19:50:22 -0800198 public void onContextMenuCreated(Menu menu) {
Michael Kolb7cdc4902011-02-03 17:54:40 -0800199 hideTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -0800200 }
201
202 @Override
203 public void onContextMenuClosed(Menu menu, boolean inLoad) {
204 if (inLoad) {
Michael Kolb7cdc4902011-02-03 17:54:40 -0800205 showTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -0800206 }
207 }
208
209 // action mode callbacks
210
211 @Override
212 public void onActionModeStarted(ActionMode mode) {
Bijan Amirzada357ec8a2014-04-08 14:19:10 -0700213 super.onActionModeStarted(mode);
Michael Kolb42c0c062011-08-02 12:56:06 -0700214 if (!isEditingUrl()) {
215 hideTitleBar();
216 }
Michael Kolb66706532010-12-12 19:50:22 -0800217 }
218
Michael Kolba4183062011-01-16 10:43:21 -0800219 @Override
John Reck6cda7b12011-03-18 15:57:13 -0700220 public void onActionModeFinished(boolean inLoad) {
Bijan Amirzada357ec8a2014-04-08 14:19:10 -0700221 super.onActionModeFinished(inLoad);
Michael Kolbc16c5952011-03-29 15:37:03 -0700222 if (inLoad) {
Michael Kolbc16c5952011-03-29 15:37:03 -0700223 showTitleBar();
224 }
John Reck6cda7b12011-03-18 15:57:13 -0700225 }
226
227 @Override
Michael Kolbc3af0672011-08-09 10:24:41 -0700228 public boolean isWebShowing() {
John Reckcc0059c2011-10-07 13:53:13 -0700229 return super.isWebShowing() && !showingNavScreen();
Michael Kolbc3af0672011-08-09 10:24:41 -0700230 }
231
232 @Override
233 public void showWeb(boolean animate) {
234 super.showWeb(animate);
Michael Kolba3194d02011-09-07 11:23:51 -0700235 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), animate);
Michael Kolbc3af0672011-08-09 10:24:41 -0700236 }
237
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800238 //Unblock touch events
239 private void unblockEvents() {
240 mUiController.setBlockEvents(false);
241 }
242 //Block touch events
243 private void blockEvents() {
244 mUiController.setBlockEvents(true);
245 }
246
247 @Override
248 public void cancelNavScreenRequest() {
249 mNavScreenRequested = false;
250 }
251
Michael Kolbf2055602011-04-09 17:20:03 -0700252 void showNavScreen() {
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700253 WebView webView = getWebView();
254 if (webView != null) {
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800255 blockEvents();
256 mNavScreenRequested = true;
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800257
Sudheer Koganti06cd42f2015-01-30 15:35:12 -0800258 //To conserve memory, get a scaled down version of the screen and
259 //scale back up to full size
260 //0.25 uses 16 times less memory than the full size
261 final float downscaleRatio = 0.25f;
262 final float upscaleRatio = 1/downscaleRatio;
263 webView.getContentBitmapAsync(
264 downscaleRatio,
265 new Rect(),
266 new ValueCallback<Bitmap>() {
267 @Override
268 public void onReceiveValue(Bitmap bm) {
269 // Discard the callback if the req is interrupted
270 if (!mNavScreenRequested) {
271 unblockEvents();
272 return;
273 }
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800274
Sudheer Koganti06cd42f2015-01-30 15:35:12 -0800275 Bitmap sbm = bm;
276 if (bm != null) {
277 //Upscale the low-res bitmap to the needed size
278 sbm = Bitmap.createBitmap((int) upscaleRatio * bm.getWidth(),
279 (int) upscaleRatio * bm.getHeight(), Bitmap.Config.RGB_565);
280 Canvas canvas = new Canvas(sbm);
281 Matrix m = new Matrix();
282 m.setScale(upscaleRatio, upscaleRatio, 0.0f, 0.0f);
283 canvas.drawBitmap(bm, m, new Paint(Paint.FILTER_BITMAP_FLAG));
284 }
285
286 onShowNavScreenContinue(sbm);
287 }
288 }
289 );
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700290 }
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700291 }
292
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800293 void onShowNavScreenContinue(Bitmap viewportBitmap) {
294 dismissIME();
295 mShowNav = true;
296 mNavScreenRequested = false;
John Reckcc0059c2011-10-07 13:53:13 -0700297 if (mNavScreen == null) {
298 mNavScreen = new NavScreen(mActivity, mUiController, this);
299 mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
300 } else {
301 mNavScreen.setVisibility(View.VISIBLE);
302 mNavScreen.setAlpha(1f);
John Reck9c5004e2011-10-07 16:00:12 -0700303 mNavScreen.refreshAdapter();
John Reckcc0059c2011-10-07 13:53:13 -0700304 }
Michael Kolbc3af0672011-08-09 10:24:41 -0700305 mActiveTab.capture();
Sagar Dhawan01493f62015-02-09 11:03:19 -0800306 if (mAnimScreen == null) {
307 mAnimScreen = new AnimScreen(mActivity);
308 } else {
309 mAnimScreen.mMain.setAlpha(1f);
310 mAnimScreen.setScaleFactor(1f);
311 }
312 mAnimScreen.set(getTitleBar(), viewportBitmap);
313 if (mAnimScreen.mMain.getParent() == null) {
314 mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
315 }
Michael Kolbf2055602011-04-09 17:20:03 -0700316 mCustomViewContainer.setVisibility(View.VISIBLE);
317 mCustomViewContainer.bringToFront();
Sagar Dhawan01493f62015-02-09 11:03:19 -0800318 mAnimScreen.mMain.layout(0, 0, mContentView.getWidth(),
319 mContentView.getHeight());
320 int fromLeft = 0;
321 int fromTop = getTitleBar().getHeight();
322 int fromRight = mContentView.getWidth();
323 int fromBottom = mContentView.getHeight();
324 int width = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_width);
325 int height = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_height);
326 int ntth = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_titleheight);
327 int toLeft = (mContentView.getWidth() - width) / 2;
328 int toTop = ((fromBottom - (ntth + height)) / 2 + ntth);
329 int toRight = toLeft + width;
330 int toBottom = toTop + height;
331 float toScaleFactor = width / (float) mContentView.getWidth();
332 ObjectAnimator tx = ObjectAnimator.ofInt(mAnimScreen.mContent, "left", fromLeft, toLeft);
333 ObjectAnimator ty = ObjectAnimator.ofInt(mAnimScreen.mContent, "top", fromTop, toTop);
334 ObjectAnimator tr = ObjectAnimator.ofInt(mAnimScreen.mContent, "right", fromRight, toRight);
335 ObjectAnimator tb = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom", fromBottom, toBottom);
336 ObjectAnimator sx = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor", 1f, toScaleFactor);
337 ObjectAnimator navTabsIn = mNavScreen.createToolbarInAnimator();
338 mAnimScreen.mContent.layout(fromLeft, fromTop, fromRight, fromBottom);
339 mAnimScreen.setScaleFactor(1f);
Michael Kolba3194d02011-09-07 11:23:51 -0700340
Sagar Dhawan01493f62015-02-09 11:03:19 -0800341 AnimatorSet inanim = new AnimatorSet();
342 inanim.playTogether(tx, ty, tr, tb, sx, navTabsIn);
343 inanim.setInterpolator(new DecelerateInterpolator());
344 inanim.setDuration(200);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800345
Sagar Dhawan01493f62015-02-09 11:03:19 -0800346 ObjectAnimator disappear = ObjectAnimator.ofFloat(mAnimScreen.mMain, "alpha", 1f, 0f);
347 disappear.setInterpolator(new DecelerateInterpolator());
348 disappear.setDuration(100);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800349
Sagar Dhawan01493f62015-02-09 11:03:19 -0800350 AnimatorSet set1 = new AnimatorSet();
351 set1.addListener(new AnimatorListenerAdapter() {
352 @Override
353 public void onAnimationStart(Animator animation) {
354 mContentView.setVisibility(View.GONE);
355 }
356 @Override
357 public void onAnimationEnd(Animator anim) {
358 mCustomViewContainer.removeView(mAnimScreen.mMain);
359 finishAnimationIn();
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800360 unblockEvents();
Sagar Dhawan01493f62015-02-09 11:03:19 -0800361 }
362 });
363 set1.playSequentially(inanim, disappear);
364 set1.start();
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800365 unblockEvents();
Michael Kolbc3af0672011-08-09 10:24:41 -0700366 }
367
368 private void finishAnimationIn() {
John Reckcc0059c2011-10-07 13:53:13 -0700369 if (showingNavScreen()) {
Michael Kolbb43f2f62011-08-17 10:39:31 -0700370 // notify accessibility manager about the screen change
371 mNavScreen.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
372 mTabControl.setOnThumbnailUpdatedListener(mNavScreen);
373 }
Michael Kolbf2055602011-04-09 17:20:03 -0700374 }
375
Michael Kolba3194d02011-09-07 11:23:51 -0700376 void hideNavScreen(int position, boolean animate) {
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800377
yijunx.zhu2230a312012-07-27 13:37:00 -0400378 mShowNav = false;
John Reckcc0059c2011-10-07 13:53:13 -0700379 if (!showingNavScreen()) return;
Michael Kolba3194d02011-09-07 11:23:51 -0700380 final Tab tab = mUiController.getTabControl().getTab(position);
Michael Kolbbf32cd02011-08-16 15:07:04 -0700381 if ((tab == null) || !animate) {
Michael Kolb365561d2011-08-18 09:56:25 -0700382 if (tab != null) {
383 setActiveTab(tab);
384 } else if (mTabControl.getTabCount() > 0) {
385 // use a fallback tab
386 setActiveTab(mTabControl.getCurrentTab());
387 }
Michael Kolbbf32cd02011-08-16 15:07:04 -0700388 mContentView.setVisibility(View.VISIBLE);
389 finishAnimateOut();
Michael Kolb8a009492011-08-15 15:37:30 -0700390 return;
Michael Kolbc3af0672011-08-09 10:24:41 -0700391 }
Michael Kolba3194d02011-09-07 11:23:51 -0700392 NavTabView tabview = (NavTabView) mNavScreen.getTabView(position);
Michael Kolbc3af0672011-08-09 10:24:41 -0700393 if (tabview == null) {
Michael Kolb365561d2011-08-18 09:56:25 -0700394 if (mTabControl.getTabCount() > 0) {
395 // use a fallback tab
396 setActiveTab(mTabControl.getCurrentTab());
397 }
Michael Kolbbf32cd02011-08-16 15:07:04 -0700398 mContentView.setVisibility(View.VISIBLE);
399 finishAnimateOut();
Michael Kolb8a009492011-08-15 15:37:30 -0700400 return;
Michael Kolbc3af0672011-08-09 10:24:41 -0700401 }
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800402 blockEvents();
Michael Kolbc3af0672011-08-09 10:24:41 -0700403 mUiController.setActiveTab(tab);
404 mContentView.setVisibility(View.VISIBLE);
John Reckcc0059c2011-10-07 13:53:13 -0700405 if (mAnimScreen == null) {
406 mAnimScreen = new AnimScreen(mActivity);
407 }
Tarun Nainani8eb00912014-07-17 12:28:32 -0700408 ImageView target = tabview.mImage;
409 int width = target.getDrawable().getIntrinsicWidth();
410 int height = target.getDrawable().getIntrinsicHeight();
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700411 Bitmap bm = tab.getScreenshot();
Vivek Sekharc549e3a2014-06-05 16:19:26 -0700412 if (bm == null)
413 bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
414 mAnimScreen.set(bm);
Michael Kolb0755fcd2012-01-10 10:19:50 -0800415 if (mAnimScreen.mMain.getParent() == null) {
416 mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
417 }
John Reckcc0059c2011-10-07 13:53:13 -0700418 mAnimScreen.mMain.layout(0, 0, mContentView.getWidth(),
Tarun Nainani8eb00912014-07-17 12:28:32 -0700419 mContentView.getHeight());
Enrico Ros80c045a2014-11-24 15:23:12 -0800420 mNavScreen.getScroller().finishScroller();
Michael Kolbc3af0672011-08-09 10:24:41 -0700421 int toLeft = 0;
Tarun Nainani8eb00912014-07-17 12:28:32 -0700422 int toTop = mTitleBar.calculateEmbeddedHeight();
Michael Kolbc3af0672011-08-09 10:24:41 -0700423 int toRight = mContentView.getWidth();
Enrico Ros80c045a2014-11-24 15:23:12 -0800424 int fromLeft = tabview.getLeft() + target.getLeft() - mNavScreen.getScroller().getScrollX();
425 int fromTop = tabview.getTop() + target.getTop() - mNavScreen.getScroller().getScrollY();
Tarun Nainani8eb00912014-07-17 12:28:32 -0700426 int fromRight = fromLeft + width;
427 int fromBottom = fromTop + height;
Michael Kolbc3af0672011-08-09 10:24:41 -0700428 float scaleFactor = mContentView.getWidth() / (float) width;
Michael Kolba3194d02011-09-07 11:23:51 -0700429 int toBottom = toTop + (int) (height * scaleFactor);
John Reck9c5004e2011-10-07 16:00:12 -0700430 mAnimScreen.mContent.setLeft(fromLeft);
431 mAnimScreen.mContent.setTop(fromTop);
432 mAnimScreen.mContent.setRight(fromRight);
433 mAnimScreen.mContent.setBottom(fromBottom);
434 mAnimScreen.setScaleFactor(1f);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800435 //ObjectAnimator fade2 = ObjectAnimator.ofFloat(mNavScreen, "alpha", 1f, 0f);
436 //fade2.setDuration(100);
437 AnimatorSet set = new AnimatorSet();
438 ObjectAnimator animAppear = ObjectAnimator.ofFloat(mAnimScreen.mMain, "alpha", 0f, 1f);
439 animAppear.setDuration(100);
440 ObjectAnimator l = ObjectAnimator.ofInt(mAnimScreen.mContent, "left", fromLeft, toLeft);
441 ObjectAnimator t = ObjectAnimator.ofInt(mAnimScreen.mContent, "top", fromTop, toTop);
442 ObjectAnimator r = ObjectAnimator.ofInt(mAnimScreen.mContent, "right", fromRight, toRight);
443 ObjectAnimator b = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom", fromBottom, toBottom);
444 ObjectAnimator scale = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor", 1f, scaleFactor);
445 set.playTogether(animAppear, l, t, r, b, scale);
446 set.setInterpolator(new DecelerateInterpolator());
447 set.setDuration(200);
448 set.addListener(new AnimatorListenerAdapter() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700449 @Override
450 public void onAnimationEnd(Animator anim) {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400451 checkTabReady();
452 }
453 });
Enrico Ros1f5a0952014-11-18 20:15:48 -0800454 set.start();
Matthew Hui1eb7a832014-04-15 12:20:58 -0400455 }
456
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700457
458 private int mNumTries = 0;
Matthew Hui1eb7a832014-04-15 12:20:58 -0400459 private void checkTabReady() {
460 boolean isready = true;
Enrico Ros1f5a0952014-11-18 20:15:48 -0800461 boolean zeroTries = mNumTries == 0;
Matthew Hui1eb7a832014-04-15 12:20:58 -0400462 Tab tab = mUiController.getTabControl().getCurrentTab();
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700463 BrowserWebView webview = null;
Matthew Hui1eb7a832014-04-15 12:20:58 -0400464 if (tab == null)
465 isready = false;
466 else {
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700467 webview = (BrowserWebView)tab.getWebView();
468 if (webview == null) {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400469 isready = false;
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700470 }
471 else if (webview.hasCrashed()) {
472 webview.reload();
473 isready = true;
474 } else {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400475 isready = webview.isReady();
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700476 }
Matthew Hui1eb7a832014-04-15 12:20:58 -0400477 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700478 // Post only when not ready and not crashed
479 if (!isready && mNumTries++ < 150) {
480 mCustomViewContainer.postDelayed(new Runnable() {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400481 public void run() {
482 checkTabReady();
483 }
484 }, 17); //WebView is not ready. check again in for next frame.
485 return;
486 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700487 mNumTries = 0;
488 final boolean hasCrashed = (webview == null) ? false : webview.hasCrashed();
Enrico Ros1f5a0952014-11-18 20:15:48 -0800489 // fast path: don't wait if we've been ready for a while
490 if (zeroTries) {
491 fadeOutCustomViewContainer(hasCrashed);
492 return;
493 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700494 mCustomViewContainer.postDelayed(new Runnable() {
Enrico Ros1f5a0952014-11-18 20:15:48 -0800495 public void run() {
496 fadeOutCustomViewContainer(hasCrashed);
497 }
498 }, 32); //WebView is ready, but give it extra 2 frame's time to display and finish the swaps
Matthew Hui1eb7a832014-04-15 12:20:58 -0400499 }
500
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700501 private void fadeOutCustomViewContainer(boolean hasCrashed) {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400502 ObjectAnimator otheralpha = ObjectAnimator.ofFloat(mCustomViewContainer, "alpha", 1f, 0f);
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700503 if (hasCrashed)
504 otheralpha.setDuration(300);
505 else
506 otheralpha.setDuration(100);
Matthew Hui1eb7a832014-04-15 12:20:58 -0400507 otheralpha.addListener(new AnimatorListenerAdapter() {
508 @Override
509 public void onAnimationEnd(Animator anim) {
John Reckcc0059c2011-10-07 13:53:13 -0700510 mCustomViewContainer.removeView(mAnimScreen.mMain);
Michael Kolbbf32cd02011-08-16 15:07:04 -0700511 finishAnimateOut();
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800512 unblockEvents();
Michael Kolbc3af0672011-08-09 10:24:41 -0700513 }
514 });
Enrico Ros1f5a0952014-11-18 20:15:48 -0800515 otheralpha.setInterpolator(new DecelerateInterpolator());
Matthew Hui1eb7a832014-04-15 12:20:58 -0400516 otheralpha.start();
Michael Kolbc3af0672011-08-09 10:24:41 -0700517 }
518
Michael Kolbbf32cd02011-08-16 15:07:04 -0700519 private void finishAnimateOut() {
John Reck8ee633f2011-08-09 16:00:35 -0700520 mTabControl.setOnThumbnailUpdatedListener(null);
John Reckcc0059c2011-10-07 13:53:13 -0700521 mNavScreen.setVisibility(View.GONE);
Michael Kolbc3af0672011-08-09 10:24:41 -0700522 mCustomViewContainer.setAlpha(1f);
Michael Kolbf2055602011-04-09 17:20:03 -0700523 mCustomViewContainer.setVisibility(View.GONE);
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700524 mAnimScreen.set(null);
Michael Kolbf2055602011-04-09 17:20:03 -0700525 }
526
John Reck6b4bd5f2011-07-12 10:14:38 -0700527 @Override
528 public boolean needsRestoreAllTabs() {
529 return false;
530 }
531
Michael Kolb20be26d2011-07-18 16:38:02 -0700532 public void toggleNavScreen() {
John Reckcc0059c2011-10-07 13:53:13 -0700533 if (!showingNavScreen()) {
Michael Kolb20be26d2011-07-18 16:38:02 -0700534 showNavScreen();
535 } else {
Michael Kolba3194d02011-09-07 11:23:51 -0700536 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
Michael Kolb20be26d2011-07-18 16:38:02 -0700537 }
538 }
539
John Reck1cf4b792011-07-26 10:22:22 -0700540 @Override
541 public boolean shouldCaptureThumbnails() {
542 return true;
543 }
544
Michael Kolbc3af0672011-08-09 10:24:41 -0700545 static class AnimScreen {
John Reck3ba45532011-08-11 16:26:53 -0700546
Michael Kolbc3af0672011-08-09 10:24:41 -0700547 private View mMain;
Michael Kolbc3af0672011-08-09 10:24:41 -0700548 private ImageView mContent;
549 private float mScale;
550
John Reckcc0059c2011-10-07 13:53:13 -0700551 public AnimScreen(Context ctx) {
Enrico Ros1f5a0952014-11-18 20:15:48 -0800552 mMain = LayoutInflater.from(ctx).inflate(R.layout.anim_screen, null);
553 mMain.setOnClickListener(new View.OnClickListener() {
554 @Override
555 public void onClick(View v) {
556 // just eat clicks when this view is visible
557 }
558 });
559 mContent = (ImageView) mMain.findViewById(R.id.anim_screen_content);
John Reckcc0059c2011-10-07 13:53:13 -0700560 mContent.setScaleType(ImageView.ScaleType.MATRIX);
561 mContent.setImageMatrix(new Matrix());
562 mScale = 1.0f;
563 setScaleFactor(getScaleFactor());
564 }
565
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700566 public void set(TitleBar tbar, Bitmap viewportBitmap) {
567 if (tbar == null) {
John Reck62077d82011-10-13 15:17:50 -0700568 return;
569 }
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700570 mContent.setImageBitmap(viewportBitmap);
Michael Kolbc3af0672011-08-09 10:24:41 -0700571 }
572
Enrico Ros1f5a0952014-11-18 20:15:48 -0800573 /*private Bitmap safeCreateBitmap(int width, int height) {
John Recka98c83b2011-10-31 12:31:58 -0700574 if (width <= 0 || height <= 0) {
575 Log.w(LOGTAG, "safeCreateBitmap failed! width: " + width
576 + ", height: " + height);
577 return null;
578 }
579 return Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800580 }*/
John Recka98c83b2011-10-31 12:31:58 -0700581
John Reckcc0059c2011-10-07 13:53:13 -0700582 public void set(Bitmap image) {
Michael Kolbc3af0672011-08-09 10:24:41 -0700583 mContent.setImageBitmap(image);
Michael Kolbc3af0672011-08-09 10:24:41 -0700584 }
585
John Reckcc0059c2011-10-07 13:53:13 -0700586 private void setScaleFactor(float sf) {
Michael Kolbc3af0672011-08-09 10:24:41 -0700587 mScale = sf;
588 Matrix m = new Matrix();
Enrico Ros1f5a0952014-11-18 20:15:48 -0800589 m.postScale(sf, sf);
Michael Kolbc3af0672011-08-09 10:24:41 -0700590 mContent.setImageMatrix(m);
591 }
592
John Reckcc0059c2011-10-07 13:53:13 -0700593 private float getScaleFactor() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700594 return mScale;
595 }
596
John Reck3ba45532011-08-11 16:26:53 -0700597 }
598
Michael Kolb66706532010-12-12 19:50:22 -0800599}