protected void restoreTab(TabView tab) {
    mBubbleFlowDraggable.restoreTab(tab);
    // Only do this if there's just 1 tab open. Fix #446
    if (getActiveTabCount() == 1) {
      // If the bubble was closed when in BubbleView mode, forcibly reset to Bubble mode
      if (mBubbleDraggable.getCurrentMode() == BubbleDraggable.Mode.BubbleView) {
        mBubbleDraggable.setVisibility(View.VISIBLE);
        collapseBubbleFlow(0);
        mBubbleFlowDraggable.setVisibility(View.GONE);

        // Ensure CanvasView has a valid ContentView
        CurrentTabChangedEvent event = new CurrentTabChangedEvent();
        event.mTab = tab;
        MainApplication.postEvent(mContext, event);

        mBubbleDraggable.snapToBubbleView();
      } else {
        final float bubblePeriod = (float) Constant.BUBBLE_ANIM_TIME / 1000.f;
        final float contentPeriod =
            bubblePeriod
                * 0.666667f; // 0.66667 is the normalized t value when f = 1.0f for overshoot
                             // interpolator of 0.5 tension
        expandBubbleFlow((long) (contentPeriod * 1000), false);
        if (Constant.ACTIVITY_WEBVIEW_RENDERING == false) {
          // No need to do this if above is true because it's already done
          showExpandedActivity();
        }
      }
    } else {
      showBadge(true);
    }
    ++mBubblesLoaded;
  }
 public void onOrientationChanged() {
   Config.init(mContext);
   Settings.get().onOrientationChange();
   mBubbleDraggable.onOrientationChanged();
   mBubbleFlowDraggable.onOrientationChanged();
   MainApplication.postEvent(mContext, mOrientationChangedEvent);
 }
  void updateScreenState(String action) {
    // Log.d(SCREEN_LOCK_TAG, "---" + action);
    CrashTracking.log("BubbleFlowView - updateScreenState(): " + action);

    if (action.equals(Intent.ACTION_SCREEN_OFF)) {
      mScreenOn = false;
      setCanDisplay(false);
      MainApplication.postEvent(mContext, mScreenOffEvent);
    } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
      updateKeyguardLocked();
      mScreenOn = true;
      MainApplication.postEvent(mContext, mScreenOnEvent);
    } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
      setCanDisplay(mHiddenByUser ? false : true);
      MainApplication.postEvent(mContext, mUserPresentEvent);
    }
  }
 public void switchToBubbleView() {
   mCanAutoDisplayLink = false;
   if (MainController.get().getActiveTabCount() > 0) {
     mBubbleDraggable.switchToBubbleView();
   } else {
     // If there's no tabs, ensuring pressing Home will cause the CanvasView to go away. Fix #448
     MainApplication.postEvent(mContext, new MainController.EndCollapseTransitionEvent());
   }
 }
 public void setHiddenByUser(boolean hiddenByUser) {
   if (mHiddenByUser != hiddenByUser) {
     mHiddenByUser = hiddenByUser;
     if (mHiddenByUser) {
       switch (mBubbleDraggable.getCurrentMode()) {
         case ContentView:
           mBubbleDraggable.snapToBubbleView();
           break;
       }
       MainApplication.postEvent(mContext, new HideContentEvent());
       MainApplication.postEvent(mContext, new MainService.ShowUnhideNotificationEvent());
     } else {
       MainApplication.postEvent(
           mContext, new CurrentTabChangedEvent(mBubbleFlowDraggable.getCurrentTab()));
       MainApplication.postEvent(mContext, new MainService.ShowDefaultNotificationEvent());
       MainApplication.postEvent(mContext, new UnhideContentEvent());
     }
     setCanDisplay(!mHiddenByUser);
   }
 }
  private void doExpandBubbleFlow(long time, boolean hideDraggable) {
    mBeginExpandTransitionEvent.mPeriod = time / 1000.0f;

    mBubbleFlowDraggable.setVisibility(View.VISIBLE);
    mSetBubbleFlowGone = false; // cancel any pending operation to set visibility to GONE (see #190)
    mBubbleFlowDraggable.expand(time, mOnBubbleFlowExpandFinishedListener);

    MainApplication.postEvent(mContext, mBeginExpandTransitionEvent);

    if (hideDraggable) {
      mBubbleDraggable.postDelayed(mSetBubbleGoneRunnable, 33);
    }
  }
  public boolean closeTab(
      TabView tabView,
      Constant.BubbleAction action,
      boolean animateOff,
      boolean canShowUndoPrompt) {

    if (tabView == null) {
      CrashTracking.log("closeTab attempt on null tabView");
      return false;
    }

    // If the tab is already closing, do nothing. Otherwise we could end up in a weird state,
    // where we attempt to show multiple prompts and crashing upon tab restore.
    if (null == tabView || tabView.mIsClosing == true) {
      CrashTracking.log("Ignoring duplicate tabView close request");
      return false;
    }
    if (null != tabView) {
      tabView.mIsClosing = true;
    } else {
      CrashTracking.log("attempt to access on null tabView");
      return false;
    }

    boolean contentViewShowing = contentViewShowing();
    CrashTracking.log(
        "MainController.closeTab(): action:"
            + action.toString()
            + ", contentViewShowing:"
            + contentViewShowing
            + ", visibleTabCount:"
            + getVisibleTabCount()
            + ", activeTabCount:"
            + getActiveTabCount()
            + ", canShowUndoPrompt:"
            + canShowUndoPrompt
            + ", animateOff:"
            + animateOff
            + ", canShowUndoPrompt:"
            + canShowUndoPrompt);
    if (mBubbleFlowDraggable != null) {
      mBubbleFlowDraggable.closeTab(
          tabView, animateOff, action, tabView != null ? tabView.getTotalTrackedLoadTime() : -1);
    }

    int activeTabCount = getActiveTabCount();
    showBadge(activeTabCount > 1 ? true : false);
    if (activeTabCount == 0) {
      hideBubbleDraggable();
      // Ensure BubbleFlowDraggable gets at least 1 update in the event items are animating off
      // screen. See #237.
      scheduleUpdate();

      MainApplication.postEvent(mContext, mMinimizeExpandedActivityEvent);
    }

    if (tabView == null) {
      CrashTracking.logHandledException(new RuntimeException("tabView = null"));
    } else {
      if (canShowUndoPrompt && Settings.get().getShowUndoCloseTab()) {
        showClosePrompt(tabView);
      } else {
        destroyTabOnDelay(tabView);
      }
    }

    return getActiveTabCount() > 0;
  }
 public void startFileBrowser(String[] acceptTypes, ValueCallback<Uri[]> filePathCallback) {
   MainApplication.postEvent(
       mContext, new ExpandedActivity.ShowFileBrowserEvent(acceptTypes, filePathCallback));
 }