Index: chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/HostedToolbar.java |
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/HostedToolbar.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/HostedToolbar.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bba90f0896bd96419ddf121dbc138a8a4bc42cb4 |
--- /dev/null |
+++ b/chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/HostedToolbar.java |
@@ -0,0 +1,404 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.chrome.browser.toolbar; |
+ |
+import android.animation.Animator; |
+import android.animation.ObjectAnimator; |
+import android.annotation.SuppressLint; |
+import android.content.Context; |
+import android.content.res.ColorStateList; |
+import android.graphics.Bitmap; |
+import android.graphics.drawable.BitmapDrawable; |
+import android.graphics.drawable.ColorDrawable; |
+import android.text.TextUtils; |
+import android.util.AttributeSet; |
+import android.util.Pair; |
+import android.view.KeyEvent; |
+import android.view.MotionEvent; |
+import android.view.View; |
+import android.widget.ImageButton; |
+import android.widget.ImageView; |
+ |
+import com.google.android.apps.chrome.R; |
+ |
+import org.chromium.base.ApiCompatibilityUtils; |
+import org.chromium.chrome.browser.ContextualMenuBar.ActionBarDelegate; |
+import org.chromium.chrome.browser.CustomSelectionActionModeCallback; |
+import org.chromium.chrome.browser.WindowDelegate; |
+import org.chromium.chrome.browser.appmenu.AppMenuButtonHelper; |
+import org.chromium.chrome.browser.document.BrandColorUtils; |
+import org.chromium.chrome.browser.dom_distiller.DomDistillerServiceFactory; |
+import org.chromium.chrome.browser.dom_distiller.DomDistillerTabUtils; |
+import org.chromium.chrome.browser.ntp.NativePageFactory; |
+import org.chromium.chrome.browser.ntp.NewTabPage; |
+import org.chromium.chrome.browser.omnibox.LocationBar; |
+import org.chromium.chrome.browser.omnibox.LocationBarLayout; |
+import org.chromium.chrome.browser.omnibox.UrlBar; |
+import org.chromium.chrome.browser.omnibox.UrlContainer; |
+import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener; |
+import org.chromium.chrome.browser.profiles.Profile; |
+import org.chromium.chrome.browser.ssl.ConnectionSecurityHelperSecurityLevel; |
+import org.chromium.chrome.browser.tab.ChromeTab; |
+import org.chromium.chrome.browser.widget.TintedImageButton; |
+import org.chromium.components.dom_distiller.core.DomDistillerService; |
+import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; |
+import org.chromium.ui.base.WindowAndroid; |
+ |
+/** |
+ * The Toolbar layout to be used for hosted mode. This is used for both phone and tablet UIs. |
+ */ |
+public class HostedToolbar extends ToolbarLayout implements LocationBar { |
+ private UrlBar mUrlBar; |
+ private ImageView mSecurityButton; |
+ private ImageButton mCustomActionButton; |
+ private int mSecurityIconType; |
+ private boolean mUseDarkColors; |
+ private UrlContainer mUrlContainer; |
+ private TintedImageButton mBackButton; |
+ private Animator mSecurityButtonShowAnimator; |
+ private boolean mBackgroundColorSet; |
+ |
+ /** |
+ * Constructor for getting this class inflated from an xml layout file. |
+ */ |
+ public HostedToolbar(Context context, AttributeSet attrs) { |
+ super(context, attrs); |
+ } |
+ |
+ @Override |
+ protected void onFinishInflate() { |
+ super.onFinishInflate(); |
+ setBackground(new ColorDrawable(getResources().getColor(R.color.default_primary_color))); |
+ mUrlBar = (UrlBar) findViewById(R.id.url_bar); |
+ mUrlBar.setHint(""); |
+ mUrlBar.setDelegate(this); |
+ mUrlBar.setEnabled(false); |
+ mUrlContainer = (UrlContainer) findViewById(R.id.url_container); |
+ mSecurityButton = (ImageButton) findViewById(R.id.security_button); |
+ mSecurityIconType = ConnectionSecurityHelperSecurityLevel.NONE; |
+ mCustomActionButton = (ImageButton) findViewById(R.id.action_button); |
+ mBackButton = (TintedImageButton) findViewById(R.id.back_button); |
+ mSecurityButtonShowAnimator = ObjectAnimator.ofFloat(mSecurityButton, ALPHA, 1); |
+ mSecurityButtonShowAnimator |
+ .setDuration(ToolbarPhone.URL_FOCUS_CHANGE_ANIMATION_DURATION_MS); |
+ } |
+ |
+ @Override |
+ public void initialize(ToolbarDataProvider toolbarDataProvider, |
+ ToolbarTabController tabController, AppMenuButtonHelper appMenuButtonHelper) { |
+ super.initialize(toolbarDataProvider, tabController, appMenuButtonHelper); |
+ updateVisualsForState(); |
+ } |
+ |
+ @Override |
+ public void setHostedBackClickHandler(OnClickListener listener) { |
+ mBackButton.setOnClickListener(listener); |
+ } |
+ |
+ @Override |
+ public void addCustomActionButton(Bitmap buttonSource, OnClickListener listener) { |
+ mCustomActionButton.setImageDrawable(new BitmapDrawable(getResources(), buttonSource)); |
+ mCustomActionButton.setOnClickListener(listener); |
+ mCustomActionButton.setVisibility(VISIBLE); |
+ } |
+ |
+ @Override |
+ public ChromeTab getCurrentTab() { |
+ return ChromeTab.fromTab(getToolbarDataProvider().getTab()); |
+ } |
+ |
+ @Override |
+ public boolean showingOriginalUrlForPreview() { |
+ return false; |
+ } |
+ |
+ @Override |
+ public boolean shouldEmphasizeHttpsScheme() { |
+ return !mUseDarkColors; |
+ } |
+ |
+ @Override |
+ public void setUrlToPageUrl() { |
+ if (getCurrentTab() == null) { |
+ mUrlContainer.setUrlText(null, null, ""); |
+ return; |
+ } |
+ |
+ String url = getCurrentTab().getUrl().trim(); |
+ |
+ if (NativePageFactory.isNativePageUrl(url, getCurrentTab().isIncognito())) { |
+ // Don't show anything for Chrome URLs. |
+ mUrlContainer.setUrlText(null, null, ""); |
+ return; |
+ } |
+ String displayText = getToolbarDataProvider().getText(); |
+ Pair<String, String> urlText = LocationBarLayout.splitPathFromUrlDisplayText(displayText); |
+ displayText = urlText.first; |
+ String path = urlText.second; |
+ |
+ if (DomDistillerUrlUtils.isDistilledPage(url)) { |
+ if (isStoredArticle(url)) { |
+ Profile profile = getCurrentTab().getProfile(); |
+ DomDistillerService domDistillerService = |
+ DomDistillerServiceFactory.getForProfile(profile); |
+ String originalUrl = domDistillerService.getUrlForEntry( |
+ DomDistillerUrlUtils.getValueForKeyInUrl(url, "entry_id")); |
+ displayText = |
+ DomDistillerTabUtils.getFormattedUrlFromOriginalDistillerUrl(originalUrl); |
+ } else if (DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url) != null) { |
+ String originalUrl = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); |
+ displayText = |
+ DomDistillerTabUtils.getFormattedUrlFromOriginalDistillerUrl(originalUrl); |
+ } |
+ } |
+ |
+ if (mUrlContainer.setUrlText(displayText, path, url)) { |
+ mUrlBar.deEmphasizeUrl(); |
+ mUrlBar.emphasizeUrl(); |
+ } |
+ } |
+ |
+ private boolean isStoredArticle(String url) { |
+ DomDistillerService domDistillerService = |
+ DomDistillerServiceFactory.getForProfile(Profile.getLastUsedProfile()); |
+ String entryIdFromUrl = DomDistillerUrlUtils.getValueForKeyInUrl(url, "entry_id"); |
+ if (TextUtils.isEmpty(entryIdFromUrl)) return false; |
+ return domDistillerService.hasEntry(entryIdFromUrl); |
+ } |
+ |
+ @Override |
+ public void updateLoadingState(boolean updateUrl) { |
+ updateSecurityIcon(getSecurityLevel()); |
+ } |
+ |
+ @Override |
+ public void updateVisualsForState() { |
+ updateSecurityIcon(getSecurityLevel()); |
+ ColorStateList colorStateList = getResources().getColorStateList(mUseDarkColors |
+ ? R.color.dark_mode_tint : R.color.light_mode_tint); |
+ mMenuButton.setTint(colorStateList); |
+ mBackButton.setTint(colorStateList); |
+ mUrlContainer.setUseDarkTextColors(mUseDarkColors); |
+ |
+ if (getProgressBar() != null) { |
+ int progressBarResource = !mUseDarkColors |
+ ? R.drawable.progress_bar_white : R.drawable.progress_bar; |
+ getProgressBar().setProgressDrawable( |
+ ApiCompatibilityUtils.getDrawable(getResources(), progressBarResource)); |
+ } |
+ } |
+ |
+ @Override |
+ public void setMenuButtonHelper(final AppMenuButtonHelper helper) { |
+ mMenuButton.setOnTouchListener(new OnTouchListener() { |
+ @SuppressLint("ClickableViewAccessibility") |
+ @Override |
+ public boolean onTouch(View v, MotionEvent event) { |
+ return helper.onTouch(v, event); |
+ } |
+ }); |
+ mMenuButton.setOnKeyListener(new OnKeyListener() { |
+ @Override |
+ public boolean onKey(View view, int keyCode, KeyEvent event) { |
+ if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) { |
+ return helper.onEnterKeyPress(view); |
+ } |
+ return false; |
+ } |
+ }); |
+ } |
+ |
+ @Override |
+ public View getMenuAnchor() { |
+ return mMenuButton; |
+ } |
+ |
+ @Override |
+ public ColorDrawable getBackground() { |
+ return (ColorDrawable) super.getBackground(); |
+ } |
+ |
+ @Override |
+ public void initializeControls(WindowDelegate windowDelegate, ActionBarDelegate delegate, |
+ WindowAndroid windowAndroid) { |
+ } |
+ |
+ private int getSecurityLevel() { |
+ if (getCurrentTab() == null) return ConnectionSecurityHelperSecurityLevel.NONE; |
+ return getCurrentTab().getSecurityLevel(); |
+ } |
+ |
+ @Override |
+ public void updateSecurityIcon(int securityLevel) { |
+ // ImageView#setImageResource is no-op if given resource is the current one. |
+ mSecurityButton.setImageResource(LocationBarLayout.getSecurityIconResource( |
+ securityLevel, !shouldEmphasizeHttpsScheme())); |
+ |
+ if (mSecurityIconType == securityLevel) return; |
+ mSecurityIconType = securityLevel; |
+ |
+ if (securityLevel == ConnectionSecurityHelperSecurityLevel.NONE) { |
+ // TODO(yusufo): Add an animator for hiding as well. |
+ mSecurityButton.setVisibility(GONE); |
+ } else { |
+ if (mSecurityButtonShowAnimator.isRunning()) mSecurityButtonShowAnimator.cancel(); |
+ mSecurityButton.setVisibility(VISIBLE); |
+ mSecurityButtonShowAnimator.start(); |
+ mUrlBar.deEmphasizeUrl(); |
+ } |
+ mUrlBar.emphasizeUrl(); |
+ mUrlBar.invalidate(); |
+ } |
+ |
+ /** |
+ * For extending classes to override and carry out the changes related with the primary color |
+ * for the current tab changing. |
+ */ |
+ @Override |
+ protected void onPrimaryColorChanged() { |
+ if (mBackgroundColorSet) return; |
+ int primaryColor = getToolbarDataProvider().getPrimaryColor(); |
+ getBackground().setColor(primaryColor); |
+ mUseDarkColors = !BrandColorUtils.shouldUseLightDrawablesForToolbar(primaryColor); |
+ updateVisualsForState(); |
+ mBackgroundColorSet = true; |
+ } |
+ |
+ @Override |
+ protected void onNavigatedToDifferentPage() { |
+ super.onNavigatedToDifferentPage(); |
+ mUrlContainer.setTrailingTextVisible(true); |
+ } |
+ |
+ @Override |
+ public void setLoadProgress(int progress) { |
+ super.setLoadProgress(progress); |
+ if (progress == 100) mUrlContainer.setTrailingTextVisible(false); |
+ } |
+ |
+ @Override |
+ public View getContainerView() { |
+ return this; |
+ } |
+ |
+ @Override |
+ public void setDefaultTextEditActionModeCallback(CustomSelectionActionModeCallback callback) { |
+ mUrlBar.setCustomSelectionActionModeCallback(callback); |
+ } |
+ |
+ private void updateLayoutParams() { |
+ int startMargin = 0; |
+ int urlContainerChildIndex = -1; |
+ for (int i = 0; i < getChildCount(); i++) { |
+ View childView = getChildAt(i); |
+ if (childView.getVisibility() != GONE) { |
+ LayoutParams childLayoutParams = (LayoutParams) childView.getLayoutParams(); |
+ if (ApiCompatibilityUtils.getMarginStart(childLayoutParams) != startMargin) { |
+ ApiCompatibilityUtils.setMarginStart(childLayoutParams, startMargin); |
+ childView.setLayoutParams(childLayoutParams); |
+ } |
+ if (childView == mUrlContainer) { |
+ urlContainerChildIndex = i; |
+ break; |
+ } |
+ int widthMeasureSpec; |
+ int heightMeasureSpec; |
+ if (childLayoutParams.width == LayoutParams.WRAP_CONTENT) { |
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec( |
+ getMeasuredWidth(), MeasureSpec.AT_MOST); |
+ } else if (childLayoutParams.width == LayoutParams.MATCH_PARENT) { |
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec( |
+ getMeasuredWidth(), MeasureSpec.EXACTLY); |
+ } else { |
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec( |
+ childLayoutParams.width, MeasureSpec.EXACTLY); |
+ } |
+ if (childLayoutParams.height == LayoutParams.WRAP_CONTENT) { |
+ heightMeasureSpec = MeasureSpec.makeMeasureSpec( |
+ getMeasuredHeight(), MeasureSpec.AT_MOST); |
+ } else if (childLayoutParams.height == LayoutParams.MATCH_PARENT) { |
+ heightMeasureSpec = MeasureSpec.makeMeasureSpec( |
+ getMeasuredHeight(), MeasureSpec.EXACTLY); |
+ } else { |
+ heightMeasureSpec = MeasureSpec.makeMeasureSpec( |
+ childLayoutParams.height, MeasureSpec.EXACTLY); |
+ } |
+ childView.measure(widthMeasureSpec, heightMeasureSpec); |
+ startMargin += childView.getMeasuredWidth(); |
+ } |
+ } |
+ |
+ assert urlContainerChildIndex != -1; |
+ int urlContainerMarginEnd = 0; |
+ for (int i = urlContainerChildIndex + 1; i < getChildCount(); i++) { |
+ View childView = getChildAt(i); |
+ if (childView.getVisibility() != GONE) { |
+ urlContainerMarginEnd += childView.getMeasuredWidth(); |
+ } |
+ } |
+ LayoutParams urlLayoutParams = (LayoutParams) mUrlContainer.getLayoutParams(); |
+ |
+ if (ApiCompatibilityUtils.getMarginEnd(urlLayoutParams) != urlContainerMarginEnd) { |
+ ApiCompatibilityUtils.setMarginEnd(urlLayoutParams, urlContainerMarginEnd); |
+ mUrlContainer.setLayoutParams(urlLayoutParams); |
+ } |
+ } |
+ |
+ @Override |
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
+ updateLayoutParams(); |
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
+ } |
+ |
+ @Override |
+ public LocationBar getLocationBar() { |
+ return this; |
+ } |
+ |
+ // Toolbar and LocationBar calls that are not relevant here. |
+ |
+ @Override |
+ public void setToolbarDataProvider(ToolbarDataProvider model) { |
+ assert model.equals(getToolbarDataProvider()); |
+ } |
+ |
+ @Override |
+ public void onUrlPreFocusChanged(boolean gainFocus) { |
+ } |
+ |
+ @Override |
+ public void setUrlFocusChangeListener(UrlFocusChangeListener listener) { } |
+ |
+ @Override |
+ public void setUrlBarFocus(boolean shouldBeFocused) { } |
+ |
+ @Override |
+ public long getFirstUrlBarFocusTime() { |
+ return 0; |
+ } |
+ |
+ @Override |
+ public void setIgnoreURLBarModification(boolean ignore) { |
+ } |
+ |
+ @Override |
+ public void hideSuggestions() { |
+ } |
+ |
+ @Override |
+ public void updateMicButtonState() { |
+ } |
+ |
+ @Override |
+ public void onTabLoadingNTP(NewTabPage ntp) { |
+ } |
+ |
+ @Override |
+ public void setAutocompleteProfile(Profile profile) { |
+ } |
+ |
+ @Override |
+ public void backKeyPressed() { } |
+} |