This commit is contained in:
Ryan VanderMeulen 2013-01-30 10:20:25 -05:00
Родитель b35109ad70 3431ca7c5f
Коммит a6bc5aed35
67 изменённых файлов: 1007 добавлений и 455 удалений

Просмотреть файл

@ -195,7 +195,8 @@ DocManager::OnStateChange(nsIWebProgress* aWebProgress,
if (loadType == LOAD_RELOAD_NORMAL ||
loadType == LOAD_RELOAD_BYPASS_CACHE ||
loadType == LOAD_RELOAD_BYPASS_PROXY ||
loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE) {
loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE ||
loadType == LOAD_RELOAD_ALLOW_MIXED_CONTENT) {
isReloading = true;
}

Просмотреть файл

@ -273,6 +273,9 @@ LogShellLoadType(nsIDocShell* aDocShell)
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
printf("reload bypass proxy and cache; ");
break;
case LOAD_RELOAD_ALLOW_MIXED_CONTENT:
printf("reload allow mixed content; ");
break;
case LOAD_LINK:
printf("link; ");
break;

Просмотреть файл

@ -757,6 +757,7 @@ pref("urlclassifier.max-complete-age", 2700);
#endif
pref("browser.geolocation.warning.infoURL", "http://www.mozilla.com/%LOCALE%/firefox/geolocation/");
pref("browser.mixedcontent.warning.infoURL", "http://support.mozilla.org/1/%APP%/%VERSION%/%OS%/%LOCALE%/mixed-content/");
pref("browser.EULA.version", 3);
pref("browser.rights.version", 3);

Просмотреть файл

@ -6648,7 +6648,7 @@ var gIdentityHandler = {
} else if (state & nsIWebProgressListener.STATE_IS_SECURE) {
this.setMode(this.IDENTITY_MODE_DOMAIN_VERIFIED);
} else if (state & nsIWebProgressListener.STATE_IS_BROKEN) {
if (gBrowser.docShell.hasMixedActiveContentLoaded) {
if (state & nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT) {
this.setMode(this.IDENTITY_MODE_MIXED_ACTIVE_CONTENT);
} else {
this.setMode(this.IDENTITY_MODE_MIXED_CONTENT);
@ -6656,6 +6656,48 @@ var gIdentityHandler = {
} else {
this.setMode(this.IDENTITY_MODE_UNKNOWN);
}
// Ensure the doorhanger is shown when mixed active content is blocked.
if (state & nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT)
this.showMixedContentDoorhanger();
},
/**
* Display the Mixed Content Blocker doohanger, providing an option
* to the user to override mixed content blocking
*/
showMixedContentDoorhanger : function() {
// If we've already got an active notification, bail out to avoid showing it repeatedly.
if (PopupNotifications.getNotification("mixed-content-blocked", gBrowser.selectedBrowser))
return;
let helplink = document.getElementById("mixed-content-blocked-helplink");
helplink.href = Services.urlFormatter.formatURLPref("browser.mixedcontent.warning.infoURL");
let brandBundle = document.getElementById("bundle_brand");
let brandShortName = brandBundle.getString("brandShortName");
let messageString = gNavigatorBundle.getFormattedString("mixedContentBlocked.message", [brandShortName]);
let action = {
label: gNavigatorBundle.getString("mixedContentBlocked.keepBlockingButton.label"),
accessKey: gNavigatorBundle.getString("mixedContentBlocked.keepBlockingButton.accesskey"),
callback: function() { /* NOP */ }
};
let secondaryActions = [
{
label: gNavigatorBundle.getString("mixedContentBlocked.unblock.label"),
accessKey: gNavigatorBundle.getString("mixedContentBlocked.unblock.accesskey"),
callback: function() {
// Reload the page with the content unblocked
BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT);
}
}
];
let options = {
dismissed: true,
};
PopupNotifications.show(gBrowser.selectedBrowser, "mixed-content-blocked",
messageString, "mixed-content-blocked-notification-icon",
action, secondaryActions, options);
},
/**

Просмотреть файл

@ -473,6 +473,17 @@
<label id="geolocation-learnmore-link" class="text-link"/>
</popupnotificationcontent>
</popupnotification>
<popupnotification id="mixed-content-blocked-notification" hidden="true">
<popupnotificationcontent orient="vertical" align="start">
<separator/>
<description id="mixed-content-blocked-moreinfo">&mixedContentBlocked.moreinfo;</description>
<separator/>
<label id="mixed-content-blocked-helplink" class="text-link"
value="&mixedContentBlocked.helplink;"/>
</popupnotificationcontent>
</popupnotification>
</popupset>
#ifdef CAN_DRAW_IN_TITLEBAR
@ -587,6 +598,7 @@
<image id="webapps-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="plugins-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="blocked-plugins-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="mixed-content-blocked-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="webRTC-shareDevices-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="webRTC-sharingDevices-notification-icon" class="notification-anchor-icon" role="button"/>
</box>

Просмотреть файл

@ -631,3 +631,6 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!ENTITY webrtcIndicatorButton.label "Camera / Microphone Access">
<!ENTITY webrtcIndicatorButton.tooltip "Display sites you are currently sharing your camera or microphone with">
<!ENTITY mixedContentBlocked.helplink "Learn more">
<!ENTITY mixedContentBlocked.moreinfo "Most websites will still work properly even when this content is blocked.">

Просмотреть файл

@ -435,3 +435,11 @@ getUserMedia.denyRequest.accesskey = D
getUserMedia.sharingCamera.message = You are currently sharing your camera with %S.
getUserMedia.sharingMicrophone.message = You are currently sharing your microphone with %S.
getUserMedia.sharingCameraAndMicrophone.message = You are currently sharing your camera and microphone with %S.
# Mixed Content Blocker Doorhanger Notification
# LOCALIZATION NOTE - %S is brandShortName
mixedContentBlocked.message = %S has blocked content that isn't secure.
mixedContentBlocked.keepBlockingButton.label = Keep Blocking
mixedContentBlocked.keepBlockingButton.accesskey = B
mixedContentBlocked.unblock.label = Disable Protection on This Page
mixedContentBlocked.unblock.accesskey = D

Просмотреть файл

@ -1302,6 +1302,10 @@ toolbar[iconsize="small"] #webrtc-status-button {
}
}
#mixed-content-blocked-notification-icon {
list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png);
}
#webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
}

Просмотреть файл

@ -30,6 +30,7 @@ browser.jar:
skin/classic/browser/identity-icons-https-mixed-active.png
skin/classic/browser/Info.png
skin/classic/browser/KUI-close.png
skin/classic/browser/mixed-content-blocked-16.png
skin/classic/browser/monitor.png
skin/classic/browser/monitor_16-10.png
* skin/classic/browser/pageInfo.css

Двоичные данные
browser/themes/gnomestripe/mixed-content-blocked-16.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 346 B

Просмотреть файл

@ -3095,6 +3095,15 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
}
}
#mixed-content-blocked-notification-icon {
list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png);
}
@media (min-resolution: 2dppx) {
#mixed-content-blocked-notification-icon {
list-style-image: url(chrome://browser/skin/mixed-content-blocked-16@2x.png);
}
}
#webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
}
@ -3188,6 +3197,19 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
list-style-image: url(chrome://browser/skin/webapps-64.png);
}
.popup-notification-icon[popupid="mixed-content-blocked"] {
list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png);
}
@media (min-resolution: 2dppx) {
.popup-notification-icon[popupid="mixed-content-blocked"] {
list-style-image: url(chrome://browser/skin/mixed-content-blocked-64@2x.png);
}
}
#mixed-content-blocked-helplink {
margin: 0px;
}
.popup-notification-icon[popupid="webRTC-sharingDevices"],
.popup-notification-icon[popupid="webRTC-shareDevices"] {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);

Просмотреть файл

@ -40,6 +40,10 @@ browser.jar:
skin/classic/browser/KUI-close.png
skin/classic/browser/menu-back.png
skin/classic/browser/menu-forward.png
skin/classic/browser/mixed-content-blocked-16.png
skin/classic/browser/mixed-content-blocked-16@2x.png
skin/classic/browser/mixed-content-blocked-64.png
skin/classic/browser/mixed-content-blocked-64@2x.png
skin/classic/browser/panel-expander-closed.png
skin/classic/browser/panel-expander-closed@2x.png
skin/classic/browser/panel-expander-open.png

Двоичные данные
browser/themes/pinstripe/mixed-content-blocked-16.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 346 B

Двоичные данные
browser/themes/pinstripe/mixed-content-blocked-16@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 691 B

Двоичные данные
browser/themes/pinstripe/mixed-content-blocked-64.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Двоичные данные
browser/themes/pinstripe/mixed-content-blocked-64@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Просмотреть файл

@ -2304,6 +2304,10 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
list-style-image: url(chrome://browser/skin/webapps-64.png);
}
.popup-notification-icon[popupid="mixed-content-blocked"] {
list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png);
}
.popup-notification-icon[popupid="webRTC-sharingDevices"],
.popup-notification-icon[popupid="webRTC-shareDevices"] {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
@ -2391,6 +2395,10 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
}
}
#mixed-content-blocked-notification-icon {
list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png);
}
#webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
}

Просмотреть файл

@ -38,6 +38,7 @@ browser.jar:
skin/classic/browser/livemark-folder.png
skin/classic/browser/menu-back.png
skin/classic/browser/menu-forward.png
skin/classic/browser/mixed-content-blocked-16.png
skin/classic/browser/monitor.png
skin/classic/browser/monitor_16-10.png
skin/classic/browser/pageInfo.css
@ -265,6 +266,7 @@ browser.jar:
skin/classic/aero/browser/livemark-folder.png (livemark-folder-aero.png)
skin/classic/aero/browser/menu-back.png (menu-back-aero.png)
skin/classic/aero/browser/menu-forward.png (menu-forward-aero.png)
skin/classic/aero/browser/mixed-content-blocked-16.png
skin/classic/aero/browser/monitor.png
skin/classic/aero/browser/monitor_16-10.png
skin/classic/aero/browser/pageInfo.css

Двоичные данные
browser/themes/winstripe/mixed-content-blocked-16.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 346 B

Просмотреть файл

@ -102,8 +102,8 @@ template<typename> class Sequence;
} // namespace mozilla
#define NS_IDOCUMENT_IID \
{ 0x2df7f766, 0xf70b, 0x4de4, \
{ 0xb0, 0xba, 0x78, 0x25, 0x07, 0x41, 0xd6, 0xce } }
{ 0x4e6f7d97, 0x091e, 0x4eda, \
{ 0xb7, 0xd6, 0xfe, 0xb0, 0xb8, 0x01, 0x2a, 0x93 } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -446,6 +446,53 @@ public:
mHasMixedActiveContentLoaded = aHasMixedActiveContentLoaded;
}
/**
* Get mixed active content blocked flag for this document.
*/
bool GetHasMixedActiveContentBlocked()
{
return mHasMixedActiveContentBlocked;
}
/**
* Set the mixed active content blocked flag for this document.
*/
void SetHasMixedActiveContentBlocked(bool aHasMixedActiveContentBlocked)
{
mHasMixedActiveContentBlocked = aHasMixedActiveContentBlocked;
}
/**
* Get the has mixed display content loaded flag for this document.
*/
bool GetHasMixedDisplayContentLoaded()
{
return mHasMixedDisplayContentLoaded;
}
/**
* Set the has mixed display content loaded flag for this document.
*/
void SetHasMixedDisplayContentLoaded(bool aHasMixedDisplayContentLoaded)
{
mHasMixedDisplayContentLoaded = aHasMixedDisplayContentLoaded;
}
/**
* Get mixed display content blocked flag for this document.
*/
bool GetHasMixedDisplayContentBlocked()
{
return mHasMixedDisplayContentBlocked;
}
/**
* Set the mixed display content blocked flag for this document.
*/
void SetHasMixedDisplayContentBlocked(bool aHasMixedDisplayContentBlocked)
{
mHasMixedDisplayContentBlocked = aHasMixedDisplayContentBlocked;
}
/**
* Get the sandbox flags for this document.
@ -2166,6 +2213,15 @@ protected:
// True if a document has loaded Mixed Active Script (see nsMixedContentBlocker.cpp)
bool mHasMixedActiveContentLoaded;
// True if a document has blocked Mixed Active Script (see nsMixedContentBlocker.cpp)
bool mHasMixedActiveContentBlocked;
// True if a document has loaded Mixed Display/Passive Content (see nsMixedContentBlocker.cpp)
bool mHasMixedDisplayContentLoaded;
// True if a document has blocked Mixed Display/Passive Content (see nsMixedContentBlocker.cpp)
bool mHasMixedDisplayContentBlocked;
// True if DisallowBFCaching has been called on this document.
bool mBFCacheDisallowed;

Просмотреть файл

@ -21,6 +21,9 @@
#include "nsIHttpChannel.h"
#include "mozilla/Preferences.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsISecureBrowserUI.h"
#include "nsIDocumentLoader.h"
#include "nsLoadGroup.h"
#include "prlog.h"
@ -72,22 +75,32 @@ public:
if (mType == eMixedScript) {
rootDoc->SetHasMixedActiveContentLoaded(true);
// See if the pref will change here. If it will, only then do we need to call OnSecurityChange() to update the UI.
if (rootDoc->GetHasMixedActiveContentLoaded()) {
return NS_OK;
}
rootDoc->SetHasMixedActiveContentLoaded(true);
// Update the security UI in the tab with the blocked mixed content
// Update the security UI in the tab with the allowed mixed active content
nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell);
if (eventSink) {
eventSink->OnSecurityChange(mContext, nsIWebProgressListener::STATE_IS_BROKEN);
eventSink->OnSecurityChange(mContext, (nsIWebProgressListener::STATE_IS_BROKEN | nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
}
} else {
if (mType == eMixedDisplay) {
//Do Nothing for now; state will already be set STATE_IS_BROKEN
}
} else if (mType == eMixedDisplay) {
// See if the pref will change here. If it will, only then do we need to call OnSecurityChange() to update the UI.
if (rootDoc->GetHasMixedDisplayContentLoaded()) {
return NS_OK;
}
rootDoc->SetHasMixedDisplayContentLoaded(true);
// Update the security UI in the tab with the allowed mixed display content.
nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell);
if (eventSink) {
eventSink->OnSecurityChange(mContext, (nsIWebProgressListener::STATE_IS_BROKEN | nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
}
}
return NS_OK;
}
private:
@ -324,11 +337,99 @@ nsMixedContentBlocker::ShouldLoad(uint32_t aContentType,
}
// If we are here we have mixed content.
// Determine if the rootDoc is https and if the user decided to allow Mixed Content
nsCOMPtr<nsIDocShell> docShell = NS_CP_GetDocShellFromContext(aRequestingContext);
NS_ENSURE_TRUE(docShell, NS_OK);
bool rootHasSecureConnection = false;
bool allowMixedContent = false;
bool isRootDocShell = false;
rv = docShell->GetAllowMixedContentAndConnectionData(&rootHasSecureConnection, &allowMixedContent, &isRootDocShell);
if (NS_FAILED(rv)) {
return rv;
}
// Get the root document from the docshell
nsCOMPtr<nsIDocShellTreeItem> currentDocShellTreeItem(do_QueryInterface(docShell));
NS_ASSERTION(currentDocShellTreeItem, "No DocShellTreeItem from docshell");
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
currentDocShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
NS_ASSERTION(sameTypeRoot, "No document shell root tree item from document shell tree item!");
nsCOMPtr<nsIDocument> rootDoc = do_GetInterface(sameTypeRoot);
NS_ASSERTION(rootDoc, "No root document from document shell root tree item.");
// Get eventSink and the current security state from the docShell
nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell);
NS_ASSERTION(eventSink, "No eventSink from docShell.");
nsCOMPtr<nsIDocShell> rootShell = do_GetInterface(sameTypeRoot);
NS_ASSERTION(rootShell, "No root docshell from document shell root tree item.");
uint32_t State = nsIWebProgressListener::STATE_IS_BROKEN;
nsCOMPtr<nsISecureBrowserUI> SecurityUI;
rootShell->GetSecurityUI(getter_AddRefs(SecurityUI));
NS_ASSERTION(SecurityUI, "No SecurityUI from the root docShell.");
nsresult stateRV = SecurityUI->GetState(&State);
// If the content is display content, and the pref says display content should be blocked, block it.
// If the content is mixed content, and the pref says mixed content should be blocked, block it.
if ( (sBlockMixedDisplay && classification == eMixedDisplay) || (sBlockMixedScript && classification == eMixedScript) ) {
*aDecision = nsIContentPolicy::REJECT_REQUEST;
return NS_OK;
if (sBlockMixedDisplay && classification == eMixedDisplay) {
if (allowMixedContent) {
*aDecision = nsIContentPolicy::ACCEPT;
rootDoc->SetHasMixedActiveContentLoaded(true);
if (!rootDoc->GetHasMixedDisplayContentLoaded() && NS_SUCCEEDED(stateRV)) {
eventSink->OnSecurityChange(aRequestingContext, (State | nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
}
} else {
*aDecision = nsIContentPolicy::REJECT_REQUEST;
if (!rootDoc->GetHasMixedDisplayContentBlocked() && NS_SUCCEEDED(stateRV)) {
eventSink->OnSecurityChange(aRequestingContext, (State | nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT));
}
}
return NS_OK;
} else if (sBlockMixedScript && classification == eMixedScript) {
// If the content is active content, and the pref says active content should be blocked, block it
// unless the user has choosen to override the pref
if (allowMixedContent) {
*aDecision = nsIContentPolicy::ACCEPT;
// See if the pref will change here. If it will, only then do we need to call OnSecurityChange() to update the UI.
if (rootDoc->GetHasMixedActiveContentLoaded()) {
return NS_OK;
}
rootDoc->SetHasMixedActiveContentLoaded(true);
if (rootHasSecureConnection) {
// User has decided to override the pref and the root is https, so change the Security State.
if (rootDoc->GetHasMixedDisplayContentLoaded()) {
// If mixed display content is loaded, make sure to include that in the state.
eventSink->OnSecurityChange(aRequestingContext, (nsIWebProgressListener::STATE_IS_BROKEN | nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT | nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
} else {
eventSink->OnSecurityChange(aRequestingContext, (nsIWebProgressListener::STATE_IS_BROKEN | nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
}
return NS_OK;
} else {
// User has already overriden the pref and the root is not https;
// mixed content was allowed on an https subframe.
if (NS_SUCCEEDED(stateRV)) {
eventSink->OnSecurityChange(aRequestingContext, (State | nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
}
return NS_OK;
}
} else {
//User has not overriden the pref by Disabling protection. Reject the request and update the security state.
*aDecision = nsIContentPolicy::REJECT_REQUEST;
// See if the pref will change here. If it will, only then do we need to call OnSecurityChange() to update the UI.
if (rootDoc->GetHasMixedActiveContentBlocked()) {
return NS_OK;
}
rootDoc->SetHasMixedActiveContentBlocked(true);
// The user has not overriden the pref, so make sure they still have an option by calling eventSink
// which will invoke the doorhanger
if (NS_SUCCEEDED(stateRV)) {
eventSink->OnSecurityChange(aRequestingContext, (State | nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT));
}
return NS_OK;
}
} else {
// The content is not blocked by the mixed content prefs.

Просмотреть файл

@ -610,6 +610,15 @@ MOCHITEST_FILES_B = \
test_mixed_content_blocker_bug803225.html \
file_mixed_content_main_bug803225.html \
file_mixed_content_main_bug803225_websocket_wsh.py \
file_bug822367_1.html \
file_bug822367_1.js \
file_bug822367_2.html \
file_bug822367_3.html \
file_bug822367_4.html \
file_bug822367_4.js \
file_bug822367_4B.html \
file_bug822367_5.html \
file_bug822367_6.html \
bug803225_test_mailto.html \
test_bug789856.html \
file_bug804395.jar \

Просмотреть файл

@ -57,4 +57,7 @@ MOCHITEST_CHROME_FILES = \
frame_bug814638.xul \
$(NULL)
MOCHITEST_BROWSER_FILES = \
browser_bug822367.js \
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,192 @@
/*
* User Override Mixed Content Block - Tests for Bug 822367
*/
const PREF_DISPLAY = "security.mixed_content.block_display_content";
const PREF_ACTIVE = "security.mixed_content.block_active_content";
const gHttpTestRoot = "https://example.com/tests/content/base/test/";
var origBlockDisplay;
var origBlockActive;
var gTestBrowser = null;
registerCleanupFunction(function() {
// Set preferences back to their original values
Services.prefs.setBoolPref(PREF_DISPLAY, origBlockDisplay);
Services.prefs.setBoolPref(PREF_ACTIVE, origBlockActive);
});
function MixedTestsCompleted() {
gBrowser.removeCurrentTab();
window.focus();
finish();
}
function test() {
waitForExplicitFinish();
origBlockDisplay = Services.prefs.getBoolPref(PREF_DISPLAY);
origBlockActive = Services.prefs.getBoolPref(PREF_ACTIVE);
Services.prefs.setBoolPref(PREF_DISPLAY, true);
Services.prefs.setBoolPref(PREF_ACTIVE, true);
var newTab = gBrowser.addTab();
gBrowser.selectedTab = newTab;
gTestBrowser = gBrowser.selectedBrowser;
newTab.linkedBrowser.stop()
// Mixed Script Test
gTestBrowser.addEventListener("load", MixedTest1A, true);
var url = gHttpTestRoot + "file_bug822367_1.html";
gTestBrowser.contentWindow.location = url;
}
// Mixed Script Test
function MixedTest1A() {
gTestBrowser.removeEventListener("load", MixedTest1A, true);
gTestBrowser.addEventListener("load", MixedTest1B, true);
var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
ok(notification, "Mixed Content Doorhanger didn't appear");
notification.secondaryActions[0].callback();
}
function MixedTest1B() {
waitForCondition(function() content.document.getElementById('p1').innerHTML == "hello", MixedTest1C, "Waited too long for mixed script to run in Test 1");
}
function MixedTest1C() {
ok(content.document.getElementById('p1').innerHTML == "hello","Mixed script didn't load in Test 1");
gTestBrowser.removeEventListener("load", MixedTest1B, true);
MixedTest2();
}
//Mixed Display Test - Doorhanger should not appear
function MixedTest2() {
gTestBrowser.addEventListener("load", MixedTest2A, true);
var url = gHttpTestRoot + "file_bug822367_2.html";
gTestBrowser.contentWindow.location = url;
}
function MixedTest2A() {
var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
ok(!notification, "Mixed Content Doorhanger appears for mixed display content!");
MixedTest3();
}
// Mixed Script and Display Test - User Override should cause both the script and the image to load.
function MixedTest3() {
gTestBrowser.removeEventListener("load", MixedTest2A, true);
gTestBrowser.addEventListener("load", MixedTest3A, true);
var url = gHttpTestRoot + "file_bug822367_3.html";
gTestBrowser.contentWindow.location = url;
}
function MixedTest3A() {
gTestBrowser.removeEventListener("load", MixedTest3A, true);
gTestBrowser.addEventListener("load", MixedTest3B, true);
var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
ok(notification, "Mixed Content Doorhanger doesn't appear for test 3");
notification.secondaryActions[0].callback();
}
function MixedTest3B() {
waitForCondition(function() content.document.getElementById('p1').innerHTML == "hello", MixedTest3C, "Waited too long for mixed script to run in Test 3");
}
function MixedTest3C() {
waitForCondition(function() content.document.getElementById('p2').innerHTML == "bye", MixedTest3D, "Waited too long for mixed image to load in Test 3");
}
function MixedTest3D() {
ok(content.document.getElementById('p1').innerHTML == "hello","Mixed script didn't load in Test 3");
ok(content.document.getElementById('p2').innerHTML == "bye","Mixed image didn't load in Test 3");
MixedTest4();
}
// Location change - User override on one page doesn't propogate to another page after location change.
function MixedTest4() {
gTestBrowser.removeEventListener("load", MixedTest3B, true);
gTestBrowser.addEventListener("load", MixedTest4A, true);
var url = gHttpTestRoot + "file_bug822367_4.html";
gTestBrowser.contentWindow.location = url;
}
function MixedTest4A() {
gTestBrowser.removeEventListener("load", MixedTest4A, true);
gTestBrowser.addEventListener("load", MixedTest4B, true);
var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
ok(notification, "Mixed Content Doorhanger doesn't appear for Test 4");
notification.secondaryActions[0].callback();
}
function MixedTest4B() {
waitForCondition(function() content.document.location == gHttpTestRoot + "file_bug822367_4B.html", MixedTest4C, "Waited too long for mixed script to run in Test 4");
}
function MixedTest4C() {
ok(content.document.location == gHttpTestRoot + "file_bug822367_4B.html", "Location didn't change in test 4");
var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
ok(notification, "Mixed Content Doorhanger doesn't appear after location change in Test 4");
waitForCondition(function() content.document.getElementById('p1').innerHTML == "", MixedTest4D, "Mixed script loaded in test 4 after location change!");
}
function MixedTest4D() {
ok(content.document.getElementById('p1').innerHTML == "","p1.innerHTML changed; mixed script loaded after location change in Test 4");
MixedTest5();
}
// Mixed script attempts to load in a document.open()
function MixedTest5() {
gTestBrowser.removeEventListener("load", MixedTest4B, true);
gTestBrowser.addEventListener("load", MixedTest5A, true);
var url = gHttpTestRoot + "file_bug822367_5.html";
gTestBrowser.contentWindow.location = url;
}
function MixedTest5A() {
gTestBrowser.removeEventListener("load", MixedTest5A, true);
gTestBrowser.addEventListener("load", MixedTest5B, true);
var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
ok(notification, "Mixed Content Doorhanger doesn't appear for Test 5");
notification.secondaryActions[0].callback();
}
function MixedTest5B() {
waitForCondition(function() content.document.getElementById('p1').innerHTML == "hello", MixedTest5C, "Waited too long for mixed script to run in Test 5");
}
function MixedTest5C() {
ok(content.document.getElementById('p1').innerHTML == "hello","Mixed script didn't load in Test 5");
MixedTest6();
}
// Mixed script attempts to load in a document.open() that is within an iframe.
function MixedTest6() {
gTestBrowser.removeEventListener("load", MixedTest5B, true);
gTestBrowser.addEventListener("load", MixedTest6A, true);
var url = gHttpTestRoot + "file_bug822367_6.html";
gTestBrowser.contentWindow.location = url;
}
function MixedTest6A() {
gTestBrowser.removeEventListener("load", MixedTest6A, true);
waitForCondition(function() PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser), MixedTest6B, "waited to long for doorhanger");
}
function MixedTest6B() {
var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
ok(notification, "Mixed Content Doorhanger doesn't appear for Test 6");
gTestBrowser.addEventListener("load", MixedTest6C, true);
notification.secondaryActions[0].callback();
}
function MixedTest6C() {
gTestBrowser.removeEventListener("load", MixedTest6C, true);
waitForCondition(function() content.document.getElementById('f1').contentDocument.getElementById('p1').innerHTML == "hello", MixedTest6D, "Waited too long for mixed script to run in Test 6");
}
function MixedTest6D() {
ok(content.document.getElementById('f1').contentDocument.getElementById('p1').innerHTML == "hello","Mixed script didn't load in Test 6");
MixedTestsCompleted();
}
function waitForCondition(condition, nextTest, errorMsg) {
var tries = 0;
var interval = setInterval(function() {
if (tries >= 30) {
ok(false, errorMsg);
moveOn();
}
if (condition()) {
moveOn();
}
tries++;
}, 100);
var moveOn = function() { clearInterval(interval); nextTest(); };
}

Просмотреть файл

@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html>
<!--
Test 1 for Mixed Content Blocker User Override - Mixed Script
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
-->
<head>
<meta charset="utf-8">
<title>Test 1 for Bug 822367</title>
</head>
<body>
<div id="testContent">
<p id="p1"></p>
</div>
<script src="http://example.com/tests/content/base/test/file_bug822367_1.js">
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1 @@
document.getElementById('p1').innerHTML="hello";

Просмотреть файл

@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<html>
<!--
Test 2 for Mixed Content Blocker User Override - Mixed Display
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
-->
<head>
<meta charset="utf-8">
<title>Test 2 for Bug 822367 - Mixed Display</title>
</head>
<body>
<div id="testContent">
<img src="http://example.com/tests/image/test/mochitest/blue.png">
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,27 @@
<!DOCTYPE HTML>
<html>
<!--
Test 3 for Mixed Content Blocker User Override - Mixed Script and Display
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
-->
<head>
<meta charset="utf-8">
<title>Test 3 for Bug 822367</title>
<script>
function foo() {
var x = document.createElement('p');
x.setAttribute("id", "p2");
x.innerHTML = "bye";
document.getElementById("testContent").appendChild(x);
}
</script>
</head>
<body>
<div id="testContent">
<p id="p1"></p>
<img src="http://example.com/tests/image/test/mochitest/blue.png" onload="foo()">
</div>
<script src="http://example.com/tests/content/base/test/file_bug822367_1.js">
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html>
<!--
Test 4 for Mixed Content Blocker User Override - Mixed Script and Display
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
-->
<head>
<meta charset="utf-8">
<title>Test 4 for Bug 822367</title>
</head>
<body>
<div id="testContent">
<p id="p1"></p>
</div>
<script src="http://example.com/tests/content/base/test/file_bug822367_4.js">
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1 @@
document.location = "https://example.com/tests/content/base/test/file_bug822367_4B.html";

Просмотреть файл

@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html>
<!--
Test 4B for Mixed Content Blocker User Override - Location Changed
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
-->
<head>
<meta charset="utf-8">
<title>Test 4B Location Change for Bug 822367</title>
</head>
<body>
<div id="testContent">
<p id="p1"></p>
</div>
<script src="http://example.com/tests/content/base/test/file_bug822367_1.js">
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,24 @@
<!DOCTYPE HTML>
<html>
<!--
Test 5 for Mixed Content Blocker User Override - Mixed Script in document.open()
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
-->
<head>
<meta charset="utf-8">
<title>Test 5 for Bug 822367</title>
<script>
function createDoc()
{
var doc=document.open("text/html","replace");
doc.write('<!DOCTYPE html><html><body><p id="p1">This is some content</p><script src="http://example.com/tests/content/base/test/file_bug822367_1.js">\<\/script\>\<\/body>\<\/html>');
doc.close();
}
</script>
</head>
<body>
<div id="testContent">
<img src="https://example.com/tests/image/test/mochitest/blue.png" onload="createDoc()">
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<html>
<!--
Test 6 for Mixed Content Blocker User Override - Mixed Script in document.open() within an iframe
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
-->
<head>
<meta charset="utf-8">
<title>Test 6 for Bug 822367</title>
</head>
<body>
<div id="testContent">
<iframe name="f1" id="f1" src="https://example.com/tests/content/base/test/file_bug822367_5.html"></iframe>
</div>
</body>
</html>

Просмотреть файл

@ -1620,6 +1620,16 @@ nsHTMLDocument::Open(JSContext* cx,
if (rv.Failed()) {
return nullptr;
}
// If the user has allowed mixed content on the rootDoc, then we should propogate it
// down to the new document channel.
bool rootHasSecureConnection = false;
bool allowMixedContent = false;
bool isDocShellRoot = false;
nsresult rvalue = shell->GetAllowMixedContentAndConnectionData(&rootHasSecureConnection, &allowMixedContent, &isDocShellRoot);
if (NS_SUCCEEDED(rvalue) && allowMixedContent && isDocShellRoot) {
shell->SetMixedContentChannel(channel);
}
}
// Before we reset the doc notify the globalwindow of the change,

Просмотреть файл

@ -89,11 +89,6 @@ public:
/* Stop the device and release the corresponding MediaStream */
virtual nsresult Stop(SourceMediaStream *aSource, TrackID aID) = 0;
/* Change device configuration. */
virtual nsresult Config(bool aEchoOn, uint32_t aEcho,
bool aAgcOn, uint32_t aAGC,
bool aNoiseOn, uint32_t aNoise) = 0;
/* Return false if device is currently allocated or started */
bool IsAvailable() {
if (mState == kAllocated || mState == kStarted) {

Просмотреть файл

@ -44,9 +44,6 @@ public:
virtual nsresult Start(SourceMediaStream*, TrackID);
virtual nsresult Stop(SourceMediaStream*, TrackID);
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
virtual nsresult Config(bool aEchoOn, uint32_t aEcho,
bool aAgcOn, uint32_t aAGC,
bool aNoiseOn, uint32_t aNoise) { return NS_OK; };
virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime);
virtual void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream *aSource,
@ -89,9 +86,6 @@ public:
virtual nsresult Start(SourceMediaStream*, TrackID);
virtual nsresult Stop(SourceMediaStream*, TrackID);
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
virtual nsresult Config(bool aEchoOn, uint32_t aEcho,
bool aAgcOn, uint32_t aAGC,
bool aNoiseOn, uint32_t aNoise) { return NS_OK; };
virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime);
virtual void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream *aSource,

Просмотреть файл

@ -35,7 +35,6 @@
#include "voice_engine/include/voe_audio_processing.h"
#include "voice_engine/include/voe_volume_control.h"
#include "voice_engine/include/voe_external_media.h"
#include "voice_engine/include/voe_audio_processing.h"
// Video Engine
#include "video_engine/include/vie_base.h"
@ -91,9 +90,6 @@ public:
virtual nsresult Start(SourceMediaStream*, TrackID);
virtual nsresult Stop(SourceMediaStream*, TrackID);
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
virtual nsresult Config(bool aEchoOn, uint32_t aEcho,
bool aAgcOn, uint32_t aAGC,
bool aNoiseOn, uint32_t aNoise) { return NS_OK; };
virtual void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream *aSource,
TrackID aId,
@ -181,10 +177,6 @@ public:
, mCapIndex(aIndex)
, mChannel(-1)
, mInitDone(false)
, mEchoOn(false), mAgcOn(false), mNoiseOn(false)
, mEchoCancel(webrtc::kEcDefault)
, mAGC(webrtc::kAgcDefault)
, mNoiseSuppress(webrtc::kNsDefault)
, mNullTransport(nullptr) {
MOZ_ASSERT(aVoiceEnginePtr);
mState = kReleased;
@ -202,10 +194,6 @@ public:
virtual nsresult Start(SourceMediaStream*, TrackID);
virtual nsresult Stop(SourceMediaStream*, TrackID);
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
virtual nsresult Config(bool aEchoOn, uint32_t aEcho,
bool aAgcOn, uint32_t aAGC,
bool aNoiseOn, uint32_t aNoise);
virtual void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream *aSource,
TrackID aId,
@ -230,7 +218,6 @@ private:
webrtc::VoEBase* mVoEBase;
webrtc::VoEExternalMedia* mVoERender;
webrtc::VoENetwork* mVoENetwork;
webrtc::VoEAudioProcessing *mVoEProcessing;
// mMonitor protects mSources[] access/changes, and transitions of mState
// from kStarted to kStopped (which are combined with EndTrack()).
@ -246,11 +233,6 @@ private:
nsString mDeviceName;
nsString mDeviceUUID;
bool mEchoOn, mAgcOn, mNoiseOn;
webrtc::EcModes mEchoCancel;
webrtc::AgcModes mAGC;
webrtc::NsModes mNoiseSuppress;
NullTransport *mNullTransport;
};

Просмотреть файл

@ -46,60 +46,6 @@ MediaEngineWebRTCAudioSource::GetUUID(nsAString& aUUID)
return;
}
nsresult
MediaEngineWebRTCAudioSource::Config(bool aEchoOn, uint32_t aEcho,
bool aAgcOn, uint32_t aAGC,
bool aNoiseOn, uint32_t aNoise)
{
LOG(("Audio config: aec: %d, agc: %d, noise: %d",
aEchoOn ? aEcho : -1,
aAgcOn ? aAGC : -1,
aNoiseOn ? aNoise : -1));
bool update_agc = (mAgcOn == aAgcOn);
bool update_noise = (mNoiseOn == aNoiseOn);
mAgcOn = aAgcOn;
mNoiseOn = aNoiseOn;
if ((webrtc::AgcModes) aAGC != webrtc::kAgcUnchanged) {
if (mAGC != (webrtc::AgcModes) aAGC) {
update_agc = true;
mAGC = (webrtc::AgcModes) aAGC;
}
}
if ((webrtc::NsModes) aNoise != webrtc::kNsUnchanged) {
if (mNoiseSuppress != (webrtc::NsModes) aNoise) {
update_noise = true;
mNoiseSuppress = (webrtc::NsModes) aNoise;
}
}
if (mInitDone) {
int error;
#if 0
// Until we can support feeding our full output audio from the browser
// through the MediaStream, this won't work. Or we need to move AEC to
// below audio input and output, perhaps invoked from here.
mEchoOn = aEchoOn;
if ((webrtc::EcModes) aEcho != webrtc::kEcUnchanged)
mEchoCancel = (webrtc::EcModes) aEcho;
mVoEProcessing->SetEcStatus(mEchoOn, aEcho);
#else
(void) aEcho; (void) aEchoOn; // suppress warnings
#endif
if (update_agc &&
0 != (error = mVoEProcessing->SetAgcStatus(mAgcOn, (webrtc::AgcModes) aAGC))) {
LOG(("%s Error setting AGC Status: %d ",__FUNCTION__, error));
}
if (update_noise &&
0 != (error = mVoEProcessing->SetNsStatus(mNoiseOn, (webrtc::NsModes) aNoise))) {
LOG(("%s Error setting NoiseSuppression Status: %d ",__FUNCTION__, error));
}
}
return NS_OK;
}
nsresult
MediaEngineWebRTCAudioSource::Allocate()
{
@ -160,11 +106,6 @@ MediaEngineWebRTCAudioSource::Start(SourceMediaStream* aStream, TrackID aID)
}
mState = kStarted;
// Configure audio processing in webrtc code
Config(mEchoOn, webrtc::kEcUnchanged,
mAgcOn, webrtc::kAgcUnchanged,
mNoiseOn, webrtc::kNsUnchanged);
if (mVoEBase->StartReceive(mChannel)) {
return NS_ERROR_FAILURE;
}
@ -251,11 +192,6 @@ MediaEngineWebRTCAudioSource::Init()
return;
}
mVoEProcessing = webrtc::VoEAudioProcessing::GetInterface(mVoiceEngine);
if (!mVoEProcessing) {
return;
}
mChannel = mVoEBase->CreateChannel();
if (mChannel < 0) {
return;

Просмотреть файл

@ -74,6 +74,8 @@
#include "nsIPrivacyTransitionObserver.h"
#include "nsCPrefetchService.h"
#include "nsJSON.h"
#include "nsIDocShellTreeItem.h"
#include "nsIChannel.h"
#include "IHistory.h"
#include "mozilla/Services.h"
#include "mozilla/Preferences.h"
@ -661,6 +663,7 @@ ConvertLoadTypeToNavigationType(uint32_t aLoadType)
case LOAD_RELOAD_BYPASS_CACHE:
case LOAD_RELOAD_BYPASS_PROXY:
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
case LOAD_RELOAD_ALLOW_MIXED_CONTENT:
result = dom::PerformanceNavigation::TYPE_RELOAD;
break;
case LOAD_STOP_CONTENT_AND_REPLACE:
@ -1145,6 +1148,9 @@ ConvertDocShellLoadInfoToLoadType(nsDocShellInfoLoadType aDocShellLoadType)
case nsIDocShellLoadInfo::loadReplaceBypassCache:
loadType = LOAD_REPLACE_BYPASS_CACHE;
break;
case nsIDocShellLoadInfo::loadMixedContent:
loadType = LOAD_RELOAD_ALLOW_MIXED_CONTENT;
break;
default:
NS_NOTREACHED("Unexpected nsDocShellInfoLoadType value");
}
@ -1216,6 +1222,9 @@ nsDocShell::ConvertLoadTypeToDocShellLoadInfo(uint32_t aLoadType)
case LOAD_REPLACE_BYPASS_CACHE:
docShellLoadType = nsIDocShellLoadInfo::loadReplaceBypassCache;
break;
case LOAD_RELOAD_ALLOW_MIXED_CONTENT:
docShellLoadType = nsIDocShellLoadInfo::loadMixedContent;
break;
default:
NS_NOTREACHED("Unexpected load type value");
}
@ -1960,13 +1969,37 @@ nsDocShell::GetChannelIsUnsafe(bool *aUnsafe)
}
NS_IMETHODIMP
nsDocShell::GetHasMixedActiveContentLoaded(bool *aHasMixedActiveContentLoaded)
nsDocShell::GetHasMixedActiveContentLoaded(bool* aHasMixedActiveContentLoaded)
{
nsCOMPtr<nsIDocument> doc(do_GetInterface(GetAsSupports(this)));
*aHasMixedActiveContentLoaded = doc && doc->GetHasMixedActiveContentLoaded();
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetHasMixedActiveContentBlocked(bool* aHasMixedActiveContentBlocked)
{
nsCOMPtr<nsIDocument> doc(do_GetInterface(GetAsSupports(this)));
*aHasMixedActiveContentBlocked = doc && doc->GetHasMixedActiveContentBlocked();
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetHasMixedDisplayContentLoaded(bool* aHasMixedDisplayContentLoaded)
{
nsCOMPtr<nsIDocument> doc(do_GetInterface(GetAsSupports(this)));
*aHasMixedDisplayContentLoaded = doc && doc->GetHasMixedDisplayContentLoaded();
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetHasMixedDisplayContentBlocked(bool* aHasMixedDisplayContentBlocked)
{
nsCOMPtr<nsIDocument> doc(do_GetInterface(GetAsSupports(this)));
*aHasMixedDisplayContentBlocked = doc && doc->GetHasMixedDisplayContentBlocked();
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetAllowPlugins(bool * aAllowPlugins)
{
@ -5310,6 +5343,73 @@ nsDocShell::GetSandboxFlags(uint32_t *aSandboxFlags)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetMixedContentChannel(nsIChannel* aMixedContentChannel)
{
#ifdef DEBUG
// if the channel is non-null
if (aMixedContentChannel) {
// Get the root docshell.
nsCOMPtr<nsIDocShellTreeItem> root;
GetSameTypeRootTreeItem(getter_AddRefs(root));
NS_WARN_IF_FALSE(
root.get() == static_cast<nsIDocShellTreeItem *>(this),
"Setting mMixedContentChannel on a docshell that is not the root docshell"
);
}
#endif
mMixedContentChannel = aMixedContentChannel;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetMixedContentChannel(nsIChannel **aMixedContentChannel)
{
NS_ENSURE_ARG_POINTER(aMixedContentChannel);
NS_IF_ADDREF(*aMixedContentChannel = mMixedContentChannel);
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetAllowMixedContentAndConnectionData(bool* aRootHasSecureConnection, bool* aAllowMixedContent, bool* aIsRootDocShell)
{
*aRootHasSecureConnection = false;
*aAllowMixedContent = false;
*aIsRootDocShell = false;
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
NS_ASSERTION(sameTypeRoot, "No document shell root tree item from document shell tree item!");
*aIsRootDocShell = sameTypeRoot.get() == static_cast<nsIDocShellTreeItem *>(this);
// now get the document from sameTypeRoot
nsCOMPtr<nsIDocument> rootDoc = do_GetInterface(sameTypeRoot);
NS_ASSERTION(rootDoc, "No root document from document shell root tree item.");
nsCOMPtr<nsIPrincipal> rootPrincipal = rootDoc->NodePrincipal();
NS_ASSERTION(rootPrincipal, "No root principal from root document");
// For things with system principal (e.g. scratchpad) there is no uri
// aRootHasSecureConnection should remain false.
if (!nsContentUtils::IsSystemPrincipal(rootPrincipal)) {
nsCOMPtr<nsIURI> rootUri;
rootPrincipal->GetURI(getter_AddRefs(rootUri));
NS_ASSERTION(rootUri, "No root uri from root principal");
nsresult rv = rootUri->SchemeIs("https", aRootHasSecureConnection);
NS_ENSURE_SUCCESS(rv, rv);
}
// Check the root doc's channel against the root docShell's mMixedContentChannel to see
// if they are the same. If they are the same, the user has overriden
// the block.
nsCOMPtr<nsIDocShell> rootDocShell = do_GetInterface(sameTypeRoot);
nsCOMPtr<nsIChannel> mixedChannel;
rootDocShell->GetMixedContentChannel(getter_AddRefs(mixedChannel));
*aAllowMixedContent = mixedChannel && (mixedChannel == rootDoc->GetChannel());
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetVisibility(bool aVisibility)
{
@ -9328,6 +9428,14 @@ nsDocShell::DoURILoad(nsIURI * aURI,
}
}
if (mLoadType == LOAD_RELOAD_ALLOW_MIXED_CONTENT) {
rv = SetMixedContentChannel(channel);
NS_ENSURE_SUCCESS(rv, rv);
} else {
rv = SetMixedContentChannel(nullptr);
NS_ENSURE_SUCCESS(rv, rv);
}
//hack
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal(do_QueryInterface(channel));
@ -9595,6 +9703,7 @@ nsresult nsDocShell::DoChannelLoad(nsIChannel * aChannel,
case LOAD_RELOAD_BYPASS_CACHE:
case LOAD_RELOAD_BYPASS_PROXY:
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
case LOAD_RELOAD_ALLOW_MIXED_CONTENT:
case LOAD_REPLACE_BYPASS_CACHE:
loadFlags |= nsIRequest::LOAD_BYPASS_CACHE |
nsIRequest::LOAD_FRESH_CONNECTION;
@ -9892,7 +10001,8 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner,
if (aChannel &&
(aLoadType == LOAD_RELOAD_BYPASS_CACHE ||
aLoadType == LOAD_RELOAD_BYPASS_PROXY ||
aLoadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE)) {
aLoadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE ||
aLoadType == LOAD_RELOAD_ALLOW_MIXED_CONTENT)) {
NS_ASSERTION(!updateSHistory,
"We shouldn't be updating session history for forced"
" reloads!");

Просмотреть файл

@ -745,6 +745,10 @@ protected:
nsCOMPtr<nsIChannel> mFailedChannel;
uint32_t mFailedLoadType;
// Set in DoURILoad when the LOAD_RELOAD_ALLOW_MIXED_CONTENT flag is set.
// Checked in nsMixedContentBlocker, to see if the channels match.
nsCOMPtr<nsIChannel> mMixedContentChannel;
// WEAK REFERENCES BELOW HERE.
// Note these are intentionally not addrefd. Doing so will create a cycle.
// For that reasons don't use nsCOMPtr.

Просмотреть файл

@ -28,8 +28,7 @@
* above 0xffff (e.g. LOAD_FLAGS_BYPASS_CLASSIFIER), since MAKE_LOAD_TYPE would
* just shift them out anyway.
*/
#define EXTRA_LOAD_FLAGS (LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP | \
LOAD_FLAGS_FIRST_LOAD | \
#define EXTRA_LOAD_FLAGS (LOAD_FLAGS_FIRST_LOAD | \
LOAD_FLAGS_ALLOW_POPUPS | \
0xffff0000)
@ -52,6 +51,7 @@ enum LoadType {
LOAD_RELOAD_NORMAL = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_RELOAD, nsIWebNavigation::LOAD_FLAGS_NONE),
LOAD_RELOAD_BYPASS_CACHE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_RELOAD, nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE),
LOAD_RELOAD_BYPASS_PROXY = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_RELOAD, nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY),
LOAD_RELOAD_ALLOW_MIXED_CONTENT = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_RELOAD, nsIWebNavigation::LOAD_FLAGS_ALLOW_MIXED_CONTENT | nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE),
LOAD_RELOAD_BYPASS_PROXY_AND_CACHE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_RELOAD, nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE | nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY),
LOAD_LINK = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_IS_LINK),
LOAD_REFRESH = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_IS_REFRESH),
@ -85,6 +85,7 @@ static inline bool IsValidLoadType(uint32_t aLoadType)
case LOAD_RELOAD_BYPASS_CACHE:
case LOAD_RELOAD_BYPASS_PROXY:
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
case LOAD_RELOAD_ALLOW_MIXED_CONTENT:
case LOAD_LINK:
case LOAD_REFRESH:
case LOAD_RELOAD_CHARSET_CHANGE:

Просмотреть файл

@ -39,7 +39,7 @@ interface nsIWebBrowserPrint;
interface nsIVariant;
interface nsIPrivacyTransitionObserver;
[scriptable, builtinclass, uuid(ca15d803-1330-4154-b3f9-063fb2b443e7)]
[scriptable, builtinclass, uuid(5ea80008-a166-4692-8a7e-39690dd192c6)]
interface nsIDocShell : nsISupports
{
/**
@ -467,14 +467,41 @@ interface nsIDocShell : nsISupports
/**
* This attribute determines whether Mixed Active Content is loaded on the
* document. When it is true, mixed active content was not blocked and has
* loaded on the page. When it is false, mixed active content has not loaded on
* the page, either because there was no mixed active content requests on the page
* or such requests were blocked by nsMixedContentBlocker.
* loaded (or is about to load) on the page. When it is false, mixed active content
* has not loaded on the page, either because there was no mixed active content
* requests on the page or such requests were blocked by nsMixedContentBlocker.
* This boolean is set to true in nsMixedContentBlocker if Mixed Active Content
* is allowed (either explicitly on the page by the user or when the about:config
* setting security.mixed_content.block_active_content is set to false).
*/
readonly attribute boolean hasMixedActiveContentLoaded;
[infallible] readonly attribute boolean hasMixedActiveContentLoaded;
/**
* This attribute determines whether a document has Mixed Active Content
* that has been blocked from loading. When it is true, there is definitely
* mixed active content on a page that has been blocked by
* nsMixedContentBlocker. When it is false, there may or may not be mixed
* active content on a page, but if there is, it will load. Note that if the
* about:config setting security.mixed_content.block_active_content is set
* false, this boolean will be false, since blocking active content has been
* disabled.
*/
[infallible] readonly attribute boolean hasMixedActiveContentBlocked;
/**
* This attribute determines whether Mixed Display Content is loaded on the
* document. When it is true, mixed display content was not blocked and has
* loaded (or is about to load) on the page. Similar behavior to
* hasMixedActiveContentLoaded.
*/
[infallible] readonly attribute boolean hasMixedDisplayContentLoaded;
/**
* This attribute determines whether a document has Mixed Display Content
* that has been blocked from loading. Similar behavior to
* hasMixedActiveContentBlocked.
*/
[infallible] readonly attribute boolean hasMixedDisplayContentBlocked;
/**
* Disconnects this docshell's editor from its window, and stores the
@ -703,6 +730,35 @@ interface nsIDocShell : nsISupports
*/
attribute unsigned long sandboxFlags;
/**
* This member variable determines whether a document has Mixed Active Content that
* was initially blocked from loading, but the user has choosen to override the
* block and allow the content to load. mMixedContentChannel is set to the document's
* channel when the user allows mixed content. The nsMixedContentBlocker content policy
* checks if the document's root channel matches the mMixedContentChannel. If it matches,
* then Mixed Content is loaded. If it does match, mixed content is blocked.
*
* A match implies that there is definitely mixed active content on a page that was
* initially blocked by nsMixedContentBlocker and then allowed and loaded by the user.
* A miss imples that IF there is mixed active content on the page AND it was
* blocked by nsMixedContentBlocker.cpp, the user has not choosen to override
* the block. Note that if the about:config setting
* security.mixed_content.block_active_content is set to false, this boolean
* will be false, mMixedContentChannel will remain null since blocking active content has
* been disabled and hence mMixedContentChannel will never be set.
*/
attribute nsIChannel mixedContentChannel;
/**
* Checks whether the channel associated with the root docShell is equal to
* mMixedContentChannel. If they are the same, allowMixedContent is set to true.
* Checks if the root document has a secure connection. If it is, sets
* rootHasSecureConnection to true. If the docShell is the root doc shell,
* isRootDocShell is set to true.
*/
void GetAllowMixedContentAndConnectionData(out boolean rootHasSecureConnection, out boolean allowMixedContent, out boolean isRootDocShell);
/**
* Are plugins allowed in the current document loaded in this docshell ?
* (if there is one). This depends on whether plugins are allowed by this

Просмотреть файл

@ -17,7 +17,7 @@ interface nsISHEntry;
typedef long nsDocShellInfoLoadType;
[scriptable, uuid(92a0a637-373e-4647-9476-ead11e005c75)]
[scriptable, uuid(5b041ea4-6655-434c-b3d3-cbbc9441f86a)]
interface nsIDocShellLoadInfo : nsISupports
{
/** This is the referrer for the load. */
@ -61,6 +61,7 @@ interface nsIDocShellLoadInfo : nsISupports
const long loadNormalBypassProxyAndCache = 16;
const long loadPushState = 17; // history.pushState or replaceState
const long loadReplaceBypassCache = 18;
const long loadMixedContent = 19;
/** Contains a load type as specified by the load* constants */
attribute nsDocShellInfoLoadType loadType;

Просмотреть файл

@ -16,7 +16,7 @@ interface nsIURI;
* location, stop or restart an in process load, or determine where the object
* has previously gone.
*/
[scriptable, uuid(F5D9E7B0-D930-11d3-B057-00A024FFC08C)]
[scriptable, uuid(28404f7e-0f17-4dc3-a21a-2074d8659b02)]
interface nsIWebNavigation : nsISupports
{
/**
@ -145,13 +145,12 @@ interface nsIWebNavigation : nsISupports
* A hint this load was prompted by an external program: take care!
*/
const unsigned long LOAD_FLAGS_FROM_EXTERNAL = 0x1000;
/**
* This flag specifies that the URI may be submitted to a third-party
* server for correction. This should only be applied to non-sensitive
* URIs entered by users. This flag must not be passed to Reload.
*/
const unsigned long LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP = 0x2000;
This flag is set when a user explicitly disables the Mixed Content
Blocker, and allows Mixed Content to load on an https page.
*/
const unsigned long LOAD_FLAGS_ALLOW_MIXED_CONTENT = 0x2000;
/**
* This flag specifies that this is the first load in this object.
@ -190,6 +189,13 @@ interface nsIWebNavigation : nsISupports
*/
const unsigned long LOAD_FLAGS_URI_IS_UTF8 = 0x80000;
/**
* This flag specifies that the URI may be submitted to a third-party
* server for correction. This should only be applied to non-sensitive
* URIs entered by users. This flag must not be passed to Reload.
*/
const unsigned long LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP = 0x100000;
/**
* Loads a given URI. This will give priority to loading the requested URI
* in the object implementing this interface. If it can't be loaded here

Просмотреть файл

@ -874,11 +874,15 @@ nsSHistory::Reload(uint32_t aReloadFlags)
{
loadType = nsIDocShellLoadInfo::loadReloadCharsetChange;
}
else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_ALLOW_MIXED_CONTENT)
{
loadType = nsIDocShellLoadInfo::loadMixedContent;
}
else
{
loadType = nsIDocShellLoadInfo::loadReloadNormal;
}
// We are reloading. Send Reload notifications.
// nsDocShellLoadFlagType is not public, where as nsIWebNavigation
// is public. So send the reload notifications with the

Просмотреть файл

@ -420,7 +420,7 @@ GetPreviewStreamResult::Run()
nsCOMPtr<nsICameraPreviewStreamCallback> onSuccess = mOnSuccessCb.get();
if (onSuccess && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
nsCOMPtr<nsIDOMMediaStream> stream = new DOMCameraPreview(mCameraControl, mWidth, mHeight, mFramesPerSecond);
nsCOMPtr<nsIDOMMediaStream> stream = new DOMCameraPreview(mCameraControl, mWidth, mHeight, mWindowId, mFramesPerSecond);
onSuccess->HandleEvent(stream);
}
return NS_OK;

Просмотреть файл

@ -7,6 +7,8 @@
#include "VideoUtils.h"
#include "DOMCameraPreview.h"
#include "CameraCommon.h"
#include "nsGlobalWindow.h"
#include "nsPIDOMWindow.h"
using namespace mozilla;
using namespace mozilla::layers;
@ -138,7 +140,7 @@ protected:
DOMCameraPreview* mDOMPreview;
};
DOMCameraPreview::DOMCameraPreview(ICameraControl* aCameraControl, uint32_t aWidth, uint32_t aHeight, uint32_t aFrameRate)
DOMCameraPreview::DOMCameraPreview(ICameraControl* aCameraControl, uint32_t aWidth, uint32_t aHeight, uint64_t aWindowId, uint32_t aFrameRate)
: nsDOMMediaStream()
, mState(STOPPED)
, mWidth(aWidth)
@ -159,6 +161,12 @@ DOMCameraPreview::DOMCameraPreview(ICameraControl* aCameraControl, uint32_t aWid
mInput->AddTrack(TRACK_VIDEO, mFramesPerSecond, 0, new VideoSegment());
mInput->AdvanceKnownTracksTime(MEDIA_TIME_MAX);
nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
(nsGlobalWindow::GetInnerWindowWithId(aWindowId));
if (window && window->GetExtantDoc()) {
this->CombineWithPrincipal(window->GetExtantDoc()->NodePrincipal());
}
}
DOMCameraPreview::~DOMCameraPreview()

Просмотреть файл

@ -26,7 +26,7 @@ protected:
enum { TRACK_VIDEO = 1 };
public:
DOMCameraPreview(ICameraControl* aCameraControl, uint32_t aWidth, uint32_t aHeight, uint32_t aFramesPerSecond = 30);
DOMCameraPreview(ICameraControl* aCameraControl, uint32_t aWidth, uint32_t aHeight, uint64_t aWindowId, uint32_t aFramesPerSecond = 30);
bool ReceiveFrame(void* aBuffer, ImageFormat aFormat, mozilla::FrameBuilder aBuilder);
bool HaveEnoughBuffered();

Просмотреть файл

@ -11,8 +11,6 @@
#include "nsIScriptGlobalObject.h"
#include "nsIPopupWindowManager.h"
#include "nsISupportsArray.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
// For PR_snprintf
#include "prprf.h"
@ -384,33 +382,6 @@ public:
mAudioSource, mVideoSource, false));
mediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
#ifdef MOZ_WEBRTC
// Right now these configs are only of use if webrtc is available
nsresult rv;
nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
if (branch) {
int32_t aec = (int32_t) webrtc::kEcUnchanged;
int32_t agc = (int32_t) webrtc::kAgcUnchanged;
int32_t noise = (int32_t) webrtc::kNsUnchanged;
bool aec_on = false, agc_on = false, noise_on = false;
branch->GetBoolPref("media.peerconnection.aec_enabled", &aec_on);
branch->GetIntPref("media.peerconnection.aec", &aec);
branch->GetBoolPref("media.peerconnection.agc_enabled", &agc_on);
branch->GetIntPref("media.peerconnection.agc", &agc);
branch->GetBoolPref("media.peerconnection.noise_enabled", &noise_on);
branch->GetIntPref("media.peerconnection.noise", &noise);
mListener->AudioConfig(aec_on, (uint32_t) aec,
agc_on, (uint32_t) agc,
noise_on, (uint32_t) noise);
}
}
#endif
// We're in the main thread, so no worries here either.
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> success(mSuccess);
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error(mError);

Просмотреть файл

@ -21,10 +21,6 @@
#include "mozilla/StaticPtr.h"
#include "prlog.h"
#ifdef MOZ_WEBRTC
#include "mtransport/runnable_utils.h"
#endif
namespace mozilla {
#ifdef PR_LOGGING
@ -132,23 +128,6 @@ public:
// Can be invoked from EITHER MainThread or MSG thread
void Invalidate();
void
AudioConfig(bool aEchoOn, uint32_t aEcho,
bool aAgcOn, uint32_t aAGC,
bool aNoiseOn, uint32_t aNoise)
{
if (mAudioSource) {
#ifdef MOZ_WEBRTC
// Right now these configs are only of use if webrtc is available
RUN_ON_THREAD(mMediaThread,
WrapRunnable(nsRefPtr<MediaEngineSource>(mAudioSource), // threadsafe
&MediaEngineSource::Config,
aEchoOn, aEcho, aAgcOn, aAGC, aNoiseOn, aNoise),
NS_DISPATCH_NORMAL);
#endif
}
}
void
Remove()
{

Просмотреть файл

@ -37,7 +37,6 @@ EXPORTS_mtransport = \
../transportlayerprsock.h \
../m_cpp_utils.h \
../runnable_utils.h \
../runnable_utils_generated.h \
../sigslot.h \
$(NULL)

Просмотреть файл

@ -3,13 +3,6 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AudioConduit.h"
#include "nsCOMPtr.h"
#include "mozilla/Services.h"
#include "nsServiceManagerUtils.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsThreadUtils.h"
#include "CSFLog.h"
#include "voice_engine/include/voe_errors.h"
@ -24,13 +17,11 @@ const unsigned int WebrtcAudioConduit::CODEC_PLNAME_SIZE = 32;
/**
* Factory Method for AudioConduit
*/
mozilla::RefPtr<AudioSessionConduit> AudioSessionConduit::Create(AudioSessionConduit *aOther)
mozilla::RefPtr<AudioSessionConduit> AudioSessionConduit::Create()
{
CSFLogDebug(logTag, "%s ", __FUNCTION__);
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
WebrtcAudioConduit* obj = new WebrtcAudioConduit();
if(obj->Init(static_cast<WebrtcAudioConduit*>(aOther)) != kMediaConduitNoError)
if(obj->Init() != kMediaConduitNoError)
{
CSFLogError(logTag, "%s AudioConduit Init Failed ", __FUNCTION__);
delete obj;
@ -45,8 +36,6 @@ mozilla::RefPtr<AudioSessionConduit> AudioSessionConduit::Create(AudioSessionCon
*/
WebrtcAudioConduit::~WebrtcAudioConduit()
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
CSFLogDebug(logTag, "%s ", __FUNCTION__);
for(std::vector<AudioCodecConfig*>::size_type i=0;i < mRecvCodecList.size();i++)
{
@ -55,27 +44,17 @@ WebrtcAudioConduit::~WebrtcAudioConduit()
delete mCurSendCodecConfig;
// The first one of a pair to be deleted shuts down media for both
if(mPtrVoEXmedia)
{
if (!mShutDown) {
mPtrVoEXmedia->SetExternalRecordingStatus(false);
mPtrVoEXmedia->SetExternalPlayoutStatus(false);
}
mPtrVoEXmedia->SetExternalRecordingStatus(false);
mPtrVoEXmedia->SetExternalPlayoutStatus(false);
mPtrVoEXmedia->Release();
}
if(mPtrVoEProcessing)
{
mPtrVoEProcessing->Release();
}
//Deal with the transport
if(mPtrVoENetwork)
{
if (!mShutDown) {
mPtrVoENetwork->DeRegisterExternalTransport(mChannel);
}
mPtrVoENetwork->DeRegisterExternalTransport(mChannel);
mPtrVoENetwork->Release();
}
@ -86,69 +65,47 @@ WebrtcAudioConduit::~WebrtcAudioConduit()
if(mPtrVoEBase)
{
if (!mShutDown) {
mPtrVoEBase->StopPlayout(mChannel);
mPtrVoEBase->StopSend(mChannel);
mPtrVoEBase->StopReceive(mChannel);
mPtrVoEBase->DeleteChannel(mChannel);
mPtrVoEBase->Terminate();
}
mPtrVoEBase->StopPlayout(mChannel);
mPtrVoEBase->StopSend(mChannel);
mPtrVoEBase->StopReceive(mChannel);
mPtrVoEBase->DeleteChannel(mChannel);
mPtrVoEBase->Terminate();
mPtrVoEBase->Release();
}
if (mOtherDirection)
if(mVoiceEngine)
{
// mOtherDirection owns these now!
mOtherDirection->mOtherDirection = NULL;
// let other side we terminated the channel
mOtherDirection->mShutDown = true;
mVoiceEngine = nullptr;
} else {
// only one opener can call Delete. Have it be the last to close.
if(mVoiceEngine)
{
webrtc::VoiceEngine::Delete(mVoiceEngine);
}
webrtc::VoiceEngine::Delete(mVoiceEngine);
}
}
/*
* WebRTCAudioConduit Implementation
*/
MediaConduitErrorCode WebrtcAudioConduit::Init(WebrtcAudioConduit *other)
MediaConduitErrorCode WebrtcAudioConduit::Init()
{
CSFLogDebug(logTag, "%s this=%p other=%p", __FUNCTION__, this, other);
CSFLogDebug(logTag, "%s ", __FUNCTION__);
if (other) {
MOZ_ASSERT(!other->mOtherDirection);
other->mOtherDirection = this;
mOtherDirection = other;
//Per WebRTC APIs below function calls return NULL on failure
if(!(mVoiceEngine = webrtc::VoiceEngine::Create()))
{
CSFLogError(logTag, "%s Unable to create voice engine", __FUNCTION__);
return kMediaConduitSessionNotInited;
}
// only one can call ::Create()/GetVoiceEngine()
MOZ_ASSERT(other->mVoiceEngine);
mVoiceEngine = other->mVoiceEngine;
} else {
//Per WebRTC APIs below function calls return NULL on failure
if(!(mVoiceEngine = webrtc::VoiceEngine::Create()))
{
CSFLogError(logTag, "%s Unable to create voice engine", __FUNCTION__);
return kMediaConduitSessionNotInited;
}
PRLogModuleInfo *logs = GetWebRTCLogInfo();
if (!gWebrtcTraceLoggingOn && logs && logs->level > 0) {
// no need to a critical section or lock here
gWebrtcTraceLoggingOn = 1;
const char *file = PR_GetEnv("WEBRTC_TRACE_FILE");
if (!file) {
file = "WebRTC.log";
}
CSFLogDebug(logTag, "%s Logging webrtc to %s level %d", __FUNCTION__,
file, logs->level);
mVoiceEngine->SetTraceFilter(logs->level);
mVoiceEngine->SetTraceFile(file);
PRLogModuleInfo *logs = GetWebRTCLogInfo();
if (!gWebrtcTraceLoggingOn && logs && logs->level > 0) {
// no need to a critical section or lock here
gWebrtcTraceLoggingOn = 1;
const char *file = PR_GetEnv("WEBRTC_TRACE_FILE");
if (!file) {
file = "WebRTC.log";
}
CSFLogDebug(logTag, "%s Logging webrtc to %s level %d", __FUNCTION__,
file, logs->level);
mVoiceEngine->SetTraceFilter(logs->level);
mVoiceEngine->SetTraceFile(file);
}
if(!(mPtrVoEBase = VoEBase::GetInterface(mVoiceEngine)))
@ -169,60 +126,51 @@ MediaConduitErrorCode WebrtcAudioConduit::Init(WebrtcAudioConduit *other)
return kMediaConduitSessionNotInited;
}
if(!(mPtrVoEProcessing = VoEAudioProcessing::GetInterface(mVoiceEngine)))
{
CSFLogError(logTag, "%s Unable to initialize VoEProcessing", __FUNCTION__);
return kMediaConduitSessionNotInited;
}
if(!(mPtrVoEXmedia = VoEExternalMedia::GetInterface(mVoiceEngine)))
{
CSFLogError(logTag, "%s Unable to initialize VoEExternalMedia", __FUNCTION__);
return kMediaConduitSessionNotInited;
}
if (other) {
mChannel = other->mChannel;
} else {
// init the engine with our audio device layer
if(mPtrVoEBase->Init() == -1)
{
CSFLogError(logTag, "%s VoiceEngine Base Not Initialized", __FUNCTION__);
return kMediaConduitSessionNotInited;
}
if( (mChannel = mPtrVoEBase->CreateChannel()) == -1)
{
CSFLogError(logTag, "%s VoiceEngine Channel creation failed",__FUNCTION__);
return kMediaConduitChannelError;
}
CSFLogDebug(logTag, "%s Channel Created %d ",__FUNCTION__, mChannel);
if(mPtrVoENetwork->RegisterExternalTransport(mChannel, *this) == -1)
{
CSFLogError(logTag, "%s VoiceEngine, External Transport Failed",__FUNCTION__);
return kMediaConduitTransportRegistrationFail;
}
if(mPtrVoEXmedia->SetExternalRecordingStatus(true) == -1)
{
CSFLogError(logTag, "%s SetExternalRecordingStatus Failed %d",__FUNCTION__,
mPtrVoEBase->LastError());
return kMediaConduitExternalPlayoutError;
}
if(mPtrVoEXmedia->SetExternalPlayoutStatus(true) == -1)
{
CSFLogError(logTag, "%s SetExternalPlayoutStatus Failed %d ",__FUNCTION__,
mPtrVoEBase->LastError());
return kMediaConduitExternalRecordingError;
}
CSFLogDebug(logTag , "%s AudioSessionConduit Initialization Done (%p)",__FUNCTION__, this);
// init the engine with our audio device layer
if(mPtrVoEBase->Init() == -1)
{
CSFLogError(logTag, "%s VoiceEngine Base Not Initialized", __FUNCTION__);
return kMediaConduitSessionNotInited;
}
if( (mChannel = mPtrVoEBase->CreateChannel()) == -1)
{
CSFLogError(logTag, "%s VoiceEngine Channel creation failed",__FUNCTION__);
return kMediaConduitChannelError;
}
CSFLogDebug(logTag, "%s Channel Created %d ",__FUNCTION__, mChannel);
if(mPtrVoENetwork->RegisterExternalTransport(mChannel, *this) == -1)
{
CSFLogError(logTag, "%s VoiceEngine, External Transport Failed",__FUNCTION__);
return kMediaConduitTransportRegistrationFail;
}
if(mPtrVoEXmedia->SetExternalRecordingStatus(true) == -1)
{
CSFLogError(logTag, "%s SetExternalRecordingStatus Failed %d",__FUNCTION__,
mPtrVoEBase->LastError());
return kMediaConduitExternalPlayoutError;
}
if(mPtrVoEXmedia->SetExternalPlayoutStatus(true) == -1)
{
CSFLogError(logTag, "%s SetExternalPlayoutStatus Failed %d ",__FUNCTION__,
mPtrVoEBase->LastError());
return kMediaConduitExternalRecordingError;
}
CSFLogDebug(logTag , "%s AudioSessionConduit Initialization Done",__FUNCTION__);
return kMediaConduitNoError;
}
// AudioSessionConduit Implementation
MediaConduitErrorCode
WebrtcAudioConduit::AttachTransport(mozilla::RefPtr<TransportInterface> aTransport)
@ -287,33 +235,6 @@ WebrtcAudioConduit::ConfigureSendMediaCodec(const AudioCodecConfig* codecConfig)
return kMediaConduitUnknownError;
}
// TEMPORARY - see bug 694814 comment 2
nsresult rv;
nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
if (branch) {
int32_t aec = 0; // 0 == unchanged
bool aec_on = false;
branch->GetBoolPref("media.peerconnection.aec_enabled", &aec_on);
branch->GetIntPref("media.peerconnection.aec", &aec);
CSFLogDebug(logTag,"Audio config: aec: %d", aec_on ? aec : -1);
mEchoOn = aec_on;
if (static_cast<webrtc::EcModes>(aec) != webrtc::kEcUnchanged)
mEchoCancel = static_cast<webrtc::EcModes>(aec);
branch->GetIntPref("media.peerconnection.capture_delay", &mCaptureDelay);
}
}
if (0 != (error = mPtrVoEProcessing->SetEcStatus(mEchoOn, mEchoCancel))) {
CSFLogError(logTag,"%s Error setting EVStatus: %d ",__FUNCTION__, error);
return kMediaConduitUnknownError;
}
//Let's Send Transport State-machine on the Engine
if(mPtrVoEBase->StartSend(mChannel) == -1)
{
@ -483,7 +404,7 @@ WebrtcAudioConduit::SendAudioFrame(const int16_t audio_data[],
return kMediaConduitSessionNotInited;
}
capture_delay = mCaptureDelay;
//Insert the samples
if(mPtrVoEXmedia->ExternalRecordingInsertData(audio_data,
lengthSamples,
@ -623,53 +544,34 @@ WebrtcAudioConduit::ReceivedRTCPPacket(const void *data, int len)
int WebrtcAudioConduit::SendPacket(int channel, const void* data, int len)
{
CSFLogDebug(logTag, "%s : channel %d %s",__FUNCTION__,channel,
(mEngineReceiving && mOtherDirection) ? "(using mOtherDirection)" : "");
CSFLogDebug(logTag, "%s : channel %d",__FUNCTION__,channel);
if (mEngineReceiving)
{
if (mOtherDirection)
{
return mOtherDirection->SendPacket(channel, data, len);
}
CSFLogDebug(logTag, "%s : Asked to send RTP without an RTP sender",
__FUNCTION__, channel);
return -1;
} else {
if(mTransport && (mTransport->SendRtpPacket(data, len) == NS_OK))
{
if(mTransport && (mTransport->SendRtpPacket(data, len) == NS_OK))
{
CSFLogDebug(logTag, "%s Sent RTP Packet ", __FUNCTION__);
return len;
} else {
CSFLogError(logTag, "%s RTP Packet Send Failed ", __FUNCTION__);
return -1;
}
}
} else {
CSFLogError(logTag, "%s RTP Packet Send Failed ", __FUNCTION__);
return -1;
}
}
int WebrtcAudioConduit::SendRTCPPacket(int channel, const void* data, int len)
{
CSFLogDebug(logTag, "%s : channel %d", __FUNCTION__, channel);
if (mEngineTransmitting)
// can't enable this assertion, because we do. Suppress it
// NS_ASSERTION(mEngineReceiving,"We shouldn't send RTCP on the receiver side");
if(mEngineReceiving && mTransport && mTransport->SendRtcpPacket(data, len) == NS_OK)
{
if (mOtherDirection)
{
return mOtherDirection->SendRTCPPacket(channel, data, len);
}
CSFLogDebug(logTag, "%s : Asked to send RTCP without an RTP receiver",
__FUNCTION__, channel);
return -1;
CSFLogDebug(logTag, "%s Sent RTCP Packet ", __FUNCTION__);
return len;
} else {
if(mTransport && mTransport->SendRtcpPacket(data, len) == NS_OK)
{
CSFLogDebug(logTag, "%s Sent RTCP Packet ", __FUNCTION__);
return len;
} else {
CSFLogError(logTag, "%s RTCP Packet Send Failed ", __FUNCTION__);
return -1;
}
CSFLogError(logTag, "%s RTCP Packet Send Failed ", __FUNCTION__);
return -1;
}
}
/**
@ -846,3 +748,4 @@ WebrtcAudioConduit::DumpCodecDB() const
}
}
}// end namespace

Просмотреть файл

@ -18,14 +18,12 @@
#include "voice_engine/include/voe_file.h"
#include "voice_engine/include/voe_network.h"
#include "voice_engine/include/voe_external_media.h"
#include "voice_engine/include/voe_audio_processing.h"
//Some WebRTC types for short notations
using webrtc::VoEBase;
using webrtc::VoENetwork;
using webrtc::VoECodec;
using webrtc::VoEExternalMedia;
using webrtc::VoEAudioProcessing;
/** This file hosts several structures identifying different aspects
* of a RTP Session.
@ -143,23 +141,18 @@ public:
WebrtcAudioConduit():
mOtherDirection(NULL),
mShutDown(false),
mVoiceEngine(NULL),
mTransport(NULL),
mEngineTransmitting(false),
mEngineReceiving(false),
mChannel(-1),
mCurSendCodecConfig(NULL),
mCaptureDelay(150),
mEchoOn(true),
mEchoCancel(webrtc::kEcAec)
mCurSendCodecConfig(NULL)
{
}
virtual ~WebrtcAudioConduit();
MediaConduitErrorCode Init(WebrtcAudioConduit *other);
MediaConduitErrorCode Init();
private:
WebrtcAudioConduit(const WebrtcAudioConduit& other) MOZ_DELETE;
@ -192,19 +185,12 @@ private:
//Utility function to dump recv codec database
void DumpCodecDB() const;
WebrtcAudioConduit* mOtherDirection;
// Other side has shut down our channel and related items already
bool mShutDown;
// These are shared by both directions. They're released by the last
// conduit to die
webrtc::VoiceEngine* mVoiceEngine;
mozilla::RefPtr<TransportInterface> mTransport;
webrtc::VoENetwork* mPtrVoENetwork;
webrtc::VoEBase* mPtrVoEBase;
webrtc::VoECodec* mPtrVoECodec;
webrtc::VoEExternalMedia* mPtrVoEXmedia;
webrtc::VoEAudioProcessing* mPtrVoEProcessing;
//engine states of our interets
bool mEngineTransmitting; // If true => VoiceEngine Send-subsystem is up
@ -214,12 +200,6 @@ private:
int mChannel;
RecvCodecList mRecvCodecList;
AudioCodecConfig* mCurSendCodecConfig;
// Current "capture" delay (really output plus input delay)
int32_t mCaptureDelay;
bool mEchoOn;
webrtc::EcModes mEchoCancel;
};
} // end namespace

Просмотреть файл

@ -226,7 +226,7 @@ public:
* return: Concrete VideoSessionConduitObject or NULL in the case
* of failure
*/
static mozilla::RefPtr<AudioSessionConduit> Create(AudioSessionConduit *aOther);
static mozilla::RefPtr<AudioSessionConduit> Create();
virtual ~AudioSessionConduit() {}

Просмотреть файл

@ -1303,18 +1303,12 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id,
if (CC_IS_AUDIO(mcap_id)) {
std::vector<mozilla::AudioCodecConfig *> configs;
// Instantiate an appropriate conduit
mozilla::RefPtr<mozilla::AudioSessionConduit> tx_conduit =
pc.impl()->media()->GetConduit(level, false);
mozilla::RefPtr<mozilla::AudioSessionConduit> conduit =
mozilla::AudioSessionConduit::Create(tx_conduit);
mozilla::AudioSessionConduit::Create();
if(!conduit)
return VCM_ERROR;
pc.impl()->media()->AddConduit(level, true, conduit);
mozilla::AudioCodecConfig *config_raw;
for(int i=0; i <num_payloads ; i++)
@ -1959,17 +1953,12 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
mozilla::ScopedDeletePtr<mozilla::AudioCodecConfig> config(config_raw);
// Instantiate an appropriate conduit
mozilla::RefPtr<mozilla::AudioSessionConduit> rx_conduit =
pc.impl()->media()->GetConduit(level, true);
mozilla::RefPtr<mozilla::AudioSessionConduit> conduit =
mozilla::AudioSessionConduit::Create(rx_conduit);
mozilla::AudioSessionConduit::Create();
if (!conduit || conduit->ConfigureSendMediaCodec(config))
return VCM_ERROR;
pc.impl()->media()->AddConduit(level, false, conduit);
mozilla::RefPtr<mozilla::MediaPipeline> pipeline =
new mozilla::MediaPipelineTransmit(
pc.impl()->GetHandle(),

Просмотреть файл

@ -293,28 +293,9 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
mozilla::RefPtr<mozilla::TransportFlow> aFlow) {
int index_inner = aIndex * 2 + (aRtcp ? 1 : 0);
MOZ_ASSERT(!mTransportFlows[index_inner]);
mTransportFlows[index_inner] = aFlow;
}
mozilla::RefPtr<mozilla::AudioSessionConduit> GetConduit(int aStreamIndex, bool aReceive) {
int index_inner = aStreamIndex * 2 + (aReceive ? 0 : 1);
if (mAudioConduits.find(index_inner) == mAudioConduits.end())
return NULL;
return mAudioConduits[index_inner];
}
// Add a conduit
void AddConduit(int aIndex, bool aReceive,
const mozilla::RefPtr<mozilla::AudioSessionConduit> &aConduit) {
int index_inner = aIndex * 2 + (aReceive ? 0 : 1);
MOZ_ASSERT(!mAudioConduits[index_inner]);
mAudioConduits[index_inner] = aConduit;
}
// ICE state signals
sigslot::signal1<mozilla::NrIceCtx *> SignalIceGatheringCompleted; // Done gathering
sigslot::signal1<mozilla::NrIceCtx *> SignalIceCompleted; // Done handshaking
@ -350,10 +331,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
// Transport flows: even is RTP, odd is RTCP
std::map<int, mozilla::RefPtr<mozilla::TransportFlow> > mTransportFlows;
// Conduits: even is receive, odd is transmit (for easier correlation with
// flows)
std::map<int, mozilla::RefPtr<mozilla::AudioSessionConduit> > mAudioConduits;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PeerConnectionMedia)
};

Просмотреть файл

@ -490,11 +490,11 @@ class TransportConduitTest : public ::testing::Test
{
//get pointer to AudioSessionConduit
int err=0;
mAudioSession = mozilla::AudioSessionConduit::Create(NULL);
mAudioSession = mozilla::AudioSessionConduit::Create();
if( !mAudioSession )
ASSERT_NE(mAudioSession, (void*)NULL);
mAudioSession2 = mozilla::AudioSessionConduit::Create(NULL);
mAudioSession2 = mozilla::AudioSessionConduit::Create();
if( !mAudioSession2 )
ASSERT_NE(mAudioSession2, (void*)NULL);

Просмотреть файл

@ -48,7 +48,7 @@ class TestAgent {
audio_prsock_(new TransportLayerPrsock()),
audio_dtls_(new TransportLayerDtls()),
audio_config_(109, "opus", 48000, 480, 1, 64000),
audio_conduit_(mozilla::AudioSessionConduit::Create(NULL)),
audio_conduit_(mozilla::AudioSessionConduit::Create()),
audio_(),
audio_pipeline_(),
video_flow_(new TransportFlow()),

Просмотреть файл

@ -3,9 +3,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# definitions to control what gets built in webrtc
# NOTE!!! if you change something here, due to .gyp files not
# being reprocessed on .gypi changes, run this before building:
# "find . -name '*.gyp' | xargs touch"
{
'variables': {
# basic stuff for everything
@ -16,8 +13,6 @@
'include_tests': 0,
'use_system_libjpeg': 1,
'use_system_libvpx': 1,
# Creates AEC internal sample dump files in current directory
# 'aec_debug_dump': 1,
# codec enable/disables:
# Note: if you change one here, you must modify shared_libs.mk!

Просмотреть файл

@ -178,15 +178,6 @@ pref("media.gstreamer.enabled", true);
pref("media.navigator.enabled", true);
pref("media.peerconnection.enabled", false);
pref("media.navigator.permission.disabled", false);
// These values (aec, agc, and noice) are from media/webrtc/trunk/webrtc/common_types.h
// kXxxUnchanged = 0, kXxxDefault = 1, and higher values are specific to each
// setting (for Xxx = Ec, Agc, or Ns). Defaults are all set to kXxxDefault here.
pref("media.peerconnection.aec_enabled", true);
pref("media.peerconnection.aec", 1);
pref("media.peerconnection.agc_enabled", false);
pref("media.peerconnection.agc", 1);
pref("media.peerconnection.noise_enabled", false);
pref("media.peerconnection.noise", 1);
#else
#ifdef ANDROID
pref("media.navigator.enabled", true);

Просмотреть файл

@ -285,7 +285,29 @@ nsSecureBrowserUIImpl::MapInternalToExternalState(uint32_t* aState, lockIconStat
if (ev && (*aState & STATE_IS_SECURE))
*aState |= nsIWebProgressListener::STATE_IDENTITY_EV_TOPLEVEL;
nsCOMPtr<nsPIDOMWindow> piwin = do_QueryReferent(mWindow);
MOZ_ASSERT(piwin);
nsIDocShell* docShell = piwin->GetDocShell();
MOZ_ASSERT(docShell);
// Has a Mixed Content Load initiated in nsMixedContentBlocker?
// If so, the state should be broken; overriding the previous state
// set by the lock parameter.
if (docShell->GetHasMixedActiveContentLoaded())
*aState = STATE_IS_BROKEN | nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT;
if (docShell->GetHasMixedDisplayContentLoaded())
*aState = STATE_IS_BROKEN | nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT;
// Has Mixed Content Been Blocked in nsMixedContentBlocker?
if (docShell->GetHasMixedActiveContentBlocked())
*aState |= nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT;
if (docShell->GetHasMixedDisplayContentBlocked())
*aState |= nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT;
return NS_OK;
}

Просмотреть файл

@ -99,7 +99,7 @@ protected:
#endif
static already_AddRefed<nsISupports> ExtractSecurityInfo(nsIRequest* aRequest);
static nsresult MapInternalToExternalState(uint32_t* aState, lockIconState lock, bool ev);
nsresult MapInternalToExternalState(uint32_t* aState, lockIconState lock, bool ev);
nsresult UpdateSecurityState(nsIRequest* aRequest, bool withNewLocation,
bool withUpdateStatus, bool withUpdateTooltip);
bool UpdateMyFlags(lockIconState &warnSecurityState);

Просмотреть файл

@ -152,11 +152,6 @@ function todo(a, message)
postMsg("TODO: " + message);
}
function todoSecurityState(expectedState, message)
{
isSecurityState(expectedState, message, todo);
}
function isSecurityState(expectedState, message, test)
{
if (!test)

Просмотреть файл

@ -24,7 +24,7 @@
req.send(null);
// Change should be immediate, the request was sent synchronously
todoSecurityState("broken", "security broken after insecure XHR");
isSecurityState("broken", "security broken after insecure XHR");
}
catch (ex)
{

Просмотреть файл

@ -169,6 +169,36 @@ interface nsIWebProgressListener : nsISupports
const unsigned long STATE_IS_BROKEN = 0x00000001;
const unsigned long STATE_IS_SECURE = 0x00000002;
/**
* Mixed active content flags
*
* May be set in addition to the State Security Flags, to indicate that
* mixed active content has been encountered.
*
* STATE_BLOCKED_MIXED_ACTIVE_CONTENT
* Mixed active content has been blocked from loading.
*
* STATE_LOADED_MIXED_ACTIVE_CONTENT
* Mixed active content has been loaded. State should be STATE_IS_BROKEN.
*/
const unsigned long STATE_BLOCKED_MIXED_ACTIVE_CONTENT = 0x00000010;
const unsigned long STATE_LOADED_MIXED_ACTIVE_CONTENT = 0x00000020;
/**
* Mixed display content flags
*
* May be set in addition to the State Security Flags, to indicate that
* mixed display content has been encountered.
*
* STATE_BLOCKED_MIXED_DISPLAY_CONTENT
* Mixed display content has been blocked from loading.
*
* STATE_LOADED_MIXED_DISPLAY_CONTENT
* Mixed display content has been loaded. State should be STATE_IS_BROKEN.
*/
const unsigned long STATE_BLOCKED_MIXED_DISPLAY_CONTENT = 0x00000100;
const unsigned long STATE_LOADED_MIXED_DISPLAY_CONTENT = 0x00000200;
/**
* Security Strength Flags
*

Просмотреть файл

@ -12,7 +12,6 @@
#include "prlog.h"
#include "nscore.h"
#include "nsTextStore.h"
#include "nsWindow.h"
#ifdef MOZ_METRO
#include "winrt/MetroWidget.h"
@ -21,6 +20,9 @@
#include "WinUtils.h"
#include "mozilla/Preferences.h"
#define INPUTSCOPE_INIT_GUID
#include "nsTextStore.h"
using namespace mozilla;
using namespace mozilla::widget;
@ -52,11 +54,6 @@ PRLogModuleInfo* sTextStoreLog = nullptr;
/* InputScopeImpl */
/******************************************************************/
// InputScope property GUID
static const GUID GUID_PROP_INPUTSCOPE =
{ 0x1713dd5a, 0x68e7, 0x4a5b,
{ 0x9a, 0xf6, 0x59, 0x2a, 0x59, 0x5c, 0x77, 0x8d } };
class InputScopeImpl MOZ_FINAL : public ITfInputScope
{
public:

Просмотреть файл

@ -16,7 +16,13 @@
#include <msctf.h>
#include <textstor.h>
#include <InputScope.h>
// GUID_PROP_INPUTSCOPE is declared in inputscope.h using INIT_GUID.
// With initguid.h, we get its instance instead of extern declaration.
#ifdef INPUTSCOPE_INIT_GUID
#include <initguid.h>
#endif
#include <inputscope.h>
struct ITfThreadMgr;
struct ITfDocumentMgr;