OLD | NEW |
(Empty) | |
| 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.webapps; |
| 6 |
| 7 import android.content.Context; |
| 8 import android.graphics.drawable.Drawable; |
| 9 import android.text.Layout; |
| 10 import android.text.TextUtils; |
| 11 import android.text.method.ScrollingMovementMethod; |
| 12 import android.util.AttributeSet; |
| 13 import android.util.Log; |
| 14 import android.util.SparseIntArray; |
| 15 import android.view.Gravity; |
| 16 import android.view.View; |
| 17 import android.view.ViewGroup; |
| 18 import android.widget.FrameLayout; |
| 19 import android.widget.TextView; |
| 20 |
| 21 import com.google.android.apps.chrome.R; |
| 22 |
| 23 import org.chromium.base.ApiCompatibilityUtils; |
| 24 import org.chromium.base.VisibleForTesting; |
| 25 import org.chromium.chrome.browser.UrlUtilities; |
| 26 import org.chromium.chrome.browser.omnibox.LocationBarLayout; |
| 27 |
| 28 import java.net.URI; |
| 29 |
| 30 /** |
| 31 * Maintains a URL bar that is displayed above the webapp's content. |
| 32 * For security reasons, this bar will appear when a user navigates to a website
that is not |
| 33 * considered the same as the one that was used to open a WebappActivity origina
lly. |
| 34 * The URL bar will disappear again once the user navigates back to the original
website. |
| 35 * |
| 36 * Example scenario: |
| 37 * 0) User opens a webapp for http://domain1.com. URL bar is hidden |
| 38 * 1) User navigates to http://domain1.com/some.html URL bar is hidden |
| 39 * 2) User navigates to http://domain2.com/ URL bar is shown |
| 40 * 3) User navigates back to http://domain1.com/some.html URL bar is hidden |
| 41 */ |
| 42 public class WebappUrlBar extends FrameLayout implements View.OnLayoutChangeList
ener { |
| 43 private static final String TAG = "WebappUrlBar"; |
| 44 |
| 45 private final TextView mUrlBar; |
| 46 private final View mSeparator; |
| 47 private final SparseIntArray mIconResourceWidths; |
| 48 |
| 49 private String mCurrentlyDisplayedUrl; |
| 50 private int mCurrentIconResource; |
| 51 |
| 52 /** |
| 53 * Creates a WebappUrlBar. |
| 54 * @param context Context to grab resources from. |
| 55 */ |
| 56 public WebappUrlBar(Context context, AttributeSet attrSet) { |
| 57 super(context, attrSet); |
| 58 mIconResourceWidths = new SparseIntArray(); |
| 59 |
| 60 mUrlBar = new TextView(context); |
| 61 mUrlBar.setSingleLine(true); |
| 62 mUrlBar.setMovementMethod(ScrollingMovementMethod.getInstance()); |
| 63 mUrlBar.setHorizontalFadingEdgeEnabled(true); |
| 64 mSeparator = new View(context); |
| 65 |
| 66 addView(mUrlBar, |
| 67 new FrameLayout.LayoutParams( |
| 68 ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutPar
ams.WRAP_CONTENT, |
| 69 Gravity.CENTER)); |
| 70 addView(mSeparator, |
| 71 new FrameLayout.LayoutParams( |
| 72 ViewGroup.LayoutParams.MATCH_PARENT, 1, Gravity.BOTTOM))
; |
| 73 |
| 74 // Set the colors. |
| 75 mSeparator.setBackgroundColor( |
| 76 context.getResources().getColor(R.color.webapp_url_bar_separator
)); |
| 77 setBackgroundColor(context.getResources().getColor(R.color.webapp_url_ba
r_bg)); |
| 78 |
| 79 // Listen for changes in the URL bar's size. |
| 80 mUrlBar.addOnLayoutChangeListener(this); |
| 81 } |
| 82 |
| 83 /** |
| 84 * Updates the URL bar for the current URL. |
| 85 * @param url URL to display. |
| 86 * @param securityLevel Security level of the Tab. |
| 87 */ |
| 88 public void update(String url, int securityLevel) { |
| 89 URI uri = createURI(url); |
| 90 updateSecurityIcon(securityLevel); |
| 91 updateDisplayedUrl(url, uri); |
| 92 } |
| 93 |
| 94 /** |
| 95 * @return the security icon being displayed for the current URL. |
| 96 */ |
| 97 @VisibleForTesting |
| 98 protected int getCurrentIconResourceForTests() { |
| 99 return mCurrentIconResource; |
| 100 } |
| 101 |
| 102 /** |
| 103 * @return the URL being displayed. |
| 104 */ |
| 105 @VisibleForTesting |
| 106 protected CharSequence getDisplayedUrlForTests() { |
| 107 return mUrlBar.getText(); |
| 108 } |
| 109 |
| 110 /** |
| 111 * Show the end of the URL rather than the beginning. |
| 112 */ |
| 113 @Override |
| 114 public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, |
| 115 int oldTop, int oldRight, int oldBottom) { |
| 116 Layout layout = mUrlBar.getLayout(); |
| 117 if (layout == null) return; |
| 118 |
| 119 // Android doesn't account for the compound Drawable in its width calcul
ations, leading to |
| 120 // improper scrolling and even Android improperly placing the horizontal
fade in its |
| 121 // TextView calculation. Get around it by calculating that width manual
ly: crbug.com/303908 |
| 122 int urlBarWidth = mUrlBar.getWidth(); |
| 123 int iconWidth = |
| 124 mCurrentIconResource == 0 ? 0 : mIconResourceWidths.get(mCurrent
IconResource); |
| 125 int availableTextWidth = urlBarWidth - iconWidth; |
| 126 int desiredWidth = (int) Layout.getDesiredWidth(layout.getText(), layout
.getPaint()); |
| 127 |
| 128 if (desiredWidth > availableTextWidth) { |
| 129 mUrlBar.scrollTo(desiredWidth - availableTextWidth, 0); |
| 130 } else { |
| 131 mUrlBar.scrollTo(0, 0); |
| 132 } |
| 133 } |
| 134 |
| 135 private static URI createURI(String url) { |
| 136 // Get rid of spaces temporarily: crbug.com/298465 |
| 137 // Get rid of the need for this hack eventually: crbug.com/296870 |
| 138 url = url.replace(" ", "%20"); |
| 139 |
| 140 try { |
| 141 return URI.create(url); |
| 142 } catch (IllegalArgumentException exception) { |
| 143 Log.e(TAG, "Failed to convert URI: ", exception); |
| 144 return null; |
| 145 } |
| 146 } |
| 147 |
| 148 private void updateSecurityIcon(int securityLevel) { |
| 149 mCurrentIconResource = LocationBarLayout.getSecurityIconResource(securit
yLevel, false); |
| 150 |
| 151 if (mCurrentIconResource != 0 && mIconResourceWidths.get(mCurrentIconRes
ource, -1) == -1) { |
| 152 Drawable icon = ApiCompatibilityUtils.getDrawable(getResources(), mC
urrentIconResource); |
| 153 mIconResourceWidths.put(mCurrentIconResource, icon.getIntrinsicWidth
()); |
| 154 } |
| 155 |
| 156 ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(mU
rlBar, |
| 157 mCurrentIconResource, 0, 0, 0); |
| 158 } |
| 159 |
| 160 private void updateDisplayedUrl(String originalUrl, URI uri) { |
| 161 boolean showScheme = mCurrentIconResource == 0; |
| 162 String displayUrl = originalUrl; |
| 163 if (uri != null) { |
| 164 String shortenedUrl = UrlUtilities.getOriginForDisplay(uri, showSche
me); |
| 165 if (!TextUtils.isEmpty(shortenedUrl)) displayUrl = shortenedUrl; |
| 166 } |
| 167 |
| 168 mUrlBar.setText(displayUrl); |
| 169 if (!TextUtils.equals(mCurrentlyDisplayedUrl, displayUrl)) { |
| 170 mCurrentlyDisplayedUrl = displayUrl; |
| 171 } |
| 172 } |
| 173 } |
OLD | NEW |