/** Test method for {@link AbstractMediaRouteController#isRemotePlaybackAvailable()}. */
  @Test
  @Feature({"MediaRemote"})
  public void testIsRemotePlaybackAvailable() {
    MediaRouter mediaRouter = mock(MediaRouter.class);
    AbstractMediaRouteController mediaRouteCtrl = new DummyMediaRouteController();
    when(mediaRouter.getSelectedRoute())
        .thenReturn(createRouteInfo(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE));
    when(mediaRouter.isRouteAvailable(any(MediaRouteSelector.class), anyInt())).thenReturn(true);

    // Default
    assertFalse(mediaRouteCtrl.isRemotePlaybackAvailable());

    ShadowMediaRouter.sMediaRouter = mediaRouter;
    mediaRouteCtrl = spy(new DummyMediaRouteController());
    assertTrue(mediaRouteCtrl.isRemotePlaybackAvailable());

    when(mediaRouter.getSelectedRoute())
        .thenReturn(createRouteInfo(MediaRouter.RouteInfo.PLAYBACK_TYPE_LOCAL));
    assertTrue(mediaRouteCtrl.isRemotePlaybackAvailable());

    when(mediaRouter.isRouteAvailable(any(MediaRouteSelector.class), anyInt())).thenReturn(false);
    assertFalse(mediaRouteCtrl.isRemotePlaybackAvailable());

    when(mediaRouter.getSelectedRoute())
        .thenReturn(createRouteInfo(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE));
    assertTrue(mediaRouteCtrl.isRemotePlaybackAvailable());
  }
  void refreshRoute() {
    if (mAttachedToWindow) {
      final MediaRouter.RouteInfo route = mRouter.getSelectedRoute();
      final boolean isRemote = !route.isDefaultOrBluetooth() && route.matchesSelector(mSelector);
      final boolean isConnecting = isRemote && route.isConnecting();

      boolean needsRefresh = false;
      if (mRemoteActive != isRemote) {
        mRemoteActive = isRemote;
        needsRefresh = true;
      }
      if (mIsConnecting != isConnecting) {
        mIsConnecting = isConnecting;
        needsRefresh = true;
      }

      if (needsRefresh) {
        updateContentDescription();
        refreshDrawableState();
        if (mRemoteIndicator.getCurrent() instanceof AnimationDrawable) {
          AnimationDrawable curDrawable = (AnimationDrawable) mRemoteIndicator.getCurrent();
          if (!curDrawable.isRunning()) {
            curDrawable.start();
          }
        }
      }
    }
  }
  /**
   * Show the route chooser or controller dialog.
   *
   * <p>If the default route is selected or if the currently selected route does not match the
   * {@link #getRouteSelector selector}, then shows the route chooser dialog. Otherwise, shows the
   * route controller dialog to offer the user a choice to disconnect from the route or perform
   * other control actions such as setting the route's volume.
   *
   * <p>The application can customize the dialogs by calling {@link #setDialogFactory} to provide a
   * customized dialog factory.
   *
   * @return True if the dialog was actually shown.
   * @throws IllegalStateException if the activity is not a subclass of {@link FragmentActivity}.
   */
  public boolean showDialog() {
    if (!mAttachedToWindow) {
      return false;
    }

    final FragmentManager fm = getFragmentManager();
    if (fm == null) {
      throw new IllegalStateException("The activity must be a subclass of FragmentActivity");
    }

    MediaRouter.RouteInfo route = mRouter.getSelectedRoute();
    if (route.isDefaultOrBluetooth() || !route.matchesSelector(mSelector)) {
      if (fm.findFragmentByTag(CHOOSER_FRAGMENT_TAG) != null) {
        Log.w(TAG, "showDialog(): Route chooser dialog already showing!");
        return false;
      }
      MediaRouteChooserDialogFragment f = mDialogFactory.onCreateChooserDialogFragment();
      f.setRouteSelector(mSelector);
      f.show(fm, CHOOSER_FRAGMENT_TAG);
    } else {
      if (fm.findFragmentByTag(CONTROLLER_FRAGMENT_TAG) != null) {
        Log.w(TAG, "showDialog(): Route controller dialog already showing!");
        return false;
      }
      MediaRouteControllerDialogFragment f = mDialogFactory.onCreateControllerDialogFragment();
      f.show(fm, CONTROLLER_FRAGMENT_TAG);
    }
    return true;
  }