• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.browser;
18 
19 import android.animation.Animator;
20 import android.animation.Animator.AnimatorListener;
21 import android.animation.ObjectAnimator;
22 import android.content.Context;
23 import android.content.res.Configuration;
24 import android.content.res.Resources;
25 import android.view.LayoutInflater;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.view.ViewStub;
29 import android.view.accessibility.AccessibilityManager;
30 import android.view.animation.Animation;
31 import android.view.animation.Animation.AnimationListener;
32 import android.view.animation.AnimationUtils;
33 import android.view.animation.DecelerateInterpolator;
34 import android.webkit.WebView;
35 import android.widget.FrameLayout;
36 import android.widget.RelativeLayout;
37 
38 
39 /**
40  * Base class for a title bar used by the browser.
41  */
42 public class TitleBar extends RelativeLayout {
43 
44     private static final int PROGRESS_MAX = 100;
45     private static final float ANIM_TITLEBAR_DECELERATE = 2.5f;
46 
47     private UiController mUiController;
48     private BaseUi mBaseUi;
49     private FrameLayout mContentView;
50     private PageProgressView mProgress;
51     private AccessibilityManager mAccessibilityManager;
52 
53     private AutologinBar mAutoLogin;
54     private NavigationBarBase mNavBar;
55     private boolean mUseQuickControls;
56     private SnapshotBar mSnapshotBar;
57 
58     //state
59     private boolean mShowing;
60     private boolean mInLoad;
61     private boolean mSkipTitleBarAnimations;
62     private Animator mTitleBarAnimator;
63     private boolean mIsFixedTitleBar;
64 
TitleBar(Context context, UiController controller, BaseUi ui, FrameLayout contentView)65     public TitleBar(Context context, UiController controller, BaseUi ui,
66             FrameLayout contentView) {
67         super(context, null);
68         mUiController = controller;
69         mBaseUi = ui;
70         mContentView = contentView;
71         mAccessibilityManager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
72         initLayout(context);
73         setFixedTitleBar();
74     }
75 
initLayout(Context context)76     private void initLayout(Context context) {
77         LayoutInflater factory = LayoutInflater.from(context);
78         factory.inflate(R.layout.title_bar, this);
79         mProgress = (PageProgressView) findViewById(R.id.progress);
80         mNavBar = (NavigationBarBase) findViewById(R.id.taburlbar);
81         mNavBar.setTitleBar(this);
82     }
83 
inflateAutoLoginBar()84     private void inflateAutoLoginBar() {
85         if (mAutoLogin != null) {
86             return;
87         }
88 
89         ViewStub stub = (ViewStub) findViewById(R.id.autologin_stub);
90         mAutoLogin = (AutologinBar) stub.inflate();
91         mAutoLogin.setTitleBar(this);
92     }
93 
inflateSnapshotBar()94     private void inflateSnapshotBar() {
95         if (mSnapshotBar != null) {
96             return;
97         }
98 
99         ViewStub stub = (ViewStub) findViewById(R.id.snapshotbar_stub);
100         mSnapshotBar = (SnapshotBar) stub.inflate();
101         mSnapshotBar.setTitleBar(this);
102     }
103 
104     @Override
onConfigurationChanged(Configuration config)105     protected void onConfigurationChanged(Configuration config) {
106         super.onConfigurationChanged(config);
107         setFixedTitleBar();
108     }
109 
110     @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)111     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
112         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
113         if (mIsFixedTitleBar) {
114             int margin = getMeasuredHeight() - calculateEmbeddedHeight();
115             mBaseUi.setContentViewMarginTop(-margin);
116         } else {
117             mBaseUi.setContentViewMarginTop(0);
118         }
119     }
120 
setFixedTitleBar()121     private void setFixedTitleBar() {
122         boolean isFixed = !mUseQuickControls
123                 && !mContext.getResources().getBoolean(R.bool.hide_title);
124         isFixed |= mAccessibilityManager.isEnabled();
125         // If getParent() returns null, we are initializing
126         ViewGroup parent = (ViewGroup)getParent();
127         if (mIsFixedTitleBar == isFixed && parent != null) return;
128         mIsFixedTitleBar = isFixed;
129         setSkipTitleBarAnimations(true);
130         show();
131         setSkipTitleBarAnimations(false);
132         if (parent != null) {
133             parent.removeView(this);
134         }
135         if (mIsFixedTitleBar) {
136             mBaseUi.addFixedTitleBar(this);
137         } else {
138             mContentView.addView(this, makeLayoutParams());
139             mBaseUi.setContentViewMarginTop(0);
140         }
141     }
142 
getUi()143     public BaseUi getUi() {
144         return mBaseUi;
145     }
146 
getUiController()147     public UiController getUiController() {
148         return mUiController;
149     }
150 
setUseQuickControls(boolean use)151     public void setUseQuickControls(boolean use) {
152         mUseQuickControls = use;
153         setFixedTitleBar();
154         if (use) {
155             this.setVisibility(View.GONE);
156         } else {
157             this.setVisibility(View.VISIBLE);
158         }
159     }
160 
setShowProgressOnly(boolean progress)161     void setShowProgressOnly(boolean progress) {
162         if (progress && !wantsToBeVisible()) {
163             mNavBar.setVisibility(View.GONE);
164         } else {
165             mNavBar.setVisibility(View.VISIBLE);
166         }
167     }
168 
setSkipTitleBarAnimations(boolean skip)169     void setSkipTitleBarAnimations(boolean skip) {
170         mSkipTitleBarAnimations = skip;
171     }
172 
setupTitleBarAnimator(Animator animator)173     void setupTitleBarAnimator(Animator animator) {
174         Resources res = mContext.getResources();
175         int duration = res.getInteger(R.integer.titlebar_animation_duration);
176         animator.setInterpolator(new DecelerateInterpolator(
177                 ANIM_TITLEBAR_DECELERATE));
178         animator.setDuration(duration);
179     }
180 
show()181     void show() {
182         cancelTitleBarAnimation(false);
183         if (mUseQuickControls || mSkipTitleBarAnimations) {
184             this.setVisibility(View.VISIBLE);
185             this.setTranslationY(0);
186         } else {
187             int visibleHeight = getVisibleTitleHeight();
188             float startPos = (-getEmbeddedHeight() + visibleHeight);
189             if (getTranslationY() != 0) {
190                 startPos = Math.max(startPos, getTranslationY());
191             }
192             mTitleBarAnimator = ObjectAnimator.ofFloat(this,
193                     "translationY",
194                     startPos, 0);
195             setupTitleBarAnimator(mTitleBarAnimator);
196             mTitleBarAnimator.start();
197         }
198         mShowing = true;
199     }
200 
hide()201     void hide() {
202         if (mUseQuickControls) {
203             this.setVisibility(View.GONE);
204         } else {
205             if (mIsFixedTitleBar) return;
206             if (!mSkipTitleBarAnimations) {
207                 cancelTitleBarAnimation(false);
208                 int visibleHeight = getVisibleTitleHeight();
209                 mTitleBarAnimator = ObjectAnimator.ofFloat(this,
210                         "translationY", getTranslationY(),
211                         (-getEmbeddedHeight() + visibleHeight));
212                 mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
213                 setupTitleBarAnimator(mTitleBarAnimator);
214                 mTitleBarAnimator.start();
215             } else {
216                 onScrollChanged();
217             }
218         }
219         mShowing = false;
220     }
221 
isShowing()222     boolean isShowing() {
223         return mShowing;
224     }
225 
cancelTitleBarAnimation(boolean reset)226     void cancelTitleBarAnimation(boolean reset) {
227         if (mTitleBarAnimator != null) {
228             mTitleBarAnimator.cancel();
229             mTitleBarAnimator = null;
230         }
231         if (reset) {
232             setTranslationY(0);
233         }
234     }
235 
236     private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {
237 
238         @Override
239         public void onAnimationStart(Animator animation) {
240         }
241 
242         @Override
243         public void onAnimationRepeat(Animator animation) {
244         }
245 
246         @Override
247         public void onAnimationEnd(Animator animation) {
248             // update position
249             onScrollChanged();
250         }
251 
252         @Override
253         public void onAnimationCancel(Animator animation) {
254         }
255     };
256 
getVisibleTitleHeight()257     private int getVisibleTitleHeight() {
258         Tab tab = mBaseUi.getActiveTab();
259         WebView webview = tab != null ? tab.getWebView() : null;
260         return webview != null ? webview.getVisibleTitleHeight() : 0;
261     }
262 
263     /**
264      * Update the progress, from 0 to 100.
265      */
setProgress(int newProgress)266     public void setProgress(int newProgress) {
267         if (newProgress >= PROGRESS_MAX) {
268             mProgress.setProgress(PageProgressView.MAX_PROGRESS);
269             mProgress.setVisibility(View.GONE);
270             mInLoad = false;
271             mNavBar.onProgressStopped();
272             // check if needs to be hidden
273             if (!isEditingUrl() && !wantsToBeVisible()) {
274                 if (mUseQuickControls) {
275                     hide();
276                 } else {
277                     mBaseUi.showTitleBarForDuration();
278                 }
279             }
280         } else {
281             if (!mInLoad) {
282                 mProgress.setVisibility(View.VISIBLE);
283                 mInLoad = true;
284                 mNavBar.onProgressStarted();
285             }
286             mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
287                     / PROGRESS_MAX);
288             if (mUseQuickControls && !isEditingUrl()) {
289                 setShowProgressOnly(true);
290             }
291             if (!mShowing) {
292                 show();
293             }
294         }
295     }
296 
getEmbeddedHeight()297     public int getEmbeddedHeight() {
298         if (mUseQuickControls || mIsFixedTitleBar) return 0;
299         return calculateEmbeddedHeight();
300     }
301 
calculateEmbeddedHeight()302     private int calculateEmbeddedHeight() {
303         int height = mNavBar.getHeight();
304         if (mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE) {
305             height += mAutoLogin.getHeight();
306         }
307         return height;
308     }
309 
updateAutoLogin(Tab tab, boolean animate)310     public void updateAutoLogin(Tab tab, boolean animate) {
311         if (mAutoLogin == null) {
312             if  (tab.getDeviceAccountLogin() == null) {
313                 return;
314             }
315             inflateAutoLoginBar();
316         }
317         mAutoLogin.updateAutoLogin(tab, animate);
318     }
319 
showAutoLogin(boolean animate)320     public void showAutoLogin(boolean animate) {
321         if (mUseQuickControls) {
322             mBaseUi.showTitleBar();
323         }
324         if (mAutoLogin == null) {
325             inflateAutoLoginBar();
326         }
327         mAutoLogin.setVisibility(View.VISIBLE);
328         if (animate) {
329             mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
330                     getContext(), R.anim.autologin_enter));
331         }
332     }
333 
hideAutoLogin(boolean animate)334     public void hideAutoLogin(boolean animate) {
335         if (mUseQuickControls) {
336             mBaseUi.hideTitleBar();
337             mAutoLogin.setVisibility(View.GONE);
338             mBaseUi.refreshWebView();
339         } else {
340             if (animate) {
341                 Animation anim = AnimationUtils.loadAnimation(getContext(),
342                         R.anim.autologin_exit);
343                 anim.setAnimationListener(new AnimationListener() {
344                     @Override
345                     public void onAnimationEnd(Animation a) {
346                         mAutoLogin.setVisibility(View.GONE);
347                         mBaseUi.refreshWebView();
348                     }
349 
350                     @Override
351                     public void onAnimationStart(Animation a) {
352                     }
353 
354                     @Override
355                     public void onAnimationRepeat(Animation a) {
356                     }
357                 });
358                 mAutoLogin.startAnimation(anim);
359             } else if (mAutoLogin.getAnimation() == null) {
360                 mAutoLogin.setVisibility(View.GONE);
361                 mBaseUi.refreshWebView();
362             }
363         }
364     }
365 
wantsToBeVisible()366     public boolean wantsToBeVisible() {
367         return inAutoLogin()
368             || (mSnapshotBar != null && mSnapshotBar.getVisibility() == View.VISIBLE
369                     && mSnapshotBar.isAnimating());
370     }
371 
inAutoLogin()372     private boolean inAutoLogin() {
373         return mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE;
374     }
375 
isEditingUrl()376     public boolean isEditingUrl() {
377         return mNavBar.isEditingUrl();
378     }
379 
getCurrentWebView()380     public WebView getCurrentWebView() {
381         Tab t = mBaseUi.getActiveTab();
382         if (t != null) {
383             return t.getWebView();
384         } else {
385             return null;
386         }
387     }
388 
getProgressView()389     public PageProgressView getProgressView() {
390         return mProgress;
391     }
392 
getNavigationBar()393     public NavigationBarBase getNavigationBar() {
394         return mNavBar;
395     }
396 
useQuickControls()397     public boolean useQuickControls() {
398         return mUseQuickControls;
399     }
400 
isInLoad()401     public boolean isInLoad() {
402         return mInLoad;
403     }
404 
makeLayoutParams()405     private ViewGroup.LayoutParams makeLayoutParams() {
406         return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
407                 LayoutParams.WRAP_CONTENT);
408     }
409 
410     @Override
focusSearch(View focused, int dir)411     public View focusSearch(View focused, int dir) {
412         WebView web = getCurrentWebView();
413         if (FOCUS_DOWN == dir && hasFocus() && web != null
414                 && web.hasFocusable() && web.getParent() != null) {
415             return web;
416         }
417         return super.focusSearch(focused, dir);
418     }
419 
onTabDataChanged(Tab tab)420     public void onTabDataChanged(Tab tab) {
421         if (mSnapshotBar != null) {
422             mSnapshotBar.onTabDataChanged(tab);
423         }
424 
425         if (tab.isSnapshot()) {
426             inflateSnapshotBar();
427             mSnapshotBar.setVisibility(VISIBLE);
428             mNavBar.setVisibility(GONE);
429         } else {
430             if (mSnapshotBar != null) {
431                 mSnapshotBar.setVisibility(GONE);
432             }
433             mNavBar.setVisibility(VISIBLE);
434         }
435     }
436 
onScrollChanged()437     public void onScrollChanged() {
438         if (!mShowing && !mIsFixedTitleBar) {
439             setTranslationY(getVisibleTitleHeight() - getEmbeddedHeight());
440         }
441     }
442 
onResume()443     public void onResume() {
444         setFixedTitleBar();
445     }
446 
447 }
448