Exemple #1
0
  // This callback is automatically executed on the UI thread.
  @Override
  public void onTabChanged(final Tab tab, final Tabs.TabEvents msg, final Object data) {
    switch (msg) {
      case CLOSED:
        // Remove any doorhangers for a tab when it's closed (make
        // a temporary set to avoid a ConcurrentModificationException)
        HashSet<DoorHanger> doorHangersToRemove = new HashSet<DoorHanger>();
        for (DoorHanger dh : mDoorHangers) {
          if (dh.getTabId() == tab.getId()) doorHangersToRemove.add(dh);
        }
        for (DoorHanger dh : doorHangersToRemove) {
          removeDoorHanger(dh);
        }
        break;

      case LOCATION_CHANGE:
        // Only remove doorhangers if the popup is hidden or if we're navigating to a new URL
        if (!isShowing() || !data.equals(tab.getURL())) removeTransientDoorHangers(tab.getId());

        // Update the popup if the location change was on the current tab
        if (Tabs.getInstance().isSelectedTab(tab)) updatePopup();
        break;

      case SELECTED:
        // Always update the popup when a new tab is selected. This will cover cases
        // where a different tab was closed, since we always need to select a new tab.
        updatePopup();
        break;
    }
  }
Exemple #2
0
  /**
   * Gets a doorhanger.
   *
   * <p>This method must be called on the UI thread.
   */
  DoorHanger getDoorHanger(int tabId, String value) {
    for (DoorHanger dh : mDoorHangers) {
      if (dh.getTabId() == tabId && dh.getValue().equals(value)) return dh;
    }

    // If there's no doorhanger for the given tabId and value, return null
    return null;
  }
Exemple #3
0
 private void fixBackgroundForFirst() {
   for (int i = 0; i < mContent.getChildCount(); i++) {
     DoorHanger dh = (DoorHanger) mContent.getChildAt(i);
     if (dh.getVisibility() == View.VISIBLE) {
       dh.setBackgroundResource(R.drawable.doorhanger_bg);
       break;
     }
   }
 }
Exemple #4
0
  /**
   * Updates the popup state.
   *
   * <p>This method must be called on the UI thread.
   */
  void updatePopup() {
    // Bail if the selected tab is null, if there are no active doorhangers,
    // or if we haven't inflated the layout yet (this can happen if updatePopup()
    // is called before the runnable from addDoorHanger() runs).
    Tab tab = Tabs.getInstance().getSelectedTab();
    if (tab == null || mDoorHangers.size() == 0 || !mInflated) {
      dismiss();
      return;
    }

    // Show doorhangers for the selected tab
    int tabId = tab.getId();
    boolean shouldShowPopup = false;
    for (DoorHanger dh : mDoorHangers) {
      if (dh.getTabId() == tabId) {
        dh.setVisibility(View.VISIBLE);
        shouldShowPopup = true;
      } else {
        dh.setVisibility(View.GONE);
      }
    }

    // Dismiss the popup if there are no doorhangers to show for this tab
    if (!shouldShowPopup) {
      dismiss();
      return;
    }

    fixBackgroundForFirst();
    if (isShowing()) {
      update();
      return;
    }

    // If there's no anchor, just show the popup at the top of the gecko app view.
    if (mAnchor == null) {
      showAtLocation(mActivity.getView(), Gravity.TOP, 0, 0);
      return;
    }

    // On tablets, we need to position the popup so that the center of the arrow points to the
    // center of the anchor view. On phones the popup stretches across the entire screen, so the
    // arrow position is determined by its left margin.
    int offset =
        mActivity.isTablet()
            ? mAnchor.getWidth() / 2
                - mArrowWidth / 2
                - ((RelativeLayout.LayoutParams) mArrow.getLayoutParams()).leftMargin
            : 0;
    showAsDropDown(mAnchor, offset, 0);
    // Make the popup focusable for keyboard accessibility.
    setFocusable(true);
  }
Exemple #5
0
  /**
   * Removes doorhangers for a given tab.
   *
   * <p>This method must be called on the UI thread.
   */
  void removeTransientDoorHangers(int tabId) {
    // Make a temporary set to avoid a ConcurrentModificationException
    HashSet<DoorHanger> doorHangersToRemove = new HashSet<DoorHanger>();
    for (DoorHanger dh : mDoorHangers) {
      // Only remove transient doorhangers for the given tab
      if (dh.getTabId() == tabId && dh.shouldRemove()) doorHangersToRemove.add(dh);
    }

    for (DoorHanger dh : doorHangersToRemove) {
      removeDoorHanger(dh);
    }
  }
Exemple #6
0
  /**
   * Adds a doorhanger.
   *
   * <p>This method must be called on the UI thread.
   */
  void addDoorHanger(
      final int tabId,
      final String value,
      final String message,
      final JSONArray buttons,
      final JSONObject options) {
    // Don't add a doorhanger for a tab that doesn't exist
    if (Tabs.getInstance().getTab(tabId) == null) return;

    // Replace the doorhanger if it already exists
    DoorHanger oldDoorHanger = getDoorHanger(tabId, value);
    if (oldDoorHanger != null) removeDoorHanger(oldDoorHanger);

    final DoorHanger newDoorHanger = new DoorHanger(mActivity, this, tabId, value);
    mDoorHangers.add(newDoorHanger);

    if (!mInflated) init();

    newDoorHanger.init(message, buttons, options);
    mContent.addView(newDoorHanger);

    // Only update the popup if we're adding a notifcation to the selected tab
    if (tabId == Tabs.getInstance().getSelectedTab().getId()) updatePopup();
  }