Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent destruction of session, so that an app restart can reconnect (chromecast). #1469

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ android {
signingConfig = releaseSigningConfig
}
getByName("debug") {
isMinifyEnabled = false
isShrinkResources = false
applicationIdSuffix = ".debug"
isDebuggable = true
aaptOptions.cruncherEnabled = false
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/assets/native/chrome.cast.js
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ var _session;
*/
chrome.cast.initialize = function (apiConfig, successCallback, errorCallback) {
execute('initialize', apiConfig.sessionRequest.appId, apiConfig.autoJoinPolicy, apiConfig.defaultActionPolicy, function (err) {
console.log('initializing app for config:', JSON.stringify(apiConfig));
if (!err) {
// Don't set the listeners config until success
_initialized = true;
Expand All @@ -553,6 +554,7 @@ chrome.cast.initialize = function (apiConfig, successCallback, errorCallback) {
*/
chrome.cast.requestSession = function (successCallback, errorCallback, opt_sessionRequest) {
execute('requestSession', function (err, obj) {
console.log('requestSession', JSON.stringify(opt_sessionRequest));
if (!err) {
successCallback(createNewSession(obj));
} else {
Expand Down Expand Up @@ -594,16 +596,19 @@ chrome.cast.Session = function Session (sessionId, appId, displayName, appImages
this.receiver = receiver;
this.media = [];
this.status = chrome.cast.SessionStatus.CONNECTED;
console.log('new session', this.sessionId, this.appId, this.displayName, this.appImages, this.receiver);
};

chrome.cast.Session.prototype = Object.create(EventEmitter.prototype);

function sessionPreCheck (sessionId) {
if (!_session || _session.status !== chrome.cast.SessionStatus.CONNECTED) {
console.error('No active session');
return new chrome.cast.Error(
chrome.cast.ErrorCode.INVALID_PARAMETER, 'No active session');
}
if (sessionId !== _session.sessionId) {
console.error('Unknown session ID', sessionId, _session.sessionId);
return new chrome.cast.Error(
chrome.cast.ErrorCode.INVALID_PARAMETER, 'Unknown session ID');
}
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/org/jellyfin/mobile/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ class MainActivity : AppCompatActivity() {
fragment.onUserLeaveHint()
}
}
super.onUserLeaveHint()
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was added due to the linter/editor complaining it should not have been left out.

}

override fun onStop() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public final class Chromecast implements IChromecast {
/**
* Object to control the media.
*/
private ChromecastSession media;
private ChromecastSession chromecastSession;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed the variable name to be more "descriptive" as to what this variable actually was. For the longest time I got a little confused and thought this was the actual media, not the session.

/**
* Holds the reference to the current client initiated scan.
*/
Expand All @@ -53,7 +53,7 @@ public final class Chromecast implements IChromecast {

public void initializePlugin(Activity activity) {
try {
this.connection = new ChromecastConnection(activity, new ChromecastConnection.Listener() {
connection = new ChromecastConnection(activity, new ChromecastConnection.Listener() {
@Override
public void onSessionRejoin(JSONObject jsonSession) {
sendEvent("SESSION_LISTENER", new JSONArray().put(jsonSession));
Expand Down Expand Up @@ -93,7 +93,7 @@ public void onMessageReceived(CastDevice device, String namespace, String messag
sendEvent("RECEIVER_MESSAGE", new JSONArray().put(namespace).put(message));
}
});
this.media = connection.getChromecastSession();
chromecastSession = connection.getChromecastSession();
} catch (RuntimeException e) {
noChromecastError = "Could not initialize chromecast: " + e.getMessage();
e.printStackTrace();
Expand Down Expand Up @@ -153,13 +153,7 @@ public boolean execute(String action, JSONArray args, JavascriptCallback cbConte
} else {
return false;
}
} catch (IllegalAccessException e) {
e.printStackTrace();
return false;
} catch (IllegalArgumentException e) {
e.printStackTrace();
return false;
} catch (InvocationTargetException e) {
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
return false;
}
Expand All @@ -173,7 +167,7 @@ public boolean execute(String action, JSONArray args, JavascriptCallback cbConte
* @return true for cordova
*/
public boolean setup(JavascriptCallback javascriptCallback) {
this.eventCallback = javascriptCallback;
eventCallback = javascriptCallback;
// Ensure any existing scan is stopped
if (connection == null) return false;
connection.stopRouteScan(clientScan, () -> {
Expand Down Expand Up @@ -275,7 +269,7 @@ public boolean setReceiverVolumeLevel(Integer newLevel, JavascriptCallback javas
* @return true for cordova
*/
public boolean setReceiverVolumeLevel(Double newLevel, JavascriptCallback javascriptCallback) {
this.media.setVolume(newLevel, javascriptCallback);
chromecastSession.setVolume(newLevel, javascriptCallback);
return true;
}

Expand All @@ -287,7 +281,7 @@ public boolean setReceiverVolumeLevel(Double newLevel, JavascriptCallback javasc
* @return true for cordova
*/
public boolean setReceiverMuted(Boolean muted, JavascriptCallback javascriptCallback) {
this.media.setMute(muted, javascriptCallback);
chromecastSession.setMute(muted, javascriptCallback);
return true;
}

Expand All @@ -300,7 +294,7 @@ public boolean setReceiverMuted(Boolean muted, JavascriptCallback javascriptCall
* @return true for cordova
*/
public boolean sendMessage(String namespace, String message, final JavascriptCallback javascriptCallback) {
this.media.sendMessage(namespace, message, javascriptCallback);
chromecastSession.sendMessage(namespace, message, javascriptCallback);
return true;
}

Expand All @@ -312,7 +306,7 @@ public boolean sendMessage(String namespace, String message, final JavascriptCal
* @return true for cordova
*/
public boolean addMessageListener(String namespace, JavascriptCallback javascriptCallback) {
this.media.addMessageListener(namespace);
chromecastSession.addMessageListener(namespace);
javascriptCallback.success();
return true;
}
Expand All @@ -337,7 +331,7 @@ public boolean loadMedia(String contentId, JSONObject customData, String content
}

private boolean loadMedia(String contentId, JSONObject customData, String contentType, Integer duration, String streamType, Boolean autoPlay, Double currentTime, JSONObject metadata, JSONObject textTrackStyle, final JavascriptCallback javascriptCallback) {
this.media.loadMedia(contentId, customData, contentType, duration, streamType, autoPlay, currentTime, metadata, textTrackStyle, javascriptCallback);
chromecastSession.loadMedia(contentId, customData, contentType, duration, streamType, autoPlay, currentTime, metadata, textTrackStyle, javascriptCallback);
return true;
}

Expand All @@ -348,7 +342,7 @@ private boolean loadMedia(String contentId, JSONObject customData, String conten
* @return true for cordova
*/
public boolean mediaPlay(JavascriptCallback javascriptCallback) {
media.mediaPlay(javascriptCallback);
chromecastSession.mediaPlay(javascriptCallback);
return true;
}

Expand All @@ -359,7 +353,7 @@ public boolean mediaPlay(JavascriptCallback javascriptCallback) {
* @return true for cordova
*/
public boolean mediaPause(JavascriptCallback javascriptCallback) {
media.mediaPause(javascriptCallback);
chromecastSession.mediaPause(javascriptCallback);
return true;
}

Expand All @@ -372,7 +366,7 @@ public boolean mediaPause(JavascriptCallback javascriptCallback) {
* @return true for cordova
*/
public boolean mediaSeek(Integer seekTime, String resumeState, JavascriptCallback javascriptCallback) {
media.mediaSeek(seekTime.longValue() * 1000, resumeState, javascriptCallback);
chromecastSession.mediaSeek(seekTime.longValue() * 1000, resumeState, javascriptCallback);
return true;
}

Expand All @@ -398,7 +392,7 @@ public boolean setMediaVolume(Integer level, Boolean muted, JavascriptCallback j
* @return true for cordova
*/
public boolean setMediaVolume(Double level, Boolean muted, JavascriptCallback javascriptCallback) {
media.mediaSetVolume(level, muted, javascriptCallback);
chromecastSession.mediaSetVolume(level, muted, javascriptCallback);
return true;
}

Expand All @@ -409,7 +403,7 @@ public boolean setMediaVolume(Double level, Boolean muted, JavascriptCallback ja
* @return true for cordova
*/
public boolean mediaStop(JavascriptCallback javascriptCallback) {
media.mediaStop(javascriptCallback);
chromecastSession.mediaStop(javascriptCallback);
return true;
}

Expand All @@ -432,7 +426,7 @@ public boolean mediaEditTracksInfo(JSONArray activeTrackIds, JSONObject textTrac
Timber.tag(TAG).e("Wrong format in activeTrackIds");
}

this.media.mediaEditTracksInfo(trackIds, textTrackStyle, javascriptCallback);
chromecastSession.mediaEditTracksInfo(trackIds, textTrackStyle, javascriptCallback);
return true;
}

Expand All @@ -444,7 +438,7 @@ public boolean mediaEditTracksInfo(JSONArray activeTrackIds, JSONObject textTrac
* @return true for cordova
*/
public boolean queueLoad(JSONObject queueLoadRequest, final JavascriptCallback javascriptCallback) {
this.media.queueLoad(queueLoadRequest, javascriptCallback);
chromecastSession.queueLoad(queueLoadRequest, javascriptCallback);
return true;
}

Expand All @@ -456,7 +450,7 @@ public boolean queueLoad(JSONObject queueLoadRequest, final JavascriptCallback j
* @return true for cordova
*/
public boolean queueJumpToItem(Integer itemId, final JavascriptCallback javascriptCallback) {
this.media.queueJumpToItem(itemId, javascriptCallback);
chromecastSession.queueJumpToItem(itemId, javascriptCallback);
return true;
}

Expand Down Expand Up @@ -578,11 +572,13 @@ protected void callback(boolean keep, @Nullable String err, @Nullable String res
};

stopRouteScan(callback);
sessionStop(callback);
if (media != null) {
media.destroy();
// Default behavior for youtube-like apps is to leave the session running if the app is closed.
// This, at least, allows the user to close the app and re-open without stopping media when trying to fix things.
sessionLeave(callback);
if (chromecastSession != null) {
chromecastSession.destroy();
}
media = null;
chromecastSession = null;
if (connection != null) {
connection.destroy();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class ChromecastConnection {
/**
* Controls the media.
*/
private final ChromecastSession media;
private final ChromecastSession chromecastSession;

/**
* Lifetime variable.
Expand Down Expand Up @@ -81,7 +81,7 @@ public class ChromecastConnection {
settings = activity.getSharedPreferences("CORDOVA-PLUGIN-CHROMECAST_ChromecastConnection", 0);
appId = settings.getString("appId", CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID);
listener = connectionListener;
media = new ChromecastSession(activity, listener);
chromecastSession = new ChromecastSession(activity, listener);

// Set the initial appId
CastOptionsProvider.setAppId(appId);
Expand All @@ -98,7 +98,7 @@ public class ChromecastConnection {
* @return the ChromecastSession object
*/
ChromecastSession getChromecastSession() {
return media;
return chromecastSession;
}

/**
Expand Down Expand Up @@ -142,7 +142,7 @@ void onRouteUpdate(List<RouteInfo> routes) {
// If we do have a session
if (session != null) {
// Let the client know
media.setSession(session);
chromecastSession.setSession(session);
listener.onSessionRejoin(ChromecastUtilities.createSessionObject(session));
}
}
Expand Down Expand Up @@ -170,8 +170,8 @@ private CastSession getSession() {
}

private void setAppId(String applicationId) {
this.appId = applicationId;
this.settings.edit().putString("appId", appId).apply();
appId = applicationId;
settings.edit().putString("appId", appId).apply();
getContext().setReceiverApplicationId(appId);
}

Expand Down Expand Up @@ -386,7 +386,7 @@ private void listenForConnection(ConnectionCallback callback) {
@Override
public void onSessionStarted(@NonNull CastSession castSession, @NonNull String sessionId) {
getSessionManager().removeSessionManagerListener(this, CastSession.class);
media.setSession(castSession);
chromecastSession.setSession(castSession);
callback.onJoin(ChromecastUtilities.createSessionObject(castSession));
}

Expand Down Expand Up @@ -500,7 +500,7 @@ public void run() {
@Override
public void onSessionEnded(@NonNull CastSession castSession, int error) {
getSessionManager().removeSessionManagerListener(this, CastSession.class);
media.setSession(null);
chromecastSession.setSession(null);
if (callback != null) {
callback.success();
}
Expand Down Expand Up @@ -637,7 +637,7 @@ public abstract static class ScanCallback extends MediaRouter.Callback {
* @param router mediaRouter object
*/
void setMediaRouter(MediaRouter router) {
this.mediaRouter = router;
mediaRouter = router;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=512m
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=1G
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a beefier debugging machine, but we can reset this down if folks want. This helped speed up my build times quite a bit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be interesting for you. I'd prefer to keep the lower defaults in this repo.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely I'll remove these changes when I can get back on my computer.

# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[versions]
# Plugins

android-plugin = "8.5.0"
kotlin = "2.0.20"
kotlin-ksp = "2.0.20-1.0.24"
Expand Down