blob: 589acf574529f15275b7adc0f18bf0227c3e0c46 [file] [log] [blame]
// Copyright 2018 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.content.Context;
import android.content.res.ColorStateList;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.ActivityTabProvider.ActivityTabTabObserver;
import org.chromium.chrome.browser.ThemeColorProvider;
import org.chromium.chrome.browser.ThemeColorProvider.TintObserver;
import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver;
import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
import org.chromium.chrome.browser.compositor.layouts.OverviewModeState;
import org.chromium.chrome.browser.flags.FeatureUtilities;
import org.chromium.chrome.browser.homepage.HomepagePolicyManager;
import org.chromium.chrome.browser.ntp.NewTabPage;
import org.chromium.chrome.browser.partnercustomizations.HomepageManager;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.ui.widget.ChromeImageButton;
/**
* The home button.
*/
public class HomeButton extends ChromeImageButton
implements TintObserver, OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener,
HomepageManager.HomepageStateListener {
private static final int ID_REMOVE = 0;
/** A provider that notifies components when the theme color changes.*/
private ThemeColorProvider mThemeColorProvider;
/** The {@link ActivityTabTabObserver} used to know when the active page changed. */
private ActivityTabTabObserver mActivityTabTabObserver;
/** The {@link ActivityTabProvider} used to know if the active tab is on the NTP. */
private ActivityTabProvider mActivityTabProvider;
/** The {@link OverviewModeBehavior} used to observe overview state changes. */
private OverviewModeBehavior mOverviewModeBehavior;
/** The {@link OvervieModeObserver} observing the OverviewModeBehavior */
private OverviewModeBehavior.OverviewModeObserver mOverviewModeObserver;
public HomeButton(Context context, AttributeSet attrs) {
super(context, attrs);
final int homeButtonIcon = R.drawable.btn_toolbar_home;
setImageDrawable(ContextCompat.getDrawable(context, homeButtonIcon));
HomepageManager.getInstance().addListener(this);
updateContextMenuListener();
mOverviewModeObserver = new EmptyOverviewModeObserver() {
@Override
public void onOverviewModeStateChanged(
@OverviewModeState int overviewModeState, boolean showTabSwitcherToolbar) {
if (overviewModeState == OverviewModeState.SHOWN_HOMEPAGE) {
updateButtonEnabledState(false);
} else {
updateButtonEnabledState(null);
}
}
};
}
public void destroy() {
if (mThemeColorProvider != null) {
mThemeColorProvider.removeTintObserver(this);
mThemeColorProvider = null;
}
if (mActivityTabTabObserver != null) {
mActivityTabTabObserver.destroy();
mActivityTabTabObserver = null;
}
HomepageManager.getInstance().removeListener(this);
if (mOverviewModeBehavior != null) {
mOverviewModeBehavior.removeOverviewModeObserver(mOverviewModeObserver);
mOverviewModeObserver = null;
}
}
public void setThemeColorProvider(ThemeColorProvider themeColorProvider) {
mThemeColorProvider = themeColorProvider;
mThemeColorProvider.addTintObserver(this);
}
public void setOverviewModeBehavior(OverviewModeBehavior overviewModeBehavior) {
assert overviewModeBehavior != null;
mOverviewModeBehavior = overviewModeBehavior;
mOverviewModeBehavior.addOverviewModeObserver(mOverviewModeObserver);
}
@Override
public void onTintChanged(ColorStateList tint, boolean useLight) {
ApiCompatibilityUtils.setImageTintList(this, tint);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
menu.add(Menu.NONE, ID_REMOVE, Menu.NONE, R.string.remove).setOnMenuItemClickListener(this);
}
@Override
public boolean onMenuItemClick(MenuItem item) {
assert item.getItemId() == ID_REMOVE;
assert !isManagedByPolicy();
HomepageManager.getInstance().setPrefHomepageEnabled(false);
return true;
}
@Override
public void onHomepageStateUpdated() {
updateButtonEnabledState(null);
}
public void setActivityTabProvider(ActivityTabProvider activityTabProvider) {
mActivityTabProvider = activityTabProvider;
mActivityTabTabObserver = new ActivityTabTabObserver(activityTabProvider) {
@Override
public void onObservingDifferentTab(Tab tab) {
if (tab == null) return;
updateButtonEnabledState(tab);
}
@Override
public void onUpdateUrl(Tab tab, String url) {
if (tab == null) return;
updateButtonEnabledState(tab);
}
};
}
/**
* Menu button is enabled when not in NTP or if in NTP and homepage is enabled and set to
* somewhere other than the NTP.
* @param tab The notifying {@link Tab} that might be selected soon, this is a hint that a tab
* change is likely.
*/
private void updateButtonEnabledState(Tab tab) {
// New tab page button takes precedence over homepage.
final boolean isHomepageEnabled = HomepageManager.isHomepageEnabled();
boolean isEnabled;
if (getActiveTab() != null) {
// Now tab shows a webpage, let's check if the webpage is not the NTP, or the webpage is
// NTP but homepage is not NTP.
isEnabled = !isTabNTP(getActiveTab())
|| (isHomepageEnabled
&& !NewTabPage.isNTPUrl(HomepageManager.getHomepageUri()));
} else {
// There is no active tab, which means tab is in transition, ex tab swither view to tab
// view, or from one tab to another tab.
isEnabled = !isTabNTP(tab);
}
updateButtonEnabledState(isEnabled);
}
private void updateButtonEnabledState(boolean isEnabled) {
setEnabled(isEnabled);
updateContextMenuListener();
}
/**
* Check if the provided tab is NTP. The tab is a hint that
* @param tab The notifying {@link Tab} that might be selected soon, this is a hint that a tab
* change is likely.
*/
private boolean isTabNTP(Tab tab) {
return tab != null && NewTabPage.isNTPUrl(tab.getUrl());
}
/**
* Return the active tab. If no active tab is shown, return null.
*/
private Tab getActiveTab() {
if (mActivityTabProvider == null) return null;
return mActivityTabProvider.get();
}
private boolean isManagedByPolicy() {
return HomepagePolicyManager.isHomepageManagedByPolicy();
}
private void updateContextMenuListener() {
if (!FeatureUtilities.isBottomToolbarEnabled() && !isManagedByPolicy()) {
setOnCreateContextMenuListener(this);
} else {
setOnCreateContextMenuListener(null);
setLongClickable(false);
}
}
}