[ https://issues.apache.org/jira/browse/CB-1599?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Bob Flavin updated CB-1599: --------------------------- Summary: successCallback not called after stopRecording, duplicate AudioPlayer objects created (was: successCallback not called after stopRecording, duplicate AudioRecorder objects created) > successCallback not called after stopRecording, duplicate AudioPlayer objects > created > ------------------------------------------------------------------------------------- > > Key: CB-1599 > URL: https://issues.apache.org/jira/browse/CB-1599 > Project: Apache Cordova > Issue Type: Bug > Components: CordovaJS > Affects Versions: 2.1.0 > Environment: Android 2.3? > Reporter: Bob Flavin > Assignee: Filip Maj > Fix For: 2.1.0 > > > A successCallback is not called sometimes after stopRecording() is called. > The problem is that javascript cordova calls to 'new Media()' and > 'mediaObj.startRecord() are dispatched by androidExec (prompt) to new threads > on the java side and are not synchronized. Thus > org.apache.cordova.AudioHandler.execute for action='create', calls new > AudioPlayer(). Asynchronously, ...AudioHandler.execute for > action='startAudioRecording' calls AudioHandler.startAudioRecording(), which > gets a null from this.players.get(id) which causes the if statement to call > new AudioRecorder which creates a second instance of AudioRecorder for that > id. > public void startRecordingAudio(String id, String file) { > AudioPlayer audio = this.players.get(id); > if ( audio == null) { > audio = new AudioPlayer(this, id, file); > this.players.put(id, audio); > } > audio.startRecording(file); > } > One instance of AudioPlayer goes into STATE MEDIA_RUNNING the other remains > in MEDIA_NONE. > When the javascript calls mediaObj.stopRecord() (and mediaObj.release()) it > may get the instance of AudioPlayer that is in MEDIA_NONE. This prevents > AudioPlayer.stopRecording() from calling this.recorder.stop() and > this.setState(STATE.MEDIA_STOPPED) because that AudioPlayer instance is in > STATE MEDIA_NONE. Thus AudioPlayer.setState doesn't call the > handler.sendJavascript to call the javascript Media.onStatus method that > would call the statusCallback and the successCallback. > I think that the AudioHandler should have a synchronized block that prevents > 'create' and 'startRecordingAudio from running at the same time and that > 'create' should use the same code that startRecodingAudio does: > AudioPlayer audio = this.players.get(id); > if ( audio == null) { > audio = new AudioPlayer(this, id, file); > this.players.put(id, audio); > } > to prevent creating a second AudioPlayer instance if the startRecordingAudio > thread executes before the 'create' thread. > There may be other actions in AudioHandler.execute that need this > synchronization as well. > One effect of this problem is that the javascript successCallback is never > called (after stopRecord) -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators For more information on JIRA, see: http://www.atlassian.com/software/jira