feat(android): add 'message' field to media error CB-11641 (#357)
* CB-11641 android: add 'message' field to media error
It was not possible before to get error message.This updated Android implementation to return error code with message similar to iOS.
* style: apply lint corrections
* refactor(android): private API sendStatusChange
Co-authored-by: Nikita Matrosov <matrosov.nikita94@gmail.com>
diff --git a/src/android/AudioPlayer.java b/src/android/AudioPlayer.java
index 079356b..e19689f 100644
--- a/src/android/AudioPlayer.java
+++ b/src/android/AudioPlayer.java
@@ -158,10 +158,11 @@
* @param file The name of the file
*/
public void startRecording(String file) {
+ String errorMessage;
switch (this.mode) {
case PLAY:
- LOG.d(LOG_TAG, "AudioPlayer Error: Can't record in play mode.");
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ errorMessage = "AudioPlayer Error: Can't record in play mode.";
+ sendErrorStatus(MEDIA_ERR_ABORTED, errorMessage);
break;
case NONE:
this.audioFile = file;
@@ -182,11 +183,11 @@
e.printStackTrace();
}
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ sendErrorStatus(MEDIA_ERR_ABORTED, null);
break;
case RECORD:
- LOG.d(LOG_TAG, "AudioPlayer Error: Already recording.");
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ errorMessage = "AudioPlayer Error: Already recording.";
+ sendErrorStatus(MEDIA_ERR_ABORTED, errorMessage);
}
}
@@ -365,7 +366,7 @@
this.player.seekTo(milliseconds);
}
LOG.d(LOG_TAG, "Send a onStatus update for the new seek");
- sendStatusChange(MEDIA_POSITION, null, (milliseconds / 1000.0f));
+ sendStatusChange(MEDIA_POSITION, null, (milliseconds / 1000.0f), null);
}
else {
this.seekOnPrepared = milliseconds;
@@ -383,8 +384,8 @@
this.setState(STATE.MEDIA_PAUSED);
}
else {
- LOG.d(LOG_TAG, "AudioPlayer Error: pausePlaying() called during invalid state: " + this.state.ordinal());
- sendErrorStatus(MEDIA_ERR_NONE_ACTIVE);
+ String errorMessage = "AudioPlayer Error: pausePlaying() called during invalid state: " + this.state.ordinal();
+ sendErrorStatus(MEDIA_ERR_NONE_ACTIVE, errorMessage);
}
}
@@ -399,8 +400,8 @@
this.setState(STATE.MEDIA_STOPPED);
}
else {
- LOG.d(LOG_TAG, "AudioPlayer Error: stopPlaying() called during invalid state: " + this.state.ordinal());
- sendErrorStatus(MEDIA_ERR_NONE_ACTIVE);
+ String errorMessage = "AudioPlayer Error: stopPlaying() called during invalid state: " + this.state.ordinal();
+ sendErrorStatus(MEDIA_ERR_NONE_ACTIVE, errorMessage);
}
}
@@ -429,7 +430,7 @@
public long getCurrentPosition() {
if ((this.state == STATE.MEDIA_RUNNING) || (this.state == STATE.MEDIA_PAUSED)) {
int curPos = this.player.getCurrentPosition();
- sendStatusChange(MEDIA_POSITION, null, (curPos / 1000.0f));
+ sendStatusChange(MEDIA_POSITION, null, (curPos / 1000.0f), null);
return curPos;
}
else {
@@ -511,7 +512,7 @@
this.prepareOnly = true;
// Send status notification to JavaScript
- sendStatusChange(MEDIA_DURATION, null, this.duration);
+ sendStatusChange(MEDIA_DURATION, null, this.duration, null);
}
/**
@@ -532,14 +533,14 @@
* @param arg2 an extra code, specific to the error.
*/
public boolean onError(MediaPlayer player, int arg1, int arg2) {
- LOG.d(LOG_TAG, "AudioPlayer.onError(" + arg1 + ", " + arg2 + ")");
+ String errorMessage = "AudioPlayer.onError(" + arg1 + ", " + arg2 + ")";
// we don't want to send success callback
// so we don't call setState() here
this.state = STATE.MEDIA_STOPPED;
this.destroy();
// Send error notification to JavaScript
- sendErrorStatus(arg1);
+ sendErrorStatus(arg1, errorMessage);
return false;
}
@@ -551,7 +552,7 @@
*/
private void setState(STATE state) {
if (this.state != state) {
- sendStatusChange(MEDIA_STATE, null, (float)state.ordinal());
+ sendStatusChange(MEDIA_STATE, null, (float)state.ordinal(), null);
}
this.state = state;
}
@@ -587,8 +588,8 @@
if (this.player != null) {
this.player.setVolume(volume, volume);
} else {
- LOG.d(LOG_TAG, "AudioPlayer Error: Cannot set volume until the audio file is initialized.");
- sendErrorStatus(MEDIA_ERR_NONE_ACTIVE);
+ String errorMessage = "AudioPlayer Error: Cannot set volume until the audio file is initialized.";
+ sendErrorStatus(MEDIA_ERR_NONE_ACTIVE, errorMessage);
}
}
@@ -604,8 +605,8 @@
case PLAY:
break;
case RECORD:
- LOG.d(LOG_TAG, "AudioPlayer Error: Can't play in record mode.");
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ String errorMessage = "AudioPlayer Error: Can't play in record mode.";
+ sendErrorStatus(MEDIA_ERR_ABORTED, errorMessage);
return false; //player is not ready
}
return true;
@@ -627,7 +628,7 @@
try {
this.loadAudioFile(file);
} catch (Exception e) {
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ sendErrorStatus(MEDIA_ERR_ABORTED, e.getMessage());
}
return false;
case MEDIA_LOADING:
@@ -651,7 +652,7 @@
try {
this.loadAudioFile(file);
} catch (Exception e) {
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ sendErrorStatus(MEDIA_ERR_ABORTED, e.getMessage());
}
return false;//we´re not ready yet
}
@@ -667,14 +668,14 @@
try {
this.loadAudioFile(file);
} catch (Exception e) {
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ sendErrorStatus(MEDIA_ERR_ABORTED, e.getMessage());
}
//if we had to prepare the file, we won't be in the correct state for playback
return false;
}
default:
- LOG.d(LOG_TAG, "AudioPlayer Error: startPlaying() called during invalid state: " + this.state);
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ String errorMessage = "AudioPlayer Error: startPlaying() called during invalid state: " + this.state;
+ sendErrorStatus(MEDIA_ERR_ABORTED, errorMessage);
}
}
return false;
@@ -723,16 +724,19 @@
}
}
- private void sendErrorStatus(int errorCode) {
- sendStatusChange(MEDIA_ERROR, errorCode, null);
+ private void sendErrorStatus(int errorCode, String errorMessage) {
+ sendStatusChange(MEDIA_ERROR, errorCode, null, errorMessage);
}
- private void sendStatusChange(int messageType, Integer additionalCode, Float value) {
-
+ private void sendStatusChange(int messageType, Integer additionalCode, Float value, String errorMessage) {
if (additionalCode != null && value != null) {
throw new IllegalArgumentException("Only one of additionalCode or value can be specified, not both");
}
+ if (errorMessage != null) {
+ LOG.d(LOG_TAG, errorMessage);
+ }
+
JSONObject statusDetails = new JSONObject();
try {
statusDetails.put("id", this.id);
@@ -740,6 +744,11 @@
if (additionalCode != null) {
JSONObject code = new JSONObject();
code.put("code", additionalCode.intValue());
+
+ if (errorMessage != null) {
+ code.put("message", errorMessage);
+ }
+
statusDetails.put("value", code);
}
else if (value != null) {
diff --git a/tests/tests.js b/tests/tests.js
index 6b9c389..b26cc42 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -232,6 +232,23 @@
badMedia.play();
});
+ it("media.spec.19 MediaError instance should contain 'code' and 'message' fields", function (done) {
+ var context = this;
+ var fileName = 'invalid.file.name';
+ var badMedia = new Media(fileName, succeed.bind(null, done, ' badMedia = new Media , Unexpected succees callback, it should not create Media object with invalid file name'), function (result) {
+ if (context.done) return;
+ context.done = true;
+ expect(result).toBeDefined();
+ expect(result.code).toBeDefined();
+ expect(result.message).toBeDefined();
+ if (badMedia) {
+ badMedia.release();
+ }
+ done();
+ });
+ badMedia.play();
+ });
+
describe('actual playback', function () {
var checkInterval, media;