content: /*
   * Copyright (C) 2006 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package android.widget;
  
  import android.annotation.NonNull;
  import android.annotation.Nullable;
  import android.annotation.UnsupportedAppUsage;
  import android.app.LocalActivityManager;
  import android.content.Context;
  import android.content.Intent;
  import android.content.res.TypedArray;
  import android.graphics.drawable.Drawable;
  import android.os.Build;
  import android.text.TextUtils;
  import android.util.AttributeSet;
  import android.view.KeyEvent;
  import android.view.LayoutInflater;
  import android.view.SoundEffectConstants;
  import android.view.View;
  import android.view.ViewGroup;
  import android.view.ViewTreeObserver;
  import android.view.Window;
  
  import com.android.internal.R;
  
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * Container for a tabbed window view. This object holds two children: a set of tab labels that the
   * user clicks to select a specific tab, and a FrameLayout object that displays the contents of that
   * page. The individual elements are typically controlled using this container object, rather than
   * setting values on the child elements themselves.
   *
   */
  public class TabHost extends FrameLayout implements ViewTreeObserver.OnTouchModeChangeListener {
  
      private static final int TABWIDGET_LOCATION_LEFT = 0;
      private static final int TABWIDGET_LOCATION_TOP = 1;
      private static final int TABWIDGET_LOCATION_RIGHT = 2;
      private static final int TABWIDGET_LOCATION_BOTTOM = 3;
      private TabWidget mTabWidget;
      private FrameLayout mTabContent;
      @UnsupportedAppUsage
      private List<TabSpec> mTabSpecs = new ArrayList<TabSpec>(2);
      /**
       * This field should be made private, so it is hidden from the SDK.
       * {@hide}
       */
      @UnsupportedAppUsage
      protected int mCurrentTab = -1;
      private View mCurrentView = null;
      /**
       * This field should be made private, so it is hidden from the SDK.
       * {@hide}
       */
      protected LocalActivityManager mLocalActivityManager = null;
      @UnsupportedAppUsage
      private OnTabChangeListener mOnTabChangeListener;
      private OnKeyListener mTabKeyListener;
  
      private int mTabLayoutId;
  
      public TabHost(Context context) {
          super(context);
          initTabHost();
      }
  
      public TabHost(Context context, AttributeSet attrs) {
          this(context, attrs, com.android.internal.R.attr.tabWidgetStyle);
      }
  
      public TabHost(Context context, AttributeSet attrs, int defStyleAttr) {
          this(context, attrs, defStyleAttr, 0);
      }
  
      public TabHost(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
          super(context, attrs);
  
          final TypedArray a = context.obtainStyledAttributes(
                  attrs, com.android.internal.R.styleable.TabWidget, defStyleAttr, defStyleRes);
          saveAttributeDataForStyleable(context, com.android.internal.R.styleable.TabWidget,
                  attrs, a, defStyleAttr, defStyleRes);
  
          mTabLayoutId = a.getResourceId(R.styleable.TabWidget_tabLayout, 0);
          a.recycle();
  
          if (mTabLayoutId == 0) {
              // In case the tabWidgetStyle does not inherit from Widget.TabWidget and tabLayout is
              // not defined.
              mTabLayoutId = R.layout.tab_indicator_holo;
          }
  
          initTabHost();
      }
  
      private void initTabHost() {
          setFocusableInTouchMode(true);
          setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
  
          mCurrentTab = -1;
          mCurrentView = null;
      }
  
      /**
       * Creates a new {@link TabSpec} associated with this tab host.
       *
       * @param tag tag for the tab specification, must be non-null
       * @throws IllegalArgumentException If the passed tag is null
       */
      @NonNull
      public TabSpec newTabSpec(@NonNull String tag) {
          if (tag == null) {
              throw new IllegalArgumentException("tag must be non-null");
          }
          return new TabSpec(tag);
      }
  
  
  
      /**
        * <p>Call setup() before adding tabs if loading TabHost using findViewById().
        * <i><b>However</i></b>: You do not need to call setup() after getTabHost()
        * in {@link android.app.TabActivity TabActivity}.
        * Example:</p>
  <pre>mTabHost = (TabHost)findViewById(R.id.tabhost);
  mTabHost.setup();
  mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
        */
      public void setup() {
          mTabWidget = findViewById(com.android.internal.R.id.tabs);
          if (mTabWidget == null) {
              throw new RuntimeException(
                      "Your TabHost must have a TabWidget whose id attribute is 'android.R.id.tabs'");
          }
  
          // KeyListener to attach to all tabs. Detects non-navigation keys
          // and relays them to the tab content.
          mTabKeyListener = new OnKeyListener() {
              public boolean onKey(View v, int keyCode, KeyEvent event) {
                  if (KeyEvent.isModifierKey(keyCode)) {
                      return false;
                  }
                  switch (keyCode) {
                      case KeyEvent.KEYCODE_DPAD_CENTER:
                      case KeyEvent.KEYCODE_DPAD_LEFT:
                      case KeyEvent.KEYCODE_DPAD_RIGHT:
                      case KeyEvent.KEYCODE_DPAD_UP:
                      case KeyEvent.KEYCODE_DPAD_DOWN:
                      case KeyEvent.KEYCODE_TAB:
                      case KeyEvent.KEYCODE_SPACE:
                      case KeyEvent.KEYCODE_ENTER:
                          return false;
  
                  }
                  mTabContent.requestFocus(View.FOCUS_FORWARD);
                  return mTabContent.dispatchKeyEvent(event);
              }
  
          };
  
          mTabWidget.setTabSelectionListener(new TabWidget.OnTabSelectionChanged() {
              public void onTabSelectionChanged(int tabIndex, boolean clicked) {
                  setCurrentTab(tabIndex);
                  if (clicked) {
                      mTabContent.requestFocus(View.FOCUS_FORWARD);
                  }
              }
          });
  
          mTabContent = findViewById(com.android.internal.R.id.tabcontent);
          if (mTabContent == null) {
              throw new RuntimeException(
                      "Your TabHost must have a FrameLayout whose id attribute is "
                              + "'android.R.id.tabcontent'");
          }
      }
  
      /** @hide */
      @Override
      public void sendAccessibilityEventInternal(int eventType) {
          /* avoid super class behavior - TabWidget sends the right events */
      }
  
      /**
       * If you are using {@link TabSpec#setContent(android.content.Intent)}, this
       * must be called since the activityGroup is needed to launch the local activity.
       *
       * This is done for you if you extend {@link android.app.TabActivity}.
       * @param activityGroup Used to launch activities for tab content.
       */
      public void setup(LocalActivityManager activityGroup) {
          setup();
          mLocalActivityManager = activityGroup;
      }
  
      @Override
      public void onTouchModeChanged(boolean isInTouchMode) {
          // No longer used, but kept to maintain API compatibility.
      }
  
      /**
       * Add a tab.
       * @param tabSpec Specifies how to create the indicator and content.
       * @throws IllegalArgumentException If the passed tab spec has null indicator strategy and / or
       *      null content strategy.
       */
      public void addTab(TabSpec tabSpec) {
  
          if (tabSpec.mIndicatorStrategy == null) {
              throw new IllegalArgumentException("you must specify a way to create the tab indicator.");
          }
  
          if (tabSpec.mContentStrategy == null) {
              throw new IllegalArgumentException("you must specify a way to create the tab content");
          }
          View tabIndicator = tabSpec.mIndicatorStrategy.createIndicatorView();
          tabIndicator.setOnKeyListener(mTabKeyListener);
  
          // If this is a custom view, then do not draw the bottom strips for
          // the tab indicators.
          if (tabSpec.mIndicatorStrategy instanceof ViewIndicatorStrategy) {
              mTabWidget.setStripEnabled(false);
          }
  
          mTabWidget.addView(tabIndicator);
          mTabSpecs.add(tabSpec);
  
          if (mCurrentTab == -1) {
              setCurrentTab(0);
          }
      }
  
  
      /**
       * Removes all tabs from the tab widget associated with this tab host.
       */
      public void clearAllTabs() {
          mTabWidget.removeAllViews();
          initTabHost();
          mTabContent.removeAllViews();
          mTabSpecs.clear();
          requestLayout();
          invalidate();
      }
  
      public TabWidget getTabWidget() {
          return mTabWidget;
      }
  
      /**
       * Returns the current tab.
       *
       * @return the current tab, may be {@code null} if no tab is set as current
       */
      @Nullable
      public int getCurrentTab() {
          return mCurrentTab;
      }
  
      /**
       * Returns the tag for the current tab.
       *
       * @return the tag for the current tab, may be {@code null} if no tab is
       *         set as current
       */
      @Nullable
      public String getCurrentTabTag() {
          if (mCurrentTab >= 0 && mCurrentTab < mTabSpecs.size()) {
              return mTabSpecs.get(mCurrentTab).getTag();
          }
          return null;
      }
  
      /**
       * Returns the view for the current tab.
       *
       * @return the view for the current tab, may be {@code null} if no tab is
       *         set as current
       */
      @Nullable
      public View getCurrentTabView() {
          if (mCurrentTab >= 0 && mCurrentTab < mTabSpecs.size()) {
              return mTabWidget.getChildTabViewAt(mCurrentTab);
          }
          return null;
      }
  
      public View getCurrentView() {
          return mCurrentView;
      }
  
      /**
       * Sets the current tab based on its tag.
       *
       * @param tag the tag for the tab to set as current
       */
      public void setCurrentTabByTag(String tag) {
          for (int i = 0, count = mTabSpecs.size(); i < count; i++) {
              if (mTabSpecs.get(i).getTag().equals(tag)) {
                  setCurrentTab(i);
                  break;
              }
          }
      }
  
      /**
       * Get the FrameLayout which holds tab content
       */
      public FrameLayout getTabContentView() {
          return mTabContent;
      }
  
      /**
       * Get the location of the TabWidget.
       *
       * @return The TabWidget location.
       */
      private int getTabWidgetLocation() {
          int location = TABWIDGET_LOCATION_TOP;
  
          switch (mTabWidget.getOrientation()) {
              case LinearLayout.VERTICAL:
                  location = (mTabContent.getLeft() < mTabWidget.getLeft()) ? TABWIDGET_LOCATION_RIGHT
                          : TABWIDGET_LOCATION_LEFT;
                  break;
              case LinearLayout.HORIZONTAL:
              default:
                  location = (mTabContent.getTop() < mTabWidget.getTop()) ? TABWIDGET_LOCATION_BOTTOM
                          : TABWIDGET_LOCATION_TOP;
                  break;
          }
          return location;
      }
  
      @Override
      public boolean dispatchKeyEvent(KeyEvent event) {
          final boolean handled = super.dispatchKeyEvent(event);
  
          // unhandled key events change focus to tab indicator for embedded
          // activities when there is nothing that will take focus from default
          // focus searching
          if (!handled
                  && (event.getAction() == KeyEvent.ACTION_DOWN)
                  && (mCurrentView != null)
                  && (mCurrentView.isRootNamespace())
                  && (mCurrentView.hasFocus())) {
              int keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_UP;
              int directionShouldChangeFocus = View.FOCUS_UP;
              int soundEffect = SoundEffectConstants.NAVIGATION_UP;
  
              switch (getTabWidgetLocation()) {
                  case TABWIDGET_LOCATION_LEFT:
                      keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_LEFT;
                      directionShouldChangeFocus = View.FOCUS_LEFT;
                      soundEffect = SoundEffectConstants.NAVIGATION_LEFT;
                      break;
                  case TABWIDGET_LOCATION_RIGHT:
                      keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_RIGHT;
                      directionShouldChangeFocus = View.FOCUS_RIGHT;
                      soundEffect = SoundEffectConstants.NAVIGATION_RIGHT;
                      break;
                  case TABWIDGET_LOCATION_BOTTOM:
                      keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_DOWN;
                      directionShouldChangeFocus = View.FOCUS_DOWN;
                      soundEffect = SoundEffectConstants.NAVIGATION_DOWN;
                      break;
                  case TABWIDGET_LOCATION_TOP:
                  default:
                      keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_UP;
                      directionShouldChangeFocus = View.FOCUS_UP;
                      soundEffect = SoundEffectConstants.NAVIGATION_UP;
                      break;
              }
              if (event.getKeyCode() == keyCodeShouldChangeFocus
                      && mCurrentView.findFocus().focusSearch(directionShouldChangeFocus) == null) {
                  mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
                  playSoundEffect(soundEffect);
                  return true;
              }
          }
          return handled;
      }
  
  
      @Override
      public void dispatchWindowFocusChanged(boolean hasFocus) {
          if (mCurrentView != null){
              mCurrentView.dispatchWindowFocusChanged(hasFocus);
          }
      }
  
      @Override
      public CharSequence getAccessibilityClassName() {
          return TabHost.class.getName();
      }
  
      public void setCurrentTab(int index) {
          if (index < 0 || index >= mTabSpecs.size()) {
              return;
          }
  
          if (index == mCurrentTab) {
              return;
          }
  
          // notify old tab content
          if (mCurrentTab != -1) {
              mTabSpecs.get(mCurrentTab).mContentStrategy.tabClosed();
          }
  
          mCurrentTab = index;
          final TabHost.TabSpec spec = mTabSpecs.get(index);
  
          // Call the tab widget's focusCurrentTab(), instead of just
          // selecting the tab.
          mTabWidget.focusCurrentTab(mCurrentTab);
  
          // tab content
          mCurrentView = spec.mContentStrategy.getContentView();
  
          if (mCurrentView.getParent() == null) {
              mTabContent
                      .addView(
                              mCurrentView,
                              new ViewGroup.LayoutParams(
                                      ViewGroup.LayoutParams.MATCH_PARENT,
                                      ViewGroup.LayoutParams.MATCH_PARENT));
          }
  
          if (!mTabWidget.hasFocus()) {
              // if the tab widget didn't take focus (likely because we're in touch mode)
              // give the current tab content view a shot
              mCurrentView.requestFocus();
          }
  
          //mTabContent.requestFocus(View.FOCUS_FORWARD);
          invokeOnTabChangeListener();
      }
  
      /**
       * Register a callback to be invoked when the selected state of any of the items
       * in this list changes
       * @param l
       * The callback that will run
       */
      public void setOnTabChangedListener(OnTabChangeListener l) {
          mOnTabChangeListener = l;
      }
  
      private void invokeOnTabChangeListener() {
          if (mOnTabChangeListener != null) {
              mOnTabChangeListener.onTabChanged(getCurrentTabTag());
          }
      }
  
      /**
       * Interface definition for a callback to be invoked when tab changed
       */
      public interface OnTabChangeListener {
          void onTabChanged(String tabId);
      }
  
  
      /**
       * Makes the content of a tab when it is selected. Use this if your tab
       * content needs to be created on demand, i.e. you are not showing an
       * existing view or starting an activity.
       */
      public interface TabContentFactory {
          /**
           * Callback to make the tab contents
           *
           * @param tag
           *            Which tab was selected.
           * @return The view to display the contents of the selected tab.
           */
          View createTabContent(String tag);
      }
  
  
      /**
       * A tab has a tab indicator, content, and a tag that is used to keep
       * track of it.  This builder helps choose among these options.
       *
       * For the tab indicator, your choices are:
       * 1) set a label
       * 2) set a label and an icon
       *
       * For the tab content, your choices are:
       * 1) the id of a {@link View}
       * 2) a {@link TabContentFactory} that creates the {@link View} content.
       * 3) an {@link Intent} that launches an {@link android.app.Activity}.
       */
      public class TabSpec {
  
          private final @NonNull String mTag;
  
          @UnsupportedAppUsage
          private IndicatorStrategy mIndicatorStrategy;
          @UnsupportedAppUsage
          private ContentStrategy mContentStrategy;
  
          /**
           * Constructs a new tab specification with the specified tag.
           *
           * @param tag the tag for the tag specification, must be non-null
           */
          private TabSpec(@NonNull String tag) {
              mTag = tag;
          }
  
          /**
           * Specify a label as the tab indicator.
           */
          public TabSpec setIndicator(CharSequence label) {
              mIndicatorStrategy = new LabelIndicatorStrategy(label);
              return this;
          }
  
          /**
           * Specify a label and icon as the tab indicator.
           */
          public TabSpec setIndicator(CharSequence label, Drawable icon) {
              mIndicatorStrategy = new LabelAndIconIndicatorStrategy(label, icon);
              return this;
          }
  
          /**
           * Specify a view as the tab indicator.
           */
          public TabSpec setIndicator(View view) {
              mIndicatorStrategy = new ViewIndicatorStrategy(view);
              return this;
          }
  
          /**
           * Specify the id of the view that should be used as the content
           * of the tab.
           */
          public TabSpec setContent(int viewId) {
              mContentStrategy = new ViewIdContentStrategy(viewId);
              return this;
          }
  
          /**
           * Specify a {@link android.widget.TabHost.TabContentFactory} to use to
           * create the content of the tab.
           */
          public TabSpec setContent(TabContentFactory contentFactory) {
              mContentStrategy = new FactoryContentStrategy(mTag, contentFactory);
              return this;
          }
  
          /**
           * Specify an intent to use to launch an activity as the tab content.
           */
          public TabSpec setContent(Intent intent) {
              mContentStrategy = new IntentContentStrategy(mTag, intent);
              return this;
          }
  
          /**
           * Returns the tag for this tab specification.
           *
           * @return the tag for this tab specification
           */
          @NonNull
          public String getTag() {
              return mTag;
          }
      }
  
      /**
       * Specifies what you do to create a tab indicator.
       */
      private static interface IndicatorStrategy {
  
          /**
           * Return the view for the indicator.
           */
          View createIndicatorView();
      }
  
      /**
       * Specifies what you do to manage the tab content.
       */
      private static interface ContentStrategy {
  
          /**
           * Return the content view.  The view should may be cached locally.
           */
          View getContentView();
  
          /**
           * Perhaps do something when the tab associated with this content has
           * been closed (i.e make it invisible, or remove it).
           */
          void tabClosed();
      }
  
      /**
       * How to create a tab indicator that just has a label.
       */
      private class LabelIndicatorStrategy implements IndicatorStrategy {
  
          private final CharSequence mLabel;
  
          private LabelIndicatorStrategy(CharSequence label) {
              mLabel = label;
          }
  
          public View createIndicatorView() {
              final Context context = getContext();
              LayoutInflater inflater =
                      (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
              View tabIndicator = inflater.inflate(mTabLayoutId,
                      mTabWidget, // tab widget is the parent
                      false); // no inflate params
  
              final TextView tv = tabIndicator.findViewById(R.id.title);
              tv.setText(mLabel);
  
              if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
                  // Donut apps get old color scheme
                  tabIndicator.setBackgroundResource(R.drawable.tab_indicator_v4);
                  tv.setTextColor(context.getColorStateList(R.color.tab_indicator_text_v4));
              }
  
              return tabIndicator;
          }
      }
  
      /**
       * How we create a tab indicator that has a label and an icon
       */
      private class LabelAndIconIndicatorStrategy implements IndicatorStrategy {
  
          private final CharSequence mLabel;
          private final Drawable mIcon;
  
          private LabelAndIconIndicatorStrategy(CharSequence label, Drawable icon) {
              mLabel = label;
              mIcon = icon;
          }
  
          public View createIndicatorView() {
              final Context context = getContext();
              LayoutInflater inflater =
                      (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
              View tabIndicator = inflater.inflate(mTabLayoutId,
                      mTabWidget, // tab widget is the parent
                      false); // no inflate params
  
              final TextView tv = tabIndicator.findViewById(R.id.title);
              final ImageView iconView = tabIndicator.findViewById(R.id.icon);
  
              // when icon is gone by default, we're in exclusive mode
              final boolean exclusive = iconView.getVisibility() == View.GONE;
              final boolean bindIcon = !exclusive || TextUtils.isEmpty(mLabel);
  
              tv.setText(mLabel);
  
              if (bindIcon && mIcon != null) {
                  iconView.setImageDrawable(mIcon);
                  iconView.setVisibility(VISIBLE);
              }
  
              if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
                  // Donut apps get old color scheme
                  tabIndicator.setBackgroundResource(R.drawable.tab_indicator_v4);
                  tv.setTextColor(context.getColorStateList(R.color.tab_indicator_text_v4));
              }
  
              return tabIndicator;
          }
      }
  
      /**
       * How to create a tab indicator by specifying a view.
       */
      private class ViewIndicatorStrategy implements IndicatorStrategy {
  
          private final View mView;
  
          private ViewIndicatorStrategy(View view) {
              mView = view;
          }
  
          public View createIndicatorView() {
              return mView;
          }
      }
  
      /**
       * How to create the tab content via a view id.
       */
      private class ViewIdContentStrategy implements ContentStrategy {
  
          private final View mView;
  
          private ViewIdContentStrategy(int viewId) {
              mView = mTabContent.findViewById(viewId);
              if (mView != null) {
                  mView.setVisibility(View.GONE);
              } else {
                  throw new RuntimeException("Could not create tab content because " +
                          "could not find view with id " + viewId);
              }
          }
  
          public View getContentView() {
              mView.setVisibility(View.VISIBLE);
              return mView;
          }
  
          public void tabClosed() {
              mView.setVisibility(View.GONE);
          }
      }
  
      /**
       * How tab content is managed using {@link TabContentFactory}.
       */
      private class FactoryContentStrategy implements ContentStrategy {
          private View mTabContent;
          private final CharSequence mTag;
          private TabContentFactory mFactory;
  
          public FactoryContentStrategy(CharSequence tag, TabContentFactory factory) {
              mTag = tag;
              mFactory = factory;
          }
  
          public View getContentView() {
              if (mTabContent == null) {
                  mTabContent = mFactory.createTabContent(mTag.toString());
              }
              mTabContent.setVisibility(View.VISIBLE);
              return mTabContent;
          }
  
          public void tabClosed() {
              mTabContent.setVisibility(View.GONE);
          }
      }
  
      /**
       * How tab content is managed via an {@link Intent}: the content view is the
       * decorview of the launched activity.
       */
      private class IntentContentStrategy implements ContentStrategy {
  
          private final String mTag;
          private final Intent mIntent;
  
          private View mLaunchedView;
  
          private IntentContentStrategy(String tag, Intent intent) {
              mTag = tag;
              mIntent = intent;
          }
  
          @UnsupportedAppUsage
          public View getContentView() {
              if (mLocalActivityManager == null) {
                  throw new IllegalStateException("Did you forget to call 'public void setup(LocalActivityManager activityGroup)'?");
              }
              final Window w = mLocalActivityManager.startActivity(
                      mTag, mIntent);
              final View wd = w != null ? w.getDecorView() : null;
              if (mLaunchedView != wd && mLaunchedView != null) {
                  if (mLaunchedView.getParent() != null) {
                      mTabContent.removeView(mLaunchedView);
                  }
              }
              mLaunchedView = wd;
  
              // XXX Set FOCUS_AFTER_DESCENDANTS on embedded activities for now so they can get
              // focus if none of their children have it. They need focus to be able to
              // display menu items.
              //
              // Replace this with something better when Bug 628886 is fixed...
              //
              if (mLaunchedView != null) {
                  mLaunchedView.setVisibility(View.VISIBLE);
                  mLaunchedView.setFocusableInTouchMode(true);
                  ((ViewGroup) mLaunchedView).setDescendantFocusability(
                          FOCUS_AFTER_DESCENDANTS);
              }
              return mLaunchedView;
          }
  
          @UnsupportedAppUsage
          public void tabClosed() {
              if (mLaunchedView != null) {
                  mLaunchedView.setVisibility(View.GONE);
              }
          }
      }
  
  }
  