From 4bfbd4fed7801948679977e0dcb02973d941f315 Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Tue, 29 Sep 2015 23:18:41 -0400 Subject: [PATCH] Remove Google Play Services dependency This disables the ability to do Casting, though it supports DLNA/UPnP so who cares?... --- app/build.gradle | 1 - app/src/main/AndroidManifest.xml | 3 - .../dsub/service/ChromeCastController.java | 522 --------------------- .../daneren2005/dsub/util/MediaRouteManager.java | 10 +- .../daneren2005/dsub/util/compat/CastCompat.java | 13 +- 5 files changed, 3 insertions(+), 546 deletions(-) delete mode 100644 app/src/main/java/github/daneren2005/dsub/service/ChromeCastController.java diff --git a/app/build.gradle b/app/build.gradle index 98571c6..bf8b440 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -39,7 +39,6 @@ dependencies { compile 'com.android.support:mediarouter-v7:22.2.+' compile 'com.android.support:recyclerview-v7:22.2.+' compile 'com.android.support:design:22.2.+' - compile 'com.google.android.gms:play-services-cast:7.0.0' compile 'com.sothree.slidinguppanel:library:3.0.0' compile 'de.hdodenhof:circleimageview:1.2.1' compile group: 'org.fourthline.cling', name: 'cling-core', version:'2.0.1' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2c756a4..5fe096f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -238,9 +238,6 @@ - diff --git a/app/src/main/java/github/daneren2005/dsub/service/ChromeCastController.java b/app/src/main/java/github/daneren2005/dsub/service/ChromeCastController.java deleted file mode 100644 index a729ed4..0000000 --- a/app/src/main/java/github/daneren2005/dsub/service/ChromeCastController.java +++ /dev/null @@ -1,522 +0,0 @@ -/* - 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 . - Copyright 2014 (C) Scott Jackson -*/ - -package github.daneren2005.dsub.service; - -import android.content.SharedPreferences; -import android.net.Uri; -import android.os.Bundle; -import android.util.Log; - -import com.google.android.gms.cast.ApplicationMetadata; -import com.google.android.gms.cast.Cast; -import com.google.android.gms.cast.CastDevice; -import com.google.android.gms.cast.MediaInfo; -import com.google.android.gms.cast.MediaMetadata; -import com.google.android.gms.cast.MediaStatus; -import com.google.android.gms.cast.RemoteMediaPlayer; -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.api.GoogleApiClient; -import com.google.android.gms.common.api.ResultCallback; -import com.google.android.gms.common.api.Status; -import com.google.android.gms.common.images.WebImage; - -import java.io.File; -import java.io.IOException; - -import github.daneren2005.dsub.R; -import github.daneren2005.dsub.domain.MusicDirectory; -import github.daneren2005.dsub.domain.PlayerState; -import github.daneren2005.dsub.domain.RemoteControlState; -import github.daneren2005.dsub.util.Constants; -import github.daneren2005.dsub.util.FileUtil; -import github.daneren2005.dsub.util.Util; -import github.daneren2005.dsub.util.compat.CastCompat; -import github.daneren2005.serverproxy.FileProxy; -import github.daneren2005.serverproxy.ServerProxy; -import github.daneren2005.serverproxy.WebProxy; - -/** - * Created by owner on 2/9/14. - */ -public class ChromeCastController extends RemoteController { - private static final String TAG = ChromeCastController.class.getSimpleName(); - - private CastDevice castDevice; - private GoogleApiClient apiClient; - - private boolean applicationStarted = false; - private boolean waitingForReconnect = false; - private boolean error = false; - private boolean ignoreNextPaused = false; - private String sessionId; - - private ServerProxy proxy; - private String rootLocation; - private RemoteMediaPlayer mediaPlayer; - private double gain = 0.5; - - public ChromeCastController(DownloadService downloadService, CastDevice castDevice) { - this.downloadService = downloadService; - this.castDevice = castDevice; - - SharedPreferences prefs = Util.getPreferences(downloadService); - rootLocation = prefs.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null); - } - - @Override - public void create(boolean playing, int seconds) { - downloadService.setPlayerState(PlayerState.PREPARING); - - ConnectionCallbacks connectionCallbacks = new ConnectionCallbacks(playing, seconds); - ConnectionFailedListener connectionFailedListener = new ConnectionFailedListener(); - Cast.Listener castClientListener = new Cast.Listener() { - @Override - public void onApplicationStatusChanged() { - if (apiClient != null && apiClient.isConnected()) { - Log.i(TAG, "onApplicationStatusChanged: " + Cast.CastApi.getApplicationStatus(apiClient)); - } - } - - @Override - public void onVolumeChanged() { - if (apiClient != null && applicationStarted) { - try { - gain = Cast.CastApi.getVolume(apiClient); - } catch (Exception e) { - Log.w(TAG, "Failed to get volume"); - } - } - } - - @Override - public void onApplicationDisconnected(int errorCode) { - shutdownInternal(); - } - - }; - - Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions.builder(castDevice, castClientListener).setVerboseLoggingEnabled(true); - apiClient = new GoogleApiClient.Builder(downloadService).useDefaultAccount() - .addApi(Cast.API, apiOptionsBuilder.build()) - .addConnectionCallbacks(connectionCallbacks) - .addOnConnectionFailedListener(connectionFailedListener) - .build(); - - apiClient.connect(); - } - - @Override - public void start() { - if(error) { - error = false; - Log.w(TAG, "Attempting to restart song"); - startSong(downloadService.getCurrentPlaying(), true, 0); - return; - } - - try { - mediaPlayer.play(apiClient); - } catch(Exception e) { - Log.e(TAG, "Failed to start"); - } - } - - @Override - public void stop() { - try { - mediaPlayer.pause(apiClient); - } catch(Exception e) { - Log.e(TAG, "Failed to pause"); - } - } - - @Override - public void shutdown() { - try { - if(mediaPlayer != null && !error) { - mediaPlayer.stop(apiClient); - } - } catch(Exception e) { - Log.e(TAG, "Failed to stop mediaPlayer", e); - } - - try { - if(apiClient != null) { - Cast.CastApi.stopApplication(apiClient); - Cast.CastApi.removeMessageReceivedCallbacks(apiClient, mediaPlayer.getNamespace()); - mediaPlayer = null; - applicationStarted = false; - } - } catch(Exception e) { - Log.e(TAG, "Failed to shutdown application", e); - } - - if(apiClient != null && apiClient.isConnected()) { - apiClient.disconnect(); - } - apiClient = null; - - if(proxy != null) { - proxy.stop(); - proxy = null; - } - } - - private void shutdownInternal() { - // This will call this.shutdown() indirectly - downloadService.setRemoteEnabled(RemoteControlState.LOCAL, null); - } - - @Override - public void updatePlaylist() { - if(downloadService.getCurrentPlaying() == null) { - startSong(null, false, 0); - } - } - - @Override - public void changePosition(int seconds) { - try { - mediaPlayer.seek(apiClient, seconds * 1000L); - } catch(Exception e) { - Log.e(TAG, "FAiled to seek to " + seconds); - } - } - - @Override - public void changeTrack(int index, DownloadFile song) { - startSong(song, true, 0); - } - - @Override - public void setVolume(int volume) { - gain = volume / 10.0; - - try { - Cast.CastApi.setVolume(apiClient, gain); - } catch(Exception e) { - Log.e(TAG, "Failed to the volume"); - } - } - @Override - public void updateVolume(boolean up) { - double delta = up ? 0.1 : -0.1; - gain += delta; - gain = Math.max(gain, 0.0); - gain = Math.min(gain, 1.0); - - try { - Cast.CastApi.setVolume(apiClient, gain); - } catch(Exception e) { - Log.e(TAG, "Failed to the volume"); - } - } - @Override - public double getVolume() { - return Cast.CastApi.getVolume(apiClient); - } - - @Override - public int getRemotePosition() { - if(mediaPlayer != null) { - return (int) (mediaPlayer.getApproximateStreamPosition() / 1000L); - } else { - return 0; - } - } - - @Override - public int getRemoteDuration() { - if(mediaPlayer != null) { - return (int) (mediaPlayer.getStreamDuration() / 1000L); - } else { - return 0; - } - } - - void startSong(DownloadFile currentPlaying, boolean autoStart, int position) { - if(currentPlaying == null) { - try { - if (mediaPlayer != null && !error) { - mediaPlayer.stop(apiClient); - } - } catch(Exception e) { - // Just means it didn't need to be stopped - } - downloadService.setPlayerState(PlayerState.IDLE); - return; - } - downloadService.setPlayerState(PlayerState.PREPARING); - MusicDirectory.Entry song = currentPlaying.getSong(); - - try { - MusicService musicService = MusicServiceFactory.getMusicService(downloadService); - String url; - // Offline, use file proxy - if(Util.isOffline(downloadService) || song.getId().indexOf(rootLocation) != -1) { - if(proxy == null) { - proxy = new FileProxy(downloadService); - proxy.start(); - } - - // Offline song - if(song.getId().indexOf(rootLocation) != -1) { - url = proxy.getPublicAddress(song.getId()); - } else { - // Playing online song in offline mode - url = proxy.getPublicAddress(currentPlaying.getCompleteFile().getPath()); - } - } else { - // Check if we want a proxy going still - if(Util.isCastProxy(downloadService)) { - if(proxy instanceof FileProxy) { - proxy.stop(); - proxy = null; - } - - if(proxy == null) { - proxy = createWebProxy(); - proxy.start(); - } - } else if(proxy != null) { - proxy.stop(); - proxy = null; - } - - if(song.isVideo()) { - url = musicService.getHlsUrl(song.getId(), currentPlaying.getBitRate(), downloadService); - } else { - url = musicService.getMusicUrl(downloadService, song, currentPlaying.getBitRate()); - } - - // If proxy is going, it is a WebProxy - if(proxy != null) { - url = proxy.getPublicAddress(url); - } - } - - // Setup song/video information - MediaMetadata meta = new MediaMetadata(song.isVideo() ? MediaMetadata.MEDIA_TYPE_MOVIE : MediaMetadata.MEDIA_TYPE_MUSIC_TRACK); - meta.putString(MediaMetadata.KEY_TITLE, song.getTitle()); - if(song.getTrack() != null) { - meta.putInt(MediaMetadata.KEY_TRACK_NUMBER, song.getTrack()); - } - if(!song.isVideo()) { - meta.putString(MediaMetadata.KEY_ARTIST, song.getArtist()); - meta.putString(MediaMetadata.KEY_ALBUM_ARTIST, song.getArtist()); - meta.putString(MediaMetadata.KEY_ALBUM_TITLE, song.getAlbum()); - - String coverArt = ""; - if(proxy == null || proxy instanceof WebProxy) { - coverArt = musicService.getCoverArtUrl(downloadService, song); - - // If proxy is going, it is a web proxy - if(proxy != null) { - coverArt = proxy.getPublicAddress(coverArt); - } - - meta.addImage(new WebImage(Uri.parse(coverArt))); - } else { - File coverArtFile = FileUtil.getAlbumArtFile(downloadService, song); - if(coverArtFile != null && coverArtFile.exists()) { - coverArt = proxy.getPublicAddress(coverArtFile.getPath()); - meta.addImage(new WebImage(Uri.parse(coverArt))); - } - } - } - - String contentType; - if(song.isVideo()) { - contentType = "application/x-mpegURL"; - } - else if(song.getTranscodedContentType() != null) { - contentType = song.getTranscodedContentType(); - } else if(song.getContentType() != null) { - contentType = song.getContentType(); - } else { - contentType = "audio/mpeg"; - } - - // Load it into a MediaInfo wrapper - MediaInfo mediaInfo = new MediaInfo.Builder(url) - .setContentType(contentType) - .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) - .setMetadata(meta) - .build(); - - if(autoStart) { - ignoreNextPaused = true; - } - - mediaPlayer.load(apiClient, mediaInfo, autoStart, position * 1000L).setResultCallback(new ResultCallback() { - @Override - public void onResult(RemoteMediaPlayer.MediaChannelResult result) { - if (result.getStatus().isSuccess()) { - // Handled in other handler - } else { - Log.e(TAG, "Failed to load: " + result.getStatus().toString()); - failedLoad(); - } - } - }); - } catch (IllegalStateException e) { - Log.e(TAG, "Problem occurred with media during loading", e); - failedLoad(); - } catch (Exception e) { - Log.e(TAG, "Problem opening media during loading", e); - failedLoad(); - } - } - - private void failedLoad() { - Util.toast(downloadService, downloadService.getResources().getString(R.string.download_failed_to_load)); - downloadService.setPlayerState(PlayerState.STOPPED); - error = true; - } - - - private class ConnectionCallbacks implements GoogleApiClient.ConnectionCallbacks { - private boolean isPlaying; - private int position; - private ResultCallback resultCallback; - - ConnectionCallbacks(boolean isPlaying, int position) { - this.isPlaying = isPlaying; - this.position = position; - - resultCallback = new ResultCallback() { - @Override - public void onResult(Cast.ApplicationConnectionResult result) { - Status status = result.getStatus(); - if (status.isSuccess()) { - ApplicationMetadata applicationMetadata = result.getApplicationMetadata(); - sessionId = result.getSessionId(); - String applicationStatus = result.getApplicationStatus(); - boolean wasLaunched = result.getWasLaunched(); - - applicationStarted = true; - setupChannel(); - } else { - shutdownInternal(); - } - } - }; - } - - @Override - public void onConnected(Bundle connectionHint) { - if (waitingForReconnect) { - Log.i(TAG, "Reconnecting"); - reconnectApplication(); - } else { - launchApplication(); - } - } - - @Override - public void onConnectionSuspended(int cause) { - Log.w(TAG, "Connection suspended"); - isPlaying = downloadService.getPlayerState() == PlayerState.STARTED; - position = getRemotePosition(); - waitingForReconnect = true; - } - - void launchApplication() { - try { - Cast.CastApi.launchApplication(apiClient, CastCompat.APPLICATION_ID, false).setResultCallback(resultCallback); - } catch (Exception e) { - Log.e(TAG, "Failed to launch application", e); - } - } - void reconnectApplication() { - try { - Cast.CastApi.joinApplication(apiClient, CastCompat.APPLICATION_ID, sessionId).setResultCallback(resultCallback); - } catch (Exception e) { - Log.e(TAG, "Failed to reconnect application", e); - } - } - void setupChannel() { - if(!waitingForReconnect) { - mediaPlayer = new RemoteMediaPlayer(); - mediaPlayer.setOnStatusUpdatedListener(new RemoteMediaPlayer.OnStatusUpdatedListener() { - @Override - public void onStatusUpdated() { - MediaStatus mediaStatus = mediaPlayer.getMediaStatus(); - if (mediaStatus == null) { - return; - } - - switch (mediaStatus.getPlayerState()) { - case MediaStatus.PLAYER_STATE_PLAYING: - if (ignoreNextPaused) { - ignoreNextPaused = false; - } - downloadService.setPlayerState(PlayerState.STARTED); - break; - case MediaStatus.PLAYER_STATE_PAUSED: - if (!ignoreNextPaused) { - downloadService.setPlayerState(PlayerState.PAUSED); - } - break; - case MediaStatus.PLAYER_STATE_BUFFERING: - downloadService.setPlayerState(PlayerState.PREPARING); - break; - case MediaStatus.PLAYER_STATE_IDLE: - if (mediaStatus.getIdleReason() == MediaStatus.IDLE_REASON_FINISHED) { - downloadService.setPlayerState(PlayerState.COMPLETED); - downloadService.postPlayCleanup(); - downloadService.onSongCompleted(); - } else if (mediaStatus.getIdleReason() == MediaStatus.IDLE_REASON_INTERRUPTED) { - if (downloadService.getPlayerState() != PlayerState.PREPARING) { - downloadService.setPlayerState(PlayerState.PREPARING); - } - } else if (mediaStatus.getIdleReason() == MediaStatus.IDLE_REASON_ERROR) { - Log.e(TAG, "Idle due to unknown error"); - downloadService.setPlayerState(PlayerState.COMPLETED); - downloadService.next(); - } else { - Log.w(TAG, "Idle reason: " + mediaStatus.getIdleReason()); - downloadService.setPlayerState(PlayerState.IDLE); - } - break; - } - } - }); - } - - try { - Cast.CastApi.setMessageReceivedCallbacks(apiClient, mediaPlayer.getNamespace(), mediaPlayer); - } catch (IOException e) { - Log.e(TAG, "Exception while creating channel", e); - } - - if(!waitingForReconnect) { - DownloadFile currentPlaying = downloadService.getCurrentPlaying(); - startSong(currentPlaying, isPlaying, position); - } - if(waitingForReconnect) { - waitingForReconnect = false; - } - } - } - - private class ConnectionFailedListener implements GoogleApiClient.OnConnectionFailedListener { - @Override - public void onConnectionFailed(ConnectionResult result) { - shutdownInternal(); - } - } -} diff --git a/app/src/main/java/github/daneren2005/dsub/util/MediaRouteManager.java b/app/src/main/java/github/daneren2005/dsub/util/MediaRouteManager.java index 9aa54c4..e8ab87a 100644 --- a/app/src/main/java/github/daneren2005/dsub/util/MediaRouteManager.java +++ b/app/src/main/java/github/daneren2005/dsub/util/MediaRouteManager.java @@ -21,9 +21,6 @@ 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; @@ -62,12 +59,7 @@ public class MediaRouteManager extends MediaRouter.Callback { 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; - } + castAvailable = false; addProviders(); buildSelector(); diff --git a/app/src/main/java/github/daneren2005/dsub/util/compat/CastCompat.java b/app/src/main/java/github/daneren2005/dsub/util/compat/CastCompat.java index ab64bca..5dac82c 100644 --- a/app/src/main/java/github/daneren2005/dsub/util/compat/CastCompat.java +++ b/app/src/main/java/github/daneren2005/dsub/util/compat/CastCompat.java @@ -17,10 +17,6 @@ package github.daneren2005.dsub.util.compat; import android.support.v7.media.MediaRouter; -import com.google.android.gms.cast.CastDevice; -import com.google.android.gms.cast.CastMediaControlIntent; - -import github.daneren2005.dsub.service.ChromeCastController; import github.daneren2005.dsub.service.DownloadService; import github.daneren2005.dsub.service.RemoteController; @@ -43,15 +39,10 @@ public final class CastCompat { } public static RemoteController getController(DownloadService downloadService, MediaRouter.RouteInfo info) { - CastDevice device = CastDevice.getFromBundle(info.getExtras()); - if(device != null) { - return new ChromeCastController(downloadService, device); - } else { - return null; - } + return null; } public static String getCastControlCategory() { - return CastMediaControlIntent.categoryForCast(APPLICATION_ID); + return null; } } -- 1.9.2