Skip to content

Commit

Permalink
Offer an API to force disconnect Chromecast
Browse files Browse the repository at this point in the history
Closes #523

Change-Id: I2a213855479dc23797468757808c05a368d907c6
  • Loading branch information
joeyparrish committed Oct 18, 2016
1 parent bdb5829 commit 5c4c8f4
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 7 deletions.
8 changes: 8 additions & 0 deletions externs/chromecast.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,14 @@ chrome.cast.Session.prototype.addMessageListener = function(
chrome.cast.Session.prototype.addUpdateListener = function(listener) {};


/**
* @param {Function} successCallback
* @param {Function} errorCallback
*/
chrome.cast.Session.prototype.leave = function(
successCallback, errorCallback) {};


/**
* @param {string} namespace
* @param {!Object|string} message
Expand Down
17 changes: 16 additions & 1 deletion lib/cast/cast_proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,16 @@ goog.inherits(shaka.cast.CastProxy, shaka.util.FakeEventTarget);
/**
* Destroys the proxy and the underlying local Player.
*
* @param {boolean=} opt_forceDisconnect If true, force the receiver app to shut
* down by disconnecting. Does nothing if not connected.
* @override
* @export
*/
shaka.cast.CastProxy.prototype.destroy = function() {
shaka.cast.CastProxy.prototype.destroy = function(opt_forceDisconnect) {
if (opt_forceDisconnect && this.sender_) {
this.sender_.forceDisconnect();
}

var async = [
this.eventManager_ ? this.eventManager_.destroy() : null,
this.localPlayer_ ? this.localPlayer_.destroy() : null,
Expand Down Expand Up @@ -207,6 +213,15 @@ shaka.cast.CastProxy.prototype.suggestDisconnect = function() {
};


/**
* Force the receiver app to shut down by disconnecting.
* @export
*/
shaka.cast.CastProxy.prototype.forceDisconnect = function() {
this.sender_.forceDisconnect();
};


/**
* Initialize the Proxies and the Cast sender.
* @private
Expand Down
20 changes: 18 additions & 2 deletions lib/cast/cast_sender.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ shaka.cast.CastSender =
shaka.cast.CastSender.prototype.destroy = function() {
this.rejectAllPromises_();
if (this.session_) {
this.session_.stop(function() {}, function() {});
this.session_.leave(function() {}, function() {});
this.session_ = null;
}

Expand All @@ -109,7 +109,6 @@ shaka.cast.CastSender.prototype.destroy = function() {
this.hasReceivers_ = false;
this.isCasting_ = false;
this.appData_ = null;
this.session_ = null;
this.cachedProperties_ = null;
this.asyncCallPromises_ = null;
this.castPromise_ = null;
Expand Down Expand Up @@ -256,6 +255,23 @@ shaka.cast.CastSender.prototype.showDisconnectDialog = function() {
};


/**
* Forces the receiver app to shut down by disconnecting. Does nothing if not
* connected.
*/
shaka.cast.CastSender.prototype.forceDisconnect = function() {
if (!this.isCasting_) {
return;
}

this.rejectAllPromises_();
if (this.session_) {
this.session_.stop(function() {}, function() {});
this.session_ = null;
}
};


/**
* Getter for properties of remote objects.
* @param {string} targetName
Expand Down
13 changes: 13 additions & 0 deletions test/cast/cast_proxy_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -630,11 +630,23 @@ describe('CastProxy', function() {
it('destroys the local player and the sender', function(done) {
expect(mockPlayer.destroy).not.toHaveBeenCalled();
expect(mockSender.destroy).not.toHaveBeenCalled();
expect(mockSender.forceDisconnect).not.toHaveBeenCalled();

proxy.destroy().catch(fail).then(done);

expect(mockPlayer.destroy).toHaveBeenCalled();
expect(mockSender.destroy).toHaveBeenCalled();
expect(mockSender.forceDisconnect).not.toHaveBeenCalled();
});

it('optionally forces the sender to disconnect', function(done) {
expect(mockSender.destroy).not.toHaveBeenCalled();
expect(mockSender.forceDisconnect).not.toHaveBeenCalled();

proxy.destroy(true).catch(fail).then(done);

expect(mockSender.destroy).toHaveBeenCalled();
expect(mockSender.forceDisconnect).toHaveBeenCalled();
});
});

Expand All @@ -658,6 +670,7 @@ describe('CastProxy', function() {
receiverName: jasmine.createSpy('receiverName'),
hasRemoteProperties: jasmine.createSpy('hasRemoteProperties'),
setAppData: jasmine.createSpy('setAppData'),
forceDisconnect: jasmine.createSpy('forceDisconnect'),
showDisconnectDialog: jasmine.createSpy('showDisconnectDialog'),
cast: jasmine.createSpy('cast'),
get: jasmine.createSpy('get'),
Expand Down
54 changes: 50 additions & 4 deletions test/cast/cast_sender_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,16 +317,24 @@ describe('CastSender', function() {
});
});

describe('disconnect', function() {
it('stops the session if we are casting', function(done) {
describe('showDisconnectDialog', function() {
it('opens the dialog if we are casting', function(done) {
sender.init();
fakeReceiverAvailability(true);
sender.cast(fakeInitState).then(function() {
expect(sender.isCasting()).toBe(true);
expect(mockSession.leave).not.toHaveBeenCalled();
expect(mockSession.stop).not.toHaveBeenCalled();
mockCastApi.requestSession.calls.reset();

sender.showDisconnectDialog();

// this call opens the dialog:
expect(mockCastApi.requestSession).toHaveBeenCalled();
// these were not used:
expect(mockSession.leave).not.toHaveBeenCalled();
expect(mockSession.stop).not.toHaveBeenCalled();

fakeRemoteDisconnect();
}).catch(fail).then(done);
fakeSessionConnection();
Expand Down Expand Up @@ -562,12 +570,13 @@ describe('CastSender', function() {
});
});

describe('destroy', function() {
describe('forceDisconnect', function() {
it('disconnects and cancels all async operations', function(done) {
sender.init();
fakeReceiverAvailability(true);
sender.cast(fakeInitState).then(function() {
expect(sender.isCasting()).toBe(true);
expect(mockSession.leave).not.toHaveBeenCalled();
expect(mockSession.stop).not.toHaveBeenCalled();

var method = sender.get('player', 'load');
Expand All @@ -577,7 +586,8 @@ describe('CastSender', function() {
// Wait a tick for the Promise status to be set.
return shaka.test.Util.delay(0.1).then(function() {
expect(p.status).toBe('pending');
sender.destroy().catch(fail);
sender.forceDisconnect();
expect(mockSession.leave).not.toHaveBeenCalled();
expect(mockSession.stop).toHaveBeenCalled();

// Wait a tick for the Promise status to change.
Expand All @@ -595,6 +605,41 @@ describe('CastSender', function() {
});
});

describe('destroy', function() {
it('leaves the session and cancels all async operations', function(done) {
sender.init();
fakeReceiverAvailability(true);
sender.cast(fakeInitState).then(function() {
expect(sender.isCasting()).toBe(true);
expect(mockSession.leave).not.toHaveBeenCalled();
expect(mockSession.stop).not.toHaveBeenCalled();

var method = sender.get('player', 'load');
var p = method();
shaka.test.Util.capturePromiseStatus(p);

// Wait a tick for the Promise status to be set.
return shaka.test.Util.delay(0.1).then(function() {
expect(p.status).toBe('pending');
sender.destroy().catch(fail);
expect(mockSession.leave).toHaveBeenCalled();
expect(mockSession.stop).not.toHaveBeenCalled();

// Wait a tick for the Promise status to change.
return shaka.test.Util.delay(0.1);
}).then(function() {
expect(p.status).toBe('rejected');
return p.catch(function(error) {
shaka.test.Util.expectToEqualError(error, new shaka.util.Error(
shaka.util.Error.Category.PLAYER,
shaka.util.Error.Code.LOAD_INTERRUPTED));
});
});
}).catch(fail).then(done);
fakeSessionConnection();
});
});

function createMockCastApi() {
return {
isAvailable: true,
Expand All @@ -612,6 +657,7 @@ describe('CastSender', function() {
receiver: { friendlyName: 'SomeDevice' },
addUpdateListener: jasmine.createSpy('Session.addUpdateListener'),
addMessageListener: jasmine.createSpy('Session.addMessageListener'),
leave: jasmine.createSpy('Session.leave'),
sendMessage: jasmine.createSpy('Session.sendMessage'),
stop: jasmine.createSpy('Session.stop')
};
Expand Down

0 comments on commit 5c4c8f4

Please sign in to comment.