Chromium Code Reviews| Index: remoting/webapp/client_session.js | 
| diff --git a/remoting/webapp/client_session.js b/remoting/webapp/client_session.js | 
| index d3114aa8782e3cf130abd2f035b7395540d8e05e..ce557b761d9572170fbfef4fc4f57b58c5f6dfa9 100644 | 
| --- a/remoting/webapp/client_session.js | 
| +++ b/remoting/webapp/client_session.js | 
| @@ -167,6 +167,18 @@ remoting.ClientSession = function(container, hostDisplayName, accessCode, | 
| this.fullScreenButton_.addEventListener( | 
| 'click', this.callToggleFullScreen_, false); | 
| + | 
| + this.isVideoRecording_ = false; | 
| + this.videoRecordingFileWriter_ = null; | 
| 
 
Jamie
2014/08/01 01:28:36
Have you run this through jscompile? I'm surprised
 
Wez
2014/08/19 00:15:52
I am doing now, yes; compile fails because of pre-
 
 | 
| + var toggleRecordingButton = document.getElementById('start-stop-recording'); | 
| + toggleRecordingButton.addEventListener( | 
| + 'click', this.startStopRecording_.bind(this), false); | 
| + var toggleRecordingMenu = document.querySelector('.menu-start-stop-recording'); | 
| 
 
Jamie
2014/08/01 01:28:36
You're using a mix of getElementById and querySele
 
Jamie
2014/08/01 01:28:37
Nit: line-length.
 
Wez
2014/08/19 00:15:53
I just cribbed from the relevant toolbar and menu
 
 | 
| + toggleRecordingMenu.addEventListener( | 
| + 'click', this.startStopRecording_.bind(this), false); | 
| + | 
| + console.log("WIBBLE"); | 
| 
 
Jamie
2014/08/01 01:28:37
I think we can probably live without this line :)
 
Wez
2014/08/19 00:15:53
Done.
 
 | 
