1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.chrome.browser.compositor.layouts.components;
6 
7 import android.content.Context;
8 import android.content.res.Resources;
9 import android.graphics.Color;
10 import android.graphics.RectF;
11 
12 import org.chromium.base.MathUtils;
13 import org.chromium.chrome.browser.tab.Tab;
14 import org.chromium.ui.modelutil.PropertyKey;
15 import org.chromium.ui.modelutil.PropertyModel;
16 
17 /**
18  * {@link LayoutTab} is used to keep track of a thumbnail's bitmap and position and to
19  * draw itself onto the GL canvas at the desired Y Offset.
20  */
21 public class LayoutTab extends PropertyModel {
22     public static final float ALPHA_THRESHOLD = 1.0f / 255.0f;
23 
24     // TODO(crbug.com/1070284): Make the following properties be part of the PropertyModel.
25     // Begin section --------------
26     // Public Layout constants.
27     public static final float CLOSE_BUTTON_WIDTH_DP = 36.f;
28     public static final float SHADOW_ALPHA_ON_LIGHT_BG = 0.8f;
29     public static final float SHADOW_ALPHA_ON_DARK_BG = 1.0f;
30 
31     public static float sDpToPx;
32     private static float sPxToDp;
33     // End section --------------
34 
35     // TODO(crbug.com/1070284): Maybe make this a ReadableIntPropertyKey
36     public static final WritableIntPropertyKey TAB_ID = new WritableIntPropertyKey();
37 
38     // TODO(crbug.com/1070284): Maybe make this a ReadableIntPropertyKey
39     public static final WritableBooleanPropertyKey IS_INCOGNITO = new WritableBooleanPropertyKey();
40 
41     // Fields initialized in init()
42     public static final WritableFloatPropertyKey SCALE = new WritableFloatPropertyKey();
43 
44     public static final WritableFloatPropertyKey TILT_X_IN_DEGREES = new WritableFloatPropertyKey();
45 
46     public static final WritableFloatPropertyKey TILT_Y_IN_DEGREES = new WritableFloatPropertyKey();
47 
48     public static final WritableFloatPropertyKey TILT_X_PIVOT_OFFSET =
49             new WritableFloatPropertyKey();
50 
51     public static final WritableFloatPropertyKey TILT_Y_PIVOT_OFFSET =
52             new WritableFloatPropertyKey();
53 
54     public static final WritableFloatPropertyKey X = new WritableFloatPropertyKey();
55 
56     public static final WritableFloatPropertyKey Y = new WritableFloatPropertyKey();
57 
58     public static final WritableFloatPropertyKey RENDER_X = new WritableFloatPropertyKey();
59 
60     public static final WritableFloatPropertyKey RENDER_Y = new WritableFloatPropertyKey();
61 
62     // The top left X offset of the clipped rectangle.
63     public static final WritableFloatPropertyKey CLIPPED_X = new WritableFloatPropertyKey();
64 
65     // The top left Y offset of the clipped rectangle.
66     public static final WritableFloatPropertyKey CLIPPED_Y = new WritableFloatPropertyKey();
67 
68     public static final WritableFloatPropertyKey CLIPPED_WIDTH = new WritableFloatPropertyKey();
69 
70     public static final WritableFloatPropertyKey CLIPPED_HEIGHT = new WritableFloatPropertyKey();
71 
72     public static final WritableFloatPropertyKey ALPHA = new WritableFloatPropertyKey();
73 
74     public static final WritableFloatPropertyKey SATURATION = new WritableFloatPropertyKey();
75 
76     public static final WritableFloatPropertyKey BORDER_ALPHA = new WritableFloatPropertyKey();
77 
78     public static final WritableFloatPropertyKey BORDER_CLOSE_BUTTON_ALPHA =
79             new WritableFloatPropertyKey();
80 
81     public static final WritableFloatPropertyKey BORDER_SCALE = new WritableFloatPropertyKey();
82 
83     public static final WritableFloatPropertyKey ORIGINAL_CONTENT_WIDTH_IN_DP =
84             new WritableFloatPropertyKey();
85 
86     public static final WritableFloatPropertyKey ORIGINAL_CONTENT_HEIGHT_IN_DP =
87             new WritableFloatPropertyKey();
88 
89     public static final WritableFloatPropertyKey MAX_CONTENT_WIDTH = new WritableFloatPropertyKey();
90 
91     public static final WritableFloatPropertyKey MAX_CONTENT_HEIGHT =
92             new WritableFloatPropertyKey();
93 
94     public static final WritableFloatPropertyKey STATIC_TO_VIEW_BLEND =
95             new WritableFloatPropertyKey();
96 
97     public static final WritableFloatPropertyKey BRIGHTNESS = new WritableFloatPropertyKey();
98 
99     public static final WritableBooleanPropertyKey IS_VISIBLE = new WritableBooleanPropertyKey();
100 
101     public static final WritableBooleanPropertyKey SHOULD_STALL = new WritableBooleanPropertyKey();
102 
103     public static final WritableBooleanPropertyKey CAN_USE_LIVE_TEXTURE =
104             new WritableBooleanPropertyKey();
105 
106     public static final WritableBooleanPropertyKey SHOW_TOOLBAR = new WritableBooleanPropertyKey();
107 
108     public static final WritableBooleanPropertyKey ANONYMIZE_TOOLBAR =
109             new WritableBooleanPropertyKey();
110 
111     public static final WritableFloatPropertyKey TOOLBAR_ALPHA = new WritableFloatPropertyKey();
112 
113     public static final WritableBooleanPropertyKey INSET_BORDER_VERTICAL =
114             new WritableBooleanPropertyKey();
115 
116     public static final WritableFloatPropertyKey TOOLBAR_Y_OFFSET = new WritableFloatPropertyKey();
117 
118     public static final WritableFloatPropertyKey SIDE_BORDER_SCALE = new WritableFloatPropertyKey();
119 
120     public static final WritableBooleanPropertyKey CLOSE_BUTTON_IS_ON_RIGHT =
121             new WritableBooleanPropertyKey();
122 
123     public static final WritableObjectPropertyKey<RectF> BOUNDS = new WritableObjectPropertyKey<>();
124 
125     public static final WritableObjectPropertyKey<RectF> CLOSE_PLACEMENT =
126             new WritableObjectPropertyKey<>();
127 
128     /** Whether we need to draw the decoration (border, shadow, ..) at all. */
129     public static final WritableFloatPropertyKey DECORATION_ALPHA = new WritableFloatPropertyKey();
130 
131     /**
132      * Whether this tab need to have its title texture generated. As this is not a free operation
133      * knowing that we won't show it might save a few cycles and memory.
134      */
135     public static final WritableBooleanPropertyKey IS_TITLE_NEEDED =
136             new WritableBooleanPropertyKey();
137 
138     /**
139      * Whether initFromHost() has been called since the last call to init().
140      */
141     public static final WritableBooleanPropertyKey INIT_FROM_HOST_CALLED =
142             new WritableBooleanPropertyKey();
143 
144     // All the members bellow are initialized from the delayed initialization.
145     //
146     // Begin section --------------
147 
148     /** The color of the background of the tab. Used as the best approximation to fill in. */
149     public static final WritableIntPropertyKey BACKGROUND_COLOR = new WritableIntPropertyKey();
150 
151     public static final WritableIntPropertyKey TOOLBAR_BACKGROUND_COLOR =
152             new WritableIntPropertyKey();
153 
154     public static final WritableIntPropertyKey TEXT_BOX_BACKGROUND_COLOR =
155             new WritableIntPropertyKey();
156 
157     public static final WritableFloatPropertyKey TEXT_BOX_ALPHA = new WritableFloatPropertyKey();
158 
159     // End section --------------
160 
161     public static final PropertyModel.WritableFloatPropertyKey CONTENT_OFFSET =
162             new PropertyModel.WritableFloatPropertyKey();
163 
164     public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {TAB_ID, IS_INCOGNITO, SCALE,
165             TILT_X_IN_DEGREES, TILT_Y_IN_DEGREES, TILT_X_PIVOT_OFFSET, TILT_Y_PIVOT_OFFSET, X, Y,
166             RENDER_X, RENDER_Y, CLIPPED_X, CLIPPED_Y, CLIPPED_WIDTH, CLIPPED_HEIGHT, ALPHA,
167             SATURATION, BORDER_ALPHA, BORDER_CLOSE_BUTTON_ALPHA, BORDER_SCALE,
168             ORIGINAL_CONTENT_WIDTH_IN_DP, ORIGINAL_CONTENT_HEIGHT_IN_DP, MAX_CONTENT_WIDTH,
169             MAX_CONTENT_HEIGHT, STATIC_TO_VIEW_BLEND, BRIGHTNESS, IS_VISIBLE, SHOULD_STALL,
170             CAN_USE_LIVE_TEXTURE, SHOW_TOOLBAR, ANONYMIZE_TOOLBAR, TOOLBAR_ALPHA,
171             INSET_BORDER_VERTICAL, TOOLBAR_Y_OFFSET, SIDE_BORDER_SCALE, CLOSE_BUTTON_IS_ON_RIGHT,
172             BOUNDS, CLOSE_PLACEMENT, DECORATION_ALPHA, IS_TITLE_NEEDED, INIT_FROM_HOST_CALLED,
173             BACKGROUND_COLOR, TOOLBAR_BACKGROUND_COLOR, TEXT_BOX_BACKGROUND_COLOR, TEXT_BOX_ALPHA,
174             CONTENT_OFFSET};
175 
176     /**
177      * Default constructor for a {@link LayoutTab}.
178      *
179      * @param tabId                   The id of the source {@link Tab}.
180      * @param isIncognito             Whether the tab in the in the incognito stack.
181      * @param maxContentTextureWidth  The maximum width for drawing the content in px.
182      * @param maxContentTextureHeight The maximum height for drawing the content in px.
183      * @param showCloseButton         Whether a close button should be displayed in the corner.
184      * @param isTitleNeeded           Whether that tab need a title texture. This is an
185      *                                optimization to save cycles and memory. This is
186      *                                ignored if the title texture is already set.
187      */
LayoutTab(int tabId, boolean isIncognito, int maxContentTextureWidth, int maxContentTextureHeight, boolean showCloseButton, boolean isTitleNeeded)188     public LayoutTab(int tabId, boolean isIncognito, int maxContentTextureWidth,
189             int maxContentTextureHeight, boolean showCloseButton, boolean isTitleNeeded) {
190         super(ALL_KEYS);
191 
192         set(TAB_ID, tabId);
193         set(IS_INCOGNITO, isIncognito);
194         set(BOUNDS, new RectF());
195         set(CLOSE_PLACEMENT, new RectF());
196         set(BACKGROUND_COLOR, Color.WHITE);
197         set(TOOLBAR_BACKGROUND_COLOR, 0xfff2f2f2);
198         set(TEXT_BOX_BACKGROUND_COLOR, Color.WHITE);
199         set(TEXT_BOX_ALPHA, 1.0f);
200 
201         init(maxContentTextureWidth, maxContentTextureHeight, showCloseButton, isTitleNeeded);
202     }
203 
204     /**
205      * Initializes a {@link LayoutTab} to its default value so it can be reused.
206      *
207      * @param maxContentTextureWidth  The maximum width of the page content in px.
208      * @param maxContentTextureHeight The maximum height of the page content in px.
209      * @param showCloseButton         Whether to show the close button on the tab border.
210      * @param isTitleNeeded           Whether that tab need a title texture. This is an
211      *                                optimization to save cycles and memory. This is
212      *                                ignored if the title texture is already set.
213      */
init(int maxContentTextureWidth, int maxContentTextureHeight, boolean showCloseButton, boolean isTitleNeeded)214     public void init(int maxContentTextureWidth, int maxContentTextureHeight,
215             boolean showCloseButton, boolean isTitleNeeded) {
216         set(ALPHA, 1.0f);
217         set(SATURATION, 1.0f);
218         set(BRIGHTNESS, 1.0f);
219         set(BORDER_ALPHA, 1.0f);
220         set(BORDER_CLOSE_BUTTON_ALPHA, showCloseButton ? 1.f : 0.f);
221         set(BORDER_SCALE, 1.0f);
222         set(CLIPPED_X, 0.0f);
223         set(CLIPPED_Y, 0.0f);
224         set(CLIPPED_WIDTH, Float.MAX_VALUE);
225         set(CLIPPED_HEIGHT, Float.MAX_VALUE);
226         set(SCALE, 1.0f);
227         set(TILT_X_IN_DEGREES, 0.0f);
228         set(TILT_Y_IN_DEGREES, 0.0f);
229         set(IS_VISIBLE, true);
230         set(X, 0.0f);
231         set(Y, 0.0f);
232         set(RENDER_X, 0.0f);
233         set(RENDER_Y, 0.0f);
234         set(STATIC_TO_VIEW_BLEND, 0.0f);
235         set(DECORATION_ALPHA, 1.0f);
236         set(IS_TITLE_NEEDED, isTitleNeeded);
237         set(CAN_USE_LIVE_TEXTURE, true);
238         set(SHOW_TOOLBAR, false);
239         set(ANONYMIZE_TOOLBAR, false);
240         set(TOOLBAR_ALPHA, 1.0f);
241         set(INSET_BORDER_VERTICAL, false);
242         set(TOOLBAR_Y_OFFSET, 0.f);
243         set(SIDE_BORDER_SCALE, 1.f);
244         set(ORIGINAL_CONTENT_WIDTH_IN_DP, maxContentTextureWidth * sPxToDp);
245         set(ORIGINAL_CONTENT_HEIGHT_IN_DP, maxContentTextureHeight * sPxToDp);
246         set(MAX_CONTENT_WIDTH, maxContentTextureWidth * sPxToDp);
247         set(MAX_CONTENT_HEIGHT, maxContentTextureHeight * sPxToDp);
248         set(INIT_FROM_HOST_CALLED, false);
249     }
250 
251     /**
252      * Initializes the {@link LayoutTab} from data extracted from a {@link Tab}.
253      * As this function may be expensive and can be delayed we initialize it as a separately.
254      *
255      * @param backgroundColor       The color of the page background.
256      * @param fallbackThumbnailId   The id of a cached thumbnail to show if the current
257      *                              thumbnail is unavailable, or {@link Tab.INVALID_TAB_ID}
258      *                              if none exists.
259      * @param shouldStall           Whether the tab should display a desaturated thumbnail and
260      *                              wait for the content layer to load.
261      * @param canUseLiveTexture     Whether the tab can use a live texture when being displayed.
262      */
initFromHost(int backgroundColor, boolean shouldStall, boolean canUseLiveTexture, int toolbarBackgroundColor, int textBoxBackgroundColor, float textBoxAlpha)263     public void initFromHost(int backgroundColor, boolean shouldStall, boolean canUseLiveTexture,
264             int toolbarBackgroundColor, int textBoxBackgroundColor, float textBoxAlpha) {
265         set(BACKGROUND_COLOR, backgroundColor);
266         set(TOOLBAR_BACKGROUND_COLOR, toolbarBackgroundColor);
267         set(TEXT_BOX_BACKGROUND_COLOR, textBoxBackgroundColor);
268         set(TEXT_BOX_ALPHA, textBoxAlpha);
269         set(SHOULD_STALL, shouldStall);
270         set(CAN_USE_LIVE_TEXTURE, canUseLiveTexture);
271         set(INIT_FROM_HOST_CALLED, true);
272     }
273 
274     /**
275      * @return Whether {@link #initFromHost} needs to be called on this {@link LayoutTab}.
276      */
isInitFromHostNeeded()277     public boolean isInitFromHostNeeded() {
278         return !get(INIT_FROM_HOST_CALLED);
279     }
280 
281     /**
282      * Helper function that gather the static constants from values/dimens.xml.
283      *
284      * @param context The Android Context.
285      */
resetDimensionConstants(Context context)286     public static void resetDimensionConstants(Context context) {
287         Resources res = context.getResources();
288         sDpToPx = res.getDisplayMetrics().density;
289         sPxToDp = 1.0f / sDpToPx;
290     }
291 
292     /**
293      * @return The scale applied to the the content of the tab. Default is 1.0.
294      */
getScale()295     public float getScale() {
296         return get(SCALE);
297     }
298 
299     /**
300      * @param scale The scale to apply on the content of the tab (everything except the borders).
301      */
setScale(float scale)302     public void setScale(float scale) {
303         set(SCALE, scale);
304     }
305 
306     /**
307      * @param tilt        The tilt angle around the X axis of the tab in degree.
308      * @param pivotOffset The offset of the X axis of the tilt pivot.
309      */
setTiltX(float tilt, float pivotOffset)310     public void setTiltX(float tilt, float pivotOffset) {
311         set(TILT_X_IN_DEGREES, tilt);
312         set(TILT_X_PIVOT_OFFSET, pivotOffset);
313     }
314 
315     /**
316      * @return The tilt angle around the X axis of the tab in degree.
317      */
getTiltX()318     public float getTiltX() {
319         return get(TILT_X_IN_DEGREES);
320     }
321 
322     /**
323      * @return The offset of the X axis of the tilt pivot.
324      */
getTiltXPivotOffset()325     public float getTiltXPivotOffset() {
326         return get(TILT_X_PIVOT_OFFSET);
327     }
328 
329     /**
330      * @param tilt        The tilt angle around the Y axis of the tab in degree.
331      * @param pivotOffset The offset of the Y axis of the tilt pivot.
332      */
setTiltY(float tilt, float pivotOffset)333     public void setTiltY(float tilt, float pivotOffset) {
334         set(TILT_Y_IN_DEGREES, tilt);
335         set(TILT_Y_PIVOT_OFFSET, pivotOffset);
336     }
337 
338     /**
339      * @return The tilt angle around the Y axis of the tab in degree.
340      */
getTiltY()341     public float getTiltY() {
342         return get(TILT_Y_IN_DEGREES);
343     }
344 
345     /**
346      * @return The offset of the Y axis of the tilt pivot.
347      */
getTiltYPivotOffset()348     public float getTiltYPivotOffset() {
349         return get(TILT_Y_IN_DEGREES);
350     }
351 
352     /**
353      * Set the clipping offset. This apply on the scaled content.
354      *
355      * @param clippedX The top left X offset of the clipped rectangle.
356      * @param clippedY The top left Y offset of the clipped rectangle.
357      */
setClipOffset(float clippedX, float clippedY)358     public void setClipOffset(float clippedX, float clippedY) {
359         set(CLIPPED_X, clippedX);
360         set(CLIPPED_Y, clippedY);
361     }
362 
363     /**
364      * Set the clipping sizes. This apply on the scaled content.
365      *
366      * @param clippedWidth  The width of the clipped rectangle. Float.MAX_VALUE for no clipping.
367      * @param clippedHeight The height of the clipped rectangle. Float.MAX_VALUE for no clipping.
368      */
setClipSize(float clippedWidth, float clippedHeight)369     public void setClipSize(float clippedWidth, float clippedHeight) {
370         set(CLIPPED_WIDTH, clippedWidth);
371         set(CLIPPED_HEIGHT, clippedHeight);
372     }
373 
374     /**
375      * @return The top left X offset of the clipped rectangle.
376      */
getClippedX()377     public float getClippedX() {
378         return get(CLIPPED_X);
379     }
380 
381     /**
382      * @return The top left Y offset of the clipped rectangle.
383      */
getClippedY()384     public float getClippedY() {
385         return get(CLIPPED_Y);
386     }
387 
388     /**
389      * @return The width of the clipped rectangle. Float.MAX_VALUE for no clipping.
390      */
getClippedWidth()391     public float getClippedWidth() {
392         return get(CLIPPED_WIDTH);
393     }
394 
395     /**
396      * @return The height of the clipped rectangle. Float.MAX_VALUE for no clipping.
397      */
getClippedHeight()398     public float getClippedHeight() {
399         return get(CLIPPED_HEIGHT);
400     }
401 
402     /**
403      * @return The maximum drawable width (scaled) of the tab contents in dp.
404      */
getScaledContentWidth()405     public float getScaledContentWidth() {
406         return getOriginalContentWidth() * get(SCALE);
407     }
408 
409     /**
410      * @return The maximum drawable height (scaled) of the tab contents in dp.
411      */
getScaledContentHeight()412     public float getScaledContentHeight() {
413         return getOriginalContentHeight() * get(SCALE);
414     }
415 
416     /**
417      * @return The maximum drawable width (not scaled) of the tab contents texture.
418      */
getOriginalContentWidth()419     public float getOriginalContentWidth() {
420         return Math.min(get(ORIGINAL_CONTENT_WIDTH_IN_DP), get(MAX_CONTENT_WIDTH));
421     }
422 
423     /**
424      * @return The maximum drawable height (not scaled) of the tab contents texture.
425      */
getOriginalContentHeight()426     public float getOriginalContentHeight() {
427         return Math.min(get(ORIGINAL_CONTENT_HEIGHT_IN_DP), get(MAX_CONTENT_HEIGHT));
428     }
429 
430     /**
431      * @return The original unclamped width (not scaled) of the tab contents texture.
432      */
getUnclampedOriginalContentHeight()433     public float getUnclampedOriginalContentHeight() {
434         return get(ORIGINAL_CONTENT_HEIGHT_IN_DP);
435     }
436 
437     /**
438      * @return The width of the drawn content (clipped and scaled).
439      */
getFinalContentWidth()440     public float getFinalContentWidth() {
441         return Math.min(get(CLIPPED_WIDTH), getScaledContentWidth());
442     }
443 
444     /**
445      * @return The height of the drawn content (clipped and scaled).
446      */
getFinalContentHeight()447     public float getFinalContentHeight() {
448         return Math.min(get(CLIPPED_HEIGHT), getScaledContentHeight());
449     }
450 
451     /**
452      * @return The maximum width the content can be.
453      */
getMaxContentWidth()454     public float getMaxContentWidth() {
455         return get(MAX_CONTENT_WIDTH);
456     }
457 
458     /**
459      * @return The maximum height the content can be.
460      */
getMaxContentHeight()461     public float getMaxContentHeight() {
462         return get(MAX_CONTENT_HEIGHT);
463     }
464 
465     /**
466      * @param width The maximum width the content can be.
467      */
setMaxContentWidth(float width)468     public void setMaxContentWidth(float width) {
469         set(MAX_CONTENT_WIDTH, width);
470     }
471 
472     /**
473      * @param height The maximum height the content can be.
474      */
setMaxContentHeight(float height)475     public void setMaxContentHeight(float height) {
476         set(MAX_CONTENT_HEIGHT, height);
477     }
478 
479     /**
480      * @return The id of the tab, same as the id from the Tab in TabModel.
481      */
getId()482     public int getId() {
483         return get(TAB_ID);
484     }
485 
486     /**
487      * @return Whether the underlying tab is incognito or not.
488      */
isIncognito()489     public boolean isIncognito() {
490         return get(IS_INCOGNITO);
491     }
492 
493     /**
494      * @param y The vertical draw position.
495      */
setY(float y)496     public void setY(float y) {
497         set(Y, y);
498     }
499 
500     /**
501      * @return The vertical draw position for the update logic.
502      */
getY()503     public float getY() {
504         return get(Y);
505     }
506 
507     /**
508      * @return The vertical draw position for the renderer.
509      */
getRenderY()510     public float getRenderY() {
511         return get(RENDER_Y);
512     }
513 
514     /**
515      * @param x The horizontal draw position.
516      */
setX(float x)517     public void setX(float x) {
518         set(X, x);
519     }
520 
521     /**
522      * @return The horizontal draw position for the update logic.
523      */
getX()524     public float getX() {
525         return get(X);
526     }
527 
528     /**
529      * @return The horizontal draw position for the renderer.
530      */
getRenderX()531     public float getRenderX() {
532         return get(RENDER_X);
533     }
534 
535     /**
536      * Set the transparency value for all of the tab (the contents,
537      * border, etc...).  For components that allow specifying
538      * their own alpha values, it will use the min of these two fields.
539      *
540      * @param f The transparency value for the tab.
541      */
setAlpha(float f)542     public void setAlpha(float f) {
543         set(ALPHA, f);
544     }
545 
546     /**
547      * @return The transparency value for all of the tab components.
548      */
getAlpha()549     public float getAlpha() {
550         return get(ALPHA);
551     }
552 
553     /**
554      * Set the saturation value for the tab contents.
555      *
556      * @param f The saturation value for the contents.
557      */
setSaturation(float f)558     public void setSaturation(float f) {
559         set(SATURATION, f);
560     }
561 
562     /**
563      * @return The saturation value for the tab contents.
564      */
getSaturation()565     public float getSaturation() {
566         return get(SCALE);
567     }
568 
569     /**
570      * @param alpha The maximum alpha value of the tab border.
571      */
setBorderAlpha(float alpha)572     public void setBorderAlpha(float alpha) {
573         set(BORDER_ALPHA, alpha);
574     }
575 
576     /**
577      * @return The current alpha value at which the tab border is drawn.
578      */
getBorderAlpha()579     public float getBorderAlpha() {
580         return Math.min(get(BORDER_ALPHA), get(ALPHA));
581     }
582 
583     /**
584      * @return The current alpha value at which the tab border inner shadow is drawn.
585      */
getBorderInnerShadowAlpha()586     public float getBorderInnerShadowAlpha() {
587         return Math.min(get(BORDER_ALPHA) * (1.0f - get(TOOLBAR_ALPHA)), get(ALPHA));
588     }
589 
590     /**
591      * @param alpha The maximum alpha value of the close button on the border.
592      */
setBorderCloseButtonAlpha(float alpha)593     public void setBorderCloseButtonAlpha(float alpha) {
594         set(BORDER_CLOSE_BUTTON_ALPHA, alpha);
595     }
596 
597     /**
598      * @return The current alpha value at which the close button on the border is drawn.
599      */
getBorderCloseButtonAlpha()600     public float getBorderCloseButtonAlpha() {
601         return get(BORDER_CLOSE_BUTTON_ALPHA);
602     }
603 
604     /**
605      * @param scale The scale factor of the border.
606      *              1.0f yields 1:1 pixel with the source image.
607      */
setBorderScale(float scale)608     public void setBorderScale(float scale) {
609         set(BORDER_SCALE, scale);
610     }
611 
612     /**
613      * @return The current scale applied on the tab border.
614      */
getBorderScale()615     public float getBorderScale() {
616         return get(BORDER_SCALE);
617     }
618 
619     /**
620      * @param decorationAlpha Whether or not to draw the decoration for this card.
621      */
setDecorationAlpha(float decorationAlpha)622     public void setDecorationAlpha(float decorationAlpha) {
623         set(DECORATION_ALPHA, decorationAlpha);
624     }
625 
626     /**
627      * @return The opacity of the decoration.
628      */
getDecorationAlpha()629     public float getDecorationAlpha() {
630         return get(DECORATION_ALPHA);
631     }
632 
633     /**
634      * @param toolbarYOffset The y offset of the toolbar.
635      */
setToolbarYOffset(float toolbarYOffset)636     public void setToolbarYOffset(float toolbarYOffset) {
637         set(TOOLBAR_Y_OFFSET, toolbarYOffset);
638     }
639 
640     /**
641      * @return The y offset of the toolbar.
642      */
getToolbarYOffset()643     public float getToolbarYOffset() {
644         return get(TOOLBAR_Y_OFFSET);
645     }
646 
647     /**
648      * @param scale The scale of the side border (from 0 to 1).
649      */
setSideBorderScale(float scale)650     public void setSideBorderScale(float scale) {
651         set(SIDE_BORDER_SCALE, MathUtils.clamp(scale, 0.f, 1.f));
652     }
653 
654     /**
655      * @return The scale of the side border (from 0 to 1).
656      */
getSideBorderScale()657     public float getSideBorderScale() {
658         return get(SIDE_BORDER_SCALE);
659     }
660 
661     /**
662      * @param brightness The brightness value to apply to the tab.
663      */
setBrightness(float brightness)664     public void setBrightness(float brightness) {
665         set(BRIGHTNESS, brightness);
666     }
667 
668     /**
669      * @return The brightness of the tab.
670      */
getBrightness()671     public float getBrightness() {
672         return get(BRIGHTNESS);
673     }
674 
675     /**
676      * @param drawDecoration Whether or not to draw decoration.
677      */
setDrawDecoration(boolean drawDecoration)678     public void setDrawDecoration(boolean drawDecoration) {
679         set(DECORATION_ALPHA, drawDecoration ? 1.0f : 0.0f);
680     }
681 
682     /**
683      * @param percentageView The blend between the old static tab and the new live one.
684      */
setStaticToViewBlend(float percentageView)685     public void setStaticToViewBlend(float percentageView) {
686         set(STATIC_TO_VIEW_BLEND, percentageView);
687     }
688 
689     /**
690      * @return The current blend between the old static tab and the new live one.
691      */
getStaticToViewBlend()692     public float getStaticToViewBlend() {
693         return get(STATIC_TO_VIEW_BLEND);
694     }
695 
696     @Override
toString()697     public String toString() {
698         return Integer.toString(getId());
699     }
700 
701     /**
702      * @param originalContentWidth  The maximum content width for the given orientation in px.
703      * @param originalContentHeight The maximum content height for the given orientation in px.
704      */
setContentSize(int originalContentWidth, int originalContentHeight)705     public void setContentSize(int originalContentWidth, int originalContentHeight) {
706         set(ORIGINAL_CONTENT_WIDTH_IN_DP, originalContentWidth * sPxToDp);
707         set(ORIGINAL_CONTENT_HEIGHT_IN_DP, originalContentHeight * sPxToDp);
708     }
709 
710     /**
711      * @return Whether the tab title should be displayed.
712      */
isTitleNeeded()713     public boolean isTitleNeeded() {
714         return get(IS_TITLE_NEEDED);
715     }
716 
717     /**
718      * @param visible True if the {@link LayoutTab} is visible and need to be drawn.
719      */
setVisible(boolean visible)720     public void setVisible(boolean visible) {
721         set(IS_VISIBLE, visible);
722     }
723 
724     /**
725      * @return True if the {@link LayoutTab} is visible and will be drawn.
726      */
isVisible()727     public boolean isVisible() {
728         return get(IS_VISIBLE);
729     }
730 
731     /**
732      * @param shouldStall Whether or not the tab should wait for the live layer to load.
733      */
setShouldStall(boolean shouldStall)734     public void setShouldStall(boolean shouldStall) {
735         set(SHOULD_STALL, shouldStall);
736     }
737 
738     /**
739      * @return Whether or not the tab should wait for the live layer to load.
740      */
shouldStall()741     public boolean shouldStall() {
742         return get(SHOULD_STALL);
743     }
744 
745     /**
746      * @return Whether the tab can use a live texture to render.
747      */
canUseLiveTexture()748     public boolean canUseLiveTexture() {
749         return get(CAN_USE_LIVE_TEXTURE);
750     }
751 
752     /**
753      * @param showToolbar Whether or not to show a toolbar at the top of the content.
754      */
setShowToolbar(boolean showToolbar)755     public void setShowToolbar(boolean showToolbar) {
756         set(SHOW_TOOLBAR, showToolbar);
757     }
758 
759     /**
760      * @return Whether or not to show a toolbar at the top of the content.
761      */
showToolbar()762     public boolean showToolbar() {
763         return get(SHOW_TOOLBAR);
764     }
765 
766     /**
767      * This value is only used if {@link #showToolbar()} is {@code true}.
768      *
769      * @param anonymize Whether or not to anonymize the toolbar (hiding URL, etc.).
770      */
setAnonymizeToolbar(boolean anonymize)771     public void setAnonymizeToolbar(boolean anonymize) {
772         set(ANONYMIZE_TOOLBAR, anonymize);
773     }
774 
775     /**
776      * This value is only used if {@link #showToolbar()} is {@code true}.
777      *
778      * @return Whether or not to anonymize the toolbar (hiding URL, etc.).
779      */
anonymizeToolbar()780     public boolean anonymizeToolbar() {
781         return get(ANONYMIZE_TOOLBAR);
782     }
783 
784     /**
785      * @param alpha The alpha of the toolbar.
786      */
setToolbarAlpha(float alpha)787     public void setToolbarAlpha(float alpha) {
788         set(TOOLBAR_ALPHA, alpha);
789     }
790 
791     /**
792      * @return The alpha of the toolbar.
793      */
getToolbarAlpha()794     public float getToolbarAlpha() {
795         return get(TOOLBAR_ALPHA);
796     }
797 
798     /**
799      * @param inset Whether or not to inset the top vertical component of the tab border or not.
800      */
setInsetBorderVertical(boolean inset)801     public void setInsetBorderVertical(boolean inset) {
802         set(INSET_BORDER_VERTICAL, inset);
803     }
804 
805     /**
806      * @return Whether or not to inset the top vertical component of the tab border or not.
807      */
insetBorderVertical()808     public boolean insetBorderVertical() {
809         return get(INSET_BORDER_VERTICAL);
810     }
811 
setCloseButtonIsOnRight(boolean closeButtonIsOnRight)812     public void setCloseButtonIsOnRight(boolean closeButtonIsOnRight) {
813         set(CLOSE_BUTTON_IS_ON_RIGHT, closeButtonIsOnRight);
814     }
815 
isCloseButtonOnRight()816     public boolean isCloseButtonOnRight() {
817         return get(CLOSE_BUTTON_IS_ON_RIGHT);
818     }
819 
820     /**
821      * @return The color of the background of the tab. Used as the best approximation to fill in.
822      */
getBackgroundColor()823     public int getBackgroundColor() {
824         return get(BACKGROUND_COLOR);
825     }
826 
827     /**
828      * @return The color of the background of the toolbar.
829      */
getToolbarBackgroundColor()830     public int getToolbarBackgroundColor() {
831         return get(TOOLBAR_BACKGROUND_COLOR);
832     }
833 
834     /**
835      * @return The color of the textbox in the toolbar. Used as the color for the anonymize rect.
836      */
getTextBoxBackgroundColor()837     public int getTextBoxBackgroundColor() {
838         return get(TEXT_BOX_BACKGROUND_COLOR);
839     }
840 
841     /**
842      * @return The alpha value of the textbox in the toolbar.
843      */
getTextBoxAlpha()844     public float getTextBoxAlpha() {
845         return get(TEXT_BOX_ALPHA);
846     }
847 }
848