gt:                 final Tab tab = Tabs.getInstance().getSelectedTab();
context: /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
   * This Source Code Form is subject to the terms of the Mozilla Public
   * License, v. 2.0. If a copy of the MPL was not distributed with this
   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  
  package org.mozilla.gecko.toolbar;
  
  import java.util.ArrayList;
  import java.util.EnumSet;
  import java.util.List;
  
  import org.mozilla.gecko.AppConstants.Versions;
  import org.mozilla.gecko.BrowserApp;
  import org.mozilla.gecko.GeckoAppShell;
  import org.mozilla.gecko.R;
  import org.mozilla.gecko.Tab;
  import org.mozilla.gecko.Tabs;
  import org.mozilla.gecko.Telemetry;
  import org.mozilla.gecko.TelemetryContract;
  import org.mozilla.gecko.animation.PropertyAnimator;
  import org.mozilla.gecko.animation.PropertyAnimator.PropertyAnimationListener;
  import org.mozilla.gecko.animation.ViewHelper;
  import org.mozilla.gecko.lwt.LightweightTheme;
  import org.mozilla.gecko.lwt.LightweightThemeDrawable;
  import org.mozilla.gecko.menu.GeckoMenu;
  import org.mozilla.gecko.menu.MenuPopup;
  import org.mozilla.gecko.tabs.TabHistoryController;
  import org.mozilla.gecko.toolbar.ToolbarDisplayLayout.OnStopListener;
  import org.mozilla.gecko.toolbar.ToolbarDisplayLayout.OnTitleChangeListener;
  import org.mozilla.gecko.toolbar.ToolbarDisplayLayout.UpdateFlags;
  import org.mozilla.gecko.util.Clipboard;
  import org.mozilla.gecko.util.ColorUtils;
  import org.mozilla.gecko.util.HardwareUtils;
  import org.mozilla.gecko.util.MenuUtils;
  import org.mozilla.gecko.widget.ThemedImageButton;
  import org.mozilla.gecko.widget.ThemedImageView;
  import org.mozilla.gecko.widget.ThemedRelativeLayout;
  
  import android.content.Context;
  import android.content.res.Resources;
  import android.graphics.Canvas;
  import android.graphics.Paint;
  import android.graphics.drawable.Drawable;
  import android.graphics.drawable.StateListDrawable;
  import android.text.TextUtils;
  import android.util.AttributeSet;
  import android.util.Log;
  import android.view.ContextMenu;
  import android.view.LayoutInflater;
  import android.view.MenuInflater;
  import android.view.MotionEvent;
  import android.view.View;
  import android.view.ViewTreeObserver.OnGlobalLayoutListener;
  import android.view.inputmethod.InputMethodManager;
  import android.widget.Button;
  import android.widget.LinearLayout;
  import android.widget.PopupWindow;
  
  /**
  * {@code BrowserToolbar} is single entry point for users of the toolbar
  * subsystem i.e. this should be the only import outside the 'toolbar'
  * package.
  *
  * {@code BrowserToolbar} serves at the single event bus for all
  * sub-components in the toolbar. It tracks tab events and gecko messages
  * and update the state of its inner components accordingly.
  *
  * It has two states, display and edit, which are controlled by
  * ToolbarEditLayout and ToolbarDisplayLayout. In display state, the toolbar
  * displays the current state for the selected tab. In edit state, it shows
  * a text entry for searching bookmarks/history. {@code BrowserToolbar}
  * provides public API to enter, cancel, and commit the edit state as well
  * as a set of listeners to allow {@code BrowserToolbar} users to react
  * to state changes accordingly.
  */
  public abstract class BrowserToolbar extends ThemedRelativeLayout
                                       implements Tabs.OnTabsChangedListener,
                                                  GeckoMenu.ActionItemBarPresenter {
      private static final String LOGTAG = "GeckoToolbar";
  
      private static final int LIGHTWEIGHT_THEME_INVERT_ALPHA = 34; // 255 - alpha = invert_alpha
  
      public interface OnActivateListener {
          public void onActivate();
      }
  
      public interface OnCommitListener {
          public void onCommit();
      }
  
      public interface OnDismissListener {
          public void onDismiss();
      }
  
      public interface OnFilterListener {
          public void onFilter(String searchText, AutocompleteHandler handler);
      }
  
      public interface OnStartEditingListener {
          public void onStartEditing();
      }
  
      public interface OnStopEditingListener {
          public void onStopEditing();
      }
  
      protected enum UIMode {
          EDIT,
          DISPLAY
      }
  
      protected final ToolbarDisplayLayout urlDisplayLayout;
      protected final ToolbarEditLayout urlEditLayout;
      protected final View urlBarEntry;
      protected boolean isSwitchingTabs;
      protected final ThemedImageButton tabsButton;
  
      private ToolbarProgressView progressBar;
      protected final TabCounter tabsCounter;
      protected final ThemedImageButton menuButton;
      protected final ThemedImageView menuIcon;
      private MenuPopup menuPopup;
      protected final List<View> focusOrder;
  
      private OnActivateListener activateListener;
      private OnFocusChangeListener focusChangeListener;
      private OnStartEditingListener startEditingListener;
      private OnStopEditingListener stopEditingListener;
  
      protected final BrowserApp activity;
      protected boolean hasSoftMenuButton;
  
      protected UIMode uiMode;
      protected TabHistoryController tabHistoryController;
  
      private final Paint shadowPaint;
      private final int shadowColor;
      private final int shadowPrivateColor;
      private final int shadowSize;
  
      private final ToolbarPrefs prefs;
      private boolean contextMenuEnabled = true;
  
      public abstract boolean isAnimating();
  
      protected abstract boolean isTabsButtonOffscreen();
  
      protected abstract void updateNavigationButtons(Tab tab);
  
      protected abstract void triggerStartEditingTransition(PropertyAnimator animator);
      protected abstract void triggerStopEditingTransition();
      public abstract void triggerTabsPanelTransition(PropertyAnimator animator, boolean areTabsShown);
  
      /**
       * Returns a Drawable overlaid with the theme's bitmap.
       */
      protected Drawable getLWTDefaultStateSetDrawable() {
          return getTheme().getDrawable(this);
      }
  
      public static BrowserToolbar create(final Context context, final AttributeSet attrs) {
          final BrowserToolbar toolbar;
          if (HardwareUtils.isTablet()) {
              toolbar = new BrowserToolbarTablet(context, attrs);
          } else if (Versions.preHC) {
              toolbar = new BrowserToolbarPreHC(context, attrs);
          } else {
              toolbar = new BrowserToolbarPhone(context, attrs);
          }
          return toolbar;
      }
  
      protected BrowserToolbar(final Context context, final AttributeSet attrs) {
          super(context, attrs);
          setWillNotDraw(false);
  
          // BrowserToolbar is attached to BrowserApp only.
          activity = (BrowserApp) context;
  
          LayoutInflater.from(context).inflate(R.layout.browser_toolbar, this);
  
          Tabs.registerOnTabsChangedListener(this);
          isSwitchingTabs = true;
  
          urlDisplayLayout = (ToolbarDisplayLayout) findViewById(R.id.display_layout);
          urlBarEntry = findViewById(R.id.url_bar_entry);
          urlEditLayout = (ToolbarEditLayout) findViewById(R.id.edit_layout);
  
          tabsButton = (ThemedImageButton) findViewById(R.id.tabs);
          tabsCounter = (TabCounter) findViewById(R.id.tabs_counter);
          if (Versions.feature11Plus) {
              tabsCounter.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
          }
  
          menuButton = (ThemedImageButton) findViewById(R.id.menu);
          menuIcon = (ThemedImageView) findViewById(R.id.menu_icon);
          hasSoftMenuButton = !HardwareUtils.hasMenuButton();
  
          // The focusOrder List should be filled by sub-classes.
          focusOrder = new ArrayList<View>();
  
          final Resources res = getResources();
          shadowSize = res.getDimensionPixelSize(R.dimen.browser_toolbar_shadow_size);
  
          shadowPaint = new Paint();
          shadowColor = ColorUtils.getColor(context, R.color.url_bar_shadow);
          shadowPrivateColor = ColorUtils.getColor(context, R.color.url_bar_shadow_private);
          shadowPaint.setColor(shadowColor);
          shadowPaint.setStrokeWidth(0.0f);
  
          setUIMode(UIMode.DISPLAY);
  
          prefs = new ToolbarPrefs();
          urlDisplayLayout.setToolbarPrefs(prefs);
          urlEditLayout.setToolbarPrefs(prefs);
      }
  
      @Override
      public void onAttachedToWindow() {
          super.onAttachedToWindow();
  
          prefs.open();
  
          setOnClickListener(new Button.OnClickListener() {
              @Override
              public void onClick(View v) {
                  if (activateListener != null) {
                      activateListener.onActivate();
                  }
              }
          });
  
          setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
              @Override
              public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
                  // We don't the context menu while editing or while dragging
                  if (isEditing() || !contextMenuEnabled) {
                      return;
                  }
  
                  // NOTE: Use MenuUtils.safeSetVisible because some actions might
                  // be on the Page menu
  
                  MenuInflater inflater = activity.getMenuInflater();
                  inflater.inflate(R.menu.titlebar_contextmenu, menu);
  
                  String clipboard = Clipboard.getText();
                  if (TextUtils.isEmpty(clipboard)) {
                      menu.findItem(R.id.pasteandgo).setVisible(false);
                      menu.findItem(R.id.paste).setVisible(false);
                  }
  
                  Tab tab = Tabs.getInstance().getSelectedTab();
                  if (tab != null) {
                      String url = tab.getURL();
                      if (url == null) {
                          menu.findItem(R.id.copyurl).setVisible(false);
                          menu.findItem(R.id.add_to_launcher).setVisible(false);
                      }
  
                      MenuUtils.safeSetVisible(menu, R.id.subscribe, tab.hasFeeds());
                      MenuUtils.safeSetVisible(menu, R.id.add_search_engine, tab.hasOpenSearch());
                  } else {
                      // if there is no tab, remove anything tab dependent
                      menu.findItem(R.id.copyurl).setVisible(false);
                      menu.findItem(R.id.add_to_launcher).setVisible(false);
                      MenuUtils.safeSetVisible(menu, R.id.subscribe, false);
                      MenuUtils.safeSetVisible(menu, R.id.add_search_engine, false);
                  }
              }
          });
  
          urlDisplayLayout.setOnStopListener(new OnStopListener() {
              @Override
              public Tab onStop() {
  