| + | 
| this.defineEvents(Object.keys(remoting.ClientSession.Events)); | 
| }; | 
| @@ -1070,6 +1082,13 @@ remoting.ClientSession.prototype.onSetCapabilities_ = function(capabilities) { | 
| clientArea.height, | 
| window.devicePixelRatio); | 
| } | 
| + if (this.hasCapability_( | 
| + remoting.ClientSession.Capability.VIDEO_RECORDER)) { | 
| 
 
Jamie
2014/08/01 01:28:37
There are a couple of ways of handling this withou
 
Wez
2014/08/19 00:15:53
OptionsMenu now sets this based on ClientSession.c
 
 | 
| + var recordingButton = document.getElementById('start-stop-recording'); | 
| + recordingButton.hidden = false; | 
| + var recordingMenu = document.querySelector('.menu-start-stop-recording'); | 
| + recordingMenu.hidden = false; | 
| + } | 
| }; | 
| /** | 
| @@ -1551,4 +1570,101 @@ remoting.ClientSession.prototype.updateMouseCursorImage_ = | 
| this.mouseCursorOverlay_.style.marginTop = '-' + hotspotY + 'px'; | 
| this.mouseCursorOverlay_.src = url; | 
| } | 
| - }; | 
| +}; | 
| + | 
| +remoting.ClientSession.prototype.startStopRecording_ = function() { | 
| 
 
Jamie
2014/08/01 01:28:36
I think there is enough code here that it's worth
 
Wez
2014/08/19 00:15:52
Agreed; already done.
 
 | 
| + var data = {}; | 
| + if (this.isVideoRecording_) { | 
| + data = { type: 'stop' } | 
| + this.isVideoRecording_ = false; | 
| + | 
| + console.log("CLICKY!"); | 
| 
 
Jamie
2014/08/01 01:28:36
I don't think so...
 
Wez
2014/08/19 00:15:53
Totally.
 
 | 
| + | 
| + chrome.fileSystem.chooseEntry( | 
| + {type: 'saveFile', suggestedName: "videoRecording.pb"}, | 
| + this.onVideoRecordingFileChosen_.bind(this)); | 
| + } else { | 
| + data = { type: 'start' } | 
| + this.isVideoRecording_ = true; | 
| + } | 
| + this.plugin_.sendClientMessage('video-recorder', JSON.stringify(data)); | 
| +} | 
| + | 
| +remoting.ClientSession.prototype.onVideoRecordingFileChosen_ = function(entry) { | 
| + if (!entry) { | 
| + console.log("Cancelled save of video frames."); | 
| + } else { | 
| + chrome.fileSystem.getDisplayPath(entry, function(path) { | 
| + console.log("Saving video frames to:" + path); | 
| + }); | 
| + entry.createWriter(this.onVideoRecordingFileWriter_.bind(this)); | 
| + } | 
| +} | 
| + | 
| +remoting.ClientSession.prototype.onVideoRecordingFileWriter_ = | 
| + function(writer) { | 
| + console.log("Obtained FileWriter for video frame write"); | 
| + writer.onwriteend = this.onVideoRecordingWriteComplete_.bind(this); | 
| + this.videoRecordingFileWriter_ = writer; | 
| + this.fetchNextVideoRecordingFrame_(); | 
| +} | 
| + | 
| +remoting.ClientSession.prototype.onVideoRecordingWriteComplete_ = function(e) { | 
| + console.log("Video frame write complete"); | 
| + this.fetchNextVideoRecordingFrame_(); | 
| +} | 
| + | 
| +remoting.ClientSession.prototype.fetchNextVideoRecordingFrame_ = function() { | 
| + console.log("Request next video frame"); | 
| + var data = { type: 'next-frame' } | 
| + this.plugin_.sendClientMessage('video-recorder', JSON.stringify(data)); | 
| +} | 
| + | 
| +remoting.ClientSession.prototype.handleVideoRecorderMessage = | 
| + function(type, data) { | 
| + if (type != 'video-recorder') { | 
| + return false; | 
| + } | 
| + | 
| + var message = getJsonObjectFromString(data); | 
| + | 
| + if (message.type == 'next-frame-reply') { | 
| + if (!this.videoRecordingFileWriter_) { | 
| + console.log("Received frame but have no writer"); | 
| + return true; | 
| + } | 
| + if (!message.data) { | 
| + console.log("Finished receiving frames"); | 
| + this.videoRecordingFileWriter_ = null; | 
| + return true; | 
| + } | 
| + | 
| + console.log("Received frame"); | 
| + var videoPacketString = atob(message.data); | 
| 
 
Wez
2014/08/19 00:15:52
This line angers jscompile, but there's no obvious
 
Jamie
2014/08/19 00:48:56
I would add it to dom_proto.js. It's not DOM-relat
 
Wez
2014/08/19 21:19:00
Done.
 
 | 
| + | 
| + console.log("Converted from Base64 - length:" + videoPacketString.length); | 
| + var byteArrays = []; | 
| + | 
| + for (var offset = 0; offset < videoPacketString.length; offset += 512) { | 
| + var slice = videoPacketString.slice(offset, offset + 512); | 
| + var byteNumbers = new Array(slice.length); | 
| + for (var i = 0; i < slice.length; i++) { | 
| + byteNumbers[i] = slice.charCodeAt(i); | 
| + } | 
| + var byteArray = new Uint8Array(byteNumbers); | 
| + byteArrays.push(byteArray); | 
| + } | 
| + | 
| + console.log("Writing frame"); | 
| + videoPacketString = null; | 
| + var videoPacketBlob = new Blob(byteArrays); | 
| + byteArrays = null; | 
| + | 
| + this.videoRecordingFileWriter_.write(videoPacketBlob); | 
| + | 
| + return true; | 
| + } | 
| + | 
| + console.log("Unrecognized message: " + message.type); | 
| + return true; | 
| +} |