mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Merge mozilla-central to mozilla-inbound on a CLOSED TREE
--HG-- extra : rebase_source : c9e6b9edae9ecf064d1318fa15d5d57ea42c102a
This commit is contained in:
commit
87db76ae1a
@ -1015,7 +1015,9 @@ var gIdentityHandler = {
|
||||
let nameLabelId = "identity-popup-permission-label-" + aPermission.id;
|
||||
nameLabel.setAttribute("id", nameLabelId);
|
||||
|
||||
let isPolicyPermission = aPermission.scope == SitePermissions.SCOPE_POLICY;
|
||||
let isPolicyPermission = [
|
||||
SitePermissions.SCOPE_POLICY, SitePermissions.SCOPE_GLOBAL
|
||||
].includes(aPermission.scope);
|
||||
|
||||
if (aPermission.id == "popup" && !isPolicyPermission) {
|
||||
let menulist = document.createXULElement("menulist");
|
||||
@ -1083,8 +1085,8 @@ var gIdentityHandler = {
|
||||
container.setAttribute("aria-labelledby", nameLabelId + " " + stateLabelId);
|
||||
|
||||
/* We return the permission item here without a remove button if the permission is a
|
||||
SCOPE_POLICY permission. Policy permissions cannot be removed/changed for the duration
|
||||
of the browser session. */
|
||||
SCOPE_POLICY or SCOPE_GLOBAL permission. Policy permissions cannot be
|
||||
removed/changed for the duration of the browser session. */
|
||||
if (isPolicyPermission) {
|
||||
return container;
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ function initRow(aPartId) {
|
||||
command.setAttribute("disabled", "true");
|
||||
}
|
||||
|
||||
if (scope == SitePermissions.SCOPE_POLICY) {
|
||||
if ([SitePermissions.SCOPE_POLICY, SitePermissions.SCOPE_GLOBAL].includes(scope)) {
|
||||
checkbox.setAttribute("disabled", "true");
|
||||
command.setAttribute("disabled", "true");
|
||||
}
|
||||
|
@ -10,6 +10,10 @@ support-files=
|
||||
support-files =
|
||||
temporary_permissions_subframe.html
|
||||
../webrtc/get_user_media.html
|
||||
[browser_autoplay_blocked.js]
|
||||
support-files =
|
||||
browser_autoplay_blocked.html
|
||||
../general/audio.ogg
|
||||
[browser_temporary_permissions_expiry.js]
|
||||
[browser_temporary_permissions_navigation.js]
|
||||
[browser_temporary_permissions_tabs.js]
|
||||
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE HTML>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<html dir="ltr" xml:lang="en-US" lang="en-US">
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
</head>
|
||||
<body>
|
||||
<audio autoplay="autoplay" >
|
||||
<source src="audio.ogg" />
|
||||
</audio>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Test that a blocked request to autoplay media is shown to the user
|
||||
*/
|
||||
|
||||
const AUTOPLAY_PAGE = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com") + "browser_autoplay_blocked.html";
|
||||
|
||||
function openIdentityPopup() {
|
||||
let promise = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
|
||||
gIdentityHandler._identityBox.click();
|
||||
return promise;
|
||||
}
|
||||
|
||||
function closeIdentityPopup() {
|
||||
let promise = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popuphidden");
|
||||
gIdentityHandler._identityPopup.hidePopup();
|
||||
return promise;
|
||||
}
|
||||
|
||||
function autoplayBlockedIcon() {
|
||||
return document.querySelector("#blocked-permissions-container " +
|
||||
".blocked-permission-icon.autoplay-media-icon");
|
||||
}
|
||||
|
||||
add_task(async function testMainViewVisible() {
|
||||
|
||||
Services.prefs.setIntPref("media.autoplay.default", Ci.nsIAutoplay.ALLOWED);
|
||||
|
||||
await BrowserTestUtils.withNewTab(AUTOPLAY_PAGE, async function() {
|
||||
let permissionsList = document.getElementById("identity-popup-permission-list");
|
||||
let emptyLabel = permissionsList.nextSibling.nextSibling;
|
||||
|
||||
ok(BrowserTestUtils.is_hidden(autoplayBlockedIcon()), "Blocked icon not shown");
|
||||
|
||||
await openIdentityPopup();
|
||||
ok(!BrowserTestUtils.is_hidden(emptyLabel), "List of permissions is empty");
|
||||
await closeIdentityPopup();
|
||||
});
|
||||
|
||||
Services.prefs.setIntPref("media.autoplay.default", Ci.nsIAutoplay.BLOCKED);
|
||||
|
||||
await BrowserTestUtils.withNewTab(AUTOPLAY_PAGE, async function() {
|
||||
let permissionsList = document.getElementById("identity-popup-permission-list");
|
||||
let emptyLabel = permissionsList.nextSibling.nextSibling;
|
||||
|
||||
ok(!BrowserTestUtils.is_hidden(autoplayBlockedIcon()), "Blocked icon is shown");
|
||||
|
||||
await openIdentityPopup();
|
||||
ok(BrowserTestUtils.is_hidden(emptyLabel), "List of permissions is not empty");
|
||||
let labelText = SitePermissions.getPermissionLabel("autoplay-media");
|
||||
let labels = permissionsList.querySelectorAll(".identity-popup-permission-label");
|
||||
is(labels.length, 1, "One permission visible in main view");
|
||||
is(labels[0].textContent, labelText, "Correct value");
|
||||
await closeIdentityPopup();
|
||||
});
|
||||
|
||||
Services.prefs.clearUserPref("media.autoplay.default");
|
||||
});
|
@ -279,6 +279,19 @@ var PermissionPromptPrototype = {
|
||||
this.browser);
|
||||
|
||||
if (state == SitePermissions.BLOCK) {
|
||||
// If the request is blocked by a global setting then we record
|
||||
// a flag that lasts for the duration of the current page load
|
||||
// to notify the user that the permission has been blocked.
|
||||
// Currently only applies to autoplay-media
|
||||
if (state == SitePermissions.getDefault(this.permissionKey) &&
|
||||
SitePermissions.showGloballyBlocked(this.permissionKey)) {
|
||||
SitePermissions.set(this.principal.URI,
|
||||
this.permissionKey,
|
||||
state,
|
||||
SitePermissions.SCOPE_GLOBAL,
|
||||
this.browser);
|
||||
}
|
||||
|
||||
this.cancel();
|
||||
return;
|
||||
}
|
||||
|
@ -129,6 +129,71 @@ const TemporaryBlockedPermissions = {
|
||||
},
|
||||
};
|
||||
|
||||
// This hold a flag per browser to indicate whether we should show the
|
||||
// user a notification as a permission has been requested that has been
|
||||
// blocked globally. We only want to notify the user in the case that
|
||||
// they actually requested the permission within the current page load
|
||||
// so will clear the flag on navigation.
|
||||
const GloballyBlockedPermissions = {
|
||||
|
||||
_stateByBrowser: new WeakMap(),
|
||||
|
||||
set(browser, id) {
|
||||
if (!this._stateByBrowser.has(browser)) {
|
||||
this._stateByBrowser.set(browser, {});
|
||||
}
|
||||
let entry = this._stateByBrowser.get(browser);
|
||||
let prePath = browser.currentURI.prePath;
|
||||
if (!entry[prePath]) {
|
||||
entry[prePath] = {};
|
||||
}
|
||||
|
||||
entry[prePath][id] = true;
|
||||
|
||||
// Listen to any top level navigations, once we see one clear the flag
|
||||
// and remove the listener.
|
||||
browser.addProgressListener({
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
|
||||
if (aWebProgress.isTopLevel) {
|
||||
GloballyBlockedPermissions.remove(browser, id);
|
||||
browser.removeProgressListener(this);
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// Removes a permission with the specified id for the specified browser.
|
||||
remove(browser, id) {
|
||||
let entry = this._stateByBrowser.get(browser);
|
||||
let prePath = browser.currentURI.prePath;
|
||||
if (entry && entry[prePath]) {
|
||||
delete entry[prePath][id];
|
||||
}
|
||||
},
|
||||
|
||||
// Gets all permissions for the specified browser.
|
||||
// Note that only permissions that apply to the current URI
|
||||
// of the passed browser element will be returned.
|
||||
getAll(browser) {
|
||||
let permissions = [];
|
||||
let entry = this._stateByBrowser.get(browser);
|
||||
let prePath = browser.currentURI.prePath;
|
||||
if (entry && entry[prePath]) {
|
||||
let timeStamps = entry[prePath];
|
||||
for (let id of Object.keys(timeStamps)) {
|
||||
permissions.push({
|
||||
id,
|
||||
state: SitePermissions.BLOCK,
|
||||
scope: SitePermissions.SCOPE_GLOBAL
|
||||
});
|
||||
}
|
||||
}
|
||||
return permissions;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* A module to manage permanent and temporary permissions
|
||||
* by URI and browser.
|
||||
@ -153,6 +218,7 @@ var SitePermissions = {
|
||||
SCOPE_SESSION: "{SitePermissions.SCOPE_SESSION}",
|
||||
SCOPE_PERSISTENT: "{SitePermissions.SCOPE_PERSISTENT}",
|
||||
SCOPE_POLICY: "{SitePermissions.SCOPE_POLICY}",
|
||||
SCOPE_GLOBAL: "{SitePermissions.SCOPE_GLOBAL}",
|
||||
|
||||
_defaultPrefBranch: Services.prefs.getBranch("permissions.default."),
|
||||
|
||||
@ -231,6 +297,10 @@ var SitePermissions = {
|
||||
permissions[permission.id] = permission;
|
||||
}
|
||||
|
||||
for (let permission of GloballyBlockedPermissions.getAll(browser)) {
|
||||
permissions[permission.id] = permission;
|
||||
}
|
||||
|
||||
for (let permission of this.getAllByURI(browser.currentURI)) {
|
||||
permissions[permission.id] = permission;
|
||||
}
|
||||
@ -330,6 +400,23 @@ var SitePermissions = {
|
||||
return this._defaultPrefBranch.getIntPref(permissionID, this.UNKNOWN);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return whether the browser should notify the user if a permission was
|
||||
* globally blocked due to a preference.
|
||||
*
|
||||
* @param {string} permissionID
|
||||
* The ID to get the state for.
|
||||
*
|
||||
* @return boolean Whether to show notification for globally blocked permissions.
|
||||
*/
|
||||
showGloballyBlocked(permissionID) {
|
||||
if (permissionID in gPermissionObject &&
|
||||
gPermissionObject[permissionID].showGloballyBlocked)
|
||||
return gPermissionObject[permissionID].showGloballyBlocked;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the state and scope of a particular permission for a given URI.
|
||||
*
|
||||
@ -404,6 +491,13 @@ var SitePermissions = {
|
||||
* This needs to be provided if the scope is SCOPE_TEMPORARY!
|
||||
*/
|
||||
set(uri, permissionID, state, scope = this.SCOPE_PERSISTENT, browser = null) {
|
||||
|
||||
if (scope == this.SCOPE_GLOBAL && state == this.BLOCK) {
|
||||
GloballyBlockedPermissions.set(browser, permissionID);
|
||||
browser.dispatchEvent(new browser.ownerGlobal.CustomEvent("PermissionStateChange"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == this.UNKNOWN || state == this.getDefault(permissionID)) {
|
||||
// Because they are controlled by two prefs with many states that do not
|
||||
// correspond to the classical ALLOW/DENY/PROMPT model, we want to always
|
||||
@ -607,13 +701,14 @@ var gPermissionObject = {
|
||||
|
||||
"autoplay-media": {
|
||||
exactHostMatch: true,
|
||||
showGloballyBlocked: true,
|
||||
getDefault() {
|
||||
let state = Services.prefs.getIntPref("media.autoplay.default",
|
||||
Ci.nsIAutoplay.PROMPT);
|
||||
if (state == Ci.nsIAutoplay.ALLOW) {
|
||||
if (state == Ci.nsIAutoplay.ALLOWED) {
|
||||
return SitePermissions.ALLOW;
|
||||
} if (state == Ci.nsIAutoplay.BLOCK) {
|
||||
return SitePermissions.DENY;
|
||||
} if (state == Ci.nsIAutoplay.BLOCKED) {
|
||||
return SitePermissions.BLOCK;
|
||||
}
|
||||
return SitePermissions.UNKNOWN;
|
||||
},
|
||||
|
@ -2010,7 +2010,7 @@ HTMLMediaElement::Load()
|
||||
HasSourceChildren(this),
|
||||
EventStateManager::IsHandlingUserInput(),
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay),
|
||||
AutoplayPolicy::IsAllowedToPlay(*this) == nsIAutoplay::ALLOWED,
|
||||
AutoplayPolicy::IsAllowedToPlay(*this),
|
||||
OwnerDoc(),
|
||||
DocumentOrigin(OwnerDoc()).get(),
|
||||
OwnerDoc() ? OwnerDoc()->HasBeenUserGestureActivated() : 0,
|
||||
@ -2529,7 +2529,7 @@ HTMLMediaElement::ResumeLoad(PreloadAction aAction)
|
||||
bool
|
||||
HTMLMediaElement::AllowedToPlay() const
|
||||
{
|
||||
return AutoplayPolicy::IsAllowedToPlay(*this) == nsIAutoplay::ALLOWED;
|
||||
return AutoplayPolicy::IsAllowedToPlay(*this);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2538,7 +2538,7 @@ HTMLMediaElement::UpdatePreloadAction()
|
||||
PreloadAction nextAction = PRELOAD_UNDEFINED;
|
||||
// If autoplay is set, or we're playing, we should always preload data,
|
||||
// as we'll need it to play.
|
||||
if ((AutoplayPolicy::IsAllowedToPlay(*this) == nsIAutoplay::ALLOWED &&
|
||||
if ((AutoplayPolicy::IsAllowedToPlay(*this) &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) ||
|
||||
!mPaused) {
|
||||
nextAction = HTMLMediaElement::PRELOAD_ENOUGH;
|
||||
@ -3071,7 +3071,7 @@ HTMLMediaElement::PauseIfShouldNotBePlaying()
|
||||
if (GetPaused()) {
|
||||
return;
|
||||
}
|
||||
if (AutoplayPolicy::IsAllowedToPlay(*this) != nsIAutoplay::ALLOWED) {
|
||||
if (!AutoplayPolicy::IsAllowedToPlay(*this)) {
|
||||
AUTOPLAY_LOG("pause because not allowed to play, element=%p", this);
|
||||
ErrorResult rv;
|
||||
Pause(rv);
|
||||
@ -4103,27 +4103,14 @@ HTMLMediaElement::Play(ErrorResult& aRv)
|
||||
UpdateHadAudibleAutoplayState();
|
||||
|
||||
const bool handlingUserInput = EventStateManager::IsHandlingUserInput();
|
||||
switch (AutoplayPolicy::IsAllowedToPlay(*this)) {
|
||||
case nsIAutoplay::ALLOWED: {
|
||||
mPendingPlayPromises.AppendElement(promise);
|
||||
PlayInternal(handlingUserInput);
|
||||
UpdateCustomPolicyAfterPlayed();
|
||||
break;
|
||||
}
|
||||
case nsIAutoplay::BLOCKED: {
|
||||
AUTOPLAY_LOG("%p play blocked.", this);
|
||||
promise->MaybeReject(NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR);
|
||||
if (StaticPrefs::MediaBlockEventEnabled()) {
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("blocked"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsIAutoplay::PROMPT: {
|
||||
// Prompt the user for permission to play.
|
||||
mPendingPlayPromises.AppendElement(promise);
|
||||
EnsureAutoplayRequested(handlingUserInput);
|
||||
break;
|
||||
}
|
||||
if (AutoplayPolicy::IsAllowedToPlay(*this)) {
|
||||
mPendingPlayPromises.AppendElement(promise);
|
||||
PlayInternal(handlingUserInput);
|
||||
UpdateCustomPolicyAfterPlayed();
|
||||
} else {
|
||||
// Prompt the user for permission to play.
|
||||
mPendingPlayPromises.AppendElement(promise);
|
||||
EnsureAutoplayRequested(handlingUserInput);
|
||||
}
|
||||
return promise.forget();
|
||||
}
|
||||
@ -6151,8 +6138,7 @@ HTMLMediaElement::ChangeReadyState(nsMediaReadyState aState)
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("canplay"));
|
||||
if (!mPaused) {
|
||||
if (mDecoder && !mPausedForInactiveDocumentOrChannel) {
|
||||
MOZ_ASSERT(AutoplayPolicy::IsAllowedToPlay(*this) ==
|
||||
nsIAutoplay::ALLOWED);
|
||||
MOZ_ASSERT(AutoplayPolicy::IsAllowedToPlay(*this));
|
||||
mDecoder->Play();
|
||||
}
|
||||
NotifyAboutPlaying();
|
||||
@ -6264,14 +6250,9 @@ HTMLMediaElement::CheckAutoplayDataReady()
|
||||
}
|
||||
|
||||
UpdateHadAudibleAutoplayState();
|
||||
switch (AutoplayPolicy::IsAllowedToPlay(*this)) {
|
||||
case nsIAutoplay::BLOCKED:
|
||||
return;
|
||||
case nsIAutoplay::PROMPT:
|
||||
EnsureAutoplayRequested(false);
|
||||
return;
|
||||
case nsIAutoplay::ALLOWED:
|
||||
break;
|
||||
if (!AutoplayPolicy::IsAllowedToPlay(*this)) {
|
||||
EnsureAutoplayRequested(false);
|
||||
return;
|
||||
}
|
||||
|
||||
mPaused = false;
|
||||
|
@ -156,7 +156,7 @@ AutoplayPolicy::WouldBeAllowedToPlayIfAutoplayDisabled(const HTMLMediaElement& a
|
||||
return IsMediaElementAllowedToPlay(aElement);
|
||||
}
|
||||
|
||||
/* static */ uint32_t
|
||||
/* static */ bool
|
||||
AutoplayPolicy::IsAllowedToPlay(const HTMLMediaElement& aElement)
|
||||
{
|
||||
const uint32_t autoplayDefault = DefaultAutoplayBehaviour();
|
||||
@ -166,15 +166,19 @@ AutoplayPolicy::IsAllowedToPlay(const HTMLMediaElement& aElement)
|
||||
// If element is blessed, it would always be allowed to play().
|
||||
return (autoplayDefault == nsIAutoplay::ALLOWED ||
|
||||
aElement.IsBlessed() ||
|
||||
EventStateManager::IsHandlingUserInput())
|
||||
? nsIAutoplay::ALLOWED : nsIAutoplay::BLOCKED;
|
||||
EventStateManager::IsHandlingUserInput());
|
||||
}
|
||||
|
||||
const uint32_t result = IsMediaElementAllowedToPlay(aElement) ?
|
||||
nsIAutoplay::ALLOWED : autoplayDefault;
|
||||
if (IsMediaElementAllowedToPlay(aElement)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool result = IsMediaElementAllowedToPlay(aElement) ||
|
||||
autoplayDefault == nsIAutoplay::ALLOWED;
|
||||
|
||||
AUTOPLAY_LOG("IsAllowedToPlay, mediaElement=%p, isAllowToPlay=%s",
|
||||
&aElement, AllowAutoplayToStr(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ class AutoplayPolicy
|
||||
{
|
||||
public:
|
||||
// Returns whether a given media element is allowed to play.
|
||||
static uint32_t IsAllowedToPlay(const HTMLMediaElement& aElement);
|
||||
static bool IsAllowedToPlay(const HTMLMediaElement& aElement);
|
||||
|
||||
// Returns true if a given media element would be allowed to play
|
||||
// if block autoplay was enabled. If this returns false, it means we would
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "mozilla/dom/DOMPoint.h"
|
||||
#include "mozilla/dom/DOMQuad.h"
|
||||
#include "mozilla/dom/DOMRect.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsCSSFrameConstructor.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "mozilla/UndisplayedNode.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsError.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsAbsoluteContainingBlock.h"
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsNodeInfoManager.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCheckboxRadioFrame.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsNodeInfoManager.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCheckboxRadioFrame.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsCheckboxRadioFrame.h"
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
#include "nsIPersistentProperties2.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
// operator dictionary entry
|
||||
|
@ -73,7 +73,6 @@
|
||||
#include "mozilla/ViewportFrame.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "ActiveLayerTracker.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "UnitTransforms.h"
|
||||
#include "LayersLogging.h"
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "nsString.h"
|
||||
#include "mozilla/ComputedStyle.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
#include "nsPresContext.h"
|
||||
#include "nsStyleChangeList.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIDocument.h"
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "mozilla/dom/MutationEventBinding.h"
|
||||
#include "mozilla/InternalMutationEvent.h"
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNodeUtils.h"
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "nsIURI.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "mozilla/layers/ScrollLinkedEffectDetector.h"
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "nsFontFaceLoader.h"
|
||||
|
||||
#include "nsError.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "mozilla/dom/CSSTransitionBinding.h"
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/ComputedStyle.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
// Keep in (case-insensitive) order:
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsFrame.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsLiteralString.h"
|
||||
|
@ -11,7 +11,6 @@
|
||||
// Keep others in (case-insensitive) order:
|
||||
#include "gfxUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsStyleStruct.h"
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "SVGImageContext.h"
|
||||
#include "mozilla/dom/MutationEventBinding.h"
|
||||
#include "mozilla/dom/SVGImageElement.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIReflowCallback.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "SVGGeometryFrame.h"
|
||||
#include "SVGImageContext.h"
|
||||
#include "mozilla/dom/SVGImageElement.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIReflowCallback.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "gfxPattern.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSVGDisplayableFrame.h"
|
||||
#include "mozilla/ComputedStyle.h"
|
||||
|
@ -5,7 +5,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsSVGUseFrame.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#include "mozilla/dom/SVGUseElement.h"
|
||||
#include "SVGObserverUtils.h"
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsNodeInfoManager.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/FromParser.h"
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "nsISound.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#endif
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsUTF8Utils.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "nsTreeContentView.h"
|
||||
#include "nsITreeSelection.h"
|
||||
#include "ChildIterator.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsError.h"
|
||||
#include "nsTreeBodyFrame.h"
|
||||
#include "mozilla/dom/TreeBoxObjectBinding.h"
|
||||
|
@ -7,6 +7,7 @@ package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException;
|
||||
import org.mozilla.gecko.GeckoScreenOrientation.ScreenOrientation;
|
||||
import org.mozilla.gecko.annotation.RobocopTarget;
|
||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||
import org.mozilla.gecko.health.HealthRecorder;
|
||||
@ -40,7 +41,6 @@ import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.ViewUtil;
|
||||
import org.mozilla.gecko.widget.ActionModePresenter;
|
||||
import org.mozilla.gecko.widget.AnchoredPopup;
|
||||
import org.mozilla.geckoview.GeckoRuntime;
|
||||
import org.mozilla.geckoview.GeckoSession;
|
||||
import org.mozilla.geckoview.GeckoSessionSettings;
|
||||
import org.mozilla.geckoview.GeckoView;
|
||||
@ -113,6 +113,7 @@ public abstract class GeckoApp extends GeckoActivity
|
||||
BundleEventListener,
|
||||
GeckoMenu.Callback,
|
||||
GeckoMenu.MenuPresenter,
|
||||
GeckoScreenOrientation.OrientationChangeListener,
|
||||
GeckoSession.ContentDelegate,
|
||||
ScreenOrientationDelegate,
|
||||
Tabs.OnTabsChangedListener,
|
||||
@ -982,6 +983,7 @@ public abstract class GeckoApp extends GeckoActivity
|
||||
} catch (ClassNotFoundException e) { }
|
||||
|
||||
GeckoAppShell.setScreenOrientationDelegate(this);
|
||||
GeckoScreenOrientation.getInstance().addListener(this);
|
||||
|
||||
// Tell Stumbler to register a local broadcast listener to listen for preference intents.
|
||||
// We do this via intents since we can't easily access Stumbler directly,
|
||||
@ -1065,8 +1067,6 @@ public abstract class GeckoApp extends GeckoActivity
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
GeckoScreenOrientation.getInstance().update(getResources().getConfiguration().orientation);
|
||||
|
||||
setContentView(getLayout());
|
||||
|
||||
// Set up Gecko layout.
|
||||
@ -1930,11 +1930,6 @@ public abstract class GeckoApp extends GeckoActivity
|
||||
|
||||
GeckoAppShell.setScreenOrientationDelegate(this);
|
||||
|
||||
int newOrientation = getResources().getConfiguration().orientation;
|
||||
if (GeckoScreenOrientation.getInstance().update(newOrientation)) {
|
||||
refreshChrome();
|
||||
}
|
||||
|
||||
// We use two times: a pseudo-unique wall-clock time to identify the
|
||||
// current session across power cycles, and the elapsed realtime to
|
||||
// track the duration of the session.
|
||||
@ -2134,6 +2129,8 @@ public abstract class GeckoApp extends GeckoActivity
|
||||
Tabs.unregisterOnTabsChangedListener(this);
|
||||
Tabs.getInstance().detachFromContext();
|
||||
|
||||
GeckoScreenOrientation.getInstance().removeListener(this);
|
||||
|
||||
if (mShutdownOnDestroy) {
|
||||
GeckoApplication.shutdown(!mRestartOnShutdown ? null : new Intent(
|
||||
Intent.ACTION_MAIN, /* uri */ null, getApplicationContext(), getClass()));
|
||||
@ -2178,19 +2175,6 @@ public abstract class GeckoApp extends GeckoActivity
|
||||
onLocaleChanged(Locales.getLanguageTag(changed));
|
||||
}
|
||||
|
||||
// onConfigurationChanged is not called for 180 degree orientation changes,
|
||||
// we will miss such rotations and the screen orientation will not be
|
||||
// updated.
|
||||
if (GeckoScreenOrientation.getInstance().update(newConfig.orientation)) {
|
||||
if (mFormAssistPopup != null)
|
||||
mFormAssistPopup.hide();
|
||||
refreshChrome();
|
||||
}
|
||||
|
||||
if (mPromptService != null) {
|
||||
mPromptService.changePromptOrientation(newConfig.orientation);
|
||||
}
|
||||
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
@ -2528,4 +2512,12 @@ public abstract class GeckoApp extends GeckoActivity
|
||||
setRequestedOrientation(requestedActivityInfoOrientation);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScreenOrientationChanged(ScreenOrientation newOrientation) {
|
||||
if (mFormAssistPopup != null) {
|
||||
mFormAssistPopup.hide();
|
||||
}
|
||||
refreshChrome();
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import android.app.PendingIntent;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@ -39,8 +38,6 @@ import org.mozilla.gecko.DoorHangerPopup;
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.FormAssistPopup;
|
||||
import org.mozilla.gecko.GeckoApplication;
|
||||
import org.mozilla.gecko.GeckoSharedPrefs;
|
||||
import org.mozilla.gecko.preferences.GeckoPreferences;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.SnackbarBuilder;
|
||||
import org.mozilla.gecko.Telemetry;
|
||||
@ -59,9 +56,7 @@ import org.mozilla.gecko.util.PackageUtil;
|
||||
import org.mozilla.gecko.webapps.WebApps;
|
||||
import org.mozilla.gecko.widget.ActionModePresenter;
|
||||
import org.mozilla.gecko.widget.GeckoPopupMenu;
|
||||
import org.mozilla.geckoview.GeckoResponse;
|
||||
import org.mozilla.geckoview.GeckoResult;
|
||||
import org.mozilla.geckoview.GeckoRuntime;
|
||||
import org.mozilla.geckoview.GeckoSession;
|
||||
import org.mozilla.geckoview.GeckoSessionSettings;
|
||||
import org.mozilla.geckoview.GeckoView;
|
||||
@ -191,15 +186,6 @@ public class CustomTabsActivity extends AppCompatActivity
|
||||
Permissions.onRequestPermissionsResult(this, permissions, grantResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
|
||||
if (mPromptService != null) {
|
||||
mPromptService.changePromptOrientation(newConfig.orientation);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendTelemetry() {
|
||||
final SafeIntent startIntent = new SafeIntent(getIntent());
|
||||
|
||||
|
@ -6,23 +6,25 @@
|
||||
package org.mozilla.gecko.prompts;
|
||||
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.GeckoScreenOrientation;
|
||||
import org.mozilla.gecko.GeckoScreenOrientation.ScreenOrientation;
|
||||
import org.mozilla.gecko.util.BundleEventListener;
|
||||
import org.mozilla.gecko.util.EventCallback;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class PromptService implements BundleEventListener {
|
||||
public class PromptService implements BundleEventListener,
|
||||
GeckoScreenOrientation.OrientationChangeListener {
|
||||
private static final String LOGTAG = "GeckoPromptService";
|
||||
|
||||
private final Context context;
|
||||
private final EventDispatcher dispatcher;
|
||||
private Prompt currentPrompt;
|
||||
private int currentOrientation;
|
||||
|
||||
public PromptService(final Context context, final EventDispatcher dispatcher) {
|
||||
this.context = context;
|
||||
this.currentOrientation = context.getResources().getConfiguration().orientation;
|
||||
GeckoScreenOrientation.getInstance().addListener(this);
|
||||
this.dispatcher = dispatcher;
|
||||
this.dispatcher.registerUiThreadListener(this,
|
||||
"Prompt:Show",
|
||||
@ -33,6 +35,7 @@ public class PromptService implements BundleEventListener {
|
||||
dispatcher.unregisterUiThreadListener(this,
|
||||
"Prompt:Show",
|
||||
"Prompt:ShowTop");
|
||||
GeckoScreenOrientation.getInstance().removeListener(this);
|
||||
}
|
||||
|
||||
// BundleEventListener implementation
|
||||
@ -49,10 +52,11 @@ public class PromptService implements BundleEventListener {
|
||||
currentPrompt.show(message);
|
||||
}
|
||||
|
||||
public void changePromptOrientation(int newOrientation) {
|
||||
if (currentPrompt != null && currentOrientation != newOrientation) {
|
||||
// OrientationChangeListener implementation
|
||||
@Override
|
||||
public void onScreenOrientationChanged(ScreenOrientation newOrientation) {
|
||||
if (currentPrompt != null) {
|
||||
currentPrompt.resetLayout();
|
||||
}
|
||||
currentOrientation = newOrientation;
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
@ -29,8 +28,6 @@ import org.mozilla.gecko.DoorHangerPopup;
|
||||
import org.mozilla.gecko.FormAssistPopup;
|
||||
import org.mozilla.gecko.GeckoApplication;
|
||||
import org.mozilla.gecko.GeckoScreenOrientation;
|
||||
import org.mozilla.gecko.GeckoSharedPrefs;
|
||||
import org.mozilla.gecko.preferences.GeckoPreferences;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.customtabs.CustomTabsActivity;
|
||||
import org.mozilla.gecko.permissions.Permissions;
|
||||
@ -39,9 +36,7 @@ import org.mozilla.gecko.text.TextSelection;
|
||||
import org.mozilla.gecko.util.ActivityUtils;
|
||||
import org.mozilla.gecko.util.ColorUtil;
|
||||
import org.mozilla.gecko.widget.ActionModePresenter;
|
||||
import org.mozilla.geckoview.GeckoResponse;
|
||||
import org.mozilla.geckoview.GeckoResult;
|
||||
import org.mozilla.geckoview.GeckoRuntime;
|
||||
import org.mozilla.geckoview.GeckoSession;
|
||||
import org.mozilla.geckoview.GeckoSessionSettings;
|
||||
import org.mozilla.geckoview.GeckoView;
|
||||
@ -178,15 +173,6 @@ public class WebAppActivity extends AppCompatActivity
|
||||
mGeckoSession.loadUri(mManifest.getStartUri().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
|
||||
if (mPromptService != null) {
|
||||
mPromptService.changePromptOrientation(newConfig.orientation);
|
||||
}
|
||||
}
|
||||
|
||||
private void fallbackToFennec(String message) {
|
||||
if (message != null) {
|
||||
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
|
||||
|
@ -28,9 +28,6 @@ import java.util.TreeMap;
|
||||
import org.mozilla.gecko.annotation.JNITarget;
|
||||
import org.mozilla.gecko.annotation.RobocopTarget;
|
||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||
import org.mozilla.gecko.permissions.Permissions;
|
||||
import org.mozilla.gecko.process.GeckoProcessManager;
|
||||
import org.mozilla.gecko.SysInfo;
|
||||
import org.mozilla.gecko.util.BitmapUtils;
|
||||
import org.mozilla.gecko.util.HardwareCodecCapabilityUtils;
|
||||
import org.mozilla.gecko.util.HardwareUtils;
|
||||
@ -39,28 +36,19 @@ import org.mozilla.gecko.util.ProxySelector;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.geckoview.BuildConfig;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.pm.Signature;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.ImageFormat;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.hardware.Camera;
|
||||
@ -78,33 +66,22 @@ import android.net.NetworkInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.LocaleList;
|
||||
import android.os.Looper;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.PowerManager;
|
||||
import android.os.StrictMode;
|
||||
import android.os.SystemClock;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.SimpleArrayMap;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.Display;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.TextureView;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.AbsoluteLayout;
|
||||
|
||||
public class GeckoAppShell
|
||||
{
|
||||
@ -261,8 +238,6 @@ public class GeckoAppShell
|
||||
@WrapForJNI(dispatchTo = "gecko")
|
||||
public static native void notifyUriVisited(String uri);
|
||||
|
||||
private static Rect sScreenSize;
|
||||
|
||||
@WrapForJNI(stubName = "NotifyObservers", dispatchTo = "gecko")
|
||||
private static native void nativeNotifyObservers(String topic, String data);
|
||||
|
||||
@ -1848,19 +1823,12 @@ public class GeckoAppShell
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static synchronized void resetScreenSize() {
|
||||
sScreenSize = null;
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
private static synchronized Rect getScreenSize() {
|
||||
if (sScreenSize == null) {
|
||||
final WindowManager wm = (WindowManager)
|
||||
getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
|
||||
final Display disp = wm.getDefaultDisplay();
|
||||
sScreenSize = new Rect(0, 0, disp.getWidth(), disp.getHeight());
|
||||
}
|
||||
return sScreenSize;
|
||||
private static Rect getScreenSize() {
|
||||
final WindowManager wm = (WindowManager)
|
||||
getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
|
||||
final Display disp = wm.getDefaultDisplay();
|
||||
return new Rect(0, 0, disp.getWidth(), disp.getHeight());
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "any")
|
||||
|
@ -13,7 +13,9 @@ import android.view.Surface;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@ -64,6 +66,12 @@ public class GeckoScreenOrientation {
|
||||
// Whether the update should notify Gecko about screen orientation changes.
|
||||
private boolean mShouldNotify = true;
|
||||
|
||||
public interface OrientationChangeListener {
|
||||
void onScreenOrientationChanged(ScreenOrientation newOrientation);
|
||||
}
|
||||
|
||||
private final List<OrientationChangeListener> mListeners;
|
||||
|
||||
public static GeckoScreenOrientation getInstance() {
|
||||
if (sInstance == null) {
|
||||
sInstance = new GeckoScreenOrientation();
|
||||
@ -72,9 +80,26 @@ public class GeckoScreenOrientation {
|
||||
}
|
||||
|
||||
private GeckoScreenOrientation() {
|
||||
mListeners = new ArrayList<>();
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when the screen orientation has changed.
|
||||
*/
|
||||
public void addListener(OrientationChangeListener aListener) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
mListeners.add(aListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a OrientationChangeListener again.
|
||||
*/
|
||||
public void removeListener(OrientationChangeListener aListener) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
mListeners.remove(aListener);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable Gecko screen orientation events on update.
|
||||
*/
|
||||
@ -129,12 +154,13 @@ public class GeckoScreenOrientation {
|
||||
*
|
||||
* @return Whether the screen orientation has changed.
|
||||
*/
|
||||
public boolean update(ScreenOrientation aScreenOrientation) {
|
||||
public synchronized boolean update(ScreenOrientation aScreenOrientation) {
|
||||
if (mScreenOrientation == aScreenOrientation) {
|
||||
return false;
|
||||
}
|
||||
mScreenOrientation = aScreenOrientation;
|
||||
Log.d(LOGTAG, "updating to new orientation " + mScreenOrientation);
|
||||
notifyListeners(mScreenOrientation);
|
||||
if (mShouldNotify) {
|
||||
// Gecko expects a definite screen orientation, so we default to the
|
||||
// primary orientations.
|
||||
@ -151,10 +177,27 @@ public class GeckoScreenOrientation {
|
||||
aScreenOrientation.value, getAngle());
|
||||
}
|
||||
}
|
||||
GeckoAppShell.resetScreenSize();
|
||||
ScreenManagerHelper.refreshScreenInfo();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void notifyListeners(final ScreenOrientation newOrientation) {
|
||||
final Runnable notifier = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (OrientationChangeListener listener : mListeners) {
|
||||
listener.onScreenOrientationChanged(newOrientation);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (ThreadUtils.isOnUiThread()) {
|
||||
notifier.run();
|
||||
} else {
|
||||
ThreadUtils.postToUiThread(notifier);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @return The Android orientation (Configuration.orientation).
|
||||
*/
|
||||
@ -193,11 +236,13 @@ public class GeckoScreenOrientation {
|
||||
Log.d(LOGTAG, "locking to " + aScreenOrientation);
|
||||
final ScreenOrientationDelegate delegate = GeckoAppShell.getScreenOrientationDelegate();
|
||||
final int activityInfoOrientation = screenOrientationToActivityInfoOrientation(aScreenOrientation);
|
||||
if (delegate.setRequestedOrientationForCurrentActivity(activityInfoOrientation)) {
|
||||
update(aScreenOrientation);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
synchronized (this) {
|
||||
if (delegate.setRequestedOrientationForCurrentActivity(activityInfoOrientation)) {
|
||||
update(aScreenOrientation);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,11 +255,13 @@ public class GeckoScreenOrientation {
|
||||
Log.d(LOGTAG, "unlocking");
|
||||
final ScreenOrientationDelegate delegate = GeckoAppShell.getScreenOrientationDelegate();
|
||||
final int activityInfoOrientation = screenOrientationToActivityInfoOrientation(ScreenOrientation.DEFAULT);
|
||||
if (delegate.setRequestedOrientationForCurrentActivity(activityInfoOrientation)) {
|
||||
update();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
synchronized (this) {
|
||||
if (delegate.setRequestedOrientationForCurrentActivity(activityInfoOrientation)) {
|
||||
update();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,20 @@ class ScreenManagerHelper {
|
||||
final static int DISPLAY_EXTERNAL = 1; // wired displays, such as HDMI, DisplayPort, etc.
|
||||
final static int DISPLAY_VIRTUAL = 2; // wireless displays, such as Chromecast, WiFi-Display, etc.
|
||||
|
||||
/**
|
||||
* Trigger a refresh of the cached screen information held by Gecko.
|
||||
*/
|
||||
public static void refreshScreenInfo() {
|
||||
// Screen data is initialised automatically on startup, so no need to queue the call if
|
||||
// Gecko isn't running yet.
|
||||
if (GeckoThread.isRunning()) {
|
||||
nativeRefreshScreenInfo();
|
||||
}
|
||||
}
|
||||
|
||||
@WrapForJNI(stubName = "RefreshScreenInfo", dispatchTo = "gecko")
|
||||
private native static void nativeRefreshScreenInfo();
|
||||
|
||||
/**
|
||||
* Add a new nsScreen when a new display in Android is available.
|
||||
*
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
package org.mozilla.geckoview;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.content.Context;
|
||||
@ -16,7 +15,7 @@ import android.util.Log;
|
||||
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoSharedPrefs;
|
||||
import org.mozilla.gecko.GeckoScreenOrientation;
|
||||
import org.mozilla.gecko.GeckoThread;
|
||||
import org.mozilla.gecko.PrefsHelper;
|
||||
import org.mozilla.gecko.util.BundleEventListener;
|
||||
@ -258,6 +257,22 @@ public final class GeckoRuntime implements Parcelable {
|
||||
return GeckoThread.getActiveProfile().getDir();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify Gecko that the screen orientation has changed.
|
||||
*/
|
||||
public void orientationChanged() {
|
||||
GeckoScreenOrientation.getInstance().update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify Gecko that the screen orientation has changed.
|
||||
* @param newOrientation The new screen orientation, as retrieved e.g. from the current
|
||||
* {@link android.content.res.Configuration}.
|
||||
*/
|
||||
public void orientationChanged(int newOrientation) {
|
||||
GeckoScreenOrientation.getInstance().update(newOrientation);
|
||||
}
|
||||
|
||||
@Override // Parcelable
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
|
@ -16,6 +16,7 @@ import org.mozilla.gecko.util.ActivityUtils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
@ -29,7 +30,6 @@ import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
@ -342,6 +342,7 @@ public class GeckoView extends FrameLayout {
|
||||
if (!mSession.isOpen()) {
|
||||
mSession.open(mRuntime);
|
||||
}
|
||||
mRuntime.orientationChanged();
|
||||
|
||||
super.onAttachedToWindow();
|
||||
}
|
||||
@ -360,6 +361,18 @@ public class GeckoView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
|
||||
if (mRuntime != null) {
|
||||
// onConfigurationChanged is not called for 180 degree orientation changes,
|
||||
// we will miss such rotations and the screen orientation will not be
|
||||
// updated.
|
||||
mRuntime.orientationChanged(newConfig.orientation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean gatherTransparentRegion(final Region region) {
|
||||
// For detecting changes in SurfaceView layout, we take a shortcut here and
|
||||
@ -393,7 +406,7 @@ public class GeckoView extends FrameLayout {
|
||||
setSession(ss.session, ss.session.getRuntime());
|
||||
} else if (ss.session != null) {
|
||||
mSession.transferFrom(ss.session);
|
||||
mRuntime = ss.session.getRuntime();
|
||||
mRuntime = mSession.getRuntime();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,10 @@ import threading
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from Queue import Queue, Empty
|
||||
try:
|
||||
from queue import Queue, Empty
|
||||
except ImportError:
|
||||
from Queue import Queue, Empty
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
@ -124,14 +127,14 @@ class ProcessHandlerMixin(object):
|
||||
thread = threading.current_thread().name
|
||||
print("DBG::MOZPROC PID:{} ({}) | {}".format(self.pid, thread, msg))
|
||||
|
||||
def __del__(self, _maxint=sys.maxint):
|
||||
def __del__(self, _maxint=sys.maxsize):
|
||||
if isWin:
|
||||
handle = getattr(self, '_handle', None)
|
||||
if handle:
|
||||
if hasattr(self, '_internal_poll'):
|
||||
self._internal_poll(_deadstate=_maxint)
|
||||
else:
|
||||
self.poll(_deadstate=sys.maxint)
|
||||
self.poll(_deadstate=sys.maxsize)
|
||||
if handle or self._job or self._io_port:
|
||||
self._cleanup()
|
||||
else:
|
||||
@ -1069,7 +1072,7 @@ class StreamOutput(object):
|
||||
|
||||
def __call__(self, line):
|
||||
try:
|
||||
self.stream.write(line + '\n')
|
||||
self.stream.write(line.decode() + '\n')
|
||||
except UnicodeDecodeError:
|
||||
# TODO: Workaround for bug #991866 to make sure we can display when
|
||||
# when normal UTF-8 display is failing
|
||||
|
@ -6,7 +6,7 @@ from __future__ import absolute_import
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
PACKAGE_VERSION = '0.26'
|
||||
PACKAGE_VERSION = '1.0.0'
|
||||
|
||||
setup(name='mozprocess',
|
||||
version=PACKAGE_VERSION,
|
||||
@ -17,7 +17,8 @@ setup(name='mozprocess',
|
||||
'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)',
|
||||
'Natural Language :: English',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3.5'
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
],
|
||||
keywords='mozilla',
|
||||
|
@ -1,6 +1,5 @@
|
||||
[DEFAULT]
|
||||
subsuite = mozbase, os == "linux"
|
||||
skip-if = python == 3
|
||||
[test_kill.py]
|
||||
[test_misc.py]
|
||||
[test_poll.py]
|
||||
|
@ -4,7 +4,10 @@ from __future__ import absolute_import, print_function
|
||||
|
||||
import argparse
|
||||
import collections
|
||||
import ConfigParser
|
||||
try:
|
||||
import configparser as ConfigParser
|
||||
except ImportError:
|
||||
import ConfigParser
|
||||
import multiprocessing
|
||||
import time
|
||||
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import io
|
||||
import os
|
||||
|
||||
import mozunit
|
||||
|
||||
import proctest
|
||||
from mozprocess import processhandler
|
||||
import six
|
||||
|
||||
here = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
@ -49,26 +49,24 @@ class ProcTestOutput(proctest.ProcTest):
|
||||
"""
|
||||
expected = '\n'.join([str(n) for n in range(0, 10)])
|
||||
|
||||
stream = io.BytesIO()
|
||||
buf = io.BufferedRandom(stream)
|
||||
stream = six.StringIO()
|
||||
|
||||
p = processhandler.ProcessHandler([self.python,
|
||||
os.path.join("scripts", "proccountfive.py")],
|
||||
cwd=here,
|
||||
stream=buf)
|
||||
stream=stream)
|
||||
|
||||
p.run()
|
||||
p.wait()
|
||||
for i in range(5, 10):
|
||||
stream.write(str(i) + '\n')
|
||||
|
||||
buf.flush()
|
||||
self.assertEquals(stream.getvalue().strip(), expected)
|
||||
|
||||
# make sure mozprocess doesn't close the stream
|
||||
# since mozprocess didn't create it
|
||||
self.assertFalse(buf.closed)
|
||||
buf.close()
|
||||
self.assertFalse(stream.closed)
|
||||
stream.close()
|
||||
|
||||
self.determine_status(p, False, ())
|
||||
|
||||
|
@ -33,11 +33,11 @@ class TestProcessReader(unittest.TestCase):
|
||||
timeout_callback=on_timeout)
|
||||
|
||||
def test_stdout_callback(self):
|
||||
proc = run_python('print 1; print 2')
|
||||
proc = run_python('print(1); print(2)')
|
||||
self.reader.start(proc)
|
||||
self.reader.thread.join()
|
||||
|
||||
self.assertEqual(self.out.output, ['1', '2'])
|
||||
self.assertEqual(self.out.output, [b'1', b'2'])
|
||||
self.assertEqual(self.err.output, [])
|
||||
|
||||
def test_stderr_callback(self):
|
||||
@ -46,15 +46,15 @@ class TestProcessReader(unittest.TestCase):
|
||||
self.reader.thread.join()
|
||||
|
||||
self.assertEqual(self.out.output, [])
|
||||
self.assertEqual(self.err.output, ['hello world'])
|
||||
self.assertEqual(self.err.output, [b'hello world'])
|
||||
|
||||
def test_stdout_and_stderr_callbacks(self):
|
||||
proc = run_python('import sys; sys.stderr.write("hello world\\n"); print 1; print 2')
|
||||
proc = run_python('import sys; sys.stderr.write("hello world\\n"); print(1); print(2)')
|
||||
self.reader.start(proc)
|
||||
self.reader.thread.join()
|
||||
|
||||
self.assertEqual(self.out.output, ['1', '2'])
|
||||
self.assertEqual(self.err.output, ['hello world'])
|
||||
self.assertEqual(self.out.output, [b'1', b'2'])
|
||||
self.assertEqual(self.err.output, [b'hello world'])
|
||||
|
||||
def test_finished_callback(self):
|
||||
self.assertFalse(self.finished)
|
||||
@ -85,21 +85,21 @@ class TestProcessReader(unittest.TestCase):
|
||||
proc = run_python('import sys; sys.stdout.write("1")')
|
||||
self.reader.start(proc)
|
||||
self.reader.thread.join()
|
||||
self.assertEqual(self.out.output, ['1'])
|
||||
self.assertEqual(self.out.output, [b'1'])
|
||||
|
||||
def test_read_with_strange_eol(self):
|
||||
proc = run_python('import sys; sys.stdout.write("1\\r\\r\\r\\n")')
|
||||
self.reader.start(proc)
|
||||
self.reader.thread.join()
|
||||
self.assertEqual(self.out.output, ['1'])
|
||||
self.assertEqual(self.out.output, [b'1'])
|
||||
|
||||
def test_mixed_stdout_stderr(self):
|
||||
proc = run_python('import sys; sys.stderr.write("hello world\\n"); print 1; print 2',
|
||||
proc = run_python('import sys; sys.stderr.write("hello world\\n"); print(1); print(2)',
|
||||
stderr=subprocess.STDOUT)
|
||||
self.reader.start(proc)
|
||||
self.reader.thread.join()
|
||||
|
||||
self.assertEqual(sorted(self.out.output), sorted(['1', '2', 'hello world']))
|
||||
self.assertEqual(sorted(self.out.output), sorted([b'1', b'2', b'hello world']))
|
||||
self.assertEqual(self.err.output, [])
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ deps = [
|
||||
'mozfile==1.*',
|
||||
'mozinfo>=0.7,<2',
|
||||
'mozlog==3.*',
|
||||
'mozprocess>=0.23,<1',
|
||||
'mozprocess>=0.23,<2',
|
||||
'mozprofile>=1.1.0,<2',
|
||||
'six>=1.10.0,<2',
|
||||
]
|
||||
|
@ -120,6 +120,12 @@ class Output(object):
|
||||
if test.test_config.get('alert_threshold') is not None:
|
||||
subtest['alertThreshold'] = \
|
||||
test.test_config['alert_threshold']
|
||||
if test.test_config.get('subtest_alerts') is not None:
|
||||
subtest['shouldAlert'] = \
|
||||
test.test_config['subtest_alerts']
|
||||
if test.test_config.get('alert_threshold') is not None:
|
||||
subtest['alertThreshold'] = \
|
||||
test.test_config['alert_threshold']
|
||||
if test.test_config.get('unit'):
|
||||
subtest['unit'] = test.test_config['unit']
|
||||
|
||||
|
@ -37,6 +37,8 @@ class Test(object):
|
||||
filters = filter.ignore_first.prepare(1) + filter.median.prepare()
|
||||
lower_is_better = True
|
||||
alert_threshold = 2.0
|
||||
perfherder_framework = 'talos'
|
||||
subtest_alerts = False
|
||||
|
||||
@classmethod
|
||||
def name(cls):
|
||||
@ -245,6 +247,7 @@ class PageloaderTest(Test):
|
||||
tpcycles = 1 # number of time to run each page
|
||||
cycles = None
|
||||
timeout = None
|
||||
|
||||
keys = ['tpmanifest', 'tpcycles', 'tppagecycles', 'tprender', 'tpchrome',
|
||||
'tpmozafterpaint', 'fnbpaint', 'tphero', 'tploadnocache', 'firstpaint',
|
||||
'userready', 'testeventmap', 'base_vs_ref', 'mainthread', 'resolution',
|
||||
@ -253,7 +256,8 @@ class PageloaderTest(Test):
|
||||
'tpscrolltest', 'xperf_counters', 'timeout', 'responsiveness',
|
||||
'profile_path', 'xperf_providers', 'xperf_user_providers', 'xperf_stackwalk',
|
||||
'format_pagename', 'filters', 'preferences', 'extensions', 'setup', 'cleanup',
|
||||
'lower_is_better', 'alert_threshold', 'unit', 'webextensions', 'profile']
|
||||
'lower_is_better', 'alert_threshold', 'unit', 'webextensions', 'profile',
|
||||
'subtest_alerts', 'perfherder_framework']
|
||||
|
||||
|
||||
class QuantumPageloadTest(PageloaderTest):
|
||||
@ -430,6 +434,8 @@ class damp(PageloaderTest):
|
||||
preferences = {'devtools.memory.enabled': True,
|
||||
'addon.test.damp.webserver': '${webserver}'}
|
||||
unit = 'ms'
|
||||
subtest_alerts = True
|
||||
perfherder_framework = 'devtools'
|
||||
|
||||
|
||||
@register_test()
|
||||
|
@ -146,6 +146,11 @@ class TTest(object):
|
||||
# remove the browser error file
|
||||
mozfile.remove(browser_config['error_filename'])
|
||||
|
||||
# individual tests can have different frameworks
|
||||
# TODO: ensure that we don't run >1 test with custom frameworks
|
||||
if test_config.get('perfherder_framework', None) is not None:
|
||||
test_results.framework = test_config['perfherder_framework']
|
||||
|
||||
# reinstall any file whose stability we need to ensure across
|
||||
# the cycles
|
||||
if test_config.get('reinstall', ''):
|
||||
|
@ -13,7 +13,7 @@ deps = ['httplib2 == 0.9.2',
|
||||
'mozhttpd == 0.7',
|
||||
'mozinfo >= 0.10',
|
||||
'mozinstall == 1.16',
|
||||
'mozprocess == 0.26',
|
||||
'mozprocess == 1.0.0',
|
||||
'mozprofile == 1.1.0',
|
||||
'mozrunner == 7.0.1',
|
||||
'mozversion == 1.5',
|
||||
|
@ -410,88 +410,66 @@ var SafeBrowsing = {
|
||||
let listManager = Cc["@mozilla.org/url-classifier/listmanager;1"].
|
||||
getService(Ci.nsIUrlListManager);
|
||||
|
||||
listManager.disableAllUpdates();
|
||||
|
||||
for (let i = 0; i < this.phishingLists.length; ++i) {
|
||||
if (this.phishingEnabled) {
|
||||
listManager.enableUpdate(this.phishingLists[i]);
|
||||
} else {
|
||||
listManager.disableUpdate(this.phishingLists[i]);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.malwareLists.length; ++i) {
|
||||
if (this.malwareEnabled) {
|
||||
listManager.enableUpdate(this.malwareLists[i]);
|
||||
} else {
|
||||
listManager.disableUpdate(this.malwareLists[i]);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.downloadBlockLists.length; ++i) {
|
||||
if (this.malwareEnabled && this.downloadsEnabled) {
|
||||
listManager.enableUpdate(this.downloadBlockLists[i]);
|
||||
} else {
|
||||
listManager.disableUpdate(this.downloadBlockLists[i]);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.downloadAllowLists.length; ++i) {
|
||||
if (this.malwareEnabled && this.downloadsEnabled) {
|
||||
listManager.enableUpdate(this.downloadAllowLists[i]);
|
||||
} else {
|
||||
listManager.disableUpdate(this.downloadAllowLists[i]);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.passwordAllowLists.length; ++i) {
|
||||
if (this.passwordsEnabled) {
|
||||
listManager.enableUpdate(this.passwordAllowLists[i]);
|
||||
} else {
|
||||
listManager.disableUpdate(this.passwordAllowLists[i]);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.trackingAnnotationLists.length; ++i) {
|
||||
if (this.trackingAnnotations) {
|
||||
listManager.enableUpdate(this.trackingAnnotationLists[i]);
|
||||
} else {
|
||||
listManager.disableUpdate(this.trackingAnnotationLists[i]);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.trackingAnnotationWhitelists.length; ++i) {
|
||||
if (this.trackingAnnotations) {
|
||||
listManager.enableUpdate(this.trackingAnnotationWhitelists[i]);
|
||||
} else {
|
||||
listManager.disableUpdate(this.trackingAnnotationWhitelists[i]);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.trackingProtectionLists.length; ++i) {
|
||||
if (this.trackingEnabled) {
|
||||
listManager.enableUpdate(this.trackingProtectionLists[i]);
|
||||
} else {
|
||||
listManager.disableUpdate(this.trackingProtectionLists[i]);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.trackingProtectionWhitelists.length; ++i) {
|
||||
if (this.trackingEnabled) {
|
||||
listManager.enableUpdate(this.trackingProtectionWhitelists[i]);
|
||||
} else {
|
||||
listManager.disableUpdate(this.trackingProtectionWhitelists[i]);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.blockedLists.length; ++i) {
|
||||
if (this.blockedEnabled) {
|
||||
listManager.enableUpdate(this.blockedLists[i]);
|
||||
} else {
|
||||
listManager.disableUpdate(this.blockedLists[i]);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.flashLists.length; ++i) {
|
||||
if (this.flashBlockEnabled) {
|
||||
listManager.enableUpdate(this.flashLists[i]);
|
||||
} else {
|
||||
listManager.disableUpdate(this.flashLists[i]);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.flashInfobarLists.length; ++i) {
|
||||
if (this.flashInfobarListEnabled) {
|
||||
listManager.enableUpdate(this.flashInfobarLists[i]);
|
||||
} else {
|
||||
listManager.disableUpdate(this.flashInfobarLists[i]);
|
||||
}
|
||||
}
|
||||
listManager.maybeToggleUpdateChecking();
|
||||
|
@ -51,7 +51,12 @@ interface nsIUrlListManager : nsISupports
|
||||
void enableUpdate(in ACString tableName);
|
||||
|
||||
/**
|
||||
* Turn off update checking for a table.
|
||||
* Turn off update checking for all tables.
|
||||
*/
|
||||
void disableAllUpdates();
|
||||
|
||||
/**
|
||||
* Turn off update checking for a single table. Only used in tests.
|
||||
*/
|
||||
void disableUpdate(in ACString tableName);
|
||||
|
||||
|
@ -168,8 +168,7 @@ PROT_ListManager.prototype.getUpdateUrl = function(tableName) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable updates for some tables
|
||||
* @param tables - an array of table names that need updating
|
||||
* Enable updates for a single table.
|
||||
*/
|
||||
PROT_ListManager.prototype.enableUpdate = function(tableName) {
|
||||
var table = this.tablesData[tableName];
|
||||
@ -194,8 +193,17 @@ PROT_ListManager.prototype.updatesNeeded_ = function(updateUrl) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Disables updates for some tables
|
||||
* @param tables - an array of table names that no longer need updating
|
||||
* Disable updates for all tables.
|
||||
*/
|
||||
PROT_ListManager.prototype.disableAllUpdates = function() {
|
||||
for (const tableName of Object.keys(this.tablesData)) {
|
||||
this.disableUpdate(tableName);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Disables updates for a single table. Avoid this internal function
|
||||
* and use disableAllUpdates() instead.
|
||||
*/
|
||||
PROT_ListManager.prototype.disableUpdate = function(tableName) {
|
||||
var table = this.tablesData[tableName];
|
||||
|
@ -26,6 +26,10 @@ class ScreenHelperAndroid::ScreenHelperSupport final
|
||||
public:
|
||||
typedef ScreenManagerHelper::Natives<ScreenHelperSupport> Base;
|
||||
|
||||
static void RefreshScreenInfo() {
|
||||
gHelper->Refresh();
|
||||
}
|
||||
|
||||
static int32_t AddDisplay(int32_t aDisplayType, int32_t aWidth, int32_t aHeight, float aDensity) {
|
||||
static Atomic<uint32_t> nextId;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user