aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml3
-rw-r--r--src/github/daneren2005/dsub/fragments/DownloadFragment.java8
-rw-r--r--src/github/daneren2005/dsub/service/ChromeCastController.java70
-rw-r--r--src/github/daneren2005/dsub/service/DownloadService.java7
-rw-r--r--src/github/daneren2005/dsub/service/DownloadServiceImpl.java38
-rw-r--r--src/github/daneren2005/dsub/util/MediaRouteManager.java91
-rw-r--r--src/github/daneren2005/dsub/util/compat/CastCompat.java52
7 files changed, 252 insertions, 17 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f1eab09d..51de852a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -201,6 +201,9 @@
<meta-data android:name="com.google.android.backup.api_key"
android:value="AEdPqrEAAAAIUhOMtwa_eG-f0oYUHnetl_Cz7cO9zae8ZXOK5w"/>
+ <meta-data
+ android:name="com.google.android.gms.version"
+ android:value="@integer/google_play_services_version" />
</application>
</manifest>
diff --git a/src/github/daneren2005/dsub/fragments/DownloadFragment.java b/src/github/daneren2005/dsub/fragments/DownloadFragment.java
index c5be820c..d3c1938e 100644
--- a/src/github/daneren2005/dsub/fragments/DownloadFragment.java
+++ b/src/github/daneren2005/dsub/fragments/DownloadFragment.java
@@ -505,7 +505,7 @@ public class DownloadFragment extends SubsonicFragment implements OnGestureListe
if(downloadService != null) {
MenuItem mediaRouteItem = menu.findItem(R.id.menu_mediaroute);
MediaRouteButton mediaRouteButton = (MediaRouteButton) mediaRouteItem.getActionView();
- mediaRouteButton.setRouteSelector(downloadService.getRemotesAvailable());
+ mediaRouteButton.setRouteSelector(downloadService.getRemoteSelector());
}
}
@@ -749,6 +749,9 @@ public class DownloadFragment extends SubsonicFragment implements OnGestureListe
if(currentPlaying == null && downloadService != null && currentPlaying == downloadService.getCurrentPlaying()) {
getImageLoader().loadImage(albumArtImageView, null, true, false);
}
+ if(downloadService != null) {
+ downloadService.startRemoteScan();
+ }
}
@Override
@@ -758,6 +761,9 @@ public class DownloadFragment extends SubsonicFragment implements OnGestureListe
if (visualizerView != null && visualizerView.isActive()) {
visualizerView.setActive(false);
}
+ if(getDownloadService() != null) {
+ getDownloadService().startRemoteScan();
+ }
}
@Override
diff --git a/src/github/daneren2005/dsub/service/ChromeCastController.java b/src/github/daneren2005/dsub/service/ChromeCastController.java
new file mode 100644
index 00000000..467e4d7b
--- /dev/null
+++ b/src/github/daneren2005/dsub/service/ChromeCastController.java
@@ -0,0 +1,70 @@
+/*
+ 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.service;
+
+import android.os.Handler;
+
+/**
+ * Created by owner on 2/9/14.
+ */
+public class ChromeCastController extends RemoteController {
+ private CastDevice castDevice;
+
+ public ChromeCastController(DownloadServiceImpl downloadService, CastDevice castDevice) {
+ this.downloadService = downloadService;
+ this.castDevice = castDevice;
+ }
+
+ @Override
+ public void start() {
+
+ }
+
+ @Override
+ public void stop() {
+
+ }
+
+ @Override
+ public void shutdown() {
+
+ }
+
+ @Override
+ public void updatePlaylist() {
+
+ }
+
+ @Override
+ public void changePosition(int seconds) {
+
+ }
+
+ @Override
+ public void changeTrack(int index, DownloadFile song) {
+
+ }
+
+ @Override
+ public void setVolume(boolean up) {
+
+ }
+
+ @Override
+ public int getRemotePosition() {
+ return 0;
+ }
+}
diff --git a/src/github/daneren2005/dsub/service/DownloadService.java b/src/github/daneren2005/dsub/service/DownloadService.java
index 1a96b2be..471b6d5d 100644
--- a/src/github/daneren2005/dsub/service/DownloadService.java
+++ b/src/github/daneren2005/dsub/service/DownloadService.java
@@ -29,6 +29,7 @@ import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.domain.PlayerState;
import github.daneren2005.dsub.domain.RemoteControlState;
import github.daneren2005.dsub.domain.RepeatMode;
+import github.daneren2005.dsub.util.MediaRouteManager;
/**
* @author Sindre Mehus
@@ -126,13 +127,17 @@ public interface DownloadService {
VisualizerController getVisualizerController();
- MediaRouteSelector getRemotesAvailable();
+ MediaRouteSelector getRemoteSelector();
boolean isRemoteEnabled();
void setRemoteEnabled(RemoteControlState newState);
void setRemoteVolume(boolean up);
+
+ void startRemoteScan();
+
+ void stopRemoteScan();
void setSleepTimerDuration(int duration);
diff --git a/src/github/daneren2005/dsub/service/DownloadServiceImpl.java b/src/github/daneren2005/dsub/service/DownloadServiceImpl.java
index ad2f0490..9a85bcdd 100644
--- a/src/github/daneren2005/dsub/service/DownloadServiceImpl.java
+++ b/src/github/daneren2005/dsub/service/DownloadServiceImpl.java
@@ -34,10 +34,10 @@ import github.daneren2005.dsub.domain.PlayerState;
import github.daneren2005.dsub.domain.PodcastEpisode;
import github.daneren2005.dsub.domain.RemoteControlState;
import github.daneren2005.dsub.domain.RepeatMode;
-import github.daneren2005.dsub.provider.JukeboxRouteProvider;
import github.daneren2005.dsub.receiver.MediaButtonIntentReceiver;
import github.daneren2005.dsub.util.CancellableTask;
import github.daneren2005.dsub.util.Constants;
+import github.daneren2005.dsub.util.MediaRouteManager;
import github.daneren2005.dsub.util.ShufflePlayBuffer;
import github.daneren2005.dsub.util.SimpleServiceBinder;
import github.daneren2005.dsub.util.Util;
@@ -64,9 +64,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
-import android.support.v7.media.MediaControlIntent;
import android.support.v7.media.MediaRouteSelector;
-import android.support.v7.media.MediaRouter;
import android.util.Log;
import android.support.v4.util.LruCache;
import java.net.URLEncoder;
@@ -140,7 +138,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
private int timerDuration;
private boolean autoPlayStart = false;
- private MediaRouteSelector remoteSelector;
+ private MediaRouteManager mediaRouter;
static {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
@@ -217,13 +215,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
showVisualization = true;
}
- MediaRouter mediaRouter = MediaRouter.getInstance(this);
- JukeboxRouteProvider routeProvider = new JukeboxRouteProvider(this);
- mediaRouter.addProvider(routeProvider);
-
- MediaRouteSelector.Builder builder = new MediaRouteSelector.Builder();
- builder.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
- remoteSelector = builder.build();
+ mediaRouter = new MediaRouteManager(this);
}
@Override
@@ -1132,8 +1124,8 @@ public class DownloadServiceImpl extends Service implements DownloadService {
}
@Override
- public MediaRouteSelector getRemotesAvailable() {
- return remoteSelector;
+ public MediaRouteSelector getRemoteSelector() {
+ return mediaRouter.getSelector();
}
@Override
@@ -1143,13 +1135,16 @@ public class DownloadServiceImpl extends Service implements DownloadService {
@Override
public void setRemoteEnabled(RemoteControlState newState) {
- setRemoteState(newState);
+ setRemoteEnabled(newState, null);
+ }
+ public void setRemoteEnabled(RemoteControlState newState, Object ref) {
+ setRemoteState(newState, ref);
SharedPreferences.Editor editor = Util.getPreferences(this).edit();
editor.putInt(Constants.PREFERENCES_KEY_CONTROL_MODE, newState.getValue());
editor.commit();
}
- private void setRemoteState(RemoteControlState newState) {
+ private void setRemoteState(RemoteControlState newState, Object ref) {
if(remoteController != null) {
remoteController.stop();
setPlayerState(PlayerState.IDLE);
@@ -1162,6 +1157,9 @@ public class DownloadServiceImpl extends Service implements DownloadService {
case JUKEBOX_SERVER:
remoteController = new JukeboxController(this, handler);
break;
+ case CHROMECAST:
+ remoteController = (RemoteController) ref;
+ break;
case LOCAL: default:
break;
}
@@ -1188,6 +1186,16 @@ public class DownloadServiceImpl extends Service implements DownloadService {
remoteController.setVolume(up);
}
+ @Override
+ public void startRemoteScan() {
+ mediaRouter.startScan();
+ }
+
+ @Override
+ public void stopRemoteScan() {
+ mediaRouter.stopScan();
+ }
+
private synchronized void bufferAndPlay() {
bufferAndPlay(0);
}
diff --git a/src/github/daneren2005/dsub/util/MediaRouteManager.java b/src/github/daneren2005/dsub/util/MediaRouteManager.java
new file mode 100644
index 00000000..ab6d6a10
--- /dev/null
+++ b/src/github/daneren2005/dsub/util/MediaRouteManager.java
@@ -0,0 +1,91 @@
+/*
+ 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.support.v7.media.MediaControlIntent;
+import android.support.v7.media.MediaRouteSelector;
+import android.support.v7.media.MediaRouter;
+
+import github.daneren2005.dsub.domain.RemoteControlState;
+import github.daneren2005.dsub.provider.JukeboxRouteProvider;
+import github.daneren2005.dsub.service.DownloadServiceImpl;
+import github.daneren2005.dsub.service.RemoteController;
+import github.daneren2005.dsub.util.compat.CastCompat;
+
+/**
+ * Created by owner on 2/8/14.
+ */
+public class MediaRouteManager extends MediaRouter.Callback {
+ private static boolean castAvailable = false;
+
+ private DownloadServiceImpl downloadService;
+ private MediaRouter router;
+ private MediaRouteSelector selector;
+
+ static {
+ try {
+ CastCompat.checkAvailable();
+ castAvailable = true;
+ } catch(Throwable t) {
+ castAvailable = false;
+ }
+ }
+
+ public MediaRouteManager(DownloadServiceImpl downloadService) {
+ this.downloadService = downloadService;
+ router = MediaRouter.getInstance(downloadService);
+ addProviders();
+ buildSelector();
+ }
+
+ @Override
+ public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) {
+ if(castAvailable) {
+ RemoteController controller = CastCompat.getController(downloadService, info);
+ if(controller != null) {
+ downloadService.setRemoteEnabled(RemoteControlState.CHROMECAST, controller);
+ }
+ }
+ }
+ @Override
+ public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) {
+ downloadService.setRemoteEnabled(RemoteControlState.LOCAL);
+ }
+
+ public void startScan() {
+ router.addCallback(selector, this, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
+ }
+ public void stopScan() {
+ router.removeCallback(this);
+ }
+
+ public MediaRouteSelector getSelector() {
+ return selector;
+ }
+
+ private void addProviders() {
+ JukeboxRouteProvider routeProvider = new JukeboxRouteProvider(downloadService);
+ router.addProvider(routeProvider);
+ }
+ private void buildSelector() {
+ MediaRouteSelector.Builder builder = new MediaRouteSelector.Builder();
+ builder.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
+ if(castAvailable) {
+ builder.addControlCategory(CastCompat.getCastControlCategory());
+ }
+ selector = builder.build();
+ }
+}
diff --git a/src/github/daneren2005/dsub/util/compat/CastCompat.java b/src/github/daneren2005/dsub/util/compat/CastCompat.java
new file mode 100644
index 00000000..0892040e
--- /dev/null
+++ b/src/github/daneren2005/dsub/util/compat/CastCompat.java
@@ -0,0 +1,52 @@
+/*
+ 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.compat;
+
+import android.support.v7.media.MediaRouter;
+
+import github.daneren2005.dsub.service.ChromeCastController;
+import github.daneren2005.dsub.service.DownloadServiceImpl;
+import github.daneren2005.dsub.service.RemoteController;
+
+/**
+ * Created by owner on 2/9/14.
+ */
+public final class CastCompat {
+ static {
+ try {
+ Class.forName("com.google.android.gms.cast.CastDevice");
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public static void checkAvailable() throws Throwable {
+ // Calling here forces class initialization.
+ }
+
+ public static RemoteController getController(DownloadServiceImpl downloadService, MediaRouter.RouteInfo info) {
+ CastDevice device = CastDevice.getFromBundle(info.getExtras());
+ if(device != null) {
+ return new ChromeCastController(downloadService, device);
+ } else {
+ return null;
+ }
+ }
+
+ public static String getCastControlCategory() {
+ return CastMediaControlIntent.categoryForCast("5F85EBEB");
+ }
+}