EMMA Coverage Report (generated Fri Aug 23 16:39:17 PDT 2013)
[all classes][org.chromium.chrome.browser]

COVERAGE SUMMARY FOR SOURCE FILE [ValidationMessageBubble.java]

nameclass, %method, %block, %line, %
ValidationMessageBubble.java0%   (0/1)0%   (0/10)0%   (0/295)0%   (0/50)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ValidationMessageBubble0%   (0/1)0%   (0/10)0%   (0/295)0%   (0/50)
ValidationMessageBubble (ContentViewCore, RectF, String, String): void 0%   (0/1)0%   (0/47)0%   (0/8)
adjustWindowPosition (ContentViewCore, int, int): Point 0%   (0/1)0%   (0/52)0%   (0/12)
close (): void 0%   (0/1)0%   (0/11)0%   (0/4)
createAndShow (ContentViewCore, int, int, int, int, String, String): Validati... 0%   (0/1)0%   (0/15)0%   (0/2)
getAnchorOffset (): float 0%   (0/1)0%   (0/35)0%   (0/4)
getWebViewOffsetYPixInScreen (ContentViewCore): float 0%   (0/1)0%   (0/16)0%   (0/3)
makePixRectInScreen (ContentViewCore, int, int, int, int): RectF 0%   (0/1)0%   (0/34)0%   (0/3)
measure (RenderCoordinates): void 0%   (0/1)0%   (0/27)0%   (0/4)
setPositionRelativeToAnchor (ContentViewCore, int, int, int, int): void 0%   (0/1)0%   (0/34)0%   (0/4)
updateTextViews (ViewGroup, String, String): void 0%   (0/1)0%   (0/24)0%   (0/6)

