mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge f-t to m-c, a=merge
This commit is contained in:
commit
e28796163e
@ -654,7 +654,7 @@ loop.conversationViews = (function(mozL10n) {
|
||||
* @private
|
||||
*/
|
||||
_isLocalLoading: function () {
|
||||
return !this.state.localSrcVideoObject && !this.props.localPosterUrl;
|
||||
return !this.state.localSrcMediaElement && !this.props.localPosterUrl;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -665,7 +665,7 @@ loop.conversationViews = (function(mozL10n) {
|
||||
* @private
|
||||
*/
|
||||
_isRemoteLoading: function() {
|
||||
return !!(!this.state.remoteSrcVideoObject &&
|
||||
return !!(!this.state.remoteSrcMediaElement &&
|
||||
!this.props.remotePosterUrl &&
|
||||
!this.state.mediaConnected);
|
||||
},
|
||||
@ -702,14 +702,14 @@ loop.conversationViews = (function(mozL10n) {
|
||||
isRemoteLoading: this._isRemoteLoading(),
|
||||
isScreenShareLoading: false,
|
||||
localPosterUrl: this.props.localPosterUrl,
|
||||
localSrcVideoObject: this.state.localSrcVideoObject,
|
||||
localSrcMediaElement: this.state.localSrcMediaElement,
|
||||
localVideoMuted: !this.props.video.enabled,
|
||||
matchMedia: this.state.matchMedia || window.matchMedia.bind(window),
|
||||
remotePosterUrl: this.props.remotePosterUrl,
|
||||
remoteSrcVideoObject: this.state.remoteSrcVideoObject,
|
||||
remoteSrcMediaElement: this.state.remoteSrcMediaElement,
|
||||
renderRemoteVideo: this.shouldRenderRemoteVideo(),
|
||||
screenShareMediaElement: this.state.screenShareMediaElement,
|
||||
screenSharePosterUrl: null,
|
||||
screenShareVideoObject: this.state.screenShareVideoObject,
|
||||
showContextRoomName: false,
|
||||
useDesktopPaths: true},
|
||||
React.createElement(loop.shared.views.ConversationToolbar, {
|
||||
@ -822,7 +822,7 @@ loop.conversationViews = (function(mozL10n) {
|
||||
dispatcher: this.props.dispatcher,
|
||||
mediaConnected: this.state.mediaConnected,
|
||||
mozLoop: this.props.mozLoop,
|
||||
remoteSrcVideoObject: this.state.remoteSrcVideoObject,
|
||||
remoteSrcMediaElement: this.state.remoteSrcMediaElement,
|
||||
remoteVideoEnabled: this.state.remoteVideoEnabled,
|
||||
video: { enabled: !this.state.videoMuted, visible: true}})
|
||||
);
|
||||
|
@ -654,7 +654,7 @@ loop.conversationViews = (function(mozL10n) {
|
||||
* @private
|
||||
*/
|
||||
_isLocalLoading: function () {
|
||||
return !this.state.localSrcVideoObject && !this.props.localPosterUrl;
|
||||
return !this.state.localSrcMediaElement && !this.props.localPosterUrl;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -665,7 +665,7 @@ loop.conversationViews = (function(mozL10n) {
|
||||
* @private
|
||||
*/
|
||||
_isRemoteLoading: function() {
|
||||
return !!(!this.state.remoteSrcVideoObject &&
|
||||
return !!(!this.state.remoteSrcMediaElement &&
|
||||
!this.props.remotePosterUrl &&
|
||||
!this.state.mediaConnected);
|
||||
},
|
||||
@ -702,14 +702,14 @@ loop.conversationViews = (function(mozL10n) {
|
||||
isRemoteLoading={this._isRemoteLoading()}
|
||||
isScreenShareLoading={false}
|
||||
localPosterUrl={this.props.localPosterUrl}
|
||||
localSrcVideoObject={this.state.localSrcVideoObject}
|
||||
localSrcMediaElement={this.state.localSrcMediaElement}
|
||||
localVideoMuted={!this.props.video.enabled}
|
||||
matchMedia={this.state.matchMedia || window.matchMedia.bind(window)}
|
||||
remotePosterUrl={this.props.remotePosterUrl}
|
||||
remoteSrcVideoObject={this.state.remoteSrcVideoObject}
|
||||
remoteSrcMediaElement={this.state.remoteSrcMediaElement}
|
||||
renderRemoteVideo={this.shouldRenderRemoteVideo()}
|
||||
screenShareMediaElement={this.state.screenShareMediaElement}
|
||||
screenSharePosterUrl={null}
|
||||
screenShareVideoObject={this.state.screenShareVideoObject}
|
||||
showContextRoomName={false}
|
||||
useDesktopPaths={true}>
|
||||
<loop.shared.views.ConversationToolbar
|
||||
@ -822,7 +822,7 @@ loop.conversationViews = (function(mozL10n) {
|
||||
dispatcher={this.props.dispatcher}
|
||||
mediaConnected={this.state.mediaConnected}
|
||||
mozLoop={this.props.mozLoop}
|
||||
remoteSrcVideoObject={this.state.remoteSrcVideoObject}
|
||||
remoteSrcMediaElement={this.state.remoteSrcMediaElement}
|
||||
remoteVideoEnabled={this.state.remoteVideoEnabled}
|
||||
video={{ enabled: !this.state.videoMuted, visible: true }} />
|
||||
);
|
||||
|
@ -707,7 +707,7 @@ loop.roomViews = (function(mozL10n) {
|
||||
*/
|
||||
_isLocalLoading: function () {
|
||||
return this.state.roomState === ROOM_STATES.MEDIA_WAIT &&
|
||||
!this.state.localSrcVideoObject;
|
||||
!this.state.localSrcMediaElement;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -719,7 +719,7 @@ loop.roomViews = (function(mozL10n) {
|
||||
*/
|
||||
_isRemoteLoading: function() {
|
||||
return !!(this.state.roomState === ROOM_STATES.HAS_PARTICIPANTS &&
|
||||
!this.state.remoteSrcVideoObject &&
|
||||
!this.state.remoteSrcMediaElement &&
|
||||
!this.state.mediaConnected);
|
||||
},
|
||||
|
||||
@ -801,14 +801,14 @@ loop.roomViews = (function(mozL10n) {
|
||||
isRemoteLoading: this._isRemoteLoading(),
|
||||
isScreenShareLoading: false,
|
||||
localPosterUrl: this.props.localPosterUrl,
|
||||
localSrcVideoObject: this.state.localSrcVideoObject,
|
||||
localSrcMediaElement: this.state.localSrcMediaElement,
|
||||
localVideoMuted: this.state.videoMuted,
|
||||
matchMedia: this.state.matchMedia || window.matchMedia.bind(window),
|
||||
remotePosterUrl: this.props.remotePosterUrl,
|
||||
remoteSrcVideoObject: this.state.remoteSrcVideoObject,
|
||||
remoteSrcMediaElement: this.state.remoteSrcMediaElement,
|
||||
renderRemoteVideo: this.shouldRenderRemoteVideo(),
|
||||
screenShareMediaElement: this.state.screenShareMediaElement,
|
||||
screenSharePosterUrl: null,
|
||||
screenShareVideoObject: this.state.screenShareVideoObject,
|
||||
showContextRoomName: false,
|
||||
useDesktopPaths: true},
|
||||
React.createElement(sharedViews.ConversationToolbar, {
|
||||
|
@ -707,7 +707,7 @@ loop.roomViews = (function(mozL10n) {
|
||||
*/
|
||||
_isLocalLoading: function () {
|
||||
return this.state.roomState === ROOM_STATES.MEDIA_WAIT &&
|
||||
!this.state.localSrcVideoObject;
|
||||
!this.state.localSrcMediaElement;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -719,7 +719,7 @@ loop.roomViews = (function(mozL10n) {
|
||||
*/
|
||||
_isRemoteLoading: function() {
|
||||
return !!(this.state.roomState === ROOM_STATES.HAS_PARTICIPANTS &&
|
||||
!this.state.remoteSrcVideoObject &&
|
||||
!this.state.remoteSrcMediaElement &&
|
||||
!this.state.mediaConnected);
|
||||
},
|
||||
|
||||
@ -801,14 +801,14 @@ loop.roomViews = (function(mozL10n) {
|
||||
isRemoteLoading={this._isRemoteLoading()}
|
||||
isScreenShareLoading={false}
|
||||
localPosterUrl={this.props.localPosterUrl}
|
||||
localSrcVideoObject={this.state.localSrcVideoObject}
|
||||
localSrcMediaElement={this.state.localSrcMediaElement}
|
||||
localVideoMuted={this.state.videoMuted}
|
||||
matchMedia={this.state.matchMedia || window.matchMedia.bind(window)}
|
||||
remotePosterUrl={this.props.remotePosterUrl}
|
||||
remoteSrcVideoObject={this.state.remoteSrcVideoObject}
|
||||
remoteSrcMediaElement={this.state.remoteSrcMediaElement}
|
||||
renderRemoteVideo={this.shouldRenderRemoteVideo()}
|
||||
screenShareMediaElement={this.state.screenShareMediaElement}
|
||||
screenSharePosterUrl={null}
|
||||
screenShareVideoObject={this.state.screenShareVideoObject}
|
||||
showContextRoomName={false}
|
||||
useDesktopPaths={true}>
|
||||
<sharedViews.ConversationToolbar
|
||||
|
@ -233,7 +233,7 @@ loop.shared.actions = (function() {
|
||||
MediaStreamCreated: Action.define("mediaStreamCreated", {
|
||||
hasVideo: Boolean,
|
||||
isLocal: Boolean,
|
||||
srcVideoObject: Object
|
||||
srcMediaElement: Object
|
||||
}),
|
||||
|
||||
/**
|
||||
@ -294,7 +294,7 @@ loop.shared.actions = (function() {
|
||||
*/
|
||||
ReceivingScreenShare: Action.define("receivingScreenShare", {
|
||||
receiving: Boolean
|
||||
// srcVideoObject: Object (only present if receiving is true)
|
||||
// srcMediaElement: Object (only present if receiving is true)
|
||||
}),
|
||||
|
||||
/**
|
||||
|
@ -106,15 +106,15 @@ loop.store.ActiveRoomStore = (function() {
|
||||
*/
|
||||
_statesToResetOnLeave: [
|
||||
"audioMuted",
|
||||
"localSrcVideoObject",
|
||||
"localSrcMediaElement",
|
||||
"localVideoDimensions",
|
||||
"mediaConnected",
|
||||
"receivingScreenShare",
|
||||
"remoteSrcVideoObject",
|
||||
"remoteSrcMediaElement",
|
||||
"remoteVideoDimensions",
|
||||
"remoteVideoEnabled",
|
||||
"screenSharingState",
|
||||
"screenShareVideoObject",
|
||||
"screenShareMediaElement",
|
||||
"videoMuted"
|
||||
],
|
||||
|
||||
@ -640,14 +640,14 @@ loop.store.ActiveRoomStore = (function() {
|
||||
if (actionData.isLocal) {
|
||||
this.setStoreState({
|
||||
localVideoEnabled: actionData.hasVideo,
|
||||
localSrcVideoObject: actionData.srcVideoObject
|
||||
localSrcMediaElement: actionData.srcMediaElement
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.setStoreState({
|
||||
remoteVideoEnabled: actionData.hasVideo,
|
||||
remoteSrcVideoObject: actionData.srcVideoObject
|
||||
remoteSrcMediaElement: actionData.srcMediaElement
|
||||
});
|
||||
},
|
||||
|
||||
@ -659,13 +659,13 @@ loop.store.ActiveRoomStore = (function() {
|
||||
mediaStreamDestroyed: function(actionData) {
|
||||
if (actionData.isLocal) {
|
||||
this.setStoreState({
|
||||
localSrcVideoObject: null
|
||||
localSrcMediaElement: null
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.setStoreState({
|
||||
remoteSrcVideoObject: null
|
||||
remoteSrcMediaElement: null
|
||||
});
|
||||
},
|
||||
|
||||
@ -713,13 +713,13 @@ loop.store.ActiveRoomStore = (function() {
|
||||
this.setStoreState({
|
||||
receivingScreenShare: actionData.receiving,
|
||||
remoteVideoDimensions: newDimensions,
|
||||
screenShareVideoObject: null
|
||||
screenShareMediaElement: null
|
||||
});
|
||||
} else {
|
||||
this.setStoreState({
|
||||
receivingScreenShare: actionData.receiving,
|
||||
screenShareVideoObject: actionData.srcVideoObject ?
|
||||
actionData.srcVideoObject : null
|
||||
screenShareMediaElement: actionData.srcMediaElement ?
|
||||
actionData.srcMediaElement : null
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -829,7 +829,7 @@ loop.store.ActiveRoomStore = (function() {
|
||||
mediaConnected: false,
|
||||
participants: participants,
|
||||
roomState: ROOM_STATES.SESSION_CONNECTED,
|
||||
remoteSrcVideoObject: null
|
||||
remoteSrcMediaElement: null
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -448,14 +448,14 @@ loop.store = loop.store || {};
|
||||
if (actionData.isLocal) {
|
||||
this.setStoreState({
|
||||
localVideoEnabled: actionData.hasVideo,
|
||||
localSrcVideoObject: actionData.srcVideoObject
|
||||
localSrcMediaElement: actionData.srcMediaElement
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.setStoreState({
|
||||
remoteVideoEnabled: actionData.hasVideo,
|
||||
remoteSrcVideoObject: actionData.srcVideoObject
|
||||
remoteSrcMediaElement: actionData.srcMediaElement
|
||||
});
|
||||
},
|
||||
|
||||
@ -467,13 +467,13 @@ loop.store = loop.store || {};
|
||||
mediaStreamDestroyed: function(actionData) {
|
||||
if (actionData.isLocal) {
|
||||
this.setStoreState({
|
||||
localSrcVideoObject: null
|
||||
localSrcMediaElement: null
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.setStoreState({
|
||||
remoteSrcVideoObject: null
|
||||
remoteSrcMediaElement: null
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -601,7 +601,7 @@ loop.OTSdkDriver = (function() {
|
||||
this.dispatcher.dispatch(new sharedActions.MediaStreamCreated({
|
||||
hasVideo: sdkSubscriberObject.stream[STREAM_PROPERTIES.HAS_VIDEO],
|
||||
isLocal: false,
|
||||
srcVideoObject: sdkSubscriberVideo
|
||||
srcMediaElement: sdkSubscriberVideo
|
||||
}));
|
||||
|
||||
this._subscribedRemoteStream = true;
|
||||
@ -635,7 +635,7 @@ loop.OTSdkDriver = (function() {
|
||||
// _handleRemoteScreenShareCreated. Maybe these should be separate
|
||||
// actions. But even so, this shouldn't be necessary....
|
||||
this.dispatcher.dispatch(new sharedActions.ReceivingScreenShare({
|
||||
receiving: true, srcVideoObject: sdkSubscriberVideo
|
||||
receiving: true, srcMediaElement: sdkSubscriberVideo
|
||||
}));
|
||||
|
||||
},
|
||||
@ -767,7 +767,7 @@ loop.OTSdkDriver = (function() {
|
||||
this.dispatcher.dispatch(new sharedActions.MediaStreamCreated({
|
||||
hasVideo: hasVideo,
|
||||
isLocal: true,
|
||||
srcVideoObject: sdkLocalVideo
|
||||
srcMediaElement: sdkLocalVideo
|
||||
}));
|
||||
|
||||
// Only dispatch the video dimensions if we actually have video.
|
||||
|
@ -1075,7 +1075,7 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
* instead of the video, and attaching a video stream to the video element.
|
||||
*/
|
||||
var MediaView = React.createClass({displayName: "MediaView",
|
||||
// srcVideoObject should be ok for a shallow comparison, so we are safe
|
||||
// srcMediaElement should be ok for a shallow comparison, so we are safe
|
||||
// to use the pure render mixin here.
|
||||
mixins: [React.addons.PureRenderMixin],
|
||||
|
||||
@ -1085,18 +1085,18 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
mediaType: React.PropTypes.string.isRequired,
|
||||
posterUrl: React.PropTypes.string,
|
||||
// Expecting "local" or "remote".
|
||||
srcVideoObject: React.PropTypes.object
|
||||
srcMediaElement: React.PropTypes.object
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
if (!this.props.displayAvatar) {
|
||||
this.attachVideo(this.props.srcVideoObject);
|
||||
this.attachVideo(this.props.srcMediaElement);
|
||||
}
|
||||
},
|
||||
|
||||
componentDidUpdate: function() {
|
||||
if (!this.props.displayAvatar) {
|
||||
this.attachVideo(this.props.srcVideoObject);
|
||||
this.attachVideo(this.props.srcMediaElement);
|
||||
}
|
||||
},
|
||||
|
||||
@ -1104,14 +1104,14 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
* Attaches a video stream from a donor video element to this component's
|
||||
* video element if the component is displaying one.
|
||||
*
|
||||
* @param {Object} srcVideoObject The src video object to clone the stream
|
||||
* @param {Object} srcMediaElement The src video object to clone the stream
|
||||
* from.
|
||||
*
|
||||
* XXX need to have a corresponding detachVideo or change this to syncVideo
|
||||
* to protect from leaks (bug 1171978)
|
||||
*/
|
||||
attachVideo: function(srcVideoObject) {
|
||||
if (!srcVideoObject) {
|
||||
attachVideo: function(srcMediaElement) {
|
||||
if (!srcMediaElement) {
|
||||
// Not got anything to display.
|
||||
return;
|
||||
}
|
||||
@ -1141,8 +1141,8 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
}
|
||||
|
||||
// If the object hasn't changed it, then don't reattach it.
|
||||
if (videoElement[attrName] !== srcVideoObject[attrName]) {
|
||||
videoElement[attrName] = srcVideoObject[attrName];
|
||||
if (videoElement[attrName] !== srcMediaElement[attrName]) {
|
||||
videoElement[attrName] = srcMediaElement[attrName];
|
||||
}
|
||||
videoElement.play();
|
||||
},
|
||||
@ -1156,7 +1156,7 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
return React.createElement(AvatarView, null);
|
||||
}
|
||||
|
||||
if (!this.props.srcVideoObject && !this.props.posterUrl) {
|
||||
if (!this.props.srcMediaElement && !this.props.posterUrl) {
|
||||
return React.createElement("div", {className: "no-video"});
|
||||
}
|
||||
|
||||
@ -1192,16 +1192,16 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
isScreenShareLoading: React.PropTypes.bool.isRequired,
|
||||
// The poster URLs are for UI-showcase testing and development.
|
||||
localPosterUrl: React.PropTypes.string,
|
||||
localSrcVideoObject: React.PropTypes.object,
|
||||
localSrcMediaElement: React.PropTypes.object,
|
||||
localVideoMuted: React.PropTypes.bool.isRequired,
|
||||
// Passing in matchMedia, allows it to be overriden for ui-showcase's
|
||||
// benefit. We expect either the override or window.matchMedia.
|
||||
matchMedia: React.PropTypes.func.isRequired,
|
||||
remotePosterUrl: React.PropTypes.string,
|
||||
remoteSrcVideoObject: React.PropTypes.object,
|
||||
remoteSrcMediaElement: React.PropTypes.object,
|
||||
renderRemoteVideo: React.PropTypes.bool.isRequired,
|
||||
screenShareMediaElement: React.PropTypes.object,
|
||||
screenSharePosterUrl: React.PropTypes.string,
|
||||
screenShareVideoObject: React.PropTypes.object,
|
||||
showContextRoomName: React.PropTypes.bool.isRequired,
|
||||
useDesktopPaths: React.PropTypes.bool.isRequired
|
||||
},
|
||||
@ -1255,7 +1255,7 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
isLoading: this.props.isLocalLoading,
|
||||
mediaType: "local",
|
||||
posterUrl: this.props.localPosterUrl,
|
||||
srcVideoObject: this.props.localSrcVideoObject})
|
||||
srcMediaElement: this.props.localSrcMediaElement})
|
||||
)
|
||||
);
|
||||
},
|
||||
@ -1274,9 +1274,9 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
var mediaWrapperClasses = React.addons.classSet({
|
||||
"media-wrapper": true,
|
||||
"receiving-screen-share": this.props.displayScreenShare,
|
||||
"showing-local-streams": this.props.localSrcVideoObject ||
|
||||
"showing-local-streams": this.props.localSrcMediaElement ||
|
||||
this.props.localPosterUrl,
|
||||
"showing-remote-streams": this.props.remoteSrcVideoObject ||
|
||||
"showing-remote-streams": this.props.remoteSrcMediaElement ||
|
||||
this.props.remotePosterUrl || this.props.isRemoteLoading
|
||||
});
|
||||
|
||||
@ -1291,7 +1291,7 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
isLoading: this.props.isRemoteLoading,
|
||||
mediaType: "remote",
|
||||
posterUrl: this.props.remotePosterUrl,
|
||||
srcVideoObject: this.props.remoteSrcVideoObject}),
|
||||
srcMediaElement: this.props.remoteSrcMediaElement}),
|
||||
this.state.localMediaAboslutelyPositioned ?
|
||||
this.renderLocalVideo() : null,
|
||||
this.props.children
|
||||
@ -1302,7 +1302,7 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
isLoading: this.props.isScreenShareLoading,
|
||||
mediaType: "screen-share",
|
||||
posterUrl: this.props.screenSharePosterUrl,
|
||||
srcVideoObject: this.props.screenShareVideoObject})
|
||||
srcMediaElement: this.props.screenShareMediaElement})
|
||||
),
|
||||
React.createElement(loop.shared.views.chat.TextChatView, {
|
||||
dispatcher: this.props.dispatcher,
|
||||
|
@ -1075,7 +1075,7 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
* instead of the video, and attaching a video stream to the video element.
|
||||
*/
|
||||
var MediaView = React.createClass({
|
||||
// srcVideoObject should be ok for a shallow comparison, so we are safe
|
||||
// srcMediaElement should be ok for a shallow comparison, so we are safe
|
||||
// to use the pure render mixin here.
|
||||
mixins: [React.addons.PureRenderMixin],
|
||||
|
||||
@ -1085,18 +1085,18 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
mediaType: React.PropTypes.string.isRequired,
|
||||
posterUrl: React.PropTypes.string,
|
||||
// Expecting "local" or "remote".
|
||||
srcVideoObject: React.PropTypes.object
|
||||
srcMediaElement: React.PropTypes.object
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
if (!this.props.displayAvatar) {
|
||||
this.attachVideo(this.props.srcVideoObject);
|
||||
this.attachVideo(this.props.srcMediaElement);
|
||||
}
|
||||
},
|
||||
|
||||
componentDidUpdate: function() {
|
||||
if (!this.props.displayAvatar) {
|
||||
this.attachVideo(this.props.srcVideoObject);
|
||||
this.attachVideo(this.props.srcMediaElement);
|
||||
}
|
||||
},
|
||||
|
||||
@ -1104,14 +1104,14 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
* Attaches a video stream from a donor video element to this component's
|
||||
* video element if the component is displaying one.
|
||||
*
|
||||
* @param {Object} srcVideoObject The src video object to clone the stream
|
||||
* @param {Object} srcMediaElement The src video object to clone the stream
|
||||
* from.
|
||||
*
|
||||
* XXX need to have a corresponding detachVideo or change this to syncVideo
|
||||
* to protect from leaks (bug 1171978)
|
||||
*/
|
||||
attachVideo: function(srcVideoObject) {
|
||||
if (!srcVideoObject) {
|
||||
attachVideo: function(srcMediaElement) {
|
||||
if (!srcMediaElement) {
|
||||
// Not got anything to display.
|
||||
return;
|
||||
}
|
||||
@ -1141,8 +1141,8 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
}
|
||||
|
||||
// If the object hasn't changed it, then don't reattach it.
|
||||
if (videoElement[attrName] !== srcVideoObject[attrName]) {
|
||||
videoElement[attrName] = srcVideoObject[attrName];
|
||||
if (videoElement[attrName] !== srcMediaElement[attrName]) {
|
||||
videoElement[attrName] = srcMediaElement[attrName];
|
||||
}
|
||||
videoElement.play();
|
||||
},
|
||||
@ -1156,7 +1156,7 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
return <AvatarView />;
|
||||
}
|
||||
|
||||
if (!this.props.srcVideoObject && !this.props.posterUrl) {
|
||||
if (!this.props.srcMediaElement && !this.props.posterUrl) {
|
||||
return <div className="no-video"/>;
|
||||
}
|
||||
|
||||
@ -1192,16 +1192,16 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
isScreenShareLoading: React.PropTypes.bool.isRequired,
|
||||
// The poster URLs are for UI-showcase testing and development.
|
||||
localPosterUrl: React.PropTypes.string,
|
||||
localSrcVideoObject: React.PropTypes.object,
|
||||
localSrcMediaElement: React.PropTypes.object,
|
||||
localVideoMuted: React.PropTypes.bool.isRequired,
|
||||
// Passing in matchMedia, allows it to be overriden for ui-showcase's
|
||||
// benefit. We expect either the override or window.matchMedia.
|
||||
matchMedia: React.PropTypes.func.isRequired,
|
||||
remotePosterUrl: React.PropTypes.string,
|
||||
remoteSrcVideoObject: React.PropTypes.object,
|
||||
remoteSrcMediaElement: React.PropTypes.object,
|
||||
renderRemoteVideo: React.PropTypes.bool.isRequired,
|
||||
screenShareMediaElement: React.PropTypes.object,
|
||||
screenSharePosterUrl: React.PropTypes.string,
|
||||
screenShareVideoObject: React.PropTypes.object,
|
||||
showContextRoomName: React.PropTypes.bool.isRequired,
|
||||
useDesktopPaths: React.PropTypes.bool.isRequired
|
||||
},
|
||||
@ -1255,7 +1255,7 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
isLoading={this.props.isLocalLoading}
|
||||
mediaType="local"
|
||||
posterUrl={this.props.localPosterUrl}
|
||||
srcVideoObject={this.props.localSrcVideoObject} />
|
||||
srcMediaElement={this.props.localSrcMediaElement} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
@ -1274,9 +1274,9 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
var mediaWrapperClasses = React.addons.classSet({
|
||||
"media-wrapper": true,
|
||||
"receiving-screen-share": this.props.displayScreenShare,
|
||||
"showing-local-streams": this.props.localSrcVideoObject ||
|
||||
"showing-local-streams": this.props.localSrcMediaElement ||
|
||||
this.props.localPosterUrl,
|
||||
"showing-remote-streams": this.props.remoteSrcVideoObject ||
|
||||
"showing-remote-streams": this.props.remoteSrcMediaElement ||
|
||||
this.props.remotePosterUrl || this.props.isRemoteLoading
|
||||
});
|
||||
|
||||
@ -1291,7 +1291,7 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
isLoading={this.props.isRemoteLoading}
|
||||
mediaType="remote"
|
||||
posterUrl={this.props.remotePosterUrl}
|
||||
srcVideoObject={this.props.remoteSrcVideoObject} />
|
||||
srcMediaElement={this.props.remoteSrcMediaElement} />
|
||||
{ this.state.localMediaAboslutelyPositioned ?
|
||||
this.renderLocalVideo() : null }
|
||||
{ this.props.children }
|
||||
@ -1302,7 +1302,7 @@ loop.shared.views = (function(_, mozL10n) {
|
||||
isLoading={this.props.isScreenShareLoading}
|
||||
mediaType="screen-share"
|
||||
posterUrl={this.props.screenSharePosterUrl}
|
||||
srcVideoObject={this.props.screenShareVideoObject} />
|
||||
srcMediaElement={this.props.screenShareMediaElement} />
|
||||
</div>
|
||||
<loop.shared.views.chat.TextChatView
|
||||
dispatcher={this.props.dispatcher}
|
||||
|
@ -513,7 +513,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
*/
|
||||
_isLocalLoading: function () {
|
||||
return this.state.roomState === ROOM_STATES.MEDIA_WAIT &&
|
||||
!this.state.localSrcVideoObject;
|
||||
!this.state.localSrcMediaElement;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -525,7 +525,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
*/
|
||||
_isRemoteLoading: function() {
|
||||
return !!(this.state.roomState === ROOM_STATES.HAS_PARTICIPANTS &&
|
||||
!this.state.remoteSrcVideoObject &&
|
||||
!this.state.remoteSrcMediaElement &&
|
||||
!this.state.mediaConnected);
|
||||
},
|
||||
|
||||
@ -538,7 +538,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
*/
|
||||
_isScreenShareLoading: function() {
|
||||
return this.state.receivingScreenShare &&
|
||||
!this.state.screenShareVideoObject &&
|
||||
!this.state.screenShareMediaElement &&
|
||||
!this.props.screenSharePosterUrl;
|
||||
},
|
||||
|
||||
@ -557,14 +557,14 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
isRemoteLoading: this._isRemoteLoading(),
|
||||
isScreenShareLoading: this._isScreenShareLoading(),
|
||||
localPosterUrl: this.props.localPosterUrl,
|
||||
localSrcVideoObject: this.state.localSrcVideoObject,
|
||||
localSrcMediaElement: this.state.localSrcMediaElement,
|
||||
localVideoMuted: this.state.videoMuted,
|
||||
matchMedia: this.state.matchMedia || window.matchMedia.bind(window),
|
||||
remotePosterUrl: this.props.remotePosterUrl,
|
||||
remoteSrcVideoObject: this.state.remoteSrcVideoObject,
|
||||
remoteSrcMediaElement: this.state.remoteSrcMediaElement,
|
||||
renderRemoteVideo: this.shouldRenderRemoteVideo(),
|
||||
screenShareMediaElement: this.state.screenShareMediaElement,
|
||||
screenSharePosterUrl: this.props.screenSharePosterUrl,
|
||||
screenShareVideoObject: this.state.screenShareVideoObject,
|
||||
showContextRoomName: true,
|
||||
useDesktopPaths: false},
|
||||
React.createElement(StandaloneRoomInfoArea, {activeRoomStore: this.props.activeRoomStore,
|
||||
|
@ -513,7 +513,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
*/
|
||||
_isLocalLoading: function () {
|
||||
return this.state.roomState === ROOM_STATES.MEDIA_WAIT &&
|
||||
!this.state.localSrcVideoObject;
|
||||
!this.state.localSrcMediaElement;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -525,7 +525,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
*/
|
||||
_isRemoteLoading: function() {
|
||||
return !!(this.state.roomState === ROOM_STATES.HAS_PARTICIPANTS &&
|
||||
!this.state.remoteSrcVideoObject &&
|
||||
!this.state.remoteSrcMediaElement &&
|
||||
!this.state.mediaConnected);
|
||||
},
|
||||
|
||||
@ -538,7 +538,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
*/
|
||||
_isScreenShareLoading: function() {
|
||||
return this.state.receivingScreenShare &&
|
||||
!this.state.screenShareVideoObject &&
|
||||
!this.state.screenShareMediaElement &&
|
||||
!this.props.screenSharePosterUrl;
|
||||
},
|
||||
|
||||
@ -557,14 +557,14 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
isRemoteLoading={this._isRemoteLoading()}
|
||||
isScreenShareLoading={this._isScreenShareLoading()}
|
||||
localPosterUrl={this.props.localPosterUrl}
|
||||
localSrcVideoObject={this.state.localSrcVideoObject}
|
||||
localSrcMediaElement={this.state.localSrcMediaElement}
|
||||
localVideoMuted={this.state.videoMuted}
|
||||
matchMedia={this.state.matchMedia || window.matchMedia.bind(window)}
|
||||
remotePosterUrl={this.props.remotePosterUrl}
|
||||
remoteSrcVideoObject={this.state.remoteSrcVideoObject}
|
||||
remoteSrcMediaElement={this.state.remoteSrcMediaElement}
|
||||
renderRemoteVideo={this.shouldRenderRemoteVideo()}
|
||||
screenShareMediaElement={this.state.screenShareMediaElement}
|
||||
screenSharePosterUrl={this.props.screenSharePosterUrl}
|
||||
screenShareVideoObject={this.state.screenShareVideoObject}
|
||||
showContextRoomName={true}
|
||||
useDesktopPaths={false}>
|
||||
<StandaloneRoomInfoArea activeRoomStore={this.props.activeRoomStore}
|
||||
|
@ -538,7 +538,7 @@ describe("loop.conversationViews", function () {
|
||||
|
||||
it("should display the remote video when the stream is enabled", function() {
|
||||
conversationStore.setStoreState({
|
||||
remoteSrcVideoObject: { fake: 1 }
|
||||
remoteSrcMediaElement: { fake: 1 }
|
||||
});
|
||||
|
||||
view = mountTestComponent({
|
||||
@ -551,7 +551,7 @@ describe("loop.conversationViews", function () {
|
||||
|
||||
it("should display the local video when the stream is enabled", function() {
|
||||
conversationStore.setStoreState({
|
||||
localSrcVideoObject: { fake: 1 }
|
||||
localSrcMediaElement: { fake: 1 }
|
||||
});
|
||||
|
||||
view = mountTestComponent({
|
||||
|
@ -594,11 +594,11 @@ describe("loop.roomViews", function () {
|
||||
sinon.assert.calledOnce(onCallTerminatedStub);
|
||||
});
|
||||
|
||||
it("should display loading spinner when localSrcVideoObject is null",
|
||||
it("should display loading spinner when localSrcMediaElement is null",
|
||||
function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.MEDIA_WAIT,
|
||||
localSrcVideoObject: null
|
||||
localSrcMediaElement: null
|
||||
});
|
||||
|
||||
view = mountTestComponent();
|
||||
@ -611,7 +611,7 @@ describe("loop.roomViews", function () {
|
||||
function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.MEDIA_WAIT,
|
||||
localSrcVideoObject: { fake: "video" }
|
||||
localSrcMediaElement: { fake: "video" }
|
||||
});
|
||||
|
||||
view = mountTestComponent();
|
||||
@ -624,7 +624,7 @@ describe("loop.roomViews", function () {
|
||||
function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: null
|
||||
remoteSrcMediaElement: null
|
||||
});
|
||||
|
||||
view = mountTestComponent();
|
||||
@ -637,7 +637,7 @@ describe("loop.roomViews", function () {
|
||||
function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: { fake: "video" }
|
||||
remoteSrcMediaElement: { fake: "video" }
|
||||
});
|
||||
|
||||
view = mountTestComponent();
|
||||
@ -664,7 +664,7 @@ describe("loop.roomViews", function () {
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
mediaConnected: true,
|
||||
remoteVideoEnabled: true,
|
||||
remoteSrcVideoObject: { fake: 1 }
|
||||
remoteSrcMediaElement: { fake: 1 }
|
||||
});
|
||||
|
||||
view = mountTestComponent();
|
||||
@ -684,7 +684,7 @@ describe("loop.roomViews", function () {
|
||||
|
||||
it("should display the local video when the stream is enabled", function() {
|
||||
activeRoomStore.setStoreState({
|
||||
localSrcVideoObject: { fake: 1 },
|
||||
localSrcMediaElement: { fake: 1 },
|
||||
videoMuted: false
|
||||
});
|
||||
|
||||
|
@ -995,23 +995,23 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
});
|
||||
|
||||
describe("#mediaStreamCreated", function() {
|
||||
var fakeVideoElement;
|
||||
var fakeStreamElement;
|
||||
|
||||
beforeEach(function() {
|
||||
fakeVideoElement = {name: "fakeVideoElement"};
|
||||
fakeStreamElement = {name: "fakeStreamElement"};
|
||||
});
|
||||
|
||||
it("should add a local video object to the store", function() {
|
||||
expect(store.getStoreState()).to.not.have.property("localSrcVideoObject");
|
||||
expect(store.getStoreState()).to.not.have.property("localSrcMediaElement");
|
||||
|
||||
store.mediaStreamCreated(new sharedActions.MediaStreamCreated({
|
||||
hasVideo: false,
|
||||
isLocal: true,
|
||||
srcVideoObject: fakeVideoElement
|
||||
srcMediaElement: fakeStreamElement
|
||||
}));
|
||||
|
||||
expect(store.getStoreState().localSrcVideoObject).eql(fakeVideoElement);
|
||||
expect(store.getStoreState()).to.not.have.property("remoteSrcVideoObject");
|
||||
expect(store.getStoreState().localSrcMediaElement).eql(fakeStreamElement);
|
||||
expect(store.getStoreState()).to.not.have.property("remoteSrcMediaElement");
|
||||
});
|
||||
|
||||
it("should set the local video enabled", function() {
|
||||
@ -1023,7 +1023,7 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
store.mediaStreamCreated(new sharedActions.MediaStreamCreated({
|
||||
hasVideo: true,
|
||||
isLocal: true,
|
||||
srcVideoObject: fakeVideoElement
|
||||
srcMediaElement: fakeStreamElement
|
||||
}));
|
||||
|
||||
expect(store.getStoreState().localVideoEnabled).eql(true);
|
||||
@ -1031,16 +1031,16 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
});
|
||||
|
||||
it("should add a remote video object to the store", function() {
|
||||
expect(store.getStoreState()).to.not.have.property("remoteSrcVideoObject");
|
||||
expect(store.getStoreState()).to.not.have.property("remoteSrcMediaElement");
|
||||
|
||||
store.mediaStreamCreated(new sharedActions.MediaStreamCreated({
|
||||
hasVideo: false,
|
||||
isLocal: false,
|
||||
srcVideoObject: fakeVideoElement
|
||||
srcMediaElement: fakeStreamElement
|
||||
}));
|
||||
|
||||
expect(store.getStoreState()).not.have.property("localSrcVideoObject");
|
||||
expect(store.getStoreState().remoteSrcVideoObject).eql(fakeVideoElement);
|
||||
expect(store.getStoreState()).not.have.property("localSrcMediaElement");
|
||||
expect(store.getStoreState().remoteSrcMediaElement).eql(fakeStreamElement);
|
||||
});
|
||||
|
||||
it("should set the remote video enabled", function() {
|
||||
@ -1052,7 +1052,7 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
store.mediaStreamCreated(new sharedActions.MediaStreamCreated({
|
||||
hasVideo: true,
|
||||
isLocal: false,
|
||||
srcVideoObject: fakeVideoElement
|
||||
srcMediaElement: fakeStreamElement
|
||||
}));
|
||||
|
||||
expect(store.getStoreState().localVideoEnabled).eql(false);
|
||||
@ -1061,14 +1061,14 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
});
|
||||
|
||||
describe("#mediaStreamDestroyed", function() {
|
||||
var fakeVideoElement;
|
||||
var fakeStreamElement;
|
||||
|
||||
beforeEach(function() {
|
||||
fakeVideoElement = {name: "fakeVideoElement"};
|
||||
fakeStreamElement = {name: "fakeStreamElement"};
|
||||
|
||||
store.setStoreState({
|
||||
localSrcVideoObject: fakeVideoElement,
|
||||
remoteSrcVideoObject: fakeVideoElement
|
||||
localSrcMediaElement: fakeStreamElement,
|
||||
remoteSrcMediaElement: fakeStreamElement
|
||||
});
|
||||
});
|
||||
|
||||
@ -1077,8 +1077,8 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
isLocal: true
|
||||
}));
|
||||
|
||||
expect(store.getStoreState().localSrcVideoObject).eql(null);
|
||||
expect(store.getStoreState().remoteSrcVideoObject).eql(fakeVideoElement);
|
||||
expect(store.getStoreState().localSrcMediaElement).eql(null);
|
||||
expect(store.getStoreState().remoteSrcMediaElement).eql(fakeStreamElement);
|
||||
});
|
||||
|
||||
it("should clear the remote video object", function() {
|
||||
@ -1086,8 +1086,8 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
isLocal: false
|
||||
}));
|
||||
|
||||
expect(store.getStoreState().localSrcVideoObject).eql(fakeVideoElement);
|
||||
expect(store.getStoreState().remoteSrcVideoObject).eql(null);
|
||||
expect(store.getStoreState().localSrcMediaElement).eql(fakeStreamElement);
|
||||
expect(store.getStoreState().remoteSrcMediaElement).eql(null);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1166,32 +1166,32 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
expect(store.getStoreState().receivingScreenShare).eql(true);
|
||||
});
|
||||
|
||||
it("should add a screenShareVideoObject to the store when sharing is active", function() {
|
||||
var fakeVideoElement = {name: "fakeVideoElement"};
|
||||
expect(store.getStoreState()).to.not.have.property("screenShareVideoObject");
|
||||
it("should add a screenShareMediaElement to the store when sharing is active", function() {
|
||||
var fakeStreamElement = {name: "fakeStreamElement"};
|
||||
expect(store.getStoreState()).to.not.have.property("screenShareMediaElement");
|
||||
|
||||
store.receivingScreenShare(new sharedActions.ReceivingScreenShare({
|
||||
receiving: true,
|
||||
srcVideoObject: fakeVideoElement
|
||||
srcMediaElement: fakeStreamElement
|
||||
}));
|
||||
|
||||
expect(store.getStoreState()).to.have.property("screenShareVideoObject",
|
||||
fakeVideoElement);
|
||||
expect(store.getStoreState()).to.have.property("screenShareMediaElement",
|
||||
fakeStreamElement);
|
||||
});
|
||||
|
||||
it("should clear the screenShareVideoObject from the store when sharing is inactive", function() {
|
||||
it("should clear the screenShareMediaElement from the store when sharing is inactive", function() {
|
||||
store.setStoreState({
|
||||
screenShareVideoObject: {
|
||||
name: "fakeVideoElement"
|
||||
screenShareMediaElement: {
|
||||
name: "fakeStreamElement"
|
||||
}
|
||||
});
|
||||
|
||||
store.receivingScreenShare(new sharedActions.ReceivingScreenShare({
|
||||
receiving: false,
|
||||
srcVideoObject: null
|
||||
srcMediaElement: null
|
||||
}));
|
||||
|
||||
expect(store.getStoreState().screenShareVideoObject).eql(null);
|
||||
expect(store.getStoreState().screenShareMediaElement).eql(null);
|
||||
});
|
||||
|
||||
it("should delete the screen remote video dimensions if screen sharing is not active", function() {
|
||||
@ -1356,14 +1356,14 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
expect(store.getStoreState().mediaConnected).eql(false);
|
||||
});
|
||||
|
||||
it("should clear the remoteSrcVideoObject", function() {
|
||||
it("should clear the remoteSrcMediaElement", function() {
|
||||
store.setStoreState({
|
||||
remoteSrcVideoObject: { name: "fakeVideoElement" }
|
||||
remoteSrcMediaElement: { name: "fakeStreamElement" }
|
||||
});
|
||||
|
||||
store.remotePeerDisconnected();
|
||||
|
||||
expect(store.getStoreState().remoteSrcVideoObject).eql(null);
|
||||
expect(store.getStoreState().remoteSrcMediaElement).eql(null);
|
||||
});
|
||||
|
||||
it("should remove non-owner participants", function() {
|
||||
|
@ -14,7 +14,7 @@ describe("loop.store.ConversationStore", function () {
|
||||
var sharedActions = loop.shared.actions;
|
||||
var sharedUtils = loop.shared.utils;
|
||||
var sandbox, dispatcher, client, store, fakeSessionData, sdkDriver;
|
||||
var contact, fakeMozLoop, fakeVideoElement;
|
||||
var contact, fakeMozLoop, fakeStreamElement;
|
||||
var connectPromise, resolveConnectPromise, rejectConnectPromise;
|
||||
var wsCancelSpy, wsCloseSpy, wsDeclineSpy, wsMediaUpSpy, fakeWebsocket;
|
||||
|
||||
@ -95,7 +95,7 @@ describe("loop.store.ConversationStore", function () {
|
||||
progressURL: "fakeURL"
|
||||
};
|
||||
|
||||
fakeVideoElement = { id: "fakeVideoElement" };
|
||||
fakeStreamElement = { id: "fakeStreamElement" };
|
||||
|
||||
var dummySocket = {
|
||||
close: sinon.spy(),
|
||||
@ -957,16 +957,16 @@ describe("loop.store.ConversationStore", function () {
|
||||
|
||||
describe("#mediaStreamCreated", function() {
|
||||
it("should add a local video object to the store", function() {
|
||||
expect(store.getStoreState()).to.not.have.property("localSrcVideoObject");
|
||||
expect(store.getStoreState()).to.not.have.property("localSrcMediaElement");
|
||||
|
||||
store.mediaStreamCreated(new sharedActions.MediaStreamCreated({
|
||||
hasVideo: false,
|
||||
isLocal: true,
|
||||
srcVideoObject: fakeVideoElement
|
||||
srcMediaElement: fakeStreamElement
|
||||
}));
|
||||
|
||||
expect(store.getStoreState().localSrcVideoObject).eql(fakeVideoElement);
|
||||
expect(store.getStoreState()).to.not.have.property("remoteSrcVideoObject");
|
||||
expect(store.getStoreState().localSrcMediaElement).eql(fakeStreamElement);
|
||||
expect(store.getStoreState()).to.not.have.property("remoteSrcMediaElement");
|
||||
});
|
||||
|
||||
it("should set the local video enabled", function() {
|
||||
@ -978,7 +978,7 @@ describe("loop.store.ConversationStore", function () {
|
||||
store.mediaStreamCreated(new sharedActions.MediaStreamCreated({
|
||||
hasVideo: true,
|
||||
isLocal: true,
|
||||
srcVideoObject: fakeVideoElement
|
||||
srcMediaElement: fakeStreamElement
|
||||
}));
|
||||
|
||||
expect(store.getStoreState().localVideoEnabled).eql(true);
|
||||
@ -986,16 +986,16 @@ describe("loop.store.ConversationStore", function () {
|
||||
});
|
||||
|
||||
it("should add a remote video object to the store", function() {
|
||||
expect(store.getStoreState()).to.not.have.property("remoteSrcVideoObject");
|
||||
expect(store.getStoreState()).to.not.have.property("remoteSrcMediaElement");
|
||||
|
||||
store.mediaStreamCreated(new sharedActions.MediaStreamCreated({
|
||||
hasVideo: false,
|
||||
isLocal: false,
|
||||
srcVideoObject: fakeVideoElement
|
||||
srcMediaElement: fakeStreamElement
|
||||
}));
|
||||
|
||||
expect(store.getStoreState()).not.have.property("localSrcVideoObject");
|
||||
expect(store.getStoreState().remoteSrcVideoObject).eql(fakeVideoElement);
|
||||
expect(store.getStoreState()).not.have.property("localSrcMediaElement");
|
||||
expect(store.getStoreState().remoteSrcMediaElement).eql(fakeStreamElement);
|
||||
});
|
||||
|
||||
it("should set the remote video enabled", function() {
|
||||
@ -1007,7 +1007,7 @@ describe("loop.store.ConversationStore", function () {
|
||||
store.mediaStreamCreated(new sharedActions.MediaStreamCreated({
|
||||
hasVideo: true,
|
||||
isLocal: false,
|
||||
srcVideoObject: fakeVideoElement
|
||||
srcMediaElement: fakeStreamElement
|
||||
}));
|
||||
|
||||
expect(store.getStoreState().localVideoEnabled).eql(false);
|
||||
@ -1018,8 +1018,8 @@ describe("loop.store.ConversationStore", function () {
|
||||
describe("#mediaStreamDestroyed", function() {
|
||||
beforeEach(function() {
|
||||
store.setStoreState({
|
||||
localSrcVideoObject: fakeVideoElement,
|
||||
remoteSrcVideoObject: fakeVideoElement
|
||||
localSrcMediaElement: fakeStreamElement,
|
||||
remoteSrcMediaElement: fakeStreamElement
|
||||
});
|
||||
});
|
||||
|
||||
@ -1028,8 +1028,8 @@ describe("loop.store.ConversationStore", function () {
|
||||
isLocal: true
|
||||
}));
|
||||
|
||||
expect(store.getStoreState().localSrcVideoObject).eql(null);
|
||||
expect(store.getStoreState().remoteSrcVideoObject).eql(fakeVideoElement);
|
||||
expect(store.getStoreState().localSrcMediaElement).eql(null);
|
||||
expect(store.getStoreState().remoteSrcMediaElement).eql(fakeStreamElement);
|
||||
});
|
||||
|
||||
it("should clear the remote video object", function() {
|
||||
@ -1037,8 +1037,8 @@ describe("loop.store.ConversationStore", function () {
|
||||
isLocal: false
|
||||
}));
|
||||
|
||||
expect(store.getStoreState().localSrcVideoObject).eql(fakeVideoElement);
|
||||
expect(store.getStoreState().remoteSrcVideoObject).eql(null);
|
||||
expect(store.getStoreState().localSrcMediaElement).eql(fakeStreamElement);
|
||||
expect(store.getStoreState().remoteSrcMediaElement).eql(null);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -901,7 +901,7 @@ describe("loop.OTSdkDriver", function () {
|
||||
new sharedActions.MediaStreamCreated({
|
||||
hasVideo: true,
|
||||
isLocal: true,
|
||||
srcVideoObject: fakeMockVideo
|
||||
srcMediaElement: fakeMockVideo
|
||||
}));
|
||||
});
|
||||
|
||||
@ -914,7 +914,7 @@ describe("loop.OTSdkDriver", function () {
|
||||
new sharedActions.MediaStreamCreated({
|
||||
hasVideo: false,
|
||||
isLocal: true,
|
||||
srcVideoObject: fakeMockVideo
|
||||
srcMediaElement: fakeMockVideo
|
||||
}));
|
||||
});
|
||||
|
||||
@ -989,7 +989,7 @@ describe("loop.OTSdkDriver", function () {
|
||||
new sharedActions.MediaStreamCreated({
|
||||
hasVideo: true,
|
||||
isLocal: false,
|
||||
srcVideoObject: videoElement
|
||||
srcMediaElement: videoElement
|
||||
}));
|
||||
});
|
||||
|
||||
@ -1006,7 +1006,7 @@ describe("loop.OTSdkDriver", function () {
|
||||
new sharedActions.MediaStreamCreated({
|
||||
hasVideo: false,
|
||||
isLocal: false,
|
||||
srcVideoObject: videoElement
|
||||
srcMediaElement: videoElement
|
||||
}));
|
||||
});
|
||||
|
||||
|
@ -1246,7 +1246,7 @@ describe("loop.shared.views", function() {
|
||||
mediaType: "local",
|
||||
// This doesn't actually get assigned to the video element, but is enough
|
||||
// for this test to check display of the video element.
|
||||
srcVideoObject: {
|
||||
srcMediaElement: {
|
||||
fake: 1
|
||||
}
|
||||
});
|
||||
@ -1272,7 +1272,7 @@ describe("loop.shared.views", function() {
|
||||
view = mountTestComponent({
|
||||
displayAvatar: false,
|
||||
mediaType: "local",
|
||||
srcVideoObject: {
|
||||
srcMediaElement: {
|
||||
fake: 1
|
||||
}
|
||||
});
|
||||
@ -1404,7 +1404,7 @@ describe("loop.shared.views", function() {
|
||||
|
||||
it("should not mark the wrapper as showing local streams when not displaying a stream", function() {
|
||||
view = mountTestComponent({
|
||||
localSrcVideoObject: null,
|
||||
localSrcMediaElement: null,
|
||||
localPosterUrl: null
|
||||
});
|
||||
|
||||
@ -1414,7 +1414,7 @@ describe("loop.shared.views", function() {
|
||||
|
||||
it("should mark the wrapper as showing local streams when displaying a stream", function() {
|
||||
view = mountTestComponent({
|
||||
localSrcVideoObject: {},
|
||||
localSrcMediaElement: {},
|
||||
localPosterUrl: null
|
||||
});
|
||||
|
||||
@ -1424,7 +1424,7 @@ describe("loop.shared.views", function() {
|
||||
|
||||
it("should mark the wrapper as showing local streams when displaying a poster url", function() {
|
||||
view = mountTestComponent({
|
||||
localSrcVideoObject: {},
|
||||
localSrcMediaElement: {},
|
||||
localPosterUrl: "fake/url"
|
||||
});
|
||||
|
||||
@ -1434,7 +1434,7 @@ describe("loop.shared.views", function() {
|
||||
|
||||
it("should not mark the wrapper as showing remote streams when not displaying a stream", function() {
|
||||
view = mountTestComponent({
|
||||
remoteSrcVideoObject: null,
|
||||
remoteSrcMediaElement: null,
|
||||
remotePosterUrl: null
|
||||
});
|
||||
|
||||
@ -1444,7 +1444,7 @@ describe("loop.shared.views", function() {
|
||||
|
||||
it("should mark the wrapper as showing remote streams when displaying a stream", function() {
|
||||
view = mountTestComponent({
|
||||
remoteSrcVideoObject: {},
|
||||
remoteSrcMediaElement: {},
|
||||
remotePosterUrl: null
|
||||
});
|
||||
|
||||
@ -1454,7 +1454,7 @@ describe("loop.shared.views", function() {
|
||||
|
||||
it("should mark the wrapper as showing remote streams when displaying a poster url", function() {
|
||||
view = mountTestComponent({
|
||||
remoteSrcVideoObject: {},
|
||||
remoteSrcMediaElement: {},
|
||||
remotePosterUrl: "fake/url"
|
||||
});
|
||||
|
||||
|
@ -486,10 +486,10 @@ describe("loop.standaloneRoomViews", function() {
|
||||
|
||||
describe("screenShare", function() {
|
||||
it("should show a loading screen if receivingScreenShare is true " +
|
||||
"but no screenShareVideoObject is present", function() {
|
||||
"but no screenShareMediaElement is present", function() {
|
||||
view.setState({
|
||||
"receivingScreenShare": true,
|
||||
"screenShareVideoObject": null
|
||||
"screenShareMediaElement": null
|
||||
});
|
||||
|
||||
expect(view.getDOMNode().querySelector(".screen .loading-stream"))
|
||||
@ -497,23 +497,23 @@ describe("loop.standaloneRoomViews", function() {
|
||||
});
|
||||
|
||||
it("should not show loading screen if receivingScreenShare is false " +
|
||||
"and screenShareVideoObject is null", function() {
|
||||
"and screenShareMediaElement is null", function() {
|
||||
view.setState({
|
||||
"receivingScreenShare": false,
|
||||
"screenShareVideoObject": null
|
||||
"screenShareMediaElement": null
|
||||
});
|
||||
|
||||
expect(view.getDOMNode().querySelector(".screen .loading-stream"))
|
||||
.eql(null);
|
||||
});
|
||||
|
||||
it("should not show a loading screen if screenShareVideoObject is set",
|
||||
it("should not show a loading screen if screenShareMediaElement is set",
|
||||
function() {
|
||||
var videoElement = document.createElement("video");
|
||||
|
||||
view.setState({
|
||||
"receivingScreenShare": true,
|
||||
"screenShareVideoObject": videoElement
|
||||
"screenShareMediaElement": videoElement
|
||||
});
|
||||
|
||||
expect(view.getDOMNode().querySelector(".screen .loading-stream"))
|
||||
@ -531,7 +531,7 @@ describe("loop.standaloneRoomViews", function() {
|
||||
it("should render local video when video_muted is false", function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
localSrcVideoObject: videoElement,
|
||||
localSrcMediaElement: videoElement,
|
||||
videoMuted: false
|
||||
});
|
||||
|
||||
@ -547,33 +547,33 @@ describe("loop.standaloneRoomViews", function() {
|
||||
expect(view.getDOMNode().querySelector(".local .avatar")).eql(null);
|
||||
});
|
||||
|
||||
it("should render local loading screen when no srcVideoObject",
|
||||
it("should render local loading screen when no srcMediaElement",
|
||||
function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.MEDIA_WAIT,
|
||||
remoteSrcVideoObject: null
|
||||
remoteSrcMediaElement: null
|
||||
});
|
||||
|
||||
expect(view.getDOMNode().querySelector(".local .loading-stream"))
|
||||
.not.eql(null);
|
||||
});
|
||||
|
||||
it("should not render local loading screen when srcVideoObject is set",
|
||||
it("should not render local loading screen when srcMediaElement is set",
|
||||
function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.MEDIA_WAIT,
|
||||
localSrcVideoObject: videoElement
|
||||
localSrcMediaElement: videoElement
|
||||
});
|
||||
|
||||
expect(view.getDOMNode().querySelector(".local .loading-stream"))
|
||||
.eql(null);
|
||||
});
|
||||
|
||||
it("should not render remote loading screen when srcVideoObject is set",
|
||||
it("should not render remote loading screen when srcMediaElement is set",
|
||||
function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: videoElement
|
||||
remoteSrcMediaElement: videoElement
|
||||
});
|
||||
|
||||
expect(view.getDOMNode().querySelector(".remote .loading-stream"))
|
||||
@ -584,7 +584,7 @@ describe("loop.standaloneRoomViews", function() {
|
||||
" remoteVideoEnabled is true", function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: videoElement,
|
||||
remoteSrcMediaElement: videoElement,
|
||||
remoteVideoEnabled: true
|
||||
});
|
||||
|
||||
@ -595,7 +595,7 @@ describe("loop.standaloneRoomViews", function() {
|
||||
" remoteVideoEnabled is true", function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: videoElement,
|
||||
remoteSrcMediaElement: videoElement,
|
||||
remoteVideoEnabled: true
|
||||
});
|
||||
|
||||
@ -606,7 +606,7 @@ describe("loop.standaloneRoomViews", function() {
|
||||
" remoteVideoEnabled is false, and mediaConnected is true", function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: videoElement,
|
||||
remoteSrcMediaElement: videoElement,
|
||||
mediaConnected: true,
|
||||
remoteVideoEnabled: false
|
||||
});
|
||||
@ -618,7 +618,7 @@ describe("loop.standaloneRoomViews", function() {
|
||||
" and both remoteVideoEnabled and mediaConnected are false", function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: videoElement,
|
||||
remoteSrcMediaElement: videoElement,
|
||||
mediaConnected: false,
|
||||
remoteVideoEnabled: false
|
||||
});
|
||||
@ -629,7 +629,7 @@ describe("loop.standaloneRoomViews", function() {
|
||||
it("should not render a remote avatar when the room is in MEDIA_WAIT", function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.MEDIA_WAIT,
|
||||
remoteSrcVideoObject: videoElement,
|
||||
remoteSrcMediaElement: videoElement,
|
||||
remoteVideoEnabled: false
|
||||
});
|
||||
|
||||
@ -640,7 +640,7 @@ describe("loop.standaloneRoomViews", function() {
|
||||
" remoteVideoEnabled is false", function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.CLOSING,
|
||||
remoteSrcVideoObject: videoElement,
|
||||
remoteSrcMediaElement: videoElement,
|
||||
remoteVideoEnabled: false
|
||||
});
|
||||
|
||||
@ -651,7 +651,7 @@ describe("loop.standaloneRoomViews", function() {
|
||||
"remoteVideoEnabled is false, and mediaConnected is true", function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: videoElement,
|
||||
remoteSrcMediaElement: videoElement,
|
||||
remoteVideoEnabled: false,
|
||||
mediaConnected: true
|
||||
});
|
||||
@ -660,10 +660,10 @@ describe("loop.standaloneRoomViews", function() {
|
||||
});
|
||||
|
||||
it("should render a remote avatar when the room HAS_PARTICIPANTS, " +
|
||||
"remoteSrcVideoObject is false, mediaConnected is true", function() {
|
||||
"remoteSrcMediaElement is false, mediaConnected is true", function() {
|
||||
activeRoomStore.setStoreState({
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: null,
|
||||
remoteSrcMediaElement: null,
|
||||
remoteVideoEnabled: false,
|
||||
mediaConnected: true
|
||||
});
|
||||
|
@ -205,7 +205,7 @@
|
||||
var loadingRemoteVideoRoomStore = makeActiveRoomStore({
|
||||
mediaConnected: false,
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: false
|
||||
remoteSrcMediaElement: false
|
||||
});
|
||||
|
||||
var readyRoomStore = makeActiveRoomStore({
|
||||
@ -246,7 +246,7 @@
|
||||
mediaConnected: false,
|
||||
receivingScreenShare: true,
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: false
|
||||
remoteSrcMediaElement: false
|
||||
});
|
||||
var loadingScreenSharingRoomStore = makeActiveRoomStore({
|
||||
receivingScreenShare: true,
|
||||
@ -256,11 +256,11 @@
|
||||
/* Set up the stores for pending screen sharing */
|
||||
loadingScreenSharingRoomStore.receivingScreenShare({
|
||||
receiving: true,
|
||||
srcVideoObject: false
|
||||
srcMediaElement: false
|
||||
});
|
||||
loadingRemoteLoadingScreenStore.receivingScreenShare({
|
||||
receiving: true,
|
||||
srcVideoObject: false
|
||||
srcMediaElement: false
|
||||
});
|
||||
|
||||
var fullActiveRoomStore = makeActiveRoomStore({
|
||||
@ -295,7 +295,7 @@
|
||||
activeRoomStore: makeActiveRoomStore({
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
mediaConnected: false,
|
||||
remoteSrcVideoObject: false
|
||||
remoteSrcMediaElement: false
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -205,7 +205,7 @@
|
||||
var loadingRemoteVideoRoomStore = makeActiveRoomStore({
|
||||
mediaConnected: false,
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: false
|
||||
remoteSrcMediaElement: false
|
||||
});
|
||||
|
||||
var readyRoomStore = makeActiveRoomStore({
|
||||
@ -246,7 +246,7 @@
|
||||
mediaConnected: false,
|
||||
receivingScreenShare: true,
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
remoteSrcVideoObject: false
|
||||
remoteSrcMediaElement: false
|
||||
});
|
||||
var loadingScreenSharingRoomStore = makeActiveRoomStore({
|
||||
receivingScreenShare: true,
|
||||
@ -256,11 +256,11 @@
|
||||
/* Set up the stores for pending screen sharing */
|
||||
loadingScreenSharingRoomStore.receivingScreenShare({
|
||||
receiving: true,
|
||||
srcVideoObject: false
|
||||
srcMediaElement: false
|
||||
});
|
||||
loadingRemoteLoadingScreenStore.receivingScreenShare({
|
||||
receiving: true,
|
||||
srcVideoObject: false
|
||||
srcMediaElement: false
|
||||
});
|
||||
|
||||
var fullActiveRoomStore = makeActiveRoomStore({
|
||||
@ -295,7 +295,7 @@
|
||||
activeRoomStore: makeActiveRoomStore({
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS,
|
||||
mediaConnected: false,
|
||||
remoteSrcVideoObject: false
|
||||
remoteSrcMediaElement: false
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -2114,7 +2114,7 @@ public abstract class GeckoApp
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
rec.close();
|
||||
rec.close(GeckoApp.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -34,8 +34,9 @@ public class ProfileInformationCache implements ProfileInformationProvider {
|
||||
* 1: Add versioning (Bug 878670).
|
||||
* 2: Bump to regenerate add-on set after landing Bug 900694 (Bug 901622).
|
||||
* 3: Add distribution, osLocale, appLocale.
|
||||
* 4: Add experiments as add-ons.
|
||||
*/
|
||||
public static final int FORMAT_VERSION = 3;
|
||||
public static final int FORMAT_VERSION = 4;
|
||||
|
||||
protected boolean initialized = false;
|
||||
protected boolean needsWrite = false;
|
||||
|
@ -8,6 +8,7 @@ package org.mozilla.gecko.health;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.lang.String;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -38,9 +39,15 @@ import org.mozilla.gecko.distribution.Distribution.DistributionDescriptor;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import com.keepsafe.switchboard.SwitchBoard;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
@ -59,7 +66,7 @@ import android.util.Log;
|
||||
*
|
||||
* Shut it down when you're done being a browser: {@link #close()}.
|
||||
*/
|
||||
public class BrowserHealthRecorder implements HealthRecorder, GeckoEventListener {
|
||||
public class BrowserHealthRecorder extends BroadcastReceiver implements HealthRecorder, GeckoEventListener {
|
||||
private static final String LOG_TAG = "GeckoHealthRec";
|
||||
private static final String PREF_ACCEPT_LANG = "intl.accept_languages";
|
||||
private static final String PREF_BLOCKLIST_ENABLED = "extensions.blocklist.enabled";
|
||||
@ -177,7 +184,7 @@ public class BrowserHealthRecorder implements HealthRecorder, GeckoEventListener
|
||||
* provider-specific uninitialization.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
public synchronized void close(final Context context) {
|
||||
switch (this.state) {
|
||||
case CLOSED:
|
||||
Log.w(LOG_TAG, "Ignoring attempt to double-close closed BrowserHealthRecorder.");
|
||||
@ -191,6 +198,9 @@ public class BrowserHealthRecorder implements HealthRecorder, GeckoEventListener
|
||||
|
||||
this.state = State.CLOSED;
|
||||
this.unregisterEventListeners();
|
||||
if (AppConstants.MOZ_SWITCHBOARD) {
|
||||
LocalBroadcastManager.getInstance(context).unregisterReceiver(this);
|
||||
}
|
||||
|
||||
// Add any necessary provider uninitialization here.
|
||||
this.storage = null;
|
||||
@ -523,6 +533,12 @@ public class BrowserHealthRecorder implements HealthRecorder, GeckoEventListener
|
||||
this.profileCache.updateLocales(osLocale, appLocale);
|
||||
this.profileCache.completeInitialization();
|
||||
|
||||
// Listen for experiment changes.
|
||||
if (AppConstants.MOZ_SWITCHBOARD) {
|
||||
IntentFilter intentFilter = new IntentFilter(SwitchBoard.ACTION_CONFIG_FETCHED);
|
||||
LocalBroadcastManager.getInstance(context).registerReceiver(this, intentFilter);
|
||||
}
|
||||
|
||||
Log.d(LOG_TAG, "Successfully restored state. Initializing storage.");
|
||||
initializeStorage();
|
||||
return;
|
||||
@ -626,6 +642,23 @@ public class BrowserHealthRecorder implements HealthRecorder, GeckoEventListener
|
||||
try {
|
||||
JSONObject json = message.getJSONObject("json");
|
||||
JSONObject addons = json.getJSONObject("addons");
|
||||
|
||||
// Treat active experiments as add-ons
|
||||
if (AppConstants.MOZ_SWITCHBOARD) {
|
||||
List<String> experiments = SwitchBoard.getActiveExperiments(GeckoAppShell.getContext());
|
||||
for (String experiment : experiments) {
|
||||
// Create a fake add-on name
|
||||
String fakeName = experiment + "@experiments.mozilla.org";
|
||||
try {
|
||||
// Create a dummy JSON object for the experiment.
|
||||
JSONObject fakeAddon = new JSONObject();
|
||||
fakeAddon.put("type", "experiment");
|
||||
addons.put(fakeName, fakeAddon);
|
||||
} catch (JSONException je) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.i(LOG_TAG, "Persisting " + addons.length() + " add-ons.");
|
||||
profileCache.setJSONForAddons(addons);
|
||||
|
||||
@ -694,6 +727,71 @@ public class BrowserHealthRecorder implements HealthRecorder, GeckoEventListener
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
switch (action) {
|
||||
case SwitchBoard.ACTION_CONFIG_FETCHED:
|
||||
Log.d(LOG_TAG, "Handle the new experiments.");
|
||||
// Get the list of active experiments.
|
||||
List<String> experiments = SwitchBoard.getActiveExperiments(context);
|
||||
|
||||
// We need to figure out which ones are new and which ones were removed. Convert
|
||||
// the active experiments to the fake add-on names for easier lookup.
|
||||
ArrayList<String> addToProfile = new ArrayList<String>();
|
||||
for (String experiment : experiments) {
|
||||
addToProfile.add(experiment + "@experiments.mozilla.org");
|
||||
}
|
||||
|
||||
// Create a list of add-ons(experiments) we need to remove.
|
||||
ArrayList<String> removeFromProfile = new ArrayList<String>();
|
||||
|
||||
// Loop over the current profile set of add-ons, and figure out
|
||||
// which add-ons (experiments) are new and which need to be removed.
|
||||
JSONObject addons = this.profileCache.getAddonsJSON();
|
||||
Iterator<?> keys = addons.keys();
|
||||
while (keys.hasNext()) {
|
||||
String addon = (String) keys.next();
|
||||
if (addon.endsWith("@experiments.mozilla.org")) {
|
||||
if (addToProfile.contains(addon)) {
|
||||
// This experiment is already in the profile. We don't need to add it again.
|
||||
addToProfile.remove(addon);
|
||||
} else {
|
||||
// The active set of experiments does not include this fake add-on.
|
||||
removeFromProfile.add(addon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we don't have any changes, exit early.
|
||||
if (addToProfile.isEmpty() && removeFromProfile.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the newly active experiments into the profile.
|
||||
for (String fakeName : addToProfile) {
|
||||
try {
|
||||
// Create a dummy JSON object for the experiment.
|
||||
JSONObject fakeAddon = new JSONObject();
|
||||
fakeAddon.put("type", "experiment");
|
||||
this.onAddonChanged(fakeName, fakeAddon);
|
||||
Log.d(LOG_TAG, "Add this experiment: " + fakeName);
|
||||
} catch (JSONException je) {
|
||||
}
|
||||
}
|
||||
|
||||
// Remove experiments that are no longer active from the profile.
|
||||
for (String fakeName : removeFromProfile) {
|
||||
this.onAddonUninstalling(fakeName);
|
||||
Log.d(LOG_TAG, "Remove this experiment: " + fakeName);
|
||||
}
|
||||
|
||||
// Something changed, so update the environment.
|
||||
this.onEnvironmentChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches.
|
||||
*/
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package org.mozilla.gecko.health;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import org.json.JSONObject;
|
||||
@ -33,7 +34,7 @@ public interface HealthRecorder {
|
||||
public void onEnvironmentChanged();
|
||||
public void onEnvironmentChanged(final boolean startNewSession, final String sessionEndReason);
|
||||
|
||||
public void close();
|
||||
public void close(final Context context);
|
||||
|
||||
public void processDelayed();
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package org.mozilla.gecko.health;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import org.json.JSONObject;
|
||||
@ -45,7 +46,7 @@ public class StubbedHealthRecorder implements HealthRecorder {
|
||||
public void onEnvironmentChanged(final boolean startNewSession, final String sessionEndReason) { }
|
||||
|
||||
@Override
|
||||
public void close() { }
|
||||
public void close(final Context context) { }
|
||||
|
||||
@Override
|
||||
public void processDelayed() { }
|
||||
|
@ -22,6 +22,9 @@ import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.UUID;
|
||||
@ -31,11 +34,12 @@ import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.Build;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
/**
|
||||
* SwitchBoard is the core class of the KeepSafe Switchboard mobile A/B testing framework.
|
||||
* This class provides a bunch of static methods that can be used in your app to run A/B tests.
|
||||
@ -66,7 +70,8 @@ public class SwitchBoard {
|
||||
/** Production server for getting the actual config file. http://staging.domain/path_to/SwitchboardDriver.php */
|
||||
private static String DYNAMIC_CONFIG_SERVER_DEFAULT_URL;
|
||||
|
||||
|
||||
public static final String ACTION_CONFIG_FETCHED = ".SwitchBoard.CONFIG_FETCHED";
|
||||
|
||||
private static final String kUpdateServerUrl = "updateServerUrl";
|
||||
private static final String kConfigServerUrl = "configServerUrl";
|
||||
|
||||
@ -229,6 +234,10 @@ public class SwitchBoard {
|
||||
} catch (NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//notify listeners that the config fetch has completed
|
||||
Intent i = new Intent(ACTION_CONFIG_FETCHED);
|
||||
LocalBroadcastManager.getInstance(c).sendBroadcast(i);
|
||||
}
|
||||
|
||||
public static boolean isInBucket(Context c, int low, int high) {
|
||||
@ -288,6 +297,37 @@ public class SwitchBoard {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns a list of all active experiments.
|
||||
*/
|
||||
public static List<String> getActiveExperiments(Context c) {
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
// lookup experiment in config
|
||||
String config = Preferences.getDynamicConfigJson(c);
|
||||
|
||||
// if it does not exist
|
||||
if (config == null) {
|
||||
return returnList;
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject experiments = new JSONObject(config);
|
||||
Iterator<?> iter = experiments.keys();
|
||||
while (iter.hasNext()) {
|
||||
String key = (String)iter.next();
|
||||
JSONObject experiment = experiments.getJSONObject(key);
|
||||
if (experiment.getBoolean(IS_EXPERIMENT_ACTIVE)) {
|
||||
returnList.add(key);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
// Something went wrong!
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a certain experiment exists.
|
||||
* @param c ApplicationContext
|
||||
|
Loading…
Reference in New Issue
Block a user