blob: f3a08f73e7619a41b6ffa23592da9f9b2d748950 [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;
Michael Kolbc3af0672011-08-09 10:24:41 -070026import android.graphics.Matrix;
Tarun Nainani87a86682015-02-05 11:47:35 -080027import android.graphics.Paint;
28import android.graphics.Rect;
29import android.os.Bundle;
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;
Tarun Nainani87a86682015-02-05 11:47:35 -080038import android.view.ViewStub;
Michael Kolb30adae62011-07-29 13:37:05 -070039import android.view.accessibility.AccessibilityEvent;
Enrico Ros1f5a0952014-11-18 20:15:48 -080040import android.view.animation.DecelerateInterpolator;
Tarun Nainani87a86682015-02-05 11:47:35 -080041import android.webkit.ValueCallback;
42import org.codeaurora.swe.WebView;
43
44import android.widget.FrameLayout;
Michael Kolbc3af0672011-08-09 10:24:41 -070045import android.widget.ImageView;
Michael Kolb66706532010-12-12 19:50:22 -080046
Bijan Amirzada41242f22014-03-21 12:12:18 -070047import com.android.browser.UrlInputView.StateListener;
Michael Kolb629b22c2011-07-13 16:26:47 -070048
Dany Rybnikovbcd37da2015-04-20 11:43:15 +030049import org.codeaurora.net.NetworkServices;
Pankaj Garg79878492015-04-01 14:48:21 -070050import org.codeaurora.swe.WebView;
51
Michael Kolb66706532010-12-12 19:50:22 -080052/**
53 * Ui for regular phone screen sizes
54 */
55public class PhoneUi extends BaseUi {
56
57 private static final String LOGTAG = "PhoneUi";
John Reck9c5004e2011-10-07 16:00:12 -070058 private static final int MSG_INIT_NAVSCREEN = 100;
Michael Kolb66706532010-12-12 19:50:22 -080059
Michael Kolbf2055602011-04-09 17:20:03 -070060 private NavScreen mNavScreen;
John Reckcc0059c2011-10-07 13:53:13 -070061 private AnimScreen mAnimScreen;
Tarun Nainani87a86682015-02-05 11:47:35 -080062 private final NavigationBarPhone mNavigationBar;
63 private final Activity mBrowser;
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -080064 private boolean mNavScreenRequested = false;
Michael Kolb66706532010-12-12 19:50:22 -080065
Michael Kolb08a687a2011-04-22 16:13:02 -070066 boolean mAnimating;
yijunx.zhu2230a312012-07-27 13:37:00 -040067 boolean mShowNav = false;
Tarun Nainani87a86682015-02-05 11:47:35 -080068 private ComboView mComboView;
Michael Kolb66706532010-12-12 19:50:22 -080069
Vivek Sekhar60eb9802014-07-21 19:13:33 -070070
Michael Kolb66706532010-12-12 19:50:22 -080071 /**
72 * @param browser
73 * @param controller
74 */
75 public PhoneUi(Activity browser, UiController controller) {
76 super(browser, controller);
John Reck0f602f32011-07-07 15:38:43 -070077 mNavigationBar = (NavigationBarPhone) mTitleBar.getNavigationBar();
Vivek Sekhar60eb9802014-07-21 19:13:33 -070078 mBrowser = browser;
John Reck285ef042011-02-11 15:44:17 -080079 }
Michael Kolb66706532010-12-12 19:50:22 -080080
John Reck285ef042011-02-11 15:44:17 -080081 @Override
Michael Kolb66706532010-12-12 19:50:22 -080082 public void onDestroy() {
Michael Kolb7cdc4902011-02-03 17:54:40 -080083 hideTitleBar();
Karthikeyan Periasamy5b8f5752015-01-13 16:00:27 -080084 // Free the allocated memory for GC to clear it from the heap.
85 mAnimScreen = null;
Michael Kolb66706532010-12-12 19:50:22 -080086 }
87
88 @Override
Michael Kolb1f9b3562012-04-24 14:38:34 -070089 public void editUrl(boolean clearInput, boolean forceIME) {
yijunx.zhu2230a312012-07-27 13:37:00 -040090 //Do nothing while at Nav show screen.
91 if (mShowNav) return;
Michael Kolb1f9b3562012-04-24 14:38:34 -070092 super.editUrl(clearInput, forceIME);
Michael Kolbdc2ee1b2011-02-14 14:34:40 -080093 }
94
95 @Override
Tarun Nainani87a86682015-02-05 11:47:35 -080096 public void showComboView(ComboViews startingView, Bundle extras) {
97
98 if (mComboView == null) {
99 mNavScreen.setVisibility(View.GONE);
100 ViewStub stub = (ViewStub) mActivity.getWindow().getDecorView().findViewById(R.id.combo_view_stub);
101 mComboView = (ComboView) stub.inflate();
102 mComboView.setVisibility(View.GONE);
103 mComboView.setupViews(mActivity);
104 }
105
106 Bundle b = new Bundle();
107 b.putString(ComboViewActivity.EXTRA_INITIAL_VIEW, startingView.name());
108 b.putBundle(ComboViewActivity.EXTRA_COMBO_ARGS, extras);
109 Tab t = getActiveTab();
110 if (t != null) {
111 b.putString(ComboViewActivity.EXTRA_CURRENT_URL, t.getUrl());
112 }
113
114 mComboView.showViews(mActivity, b);
115 }
116
117 @Override
118 public void hideComboView() {
119 mComboView.hideViews();
120 }
121
122 @Override
Michael Kolb66706532010-12-12 19:50:22 -0800123 public boolean onBackKey() {
John Reckcc0059c2011-10-07 13:53:13 -0700124 if (showingNavScreen()) {
Michael Kolba3194d02011-09-07 11:23:51 -0700125 mNavScreen.close(mUiController.getTabControl().getCurrentPosition());
Michael Kolbf2055602011-04-09 17:20:03 -0700126 return true;
Michael Kolb66706532010-12-12 19:50:22 -0800127 }
Tarun Nainani87a86682015-02-05 11:47:35 -0800128 if (showingComboView()) {
129 hideComboView();
130 return true;
131 }
Michael Kolb66706532010-12-12 19:50:22 -0800132 return super.onBackKey();
133 }
134
John Reckcc0059c2011-10-07 13:53:13 -0700135 private boolean showingNavScreen() {
136 return mNavScreen != null && mNavScreen.getVisibility() == View.VISIBLE;
137 }
138
Tarun Nainani87a86682015-02-05 11:47:35 -0800139 private boolean showingComboView() {
140 return mComboView != null && mComboView.getVisibility() == View.VISIBLE;
141 }
142
Michael Kolb66706532010-12-12 19:50:22 -0800143 @Override
Michael Kolbf2055602011-04-09 17:20:03 -0700144 public boolean dispatchKey(int code, KeyEvent event) {
Michael Kolbf2055602011-04-09 17:20:03 -0700145 return false;
146 }
147
148 @Override
John Reck30c714c2010-12-16 17:30:34 -0800149 public void onProgressChanged(Tab tab) {
Michael Kolbe8a82332012-04-25 14:14:26 -0700150 super.onProgressChanged(tab);
John Reck9c5004e2011-10-07 16:00:12 -0700151 if (mNavScreen == null && getTitleBar().getHeight() > 0) {
152 mHandler.sendEmptyMessage(MSG_INIT_NAVSCREEN);
153 }
154 }
155
156 @Override
157 protected void handleMessage(Message msg) {
158 super.handleMessage(msg);
159 if (msg.what == MSG_INIT_NAVSCREEN) {
160 if (mNavScreen == null) {
161 mNavScreen = new NavScreen(mActivity, mUiController, this);
162 mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
163 mNavScreen.setVisibility(View.GONE);
164 }
165 if (mAnimScreen == null) {
166 mAnimScreen = new AnimScreen(mActivity);
John Reck9c5004e2011-10-07 16:00:12 -0700167 }
168 }
Michael Kolb66706532010-12-12 19:50:22 -0800169 }
170
171 @Override
Michael Kolbfdb70242011-03-24 09:41:11 -0700172 public void setActiveTab(final Tab tab) {
John Reck8ee633f2011-08-09 16:00:35 -0700173 mTitleBar.cancelTitleBarAnimation(true);
174 mTitleBar.setSkipTitleBarAnimations(true);
John Reck5d43ce82011-06-21 17:16:51 -0700175 super.setActiveTab(tab);
yijunx.zhu2230a312012-07-27 13:37:00 -0400176
177 //if at Nav screen show, detach tab like what showNavScreen() do.
178 if (mShowNav) {
179 detachTab(mActiveTab);
180 }
181
Michael Kolbfdb70242011-03-24 09:41:11 -0700182 BrowserWebView view = (BrowserWebView) tab.getWebView();
Michael Kolb376b5412010-12-15 11:52:57 -0800183 // TabControl.setCurrentTab has been called before this,
184 // so the tab is guaranteed to have a webview
185 if (view == null) {
186 Log.e(LOGTAG, "active tab with no webview detected");
187 return;
188 }
Michael Kolbfdb70242011-03-24 09:41:11 -0700189 // Request focus on the top window.
Vivek Sekhar3bec6a32014-10-22 17:03:42 -0700190 view.setTitleBar(mTitleBar);
191
Michael Kolb629b22c2011-07-13 16:26:47 -0700192 // update nav bar state
193 mNavigationBar.onStateChanged(StateListener.STATE_NORMAL);
Michael Kolbfdb70242011-03-24 09:41:11 -0700194 updateLockIconToLatest(tab);
John Reck8ee633f2011-08-09 16:00:35 -0700195 mTitleBar.setSkipTitleBarAnimations(false);
Michael Kolb376b5412010-12-15 11:52:57 -0800196 }
197
Michael Kolb66706532010-12-12 19:50:22 -0800198 // menu handling callbacks
199
200 @Override
Michael Kolb3ca12752011-07-20 13:52:25 -0700201 public boolean onPrepareOptionsMenu(Menu menu) {
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700202 updateMenuState(mActiveTab, menu);
Michael Kolb3ca12752011-07-20 13:52:25 -0700203 return true;
204 }
205
206 @Override
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700207 public void updateMenuState(Tab tab, Menu menu) {
Michael Kolb0d0245f2011-12-05 16:36:05 -0800208 MenuItem bm = menu.findItem(R.id.bookmarks_menu_id);
209 if (bm != null) {
210 bm.setVisible(!showingNavScreen());
211 }
Michael Kolb315d5022011-10-13 12:47:11 -0700212 MenuItem info = menu.findItem(R.id.page_info_menu_id);
213 if (info != null) {
214 info.setVisible(false);
215 }
Pankaj Garg49b79252014-11-07 17:33:41 -0800216
John Reckcc0059c2011-10-07 13:53:13 -0700217 if (showingNavScreen()) {
Pankaj Garg49b79252014-11-07 17:33:41 -0800218 setMenuItemVisibility(menu, R.id.history_menu_id, false);
219 setMenuItemVisibility(menu, R.id.find_menu_id, false);
John Recke1a03a32011-09-14 17:04:16 -0700220 menu.setGroupVisible(R.id.LIVE_MENU, false);
Pankaj Garg49b79252014-11-07 17:33:41 -0800221 setMenuItemVisibility(menu, R.id.save_snapshot_menu_id, false);
John Recke1a03a32011-09-14 17:04:16 -0700222 menu.setGroupVisible(R.id.SNAPSHOT_MENU, false);
John Recke1a03a32011-09-14 17:04:16 -0700223 menu.setGroupVisible(R.id.NAV_MENU, false);
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700224 }
Tarun Nainani87a86682015-02-05 11:47:35 -0800225
226 if (showingComboView()) {
227 menu.setGroupVisible(R.id.MAIN_MENU, false);
228 menu.setGroupEnabled(R.id.MAIN_MENU, false);
229 menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
230 }
231
Michael Kolb7bdee0b2011-08-01 11:55:38 -0700232 }
233
234 @Override
Michael Kolb3ca12752011-07-20 13:52:25 -0700235 public boolean onOptionsItemSelected(MenuItem item) {
Michael Kolb315d5022011-10-13 12:47:11 -0700236 if (showingNavScreen()
237 && (item.getItemId() != R.id.history_menu_id)
238 && (item.getItemId() != R.id.snapshots_menu_id)) {
Michael Kolba3194d02011-09-07 11:23:51 -0700239 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
Michael Kolb3ca12752011-07-20 13:52:25 -0700240 }
241 return false;
242 }
243
244 @Override
Michael Kolb66706532010-12-12 19:50:22 -0800245 public void onContextMenuCreated(Menu menu) {
Michael Kolb7cdc4902011-02-03 17:54:40 -0800246 hideTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -0800247 }
248
249 @Override
250 public void onContextMenuClosed(Menu menu, boolean inLoad) {
251 if (inLoad) {
Michael Kolb7cdc4902011-02-03 17:54:40 -0800252 showTitleBar();
Michael Kolb66706532010-12-12 19:50:22 -0800253 }
254 }
255
256 // action mode callbacks
257
258 @Override
259 public void onActionModeStarted(ActionMode mode) {
Bijan Amirzada357ec8a2014-04-08 14:19:10 -0700260 super.onActionModeStarted(mode);
Michael Kolb42c0c062011-08-02 12:56:06 -0700261 if (!isEditingUrl()) {
262 hideTitleBar();
263 }
Michael Kolb66706532010-12-12 19:50:22 -0800264 }
265
Michael Kolba4183062011-01-16 10:43:21 -0800266 @Override
John Reck6cda7b12011-03-18 15:57:13 -0700267 public void onActionModeFinished(boolean inLoad) {
Bijan Amirzada357ec8a2014-04-08 14:19:10 -0700268 super.onActionModeFinished(inLoad);
Michael Kolbc16c5952011-03-29 15:37:03 -0700269 if (inLoad) {
Michael Kolbc16c5952011-03-29 15:37:03 -0700270 showTitleBar();
271 }
John Reck6cda7b12011-03-18 15:57:13 -0700272 }
273
274 @Override
Michael Kolbc3af0672011-08-09 10:24:41 -0700275 public boolean isWebShowing() {
Tarun Nainani87a86682015-02-05 11:47:35 -0800276 return super.isWebShowing() && !showingNavScreen() && !showingComboView();
277 }
278
279 @Override
280 public boolean isComboViewShowing() {
281 return showingComboView();
Michael Kolbc3af0672011-08-09 10:24:41 -0700282 }
283
284 @Override
285 public void showWeb(boolean animate) {
286 super.showWeb(animate);
Michael Kolba3194d02011-09-07 11:23:51 -0700287 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), animate);
Michael Kolbc3af0672011-08-09 10:24:41 -0700288 }
289
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800290 //Unblock touch events
291 private void unblockEvents() {
292 mUiController.setBlockEvents(false);
293 }
294 //Block touch events
295 private void blockEvents() {
296 mUiController.setBlockEvents(true);
297 }
298
299 @Override
300 public void cancelNavScreenRequest() {
301 mNavScreenRequested = false;
302 }
303
Michael Kolbf2055602011-04-09 17:20:03 -0700304 void showNavScreen() {
Pankaj Garg79878492015-04-01 14:48:21 -0700305 blockEvents();
306 mNavScreenRequested = true;
307 mTabControl.setOnThumbnailUpdatedListener(
308 new TabControl.OnThumbnailUpdatedListener() {
309 @Override
310 public void onThumbnailUpdated(Tab t) {
311 mTabControl.setOnThumbnailUpdatedListener(null);
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800312
Pankaj Garg79878492015-04-01 14:48:21 -0700313 // Discard the callback if the req is interrupted
314 if (!mNavScreenRequested) {
315 unblockEvents();
316 return;
Sudheer Koganti06cd42f2015-01-30 15:35:12 -0800317 }
Pankaj Garg79878492015-04-01 14:48:21 -0700318
319 Bitmap bm = t.getScreenshot();
320 Bitmap sbm;
321 WebView webView = getWebView();
322 if (webView != null) {
323 int view_width = webView.getWidth();
324 int capture_width = mActivity.getResources().getDimensionPixelSize(
325 R.dimen.tab_thumbnail_width);
326
327 float scale = (float) view_width / capture_width;
328
329 //Upscale the low-res bitmap to the needed size
330 Matrix m = new Matrix();
331 m.postScale(scale, scale);
332 sbm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
333 bm.getHeight(), m, false);
334 } else {
335 sbm = bm;
336 }
337
338 onShowNavScreenContinue(sbm);
Sudheer Koganti06cd42f2015-01-30 15:35:12 -0800339 }
Pankaj Garg79878492015-04-01 14:48:21 -0700340 });
Dany Rybnikovbcd37da2015-04-20 11:43:15 +0300341 if (!BrowserSettings.getInstance().isPowerSaveModeEnabled()) {
342 //Notify about anticipated network activity
343 NetworkServices.hintUpcomingUserActivity();
344 }
Pankaj Garg79878492015-04-01 14:48:21 -0700345 mActiveTab.capture();
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700346 }
347
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800348 void onShowNavScreenContinue(Bitmap viewportBitmap) {
349 dismissIME();
350 mShowNav = true;
351 mNavScreenRequested = false;
John Reckcc0059c2011-10-07 13:53:13 -0700352 if (mNavScreen == null) {
353 mNavScreen = new NavScreen(mActivity, mUiController, this);
354 mCustomViewContainer.addView(mNavScreen, COVER_SCREEN_PARAMS);
355 } else {
356 mNavScreen.setVisibility(View.VISIBLE);
357 mNavScreen.setAlpha(1f);
John Reck9c5004e2011-10-07 16:00:12 -0700358 mNavScreen.refreshAdapter();
John Reckcc0059c2011-10-07 13:53:13 -0700359 }
Sagar Dhawan01493f62015-02-09 11:03:19 -0800360 if (mAnimScreen == null) {
361 mAnimScreen = new AnimScreen(mActivity);
362 } else {
363 mAnimScreen.mMain.setAlpha(1f);
364 mAnimScreen.setScaleFactor(1f);
365 }
366 mAnimScreen.set(getTitleBar(), viewportBitmap);
367 if (mAnimScreen.mMain.getParent() == null) {
368 mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
369 }
Michael Kolbf2055602011-04-09 17:20:03 -0700370 mCustomViewContainer.setVisibility(View.VISIBLE);
371 mCustomViewContainer.bringToFront();
Sagar Dhawan01493f62015-02-09 11:03:19 -0800372 mAnimScreen.mMain.layout(0, 0, mContentView.getWidth(),
373 mContentView.getHeight());
374 int fromLeft = 0;
375 int fromTop = getTitleBar().getHeight();
376 int fromRight = mContentView.getWidth();
377 int fromBottom = mContentView.getHeight();
378 int width = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_width);
379 int height = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_height);
380 int ntth = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_titleheight);
381 int toLeft = (mContentView.getWidth() - width) / 2;
382 int toTop = ((fromBottom - (ntth + height)) / 2 + ntth);
383 int toRight = toLeft + width;
384 int toBottom = toTop + height;
385 float toScaleFactor = width / (float) mContentView.getWidth();
386 ObjectAnimator tx = ObjectAnimator.ofInt(mAnimScreen.mContent, "left", fromLeft, toLeft);
387 ObjectAnimator ty = ObjectAnimator.ofInt(mAnimScreen.mContent, "top", fromTop, toTop);
388 ObjectAnimator tr = ObjectAnimator.ofInt(mAnimScreen.mContent, "right", fromRight, toRight);
389 ObjectAnimator tb = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom", fromBottom, toBottom);
390 ObjectAnimator sx = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor", 1f, toScaleFactor);
391 ObjectAnimator navTabsIn = mNavScreen.createToolbarInAnimator();
392 mAnimScreen.mContent.layout(fromLeft, fromTop, fromRight, fromBottom);
393 mAnimScreen.setScaleFactor(1f);
Michael Kolba3194d02011-09-07 11:23:51 -0700394
Sagar Dhawan01493f62015-02-09 11:03:19 -0800395 AnimatorSet inanim = new AnimatorSet();
396 inanim.playTogether(tx, ty, tr, tb, sx, navTabsIn);
397 inanim.setInterpolator(new DecelerateInterpolator());
398 inanim.setDuration(200);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800399
Sagar Dhawan01493f62015-02-09 11:03:19 -0800400 ObjectAnimator disappear = ObjectAnimator.ofFloat(mAnimScreen.mMain, "alpha", 1f, 0f);
401 disappear.setInterpolator(new DecelerateInterpolator());
402 disappear.setDuration(100);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800403
Sagar Dhawan01493f62015-02-09 11:03:19 -0800404 AnimatorSet set1 = new AnimatorSet();
405 set1.addListener(new AnimatorListenerAdapter() {
406 @Override
407 public void onAnimationStart(Animator animation) {
408 mContentView.setVisibility(View.GONE);
409 }
410 @Override
411 public void onAnimationEnd(Animator anim) {
412 mCustomViewContainer.removeView(mAnimScreen.mMain);
413 finishAnimationIn();
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800414 unblockEvents();
Sagar Dhawan01493f62015-02-09 11:03:19 -0800415 }
416 });
417 set1.playSequentially(inanim, disappear);
418 set1.start();
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800419 unblockEvents();
Michael Kolbc3af0672011-08-09 10:24:41 -0700420 }
421
422 private void finishAnimationIn() {
John Reckcc0059c2011-10-07 13:53:13 -0700423 if (showingNavScreen()) {
Michael Kolbb43f2f62011-08-17 10:39:31 -0700424 // notify accessibility manager about the screen change
425 mNavScreen.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
Michael Kolbb43f2f62011-08-17 10:39:31 -0700426 }
Michael Kolbf2055602011-04-09 17:20:03 -0700427 }
428
Michael Kolba3194d02011-09-07 11:23:51 -0700429 void hideNavScreen(int position, boolean animate) {
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800430
yijunx.zhu2230a312012-07-27 13:37:00 -0400431 mShowNav = false;
John Reckcc0059c2011-10-07 13:53:13 -0700432 if (!showingNavScreen()) return;
Michael Kolba3194d02011-09-07 11:23:51 -0700433 final Tab tab = mUiController.getTabControl().getTab(position);
Michael Kolbbf32cd02011-08-16 15:07:04 -0700434 if ((tab == null) || !animate) {
Michael Kolb365561d2011-08-18 09:56:25 -0700435 if (tab != null) {
436 setActiveTab(tab);
437 } else if (mTabControl.getTabCount() > 0) {
438 // use a fallback tab
439 setActiveTab(mTabControl.getCurrentTab());
440 }
Michael Kolbbf32cd02011-08-16 15:07:04 -0700441 mContentView.setVisibility(View.VISIBLE);
442 finishAnimateOut();
Michael Kolb8a009492011-08-15 15:37:30 -0700443 return;
Michael Kolbc3af0672011-08-09 10:24:41 -0700444 }
Michael Kolba3194d02011-09-07 11:23:51 -0700445 NavTabView tabview = (NavTabView) mNavScreen.getTabView(position);
Michael Kolbc3af0672011-08-09 10:24:41 -0700446 if (tabview == null) {
Michael Kolb365561d2011-08-18 09:56:25 -0700447 if (mTabControl.getTabCount() > 0) {
448 // use a fallback tab
449 setActiveTab(mTabControl.getCurrentTab());
450 }
Michael Kolbbf32cd02011-08-16 15:07:04 -0700451 mContentView.setVisibility(View.VISIBLE);
452 finishAnimateOut();
Michael Kolb8a009492011-08-15 15:37:30 -0700453 return;
Michael Kolbc3af0672011-08-09 10:24:41 -0700454 }
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800455 blockEvents();
Michael Kolbc3af0672011-08-09 10:24:41 -0700456 mUiController.setActiveTab(tab);
457 mContentView.setVisibility(View.VISIBLE);
John Reckcc0059c2011-10-07 13:53:13 -0700458 if (mAnimScreen == null) {
459 mAnimScreen = new AnimScreen(mActivity);
460 }
Tarun Nainani8eb00912014-07-17 12:28:32 -0700461 ImageView target = tabview.mImage;
462 int width = target.getDrawable().getIntrinsicWidth();
463 int height = target.getDrawable().getIntrinsicHeight();
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700464 Bitmap bm = tab.getScreenshot();
Vivek Sekharc549e3a2014-06-05 16:19:26 -0700465 if (bm == null)
466 bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
467 mAnimScreen.set(bm);
Michael Kolb0755fcd2012-01-10 10:19:50 -0800468 if (mAnimScreen.mMain.getParent() == null) {
469 mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
470 }
John Reckcc0059c2011-10-07 13:53:13 -0700471 mAnimScreen.mMain.layout(0, 0, mContentView.getWidth(),
Tarun Nainani8eb00912014-07-17 12:28:32 -0700472 mContentView.getHeight());
Enrico Ros80c045a2014-11-24 15:23:12 -0800473 mNavScreen.getScroller().finishScroller();
Michael Kolbc3af0672011-08-09 10:24:41 -0700474 int toLeft = 0;
Tarun Nainani8eb00912014-07-17 12:28:32 -0700475 int toTop = mTitleBar.calculateEmbeddedHeight();
Michael Kolbc3af0672011-08-09 10:24:41 -0700476 int toRight = mContentView.getWidth();
Enrico Ros80c045a2014-11-24 15:23:12 -0800477 int fromLeft = tabview.getLeft() + target.getLeft() - mNavScreen.getScroller().getScrollX();
478 int fromTop = tabview.getTop() + target.getTop() - mNavScreen.getScroller().getScrollY();
Tarun Nainani8eb00912014-07-17 12:28:32 -0700479 int fromRight = fromLeft + width;
480 int fromBottom = fromTop + height;
Michael Kolbc3af0672011-08-09 10:24:41 -0700481 float scaleFactor = mContentView.getWidth() / (float) width;
Michael Kolba3194d02011-09-07 11:23:51 -0700482 int toBottom = toTop + (int) (height * scaleFactor);
John Reck9c5004e2011-10-07 16:00:12 -0700483 mAnimScreen.mContent.setLeft(fromLeft);
484 mAnimScreen.mContent.setTop(fromTop);
485 mAnimScreen.mContent.setRight(fromRight);
486 mAnimScreen.mContent.setBottom(fromBottom);
487 mAnimScreen.setScaleFactor(1f);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800488 //ObjectAnimator fade2 = ObjectAnimator.ofFloat(mNavScreen, "alpha", 1f, 0f);
489 //fade2.setDuration(100);
490 AnimatorSet set = new AnimatorSet();
491 ObjectAnimator animAppear = ObjectAnimator.ofFloat(mAnimScreen.mMain, "alpha", 0f, 1f);
492 animAppear.setDuration(100);
493 ObjectAnimator l = ObjectAnimator.ofInt(mAnimScreen.mContent, "left", fromLeft, toLeft);
494 ObjectAnimator t = ObjectAnimator.ofInt(mAnimScreen.mContent, "top", fromTop, toTop);
495 ObjectAnimator r = ObjectAnimator.ofInt(mAnimScreen.mContent, "right", fromRight, toRight);
496 ObjectAnimator b = ObjectAnimator.ofInt(mAnimScreen.mContent, "bottom", fromBottom, toBottom);
497 ObjectAnimator scale = ObjectAnimator.ofFloat(mAnimScreen, "scaleFactor", 1f, scaleFactor);
498 set.playTogether(animAppear, l, t, r, b, scale);
499 set.setInterpolator(new DecelerateInterpolator());
500 set.setDuration(200);
501 set.addListener(new AnimatorListenerAdapter() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700502 @Override
503 public void onAnimationEnd(Animator anim) {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400504 checkTabReady();
505 }
506 });
Enrico Ros1f5a0952014-11-18 20:15:48 -0800507 set.start();
Matthew Hui1eb7a832014-04-15 12:20:58 -0400508 }
509
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700510
511 private int mNumTries = 0;
Matthew Hui1eb7a832014-04-15 12:20:58 -0400512 private void checkTabReady() {
513 boolean isready = true;
Enrico Ros1f5a0952014-11-18 20:15:48 -0800514 boolean zeroTries = mNumTries == 0;
Matthew Hui1eb7a832014-04-15 12:20:58 -0400515 Tab tab = mUiController.getTabControl().getCurrentTab();
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700516 BrowserWebView webview = null;
Matthew Hui1eb7a832014-04-15 12:20:58 -0400517 if (tab == null)
518 isready = false;
519 else {
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700520 webview = (BrowserWebView)tab.getWebView();
521 if (webview == null) {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400522 isready = false;
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700523 } else {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400524 isready = webview.isReady();
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700525 }
Matthew Hui1eb7a832014-04-15 12:20:58 -0400526 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700527 // Post only when not ready and not crashed
528 if (!isready && mNumTries++ < 150) {
529 mCustomViewContainer.postDelayed(new Runnable() {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400530 public void run() {
531 checkTabReady();
532 }
533 }, 17); //WebView is not ready. check again in for next frame.
534 return;
535 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700536 mNumTries = 0;
Vivek Sekharc70ae632015-04-08 17:54:05 -0700537 final boolean hasCrashed = (webview == null) ? false :false;
Enrico Ros1f5a0952014-11-18 20:15:48 -0800538 // fast path: don't wait if we've been ready for a while
539 if (zeroTries) {
Vivek Sekharc70ae632015-04-08 17:54:05 -0700540 fadeOutCustomViewContainer();
Enrico Ros1f5a0952014-11-18 20:15:48 -0800541 return;
542 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700543 mCustomViewContainer.postDelayed(new Runnable() {
Enrico Ros1f5a0952014-11-18 20:15:48 -0800544 public void run() {
Vivek Sekharc70ae632015-04-08 17:54:05 -0700545 fadeOutCustomViewContainer();
Enrico Ros1f5a0952014-11-18 20:15:48 -0800546 }
547 }, 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 -0400548 }
549
Vivek Sekharc70ae632015-04-08 17:54:05 -0700550 private void fadeOutCustomViewContainer() {
Matthew Hui1eb7a832014-04-15 12:20:58 -0400551 ObjectAnimator otheralpha = ObjectAnimator.ofFloat(mCustomViewContainer, "alpha", 1f, 0f);
Vivek Sekharc70ae632015-04-08 17:54:05 -0700552 otheralpha.setDuration(100);
Matthew Hui1eb7a832014-04-15 12:20:58 -0400553 otheralpha.addListener(new AnimatorListenerAdapter() {
554 @Override
555 public void onAnimationEnd(Animator anim) {
John Reckcc0059c2011-10-07 13:53:13 -0700556 mCustomViewContainer.removeView(mAnimScreen.mMain);
Michael Kolbbf32cd02011-08-16 15:07:04 -0700557 finishAnimateOut();
Sagar Dhawanf7b5d0b2015-02-06 15:47:20 -0800558 unblockEvents();
Michael Kolbc3af0672011-08-09 10:24:41 -0700559 }
560 });
Enrico Ros1f5a0952014-11-18 20:15:48 -0800561 otheralpha.setInterpolator(new DecelerateInterpolator());
Matthew Hui1eb7a832014-04-15 12:20:58 -0400562 otheralpha.start();
Michael Kolbc3af0672011-08-09 10:24:41 -0700563 }
564
Michael Kolbbf32cd02011-08-16 15:07:04 -0700565 private void finishAnimateOut() {
John Reckcc0059c2011-10-07 13:53:13 -0700566 mNavScreen.setVisibility(View.GONE);
Michael Kolbc3af0672011-08-09 10:24:41 -0700567 mCustomViewContainer.setAlpha(1f);
Michael Kolbf2055602011-04-09 17:20:03 -0700568 mCustomViewContainer.setVisibility(View.GONE);
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700569 mAnimScreen.set(null);
Michael Kolbf2055602011-04-09 17:20:03 -0700570 }
571
John Reck6b4bd5f2011-07-12 10:14:38 -0700572 @Override
573 public boolean needsRestoreAllTabs() {
574 return false;
575 }
576
Michael Kolb20be26d2011-07-18 16:38:02 -0700577 public void toggleNavScreen() {
John Reckcc0059c2011-10-07 13:53:13 -0700578 if (!showingNavScreen()) {
Michael Kolb20be26d2011-07-18 16:38:02 -0700579 showNavScreen();
580 } else {
Michael Kolba3194d02011-09-07 11:23:51 -0700581 hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
Michael Kolb20be26d2011-07-18 16:38:02 -0700582 }
583 }
584
John Reck1cf4b792011-07-26 10:22:22 -0700585 @Override
586 public boolean shouldCaptureThumbnails() {
587 return true;
588 }
589
Michael Kolbc3af0672011-08-09 10:24:41 -0700590 static class AnimScreen {
John Reck3ba45532011-08-11 16:26:53 -0700591
Michael Kolbc3af0672011-08-09 10:24:41 -0700592 private View mMain;
Michael Kolbc3af0672011-08-09 10:24:41 -0700593 private ImageView mContent;
594 private float mScale;
595
John Reckcc0059c2011-10-07 13:53:13 -0700596 public AnimScreen(Context ctx) {
Enrico Ros1f5a0952014-11-18 20:15:48 -0800597 mMain = LayoutInflater.from(ctx).inflate(R.layout.anim_screen, null);
598 mMain.setOnClickListener(new View.OnClickListener() {
599 @Override
600 public void onClick(View v) {
601 // just eat clicks when this view is visible
602 }
603 });
604 mContent = (ImageView) mMain.findViewById(R.id.anim_screen_content);
John Reckcc0059c2011-10-07 13:53:13 -0700605 mContent.setScaleType(ImageView.ScaleType.MATRIX);
606 mContent.setImageMatrix(new Matrix());
607 mScale = 1.0f;
608 setScaleFactor(getScaleFactor());
609 }
610
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700611 public void set(TitleBar tbar, Bitmap viewportBitmap) {
612 if (tbar == null) {
John Reck62077d82011-10-13 15:17:50 -0700613 return;
614 }
Tarun Nainaniea28dde2014-08-27 17:25:09 -0700615 mContent.setImageBitmap(viewportBitmap);
Michael Kolbc3af0672011-08-09 10:24:41 -0700616 }
617
Enrico Ros1f5a0952014-11-18 20:15:48 -0800618 /*private Bitmap safeCreateBitmap(int width, int height) {
John Recka98c83b2011-10-31 12:31:58 -0700619 if (width <= 0 || height <= 0) {
620 Log.w(LOGTAG, "safeCreateBitmap failed! width: " + width
621 + ", height: " + height);
622 return null;
623 }
624 return Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800625 }*/
John Recka98c83b2011-10-31 12:31:58 -0700626
John Reckcc0059c2011-10-07 13:53:13 -0700627 public void set(Bitmap image) {
Michael Kolbc3af0672011-08-09 10:24:41 -0700628 mContent.setImageBitmap(image);
Michael Kolbc3af0672011-08-09 10:24:41 -0700629 }
630
John Reckcc0059c2011-10-07 13:53:13 -0700631 private void setScaleFactor(float sf) {
Michael Kolbc3af0672011-08-09 10:24:41 -0700632 mScale = sf;
633 Matrix m = new Matrix();
Enrico Ros1f5a0952014-11-18 20:15:48 -0800634 m.postScale(sf, sf);
Michael Kolbc3af0672011-08-09 10:24:41 -0700635 mContent.setImageMatrix(m);
636 }
637
John Reckcc0059c2011-10-07 13:53:13 -0700638 private float getScaleFactor() {
Michael Kolbc3af0672011-08-09 10:24:41 -0700639 return mScale;
640 }
641
John Reck3ba45532011-08-11 16:26:53 -0700642 }
643
Michael Kolb66706532010-12-12 19:50:22 -0800644}