/* This file is part of Subsonic. Subsonic is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Subsonic is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Subsonic. If not, see <http://www.gnu.org/licenses/>. Copyright 2014 (C) Scott Jackson */ package github.daneren2005.dsub.util; import android.os.Build; import android.support.v7.media.MediaRouteProvider; import android.support.v7.media.MediaRouteSelector; import android.support.v7.media.MediaRouter; import android.util.Log; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import java.util.ArrayList; import java.util.List; import github.daneren2005.dsub.domain.RemoteControlState; import github.daneren2005.dsub.provider.DLNARouteProvider; import github.daneren2005.dsub.provider.JukeboxRouteProvider; import github.daneren2005.dsub.service.DownloadService; import github.daneren2005.dsub.service.RemoteController; import github.daneren2005.dsub.util.compat.CastCompat; import static android.support.v7.media.MediaRouter.RouteInfo; /** * Created by owner on 2/8/14. */ public class MediaRouteManager extends MediaRouter.Callback { private static final String TAG = MediaRouteManager.class.getSimpleName(); private static boolean castAvailable = false; private DownloadService downloadService; private MediaRouter router; private MediaRouteSelector selector; private List<MediaRouteProvider> providers = new ArrayList<MediaRouteProvider>(); private List<MediaRouteProvider> onlineProviders = new ArrayList<MediaRouteProvider>(); private DLNARouteProvider dlnaProvider; static { try { CastCompat.checkAvailable(); castAvailable = true; } catch(Throwable t) { castAvailable = false; } } public MediaRouteManager(DownloadService downloadService) { this.downloadService = downloadService; router = MediaRouter.getInstance(downloadService); // Check if play services is available int result = GooglePlayServicesUtil.isGooglePlayServicesAvailable(downloadService); if(result != ConnectionResult.SUCCESS){ Log.w(TAG, "No play services, failed with result: " + result); castAvailable = false; } addProviders(); buildSelector(); } public void destroy() { for(MediaRouteProvider provider: providers) { router.removeProvider(provider); } } @Override public void onRouteSelected(MediaRouter router, RouteInfo info) { if(castAvailable) { RemoteController controller = CastCompat.getController(downloadService, info); if(controller != null) { downloadService.setRemoteEnabled(RemoteControlState.CHROMECAST, controller); } } if(downloadService.isRemoteEnabled()) { downloadService.registerRoute(router); } } @Override public void onRouteUnselected(MediaRouter router, RouteInfo info) { if(downloadService.isRemoteEnabled()) { downloadService.unregisterRoute(router); } downloadService.setRemoteEnabled(RemoteControlState.LOCAL); } public void setDefaultRoute() { router.selectRoute(router.getDefaultRoute()); } public void startScan() { router.addCallback(selector, this, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN); } public void stopScan() { router.removeCallback(this); } public MediaRouteSelector getSelector() { return selector; } public RouteInfo getSelectedRoute() { return router.getSelectedRoute(); } public RouteInfo getRouteForId(String id) { if(id == null) { return null; } // Try to find matching id for(RouteInfo info: router.getRoutes()) { if(id.equals(info.getId())) { router.selectRoute(info); return info; } } return null; } public RemoteController getRemoteController(RouteInfo info) { if(castAvailable) { return CastCompat.getController(downloadService, info); } else { return null; } } public void addOnlineProviders() { JukeboxRouteProvider jukeboxProvider = new JukeboxRouteProvider(downloadService); router.addProvider(jukeboxProvider); providers.add(jukeboxProvider); onlineProviders.add(jukeboxProvider); } public void removeOnlineProviders() { for(MediaRouteProvider provider: onlineProviders) { router.removeProvider(provider); } } private void addProviders() { if(!Util.isOffline(downloadService)) { addOnlineProviders(); } if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && Util.getPreferences(downloadService).getBoolean(Constants.PREFERENCES_KEY_DLNA_CASTING_ENABLED, true)) { addDLNAProvider(); } } public void buildSelector() { MediaRouteSelector.Builder builder = new MediaRouteSelector.Builder(); if(UserUtil.canJukebox()) { builder.addControlCategory(JukeboxRouteProvider.CATEGORY_JUKEBOX_ROUTE); } if(castAvailable) { builder.addControlCategory(CastCompat.getCastControlCategory()); } if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { builder.addControlCategory(DLNARouteProvider.CATEGORY_DLNA); } selector = builder.build(); } public void addDLNAProvider() { if(dlnaProvider == null) { dlnaProvider = new DLNARouteProvider(downloadService); router.addProvider(dlnaProvider); providers.add(dlnaProvider); } } public void removeDLNAProvider() { if(dlnaProvider != null) { router.removeProvider(dlnaProvider); providers.remove(dlnaProvider); dlnaProvider.destroy(); dlnaProvider = null; } } }