/* * Copyright (C) 2015 Google Inc. All Rights Reserved. * * 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 com.google.android.libraries.cast.companionlibrary.cast; import static com.google.android.libraries.cast.companionlibrary.utils.LogUtils.LOGD; import com.google.android.gms.cast.CastDevice; import com.google.android.libraries.cast.companionlibrary.utils.LogUtils; import android.support.v7.media.MediaRouter; import android.support.v7.media.MediaRouter.RouteInfo; /** * Provides a handy implementation of {@link MediaRouter.Callback}. When a {@link RouteInfo} is * selected by user from the list of available routes, this class will call the * {@link BaseCastManager#setDevice(CastDevice))} of the listener that was passed to it in * the constructor. In addition, as soon as a non-default route is discovered, the * {@link BaseCastManager#onCastDeviceDetected(RouteInfo))} is called. * <p> * There is also some logic in this class to help with the process of previous session recovery. */ public class CastMediaRouterCallback extends MediaRouter.Callback { private static final String TAG = LogUtils.makeLogTag(CastMediaRouterCallback.class); private final BaseCastManager mCastManager; private boolean mRouteAvailable = false; public CastMediaRouterCallback(BaseCastManager castManager) { mCastManager = castManager; } @Override public void onRouteSelected(MediaRouter router, RouteInfo info) { LOGD(TAG, "onRouteSelected: info=" + info); if (mCastManager.getReconnectionStatus() == BaseCastManager.RECONNECTION_STATUS_FINALIZED) { mCastManager.setReconnectionStatus(BaseCastManager.RECONNECTION_STATUS_INACTIVE); mCastManager.cancelReconnectionTask(); return; } mCastManager.getPreferenceAccessor().saveStringToPreference( BaseCastManager.PREFS_KEY_ROUTE_ID, info.getId()); CastDevice device = CastDevice.getFromBundle(info.getExtras()); mCastManager.onDeviceSelected(device, info); LOGD(TAG, "onRouteSelected: mSelectedDevice=" + (device != null ? device.getFriendlyName() : "Null")); } @Override public void onRouteUnselected(MediaRouter router, RouteInfo routeInfo) { LOGD(TAG, "onRouteUnselected: route=" + routeInfo); mCastManager.onDeviceSelected(null, routeInfo); } @Override public void onRouteAdded(MediaRouter router, RouteInfo routeInfo) { if (!router.getDefaultRoute().equals(routeInfo)) { notifyRouteAvailabilityChangedIfNeeded(router); mCastManager.onCastDeviceDetected(routeInfo); } if (mCastManager.getReconnectionStatus() == BaseCastManager.RECONNECTION_STATUS_STARTED) { String routeId = mCastManager.getPreferenceAccessor().getStringFromPreference( BaseCastManager.PREFS_KEY_ROUTE_ID); if (routeInfo.getId().equals(routeId)) { // we found the route, so lets go with that LOGD(TAG, "onRouteAdded: Attempting to recover a session with info=" + routeInfo); mCastManager.setReconnectionStatus(BaseCastManager.RECONNECTION_STATUS_IN_PROGRESS); CastDevice device = CastDevice.getFromBundle(routeInfo.getExtras()); LOGD(TAG, "onRouteAdded: Attempting to recover a session with device: " + (device != null ? device.getFriendlyName() : "Null")); mCastManager.onDeviceSelected(device, routeInfo); } } } @Override public void onRouteRemoved(MediaRouter router, RouteInfo route) { notifyRouteAvailabilityChangedIfNeeded(router); mCastManager.onRouteRemoved(route); } @Override public void onRouteChanged(MediaRouter router, RouteInfo route) { notifyRouteAvailabilityChangedIfNeeded(router); } private void notifyRouteAvailabilityChangedIfNeeded(MediaRouter router) { boolean routeAvailable = isRouteAvailable(router); if (routeAvailable != mRouteAvailable) { // availability of routes have changed mRouteAvailable = routeAvailable; mCastManager.onCastAvailabilityChanged(mRouteAvailable); } } private boolean isRouteAvailable(MediaRouter router) { return router.isRouteAvailable(mCastManager.getMediaRouteSelector(), MediaRouter.AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE | MediaRouter.AVAILABILITY_FLAG_REQUIRE_MATCH); } /** * Returns {@code true} if and only if there is at least one route matching the * {@link BaseCastManager#getMediaRouteSelector()}. */ public boolean isRouteAvailable() { return mRouteAvailable; } }