1// Copyright 2013 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 
5package org.chromium.chrome.browser;
6 
7import android.content.res.Resources;
8import android.graphics.Point;
9import android.graphics.RectF;
10import android.text.TextUtils;
11import android.view.Gravity;
12import android.view.View;
13import android.view.ViewGroup;
14import android.widget.PopupWindow;
15import android.widget.RelativeLayout;
16import android.widget.TextView;
17import org.chromium.base.ApiCompatibilityUtils;
18import org.chromium.base.CalledByNative;
19import org.chromium.chrome.R;
20import org.chromium.content.browser.ContentViewCore;
21import org.chromium.content.browser.RenderCoordinates;
22 
23/**
24 * This class is an implementation of validation message bubble UI.
25 */
26class ValidationMessageBubble {
27    private PopupWindow mPopup;
28 
29    /**
30     * Creates a popup window to show the specified messages, and show it on
31     * the specified anchor rectangle.
32     *
33     * @param contentViewCore The ContentViewCore object to provide various
34     *                        information.
35     * @param anchorX Anchor position in the CSS unit.
36     * @param anchorY Anchor position in the CSS unit.
37     * @param anchorWidth Anchor size in the CSS unit.
38     * @param anchorHeight Anchor size in the CSS unit.
39     * @param mainText The main message. It will shown at the top of the popup
40     *                 window, and its font size is larger.
41     * @param subText The sub message. It will shown below the main message, and
42     *                its font size is smaller.
43     */
44    @CalledByNative
45    private static ValidationMessageBubble createAndShow(
46            ContentViewCore contentViewCore, int anchorX, int anchorY,
47            int anchorWidth, int anchorHeight, String mainText, String subText) {
48        final RectF anchorPixInScreen = makePixRectInScreen(
49                contentViewCore, anchorX, anchorY, anchorWidth, anchorHeight);
50        return new ValidationMessageBubble(contentViewCore, anchorPixInScreen, mainText, subText);
51    }
52 
53    private ValidationMessageBubble(
54            ContentViewCore contentViewCore, RectF anchor, String mainText, String subText) {
55        final ViewGroup root = (ViewGroup) View.inflate(contentViewCore.getContext(),
56                R.layout.validation_message_bubble, null);
57        mPopup = new PopupWindow(root);
58        updateTextViews(root, mainText, subText);
59        measure(contentViewCore.getRenderCoordinates());
60        Point origin = adjustWindowPosition(
61                contentViewCore, (int) (anchor.centerX() - getAnchorOffset()), (int) anchor.bottom);
62        mPopup.showAtLocation(
63                contentViewCore.getContainerView(), Gravity.NO_GRAVITY, origin.x, origin.y);
64    }
65 
66    @CalledByNative
67    private void close() {
68        if (mPopup == null) return;
69        mPopup.dismiss();
70        mPopup = null;
71    }
72 
73    /**
74     * Moves the popup window on the specified anchor rectangle.
75     *
76     * @param contentViewCore The ContentViewCore object to provide various
77     *                        information.
78     * @param anchorX Anchor position in the CSS unit.
79     * @param anchorY Anchor position in the CSS unit.
80     * @param anchorWidth Anchor size in the CSS unit.
81     * @param anchorHeight Anchor size in the CSS unit.
82     */
83    @CalledByNative
84    private void setPositionRelativeToAnchor(ContentViewCore contentViewCore,
85            int anchorX, int anchorY, int anchorWidth, int anchorHeight) {
86        RectF anchor = makePixRectInScreen(
87                contentViewCore, anchorX, anchorY, anchorWidth, anchorHeight);
88        Point origin = adjustWindowPosition(
89                contentViewCore, (int) (anchor.centerX() - getAnchorOffset()), (int) anchor.bottom);
90        mPopup.update(origin.x, origin.y, mPopup.getWidth(), mPopup.getHeight());
91    }
92 
93    private static RectF makePixRectInScreen(ContentViewCore contentViewCore,
94            int anchorX, int anchorY, int anchorWidth, int anchorHeight) {
95        final RenderCoordinates coordinates = contentViewCore.getRenderCoordinates();
96        final float yOffset = getWebViewOffsetYPixInScreen(contentViewCore);
97        return new RectF(
98                coordinates.fromLocalCssToPix(anchorX),
99                coordinates.fromLocalCssToPix(anchorY) + yOffset,
100                coordinates.fromLocalCssToPix(anchorX + anchorWidth),
101                coordinates.fromLocalCssToPix(anchorY + anchorHeight) + yOffset);
102    }
103 
104    private static float getWebViewOffsetYPixInScreen(ContentViewCore contentViewCore) {
105        int[] location = new int[2];
106        contentViewCore.getContainerView().getLocationOnScreen(location);
107        return location[1] + contentViewCore.getRenderCoordinates().getContentOffsetYPix();
108    }
109 
110    private static void updateTextViews(ViewGroup root, String mainText, String subText) {
111        ((TextView) root.findViewById(R.id.main_text)).setText(mainText);
112        final TextView subTextView = (TextView) root.findViewById(R.id.sub_text);
113        if (!TextUtils.isEmpty(subText)) {
114            subTextView.setText(subText);
115        } else {
116            ((ViewGroup) subTextView.getParent()).removeView(subTextView);
117        }
118    }
119 
120    private void measure(RenderCoordinates coordinates) {
121        mPopup.setWindowLayoutMode(
122                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
123        mPopup.getContentView().setLayoutParams(
124                new RelativeLayout.LayoutParams(
125                        RelativeLayout.LayoutParams.WRAP_CONTENT,
126                        RelativeLayout.LayoutParams.WRAP_CONTENT));
127        mPopup.getContentView().measure(
128                View.MeasureSpec.makeMeasureSpec(coordinates.getLastFrameViewportWidthPixInt(),
129                        View.MeasureSpec.AT_MOST),
130                View.MeasureSpec.makeMeasureSpec(coordinates.getLastFrameViewportHeightPixInt(),
131                        View.MeasureSpec.AT_MOST));
132    }
133 
134    private float getAnchorOffset() {
135        final View root = mPopup.getContentView();
136        final int width = root.getMeasuredWidth();
137        final int arrowWidth = root.findViewById(R.id.arrow_image).getMeasuredWidth();
138        return ApiCompatibilityUtils.isLayoutRtl(root) ?
139                (width * 3 / 4 - arrowWidth / 2) : (width / 4 + arrowWidth / 2);
140    }
141 
142    /**
143     * This adjusts the position if the popup protrudes the web view.
144     */
145    private Point adjustWindowPosition(ContentViewCore contentViewCore, int x, int y) {
146        final RenderCoordinates coordinates = contentViewCore.getRenderCoordinates();
147        final int viewWidth = coordinates.getLastFrameViewportWidthPixInt();
148        final int viewBottom = (int) getWebViewOffsetYPixInScreen(contentViewCore) +
149                coordinates.getLastFrameViewportHeightPixInt();
150        final int width = mPopup.getContentView().getMeasuredWidth();
151        final int height = mPopup.getContentView().getMeasuredHeight();
152        if (x < 0) {
153            x = 0;
154        } else if (x + width > viewWidth) {
155            x = viewWidth - width;
156        }
157        if (y + height > viewBottom) {
158            y = viewBottom - height;
159        }
160        return new Point(x, y);
161    }
162}

[all classes][org.chromium.chrome.browser]
EMMA 2.0.5312 (C) Vladimir Roubtsov