Skip to content

Commit 22f99bc

Browse files
committed
CB-11757 (ios) Error out if trying to stop playback while in a wrong state
1 parent 0405a2e commit 22f99bc

File tree

3 files changed

+61
-9
lines changed

3 files changed

+61
-9
lines changed

src/ios/CDVSound.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#import <Cordova/CDVPlugin.h>
2323

2424
enum CDVMediaError {
25+
MEDIA_ERR_NONE_ACTIVE = 0,
2526
MEDIA_ERR_ABORTED = 1,
2627
MEDIA_ERR_NETWORK = 2,
2728
MEDIA_ERR_DECODE = 3,

src/ios/CDVSound.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,10 @@ - (void)stopPlayingAudio:(CDVInvokedUrlCommand*)command
495495
}];
496496
jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED];
497497
} else {
498-
// cannot seek, do nothing
498+
// cannot seek, wrong state
499+
CDVMediaError errcode = MEDIA_ERR_NONE_ACTIVE;
500+
NSString* errMsg = @"Cannot service stop request until the avPlayer is in 'AVPlayerStatusReadyToPlay' state.";
501+
jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:errcode message:errMsg]];
499502
}
500503
}
501504
// ignore if no media playing

tests/tests.js

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ exports.defineAutoTests = function () {
403403
expect(position).toBeLessThan(10);
404404
media1.stop();
405405
media1.release();
406+
context.done = true;
406407
done();
407408
}, failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position'),context);
408409
}, 4000);
@@ -436,6 +437,7 @@ exports.defineAutoTests = function () {
436437
expect(true).toBe(true);
437438
media1.stop();
438439
media1.release();
440+
context.done = true;
439441
done();
440442
}
441443
};
@@ -444,27 +446,73 @@ exports.defineAutoTests = function () {
444446
media1.play();
445447
}, ACTUAL_PLAYBACK_TEST_TIMEOUT);
446448

447-
it("media.spec.26 should not crash or throw when setting the volume right after creating the media", function () {
449+
it("media.spec.26 should not crash or throw when setting the volume right after creating the media", function (done) {
448450
//bb10 dialog pops up, preventing tests from running
449451
if (cordova.platformId === 'blackberry10') {
450452
pending();
451453
}
452454

453-
var context = this;
454455
var mediaFile = WEB_MP3_FILE;
455456
var media = null;
456457

457-
var successCallback = function () { };
458-
var statusChange = function () { };
459-
460458
expect(function () {
461-
media = new Media(mediaFile, successCallback, failed.bind(null, successCallback, 'Error creating Media object. Media file: ' + mediaFile, context), statusChange);
459+
media = new Media(mediaFile);
462460
media.setVolume('0.5');
463461
}).not.toThrow();
464-
if (media) {
465-
media.release();
462+
463+
// if there is no exception or crash in 3 seconds, the spec is completed
464+
setTimeout(function () {
465+
if (media) {
466+
media.release();
467+
done();
468+
}
469+
}, 3000);
470+
});
471+
472+
it("media.spec.27 should call success or error when trying to stop a media that is in starting state", function (done) {
473+
//bb10 dialog pops up, preventing tests from running
474+
if (!isAudioSupported || cordova.platformId === 'blackberry10') {
475+
pending();
466476
}
477+
478+
var mediaFile = WEB_MP3_FILE;
479+
var media = null;
480+
var context = this;
481+
var beenStarting = false;
482+
var safeDone = function () {
483+
if (!context.done) {
484+
media.release();
485+
context.done = true;
486+
done();
487+
}
488+
};
489+
490+
var errorCallback = jasmine.createSpy('errorCallback').and.callFake(function (e) {
491+
expect(beenStarting).toBe(true);
492+
safeDone();
493+
});
494+
var successCallback = function () {
495+
expect(true).toBe(true);
496+
safeDone();
497+
};
498+
var statusChange = function (s) {
499+
if ((s == Media.MEDIA_STARTING) && !context.done) {
500+
beenStarting = true;
501+
media.stop();
502+
} else if (s == Media.MEDIA_RUNNING) {
503+
// Some plugin implementations may skip "Starting" state
504+
// so we'll also try to call stop in "Running" state,
505+
// but in this case we should check that the "Starting" state wasn't really reached,
506+
// otherwise it would mean that the previous media.stop() call has been ignored
507+
expect(beenStarting).toBe(false);
508+
media.stop();
509+
}
510+
};
511+
512+
media = new Media(mediaFile, successCallback, errorCallback, statusChange);
513+
media.play();
467514
});
515+
468516
});
469517
};
470518

0 commit comments

Comments
 (0)