blob: 9f56b12e86855be7265ecd29414faa60eca555c0 [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;
Pankaj Garg175dfbc2015-07-10 15:03:49 -070023import android.app.ActionBar;
Michael Kolb66706532010-12-12 19:50:22 -080024import android.app.Activity;
Michael Kolbc3af0672011-08-09 10:24:41 -070025import android.content.Context;
26import android.graphics.Bitmap;
Michael Kolbc3af0672011-08-09 10:24:41 -070027import android.graphics.Matrix;
Tarun Nainani87a86682015-02-05 11:47:35 -080028import android.os.Bundle;
Pankaj Gargb4b4f012015-08-04 16:19:14 -070029import android.os.CountDownTimer;
Michael Kolb376b5412010-12-15 11:52:57 -080030import android.util.Log;
Michael Kolb66706532010-12-12 19:50:22 -080031import android.view.ActionMode;
Michael Kolba4183062011-01-16 10:43:21 -080032import android.view.KeyEvent;
Michael Kolbc3af0672011-08-09 10:24:41 -070033import android.view.LayoutInflater;
Michael Kolb66706532010-12-12 19:50:22 -080034import android.view.Menu;
Michael Kolb3ca12752011-07-20 13:52:25 -070035import android.view.MenuItem;
Michael Kolb66706532010-12-12 19:50:22 -080036import android.view.View;
Tarun Nainani87a86682015-02-05 11:47:35 -080037import android.view.ViewStub;
Michael Kolb30adae62011-07-29 13:37:05 -070038import android.view.accessibility.AccessibilityEvent;
Enrico Ros1f5a0952014-11-18 20:15:48 -080039import android.view.animation.DecelerateInterpolator;
Pankaj Garg66f8cef2015-07-07 17:29:03 -070040
Tarun Nainani87a86682015-02-05 11:47:35 -080041import org.codeaurora.swe.WebView;
42
Michael Kolbc3af0672011-08-09 10:24:41 -070043import android.widget.ImageView;
Michael Kolb66706532010-12-12 19:50:22 -080044
Bijan Amirzada41242f22014-03-21 12:12:18 -070045import com.android.browser.UrlInputView.StateListener;
Michael Kolb629b22c2011-07-13 16:26:47 -070046
Dany Rybnikovbcd37da2015-04-20 11:43:15 +030047import org.codeaurora.net.NetworkServices;
Pankaj Garg79878492015-04-01 14:48:21 -070048
Michael Kolb66706532010-12-12 19:50:22 -080049/**
50 * Ui for regular phone screen sizes
51 */
52public class PhoneUi extends BaseUi {
53
54 private static final String LOGTAG = "PhoneUi";
55
Michael Kolbf2055602011-04-09 17:20:03 -070056 private NavScreen mNavScreen;
John Reckcc0059c2011-10-07 13:53:13 -070057 private AnimScreen mAnimScreen;
Tarun Nainani87a86682015-02-05 11:47:35 -080058 private final NavigationBarPhone mNavigationBar;
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -080059 private boolean mNavScreenRequested = false;
Michael Kolb66706532010-12-12 19:50:22 -080060
yijunx.zhu2230a312012-07-27 13:37:00 -040061 boolean mShowNav = false;
Tarun Nainani87a86682015-02-05 11:47:35 -080062 private ComboView mComboView;
Michael Kolb66706532010-12-12 19:50:22 -080063
Pankaj Gargb4b4f012015-08-04 16:19:14 -070064 private CountDownTimer mCaptureTimer;
65 private static final int mCaptureMaxWaitMS = 1000;
Vivek Sekhar60eb9802014-07-21 19:13:33 -070066
Michael Kolb66706532010-12-12 19:50:22 -080067 /**
68 * @param browser
69 * @param controller
70 */
71 public PhoneUi(Activity browser, UiController controller) {
72 super(browser, controller);
John Reck0f602f32011-07-07 15:38:43 -070073 mNavigationBar = (NavigationBarPhone) mTitleBar.getNavigationBar();
John Reck285ef042011-02-11 15:44:17 -080074 }
Michael Kolb66706532010-12-12 19:50:22 -080075
John Reck285ef042011-02-11 15:44:17 -080076 @Override
Michael Kolb66706532010-12-12 19:50:22 -080077 public void onDestroy() {
Michael Kolb7cdc4902011-02-03 17:54:40 -080078 hideTitleBar();
Karthikeyan Periasamy5b8f5752015-01-13 16:00:27 -080079 // Free the allocated memory for GC to clear it from the heap.
80 mAnimScreen = null;
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) {
yijunx.zhu2230a312012-07-27 13:37:00 -040085 //Do nothing while at Nav show screen.
86 if (mShowNav) return;
Michael Kolb1f9b3562012-04-24 14:38:34 -070087 super.editUrl(clearInput, forceIME);
Michael Kolbdc2ee1b2011-02-14 14:34:40 -080088 }
89
90 @Override
Tarun Nainani87a86682015-02-05 11:47:35 -080091 public void showComboView(ComboViews startingView, Bundle extras) {
92
93 if (mComboView == null) {
Pankaj Garg66f8cef2015-07-07 17:29:03 -070094 if (mNavScreen != null) {
95 mNavScreen.setVisibility(View.GONE);
96 }
97 ViewStub stub = (ViewStub) mActivity.getWindow().
98 getDecorView().findViewById(R.id.combo_view_stub);
Tarun Nainani87a86682015-02-05 11:47:35 -080099 mComboView = (ComboView) stub.inflate();
100 mComboView.setVisibility(View.GONE);
101 mComboView.setupViews(mActivity);
102 }
103
104 Bundle b = new Bundle();
105 b.putString(ComboViewActivity.EXTRA_INITIAL_VIEW, startingView.name());
106 b.putBundle(ComboViewActivity.EXTRA_COMBO_ARGS, extras);
107 Tab t = getActiveTab();
108 if (t != null) {
109 b.putString(ComboViewActivity.EXTRA_CURRENT_URL, t.getUrl());
110 }
111
112 mComboView.showViews(mActivity, b);
113 }
114
115 @Override
116 public void hideComboView() {
Vivek Sekharb0cd8762015-10-22 13:50:30 -0700117 if (mComboView != null)
118 mComboView.hideViews();
Tarun Nainani87a86682015-02-05 11:47:35 -0800119 }
120
121 @Override
Michael Kolb66706532010-12-12 19:50:22 -0800122 public boolean onBackKey() {
John Reckcc0059c2011-10-07 13:53:13 -0700123 if (showingNavScreen()) {
Michael Kolba3194d02011-09-07 11:23:51 -0700124 mNavScreen.close(mUiController.getTabControl().getCurrentPosition());
Michael Kolbf2055602011-04-09 17:20:03 -0700125 return true;
Michael Kolb66706532010-12-12 19:50:22 -0800126 }
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700127 if (isComboViewShowing()) {
Tarun Nainani87a86682015-02-05 11:47:35 -0800128 hideComboView();
129 return true;
130 }
Michael Kolb66706532010-12-12 19:50:22 -0800131 return super.onBackKey();
132 }
133
John Reckcc0059c2011-10-07 13:53:13 -0700134 private boolean showingNavScreen() {
135 return mNavScreen != null && mNavScreen.getVisibility() == View.VISIBLE;
136 }
137
Michael Kolb66706532010-12-12 19:50:22 -0800138 @Override
Michael Kolbf2055602011-04-09 17:20:03 -0700139 public boolean dispatchKey(int code, KeyEvent event) {
Michael Kolbf2055602011-04-09 17:20:03 -0700140 return false;
141 }
142
143 @Override
Michael Kolbfdb70242011-03-24 09:41:11 -0700144 public void setActiveTab(final Tab tab) {
John Reck5d43ce82011-06-21 17:16:51 -0700145 super.setActiveTab(tab);
yijunx.zhu2230a312012-07-27 13:37:00 -0400146
147 //if at Nav screen show, detach tab like what showNavScreen() do.
148 if (mShowNav) {
149 detachTab(mActiveTab);
150 }
151
Michael Kolbfdb70242011-03-24 09:41:11 -0700152 BrowserWebView view = (BrowserWebView) tab.getWebView();
Michael Kolb376b5412010-12-15 11:52:57 -0800153 // TabControl.setCurrentTab has been called before this,
154 // so the tab is guaranteed to have a webview
155 if (view == null) {
156 Log.e(LOGTAG, "active tab with no webview detected");
157 return;
158 }
Michael Kolbfdb70242011-03-24 09:41:11 -0700159 // Request focus on the top window.
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700160 view.setTitleBar(mTitleBar);
161
Michael Kolb629b22c2011-07-13 16:26:47 -0700162 // update nav bar state
163 mNavigationBar.onStateChanged(StateListener.STATE_NORMAL);
Michael Kolb376b5412010-12-15 11:52:57 -0800164 }
165
Michael Kolb66706532010-12-12 19:50:22 -0800166 // menu handling callbacks
167
168 @Override
Michael Kolb3ca12752011-07-20 13:52:25 -0700169 public boolean onPrepareOptionsMenu(Menu menu) {
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700170 updateMenuState(mActiveTab, menu);
Michael Kolb3ca12752011-07-20 13:52:25 -0700171 return true;
172 }
173
174 @Override
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700175 public void updateMenuState(Tab tab, Menu menu) {
Michael Kolb0d0245f2011-12-05 16:36:05 -0800176 MenuItem bm = menu.findItem(R.id.bookmarks_menu_id);
177 if (bm != null) {
178 bm.setVisible(!showingNavScreen());
179 }
Michael Kolb315d5022011-10-13 12:47:11 -0700180 MenuItem info = menu.findItem(R.id.page_info_menu_id);
181 if (info != null) {
182 info.setVisible(false);
183 }
Pankaj Garg49b79252014-11-07 17:33:41 -0800184
John Reckcc0059c2011-10-07 13:53:13 -0700185 if (showingNavScreen()) {
Pankaj Garg49b79252014-11-07 17:33:41 -0800186 setMenuItemVisibility(menu, R.id.find_menu_id, false);
John Recke1a03a32011-09-14 17:04:16 -0700187 menu.setGroupVisible(R.id.LIVE_MENU, false);
Pankaj Garg49b79252014-11-07 17:33:41 -0800188 setMenuItemVisibility(menu, R.id.save_snapshot_menu_id, false);
John Recke1a03a32011-09-14 17:04:16 -0700189 menu.setGroupVisible(R.id.SNAPSHOT_MENU, false);
John Recke1a03a32011-09-14 17:04:16 -0700190 menu.setGroupVisible(R.id.NAV_MENU, false);
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700191 }
Tarun Nainani87a86682015-02-05 11:47:35 -0800192
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700193 if (isComboViewShowing()) {
Tarun Nainani87a86682015-02-05 11:47:35 -0800194 menu.setGroupVisible(R.id.MAIN_MENU, false);
195 menu.setGroupEnabled(R.id.MAIN_MENU, false);
196 menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
197 }
198
jrizzolidb51f632016-03-22 15:57:18 +0100199 MenuItem closeOthers = menu.findItem(R.id.close_other_tabs_id);
200 if (closeOthers != null) {
201 boolean isLastTab = true;
202 if (tab != null) {
203 isLastTab = (mTabControl.getTabCount() <= 1);
204 }
205 closeOthers.setVisible(!isLastTab);
206 }
207
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700208 }
209
210 @Override
Michael Kolb3ca12752011-07-20 13:52:25 -0700211 public boolean onOptionsItemSelected(MenuItem item) {
Michael Kolb315d5022011-10-13 12:47:11 -0700212 if (showingNavScreen()
Michael Kolb315d5022011-10-13 12:47:11 -0700213 && (item.getItemId() != R.id.snapshots_menu_id)) {
Michael Kolba3194d02011-09-07 11:23:51 -0700214 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
Michael Kolb3ca12752011-07-20 13:52:25 -0700215 }
216 return false;
217 }
218
219 @Override
Michael Kolb66706532010-12-12 19:50:22 -0800220 public void onContextMenuCreated(Menu menu) {
Michael Kolb7cdc4902011-02-03 17:54:40 -0800221 hideTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -0800222 }
223
224 @Override
225 public void onContextMenuClosed(Menu menu, boolean inLoad) {
226 if (inLoad) {
Michael Kolb7cdc4902011-02-03 17:54:40 -0800227 showTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -0800228 }
229 }
230
231 // action mode callbacks
232
233 @Override
234 public void onActionModeStarted(ActionMode mode) {
Bijan Amirzada357ec8a2014-04-08 14:19:10 -0700235 super.onActionModeStarted(mode);
Michael Kolb42c0c062011-08-02 12:56:06 -0700236 if (!isEditingUrl()) {
Pankaj Garg175dfbc2015-07-10 15:03:49 -0700237 mTitleBar.setVisibility(View.GONE);
238 }
239
240 ActionBar actionBar = mActivity.getActionBar();
241 if (actionBar != null) {
242 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
243 actionBar.hide();
Michael Kolb42c0c062011-08-02 12:56:06 -0700244 }
Michael Kolb66706532010-12-12 19:50:22 -0800245 }
246
Michael Kolba4183062011-01-16 10:43:21 -0800247 @Override
John Reck6cda7b12011-03-18 15:57:13 -0700248 public void onActionModeFinished(boolean inLoad) {
Bijan Amirzada357ec8a2014-04-08 14:19:10 -0700249 super.onActionModeFinished(inLoad);
Pankaj Garg175dfbc2015-07-10 15:03:49 -0700250 mTitleBar.setVisibility(View.VISIBLE);
John Reck6cda7b12011-03-18 15:57:13 -0700251 }
252
253 @Override
Michael Kolbc3af0672011-08-09 10:24:41 -0700254 public boolean isWebShowing() {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700255 return super.isWebShowing() && !showingNavScreen() && !isComboViewShowing();
Tarun Nainani87a86682015-02-05 11:47:35 -0800256 }
257
258 @Override
259 public boolean isComboViewShowing() {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700260 return mComboView != null && mComboView.getVisibility() == View.VISIBLE;
Michael Kolbc3af0672011-08-09 10:24:41 -0700261 }
262
263 @Override
264 public void showWeb(boolean animate) {
265 super.showWeb(animate);
Michael Kolba3194d02011-09-07 11:23:51 -0700266 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), animate);
Michael Kolbc3af0672011-08-09 10:24:41 -0700267 }
268
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800269 //Unblock touch events
270 private void unblockEvents() {
271 mUiController.setBlockEvents(false);
272 }
273 //Block touch events
274 private void blockEvents() {
275 mUiController.setBlockEvents(true);
276 }
277
278 @Override
279 public void cancelNavScreenRequest() {
280 mNavScreenRequested = false;
281 }
282
Pankaj Gargb4b4f012015-08-04 16:19:14 -0700283 private void thumbnailUpdated(Tab t) {
284 mTabControl.setOnThumbnailUpdatedListener(null);
285
286 // Discard the callback if the req is interrupted
287 if (!mNavScreenRequested) {
288 unblockEvents();
289 return;
290 }
291
292 Bitmap bm = t.getScreenshot();
293 if (bm == null) {
294 t.initCaptureBitmap();
295 bm = t.getScreenshot();
296 }
297
298 Bitmap sbm;
299 WebView webView = getWebView();
Sudheer Koganti725fcf82015-11-24 09:24:23 -0800300 if (webView != null && webView.getWidth() != 0) {
Pankaj Gargb4b4f012015-08-04 16:19:14 -0700301 int view_width = webView.getWidth();
302 int capture_width = mActivity.getResources().getDimensionPixelSize(
303 R.dimen.tab_thumbnail_width);
304
305 float scale = (float) view_width / capture_width;
306
307 //Upscale the low-res bitmap to the needed size
308 Matrix m = new Matrix();
309 m.postScale(scale, scale);
310 sbm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
311 bm.getHeight(), m, false);
312 } else {
313 sbm = bm;
314 }
315
316 onShowNavScreenContinue(sbm);
317 }
318
319 private void startCaptureTimer(final Tab tab) {
320 mCaptureTimer = new CountDownTimer(mCaptureMaxWaitMS, mCaptureMaxWaitMS) {
321 @Override
322 public void onTick(long millisUntilFinished) {
323 // Do nothing
324 }
325
326 @Override
327 public void onFinish() {
328 Log.e(LOGTAG, "Screen capture timed out while showing navigation screen");
329 thumbnailUpdated(tab);
330 }
331 }.start();
332 }
333
334 private void stopCaptureTimer() {
335 if (mCaptureTimer != null) {
336 mCaptureTimer.cancel();
337 mCaptureTimer = null;
338 }
339 }
340
Michael Kolbf2055602011-04-09 17:20:03 -0700341 void showNavScreen() {
Pankaj Garg79878492015-04-01 14:48:21 -0700342 blockEvents();
Pankaj Gargb4b4f012015-08-04 16:19:14 -0700343 stopCaptureTimer();
344
Pankaj Garg79878492015-04-01 14:48:21 -0700345 mNavScreenRequested = true;
346 mTabControl.setOnThumbnailUpdatedListener(
347 new TabControl.OnThumbnailUpdatedListener() {
348 @Override
349 public void onThumbnailUpdated(Tab t) {
Pankaj Gargb4b4f012015-08-04 16:19:14 -0700350 stopCaptureTimer();
351 thumbnailUpdated(t);
Sudheer Koganti06cd42f2015-01-30 15:35:12 -0800352 }
Pankaj Garg79878492015-04-01 14:48:21 -0700353 });
Dany Rybnikovbcd37da2015-04-20 11:43:15 +0300354 if (!BrowserSettings.getInstance().isPowerSaveModeEnabled()) {
355 //Notify about anticipated network activity
356 NetworkServices.hintUpcomingUserActivity();
357 }
Pankaj Garg79878492015-04-01 14:48:21 -0700358 mActiveTab.capture();
Pankaj Gargb4b4f012015-08-04 16:19:14 -0700359 startCaptureTimer(mActiveTab);
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700360 }
361
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800362 void onShowNavScreenContinue(Bitmap viewportBitmap) {
363 dismissIME();
364 mShowNav = true;
365 mNavScreenRequested = false;
John Reckcc0059c2011-10-07 13:53:13 -0700366 if (mNavScreen == null) {
367 mNavScreen = new NavScreen(mActivity, mUiController, this);
368 mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
369 } else {
370 mNavScreen.setVisibility(View.VISIBLE);
371 mNavScreen.setAlpha(1f);
John Reck9c5004e2011-10-07 16:00:12 -0700372 mNavScreen.refreshAdapter();
John Reckcc0059c2011-10-07 13:53:13 -0700373 }
Sagar Dhawan01493f62015-02-09 11:03:19 -0800374 if (mAnimScreen == null) {
375 mAnimScreen = new AnimScreen(mActivity);
376 } else {
377 mAnimScreen.mMain.setAlpha(1f);
378 mAnimScreen.setScaleFactor(1f);
379 }
380 mAnimScreen.set(getTitleBar(), viewportBitmap);
381 if (mAnimScreen.mMain.getParent() == null) {
382 mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
383 }
Michael Kolbf2055602011-04-09 17:20:03 -0700384 mCustomViewContainer.setVisibility(View.VISIBLE);
385 mCustomViewContainer.bringToFront();
Sagar Dhawan01493f62015-02-09 11:03:19 -0800386 mAnimScreen.mMain.layout(0, 0, mContentView.getWidth(),
387 mContentView.getHeight());
388 int fromLeft = 0;
389 int fromTop = getTitleBar().getHeight();
390 int fromRight = mContentView.getWidth();
391 int fromBottom = mContentView.getHeight();
392 int width = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_width);
393 int height = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_height);
394 int ntth = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_titleheight);
395 int toLeft = (mContentView.getWidth() - width) / 2;
396 int toTop = ((fromBottom - (ntth + height)) / 2 + ntth);
397 int toRight = toLeft + width;
398 int toBottom = toTop + height;
399 float toScaleFactor = width / (float) mContentView.getWidth();
400 ObjectAnimator tx = ObjectAnimator.ofInt(mAnimScreen.mContent, "left", fromLeft, toLeft);
401 ObjectAnimator ty = ObjectAnimator.ofInt(mAnimScreen.mContent, "top", fromTop, toTop);
402 ObjectAnimator tr = ObjectAnimator.ofInt(mAnimScreen.mContent, "right", fromRight, toRight);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700403 ObjectAnimator tb = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom",
404 fromBottom, toBottom);
Sagar Dhawan01493f62015-02-09 11:03:19 -0800405 ObjectAnimator sx = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor", 1f, toScaleFactor);
406 ObjectAnimator navTabsIn = mNavScreen.createToolbarInAnimator();
407 mAnimScreen.mContent.layout(fromLeft, fromTop, fromRight, fromBottom);
408 mAnimScreen.setScaleFactor(1f);
Michael Kolba3194d02011-09-07 11:23:51 -0700409
Sagar Dhawan01493f62015-02-09 11:03:19 -0800410 AnimatorSet inanim = new AnimatorSet();
411 inanim.playTogether(tx, ty, tr, tb, sx, navTabsIn);
412 inanim.setInterpolator(new DecelerateInterpolator());
413 inanim.setDuration(200);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800414
Sagar Dhawan01493f62015-02-09 11:03:19 -0800415 ObjectAnimator disappear = ObjectAnimator.ofFloat(mAnimScreen.mMain, "alpha", 1f, 0f);
416 disappear.setInterpolator(new DecelerateInterpolator());
417 disappear.setDuration(100);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800418
Sagar Dhawan01493f62015-02-09 11:03:19 -0800419 AnimatorSet set1 = new AnimatorSet();
420 set1.addListener(new AnimatorListenerAdapter() {
421 @Override
422 public void onAnimationStart(Animator animation) {
423 mContentView.setVisibility(View.GONE);
424 }
425 @Override
426 public void onAnimationEnd(Animator anim) {
427 mCustomViewContainer.removeView(mAnimScreen.mMain);
428 finishAnimationIn();
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800429 unblockEvents();
Sagar Dhawan01493f62015-02-09 11:03:19 -0800430 }
431 });
432 set1.playSequentially(inanim, disappear);
433 set1.start();
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800434 unblockEvents();
Michael Kolbc3af0672011-08-09 10:24:41 -0700435 }
436
437 private void finishAnimationIn() {
John Reckcc0059c2011-10-07 13:53:13 -0700438 if (showingNavScreen()) {
Michael Kolbb43f2f62011-08-17 10:39:31 -0700439 // notify accessibility manager about the screen change
440 mNavScreen.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
Michael Kolbb43f2f62011-08-17 10:39:31 -0700441 }
Michael Kolbf2055602011-04-09 17:20:03 -0700442 }
443
Michael Kolba3194d02011-09-07 11:23:51 -0700444 void hideNavScreen(int position, boolean animate) {
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800445
yijunx.zhu2230a312012-07-27 13:37:00 -0400446 mShowNav = false;
John Reckcc0059c2011-10-07 13:53:13 -0700447 if (!showingNavScreen()) return;
Michael Kolba3194d02011-09-07 11:23:51 -0700448 final Tab tab = mUiController.getTabControl().getTab(position);
Michael Kolbbf32cd02011-08-16 15:07:04 -0700449 if ((tab == null) || !animate) {
Michael Kolb365561d2011-08-18 09:56:25 -0700450 if (tab != null) {
451 setActiveTab(tab);
452 } else if (mTabControl.getTabCount() > 0) {
453 // use a fallback tab
454 setActiveTab(mTabControl.getCurrentTab());
455 }
Michael Kolbbf32cd02011-08-16 15:07:04 -0700456 mContentView.setVisibility(View.VISIBLE);
457 finishAnimateOut();
Michael Kolb8a009492011-08-15 15:37:30 -0700458 return;
Michael Kolbc3af0672011-08-09 10:24:41 -0700459 }
Michael Kolba3194d02011-09-07 11:23:51 -0700460 NavTabView tabview = (NavTabView) mNavScreen.getTabView(position);
Michael Kolbc3af0672011-08-09 10:24:41 -0700461 if (tabview == null) {
Michael Kolb365561d2011-08-18 09:56:25 -0700462 if (mTabControl.getTabCount() > 0) {
463 // use a fallback tab
464 setActiveTab(mTabControl.getCurrentTab());
465 }
Michael Kolbbf32cd02011-08-16 15:07:04 -0700466 mContentView.setVisibility(View.VISIBLE);
467 finishAnimateOut();
Michael Kolb8a009492011-08-15 15:37:30 -0700468 return;
Michael Kolbc3af0672011-08-09 10:24:41 -0700469 }
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800470 blockEvents();
Michael Kolbc3af0672011-08-09 10:24:41 -0700471 mUiController.setActiveTab(tab);
472 mContentView.setVisibility(View.VISIBLE);
John Reckcc0059c2011-10-07 13:53:13 -0700473 if (mAnimScreen == null) {
474 mAnimScreen = new AnimScreen(mActivity);
475 }
Tarun Nainani8eb00912014-07-17 12:28:32 -0700476 ImageView target = tabview.mImage;
477 int width = target.getDrawable().getIntrinsicWidth();
478 int height = target.getDrawable().getIntrinsicHeight();
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700479 Bitmap bm = tab.getScreenshot();
Vivek Sekharc549e3a2014-06-05 16:19:26 -0700480 if (bm == null)
481 bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
482 mAnimScreen.set(bm);
Michael Kolb0755fcd2012-01-10 10:19:50 -0800483 if (mAnimScreen.mMain.getParent() == null) {
484 mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
485 }
John Reckcc0059c2011-10-07 13:53:13 -0700486 mAnimScreen.mMain.layout(0, 0, mContentView.getWidth(),
Tarun Nainani8eb00912014-07-17 12:28:32 -0700487 mContentView.getHeight());
Enrico Ros80c045a2014-11-24 15:23:12 -0800488 mNavScreen.getScroller().finishScroller();
Michael Kolbc3af0672011-08-09 10:24:41 -0700489 int toLeft = 0;
Tarun Nainani8eb00912014-07-17 12:28:32 -0700490 int toTop = mTitleBar.calculateEmbeddedHeight();
Michael Kolbc3af0672011-08-09 10:24:41 -0700491 int toRight = mContentView.getWidth();
Enrico Ros80c045a2014-11-24 15:23:12 -0800492 int fromLeft = tabview.getLeft() + target.getLeft() - mNavScreen.getScroller().getScrollX();
493 int fromTop = tabview.getTop() + target.getTop() - mNavScreen.getScroller().getScrollY();
Tarun Nainani8eb00912014-07-17 12:28:32 -0700494 int fromRight = fromLeft + width;
495 int fromBottom = fromTop + height;
Michael Kolbc3af0672011-08-09 10:24:41 -0700496 float scaleFactor = mContentView.getWidth() / (float) width;
Michael Kolba3194d02011-09-07 11:23:51 -0700497 int toBottom = toTop + (int) (height * scaleFactor);
John Reck9c5004e2011-10-07 16:00:12 -0700498 mAnimScreen.mContent.setLeft(fromLeft);
499 mAnimScreen.mContent.setTop(fromTop);
500 mAnimScreen.mContent.setRight(fromRight);
501 mAnimScreen.mContent.setBottom(fromBottom);
502 mAnimScreen.setScaleFactor(1f);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800503 //ObjectAnimator fade2 = ObjectAnimator.ofFloat(mNavScreen, "alpha", 1f, 0f);
504 //fade2.setDuration(100);
505 AnimatorSet set = new AnimatorSet();
506 ObjectAnimator animAppear = ObjectAnimator.ofFloat(mAnimScreen.mMain, "alpha", 0f, 1f);
507 animAppear.setDuration(100);
508 ObjectAnimator l = ObjectAnimator.ofInt(mAnimScreen.mContent, "left", fromLeft, toLeft);
509 ObjectAnimator t = ObjectAnimator.ofInt(mAnimScreen.mContent, "top", fromTop, toTop);
510 ObjectAnimator r = ObjectAnimator.ofInt(mAnimScreen.mContent, "right", fromRight, toRight);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700511 ObjectAnimator b = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom",
512 fromBottom, toBottom);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800513 ObjectAnimator scale = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor", 1f, scaleFactor);
514 set.playTogether(animAppear, l, t, r, b, scale);
515 set.setInterpolator(new DecelerateInterpolator());
516 set.setDuration(200);
517 set.addListener(new AnimatorListenerAdapter() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700518 @Override
519 public void onAnimationEnd(Animator anim) {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400520 checkTabReady();
521 }
522 });
Enrico Ros1f5a0952014-11-18 20:15:48 -0800523 set.start();
Matthew Hui1eb7a832014-04-15 12:20:58 -0400524 }
525
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700526
527 private int mNumTries = 0;
Matthew Hui1eb7a832014-04-15 12:20:58 -0400528 private void checkTabReady() {
529 boolean isready = true;
Enrico Ros1f5a0952014-11-18 20:15:48 -0800530 boolean zeroTries = mNumTries == 0;
Matthew Hui1eb7a832014-04-15 12:20:58 -0400531 Tab tab = mUiController.getTabControl().getCurrentTab();
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700532 BrowserWebView webview = null;
Matthew Hui1eb7a832014-04-15 12:20:58 -0400533 if (tab == null)
534 isready = false;
535 else {
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700536 webview = (BrowserWebView)tab.getWebView();
537 if (webview == null) {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400538 isready = false;
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700539 } else {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400540 isready = webview.isReady();
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700541 }
Matthew Hui1eb7a832014-04-15 12:20:58 -0400542 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700543 // Post only when not ready and not crashed
544 if (!isready && mNumTries++ < 150) {
545 mCustomViewContainer.postDelayed(new Runnable() {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400546 public void run() {
547 checkTabReady();
548 }
549 }, 17); //WebView is not ready. check again in for next frame.
550 return;
551 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700552 mNumTries = 0;
Vivek Sekharc70ae632015-04-08 17:54:05 -0700553 final boolean hasCrashed = (webview == null) ? false :false;
Enrico Ros1f5a0952014-11-18 20:15:48 -0800554 // fast path: don't wait if we've been ready for a while
555 if (zeroTries) {
Vivek Sekharc70ae632015-04-08 17:54:05 -0700556 fadeOutCustomViewContainer();
Enrico Ros1f5a0952014-11-18 20:15:48 -0800557 return;
558 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700559 mCustomViewContainer.postDelayed(new Runnable() {
Enrico Ros1f5a0952014-11-18 20:15:48 -0800560 public void run() {
Vivek Sekharc70ae632015-04-08 17:54:05 -0700561 fadeOutCustomViewContainer();
Enrico Ros1f5a0952014-11-18 20:15:48 -0800562 }
563 }, 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 -0400564 }
565
Vivek Sekharc70ae632015-04-08 17:54:05 -0700566 private void fadeOutCustomViewContainer() {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400567 ObjectAnimator otheralpha = ObjectAnimator.ofFloat(mCustomViewContainer, "alpha", 1f, 0f);
Vivek Sekharc70ae632015-04-08 17:54:05 -0700568 otheralpha.setDuration(100);
Matthew Hui1eb7a832014-04-15 12:20:58 -0400569 otheralpha.addListener(new AnimatorListenerAdapter() {
570 @Override
571 public void onAnimationEnd(Animator anim) {
John Reckcc0059c2011-10-07 13:53:13 -0700572 mCustomViewContainer.removeView(mAnimScreen.mMain);
Michael Kolbbf32cd02011-08-16 15:07:04 -0700573 finishAnimateOut();
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800574 unblockEvents();
Michael Kolbc3af0672011-08-09 10:24:41 -0700575 }
576 });
Enrico Ros1f5a0952014-11-18 20:15:48 -0800577 otheralpha.setInterpolator(new DecelerateInterpolator());
Matthew Hui1eb7a832014-04-15 12:20:58 -0400578 otheralpha.start();
Michael Kolbc3af0672011-08-09 10:24:41 -0700579 }
580
Michael Kolbbf32cd02011-08-16 15:07:04 -0700581 private void finishAnimateOut() {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700582 if (mNavScreen != null) {
583 mNavScreen.setVisibility(View.GONE);
584 }
Michael Kolbc3af0672011-08-09 10:24:41 -0700585 mCustomViewContainer.setAlpha(1f);
Michael Kolbf2055602011-04-09 17:20:03 -0700586 mCustomViewContainer.setVisibility(View.GONE);
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700587 mAnimScreen.set(null);
Michael Kolbf2055602011-04-09 17:20:03 -0700588 }
589
John Reck6b4bd5f2011-07-12 10:14:38 -0700590 @Override
591 public boolean needsRestoreAllTabs() {
592 return false;
593 }
594
Michael Kolb20be26d2011-07-18 16:38:02 -0700595 public void toggleNavScreen() {
John Reckcc0059c2011-10-07 13:53:13 -0700596 if (!showingNavScreen()) {
Michael Kolb20be26d2011-07-18 16:38:02 -0700597 showNavScreen();
598 } else {
Michael Kolba3194d02011-09-07 11:23:51 -0700599 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
Michael Kolb20be26d2011-07-18 16:38:02 -0700600 }
601 }
602
Michael Kolbc3af0672011-08-09 10:24:41 -0700603 static class AnimScreen {
John Reck3ba45532011-08-11 16:26:53 -0700604
Michael Kolbc3af0672011-08-09 10:24:41 -0700605 private View mMain;
Michael Kolbc3af0672011-08-09 10:24:41 -0700606 private ImageView mContent;
607 private float mScale;
608
John Reckcc0059c2011-10-07 13:53:13 -0700609 public AnimScreen(Context ctx) {
Enrico Ros1f5a0952014-11-18 20:15:48 -0800610 mMain = LayoutInflater.from(ctx).inflate(R.layout.anim_screen, null);
611 mMain.setOnClickListener(new View.OnClickListener() {
612 @Override
613 public void onClick(View v) {
614 // just eat clicks when this view is visible
615 }
616 });
617 mContent = (ImageView) mMain.findViewById(R.id.anim_screen_content);
John Reckcc0059c2011-10-07 13:53:13 -0700618 mContent.setScaleType(ImageView.ScaleType.MATRIX);
619 mContent.setImageMatrix(new Matrix());
620 mScale = 1.0f;
621 setScaleFactor(getScaleFactor());
622 }
623
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700624 public void set(TitleBar tbar, Bitmap viewportBitmap) {
625 if (tbar == null) {
John Reck62077d82011-10-13 15:17:50 -0700626 return;
627 }
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700628 mContent.setImageBitmap(viewportBitmap);
Michael Kolbc3af0672011-08-09 10:24:41 -0700629 }
630
John Reckcc0059c2011-10-07 13:53:13 -0700631 public void set(Bitmap image) {
Michael Kolbc3af0672011-08-09 10:24:41 -0700632 mContent.setImageBitmap(image);
Michael Kolbc3af0672011-08-09 10:24:41 -0700633 }
634
John Reckcc0059c2011-10-07 13:53:13 -0700635 private void setScaleFactor(float sf) {
Michael Kolbc3af0672011-08-09 10:24:41 -0700636 mScale = sf;
637 Matrix m = new Matrix();
Enrico Ros1f5a0952014-11-18 20:15:48 -0800638 m.postScale(sf, sf);
Michael Kolbc3af0672011-08-09 10:24:41 -0700639 mContent.setImageMatrix(m);
640 }
641
John Reckcc0059c2011-10-07 13:53:13 -0700642 private float getScaleFactor() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700643 return mScale;
644 }
645
John Reck3ba45532011-08-11 16:26:53 -0700646 }
647
Michael Kolb66706532010-12-12 19:50:22 -0800648}