// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.chrome.browser.media.router; import android.content.Context; import android.support.v7.app.MediaRouteChooserDialogFragment; import android.support.v7.app.MediaRouteControllerDialogFragment; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.chrome.browser.media.router.cast.MediaSink; import org.chromium.chrome.browser.media.router.cast.MediaSource; /** * Implements the JNI interface called from the C++ Media Router dialog controller implementation * on Android. */ @JNINamespace("media_router") public class ChromeMediaRouterDialogController implements MediaRouteDialogDelegate { private static final String MEDIA_ROUTE_CONTROLLER_DIALOG_FRAGMENT = "android.support.v7.mediarouter:MediaRouteControllerDialogFragment"; private final long mNativeDialogController; private final Context mApplicationContext; private MediaRouteDialogManager mDialogManager; /** * Returns a new initialized {@link ChromeMediaRouterDialogController}. * @param nativeDialogController the handle of the native object. * @param context the application context. * @return a new dialog controller to use from the native side. */ @CalledByNative public static ChromeMediaRouterDialogController create( long nativeDialogController, Context context) { return new ChromeMediaRouterDialogController(nativeDialogController, context); } /** * Shows the {@link MediaRouteChooserDialogFragment} if it's not shown yet. * @param sourceUrn the URN identifying the media source to filter the devices with. */ @CalledByNative public void openRouteChooserDialog(String sourceUrn) { if (isShowingDialog()) return; MediaSource source = MediaSource.from(sourceUrn); if (source == null) return; mDialogManager = new MediaRouteChooserDialogManager(source, mApplicationContext, this); mDialogManager.openDialog(); } /** * Shows the {@link MediaRouteControllerDialogFragment} if it's not shown yet. * @param sourceUrn the URN identifying the media source of the current media route. * @param mediaRouteId the identifier of the route to be controlled. */ @CalledByNative public void openRouteControllerDialog(String sourceUrn, String mediaRouteId) { if (isShowingDialog()) return; MediaSource source = MediaSource.from(sourceUrn); if (source == null) return; mDialogManager = new MediaRouteControllerDialogManager( source, mediaRouteId, mApplicationContext, this); mDialogManager.openDialog(); } /** * Closes the currently open dialog if it's open. */ @CalledByNative public void closeDialog() { if (!isShowingDialog()) return; mDialogManager.closeDialog(); mDialogManager = null; } /** * @return if any media route dialog is currently open. */ @CalledByNative public boolean isShowingDialog() { return mDialogManager != null && mDialogManager.isShowingDialog(); } @Override public void onSinkSelected(MediaSink sink) { mDialogManager = null; nativeOnSinkSelected(mNativeDialogController, sink.getId()); } @Override public void onRouteClosed(String mediaRouteId) { mDialogManager = null; nativeOnRouteClosed(mNativeDialogController, mediaRouteId); } @Override public void onDialogCancelled() { // For MediaRouteControllerDialog this method will be called in case the route is closed // since it only call onDismiss() and there's no way to distinguish between the two. // Here we can figure it out: if mDialogManager is null, onRouteClosed() was called and // there's no need to tell the native controller the dialog has been cancelled. if (mDialogManager == null) return; mDialogManager = null; nativeOnDialogCancelled(mNativeDialogController); } private ChromeMediaRouterDialogController(long nativeDialogController, Context context) { mNativeDialogController = nativeDialogController; mApplicationContext = context; } native void nativeOnDialogCancelled(long nativeMediaRouterDialogControllerAndroid); native void nativeOnSinkSelected( long nativeMediaRouterDialogControllerAndroid, String sinkId); native void nativeOnRouteClosed(long nativeMediaRouterDialogControllerAndroid, String routeId); }