Merge mozilla-central and fx-team

This commit is contained in:
Ed Morley 2014-08-20 15:18:31 +01:00
commit aae02d523c
24 changed files with 422 additions and 54 deletions

View File

@ -9,6 +9,21 @@ var FullScreen = {
delete this._fullScrToggler;
return this._fullScrToggler = document.getElementById("fullscr-toggler");
},
init: function() {
// called when we go into full screen, even if initiated by a web page script
window.addEventListener("fullscreen", this, true);
window.messageManager.addMessageListener("MozEnteredDomFullscreen", this);
if (window.fullScreen)
this.toggle();
},
uninit: function() {
window.messageManager.removeMessageListener("MozEnteredDomFullscreen", this);
this.cleanup();
},
toggle: function (event) {
var enterFS = window.fullScreen;
@ -95,9 +110,12 @@ var FullScreen = {
switch (event.type) {
case "activate":
if (document.mozFullScreen) {
this.showWarning(this.fullscreenDoc);
this.showWarning(this.fullscreenOrigin);
}
break;
case "fullscreen":
this.toggle(event);
break;
case "transitionend":
if (event.propertyName == "opacity")
this.cancelWarning();
@ -105,18 +123,33 @@ var FullScreen = {
}
},
enterDomFullscreen : function(event) {
receiveMessage: function(aMessage) {
if (aMessage.name == "MozEnteredDomFullscreen") {
// If we're a multiprocess browser, then the request to enter fullscreen
// did not bubble up to the root browser document - it stopped at the root
// of the content document. That means we have to kick off the switch to
// fullscreen here at the operating system level in the parent process
// ourselves.
let data = aMessage.data;
let browser = aMessage.target;
if (gMultiProcessBrowser && browser.getAttribute("remote") == "true") {
let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
windowUtils.remoteFrameFullscreenChanged(browser, data.origin);
}
this.enterDomFullscreen(browser, data.origin);
}
},
enterDomFullscreen : function(aBrowser, aOrigin) {
if (!document.mozFullScreen)
return;
// However, if we receive a "MozEnteredDomFullScreen" event for a document
// which is not a subdocument of a currently active (ie. visible) browser
// or iframe, we know that we've switched to a different frame since the
// request to enter full-screen was made, so we should exit full-screen
// since the "full-screen document" isn't acutally visible.
if (!event.target.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell).isActive) {
// If we've received a fullscreen notification, we have to ensure that the
// element that's requesting fullscreen belongs to the browser that's currently
// active. If not, we exit fullscreen since the "full-screen document" isn't
// actually visible now.
if (gBrowser.selectedBrowser != aBrowser) {
document.mozCancelFullScreen();
return;
}
@ -136,7 +169,7 @@ var FullScreen = {
if (gFindBarInitialized)
gFindBar.close();
this.showWarning(event.target);
this.showWarning(aOrigin);
// Exit DOM full-screen mode upon open, close, or change tab.
gBrowser.tabContainer.addEventListener("TabOpen", this.exitDomFullScreen);
@ -178,7 +211,9 @@ var FullScreen = {
gBrowser.tabContainer.removeEventListener("TabSelect", this.exitDomFullScreen);
if (!this.useLionFullScreen)
window.removeEventListener("activate", this);
this.fullscreenDoc = null;
window.messageManager
.broadcastAsyncMessage("DOMFullscreen:Cleanup");
}
},
@ -337,7 +372,7 @@ var FullScreen = {
// the permission manager can't handle (documents with URIs without a host).
// We simply require those to be approved every time instead.
let rememberCheckbox = document.getElementById("full-screen-remember-decision");
let uri = this.fullscreenDoc.nodePrincipal.URI;
let uri = BrowserUtils.makeURI(this.fullscreenOrigin);
if (!rememberCheckbox.hidden) {
if (rememberCheckbox.checked)
Services.perms.add(uri,
@ -370,27 +405,29 @@ var FullScreen = {
// If the document has been granted fullscreen, notify Gecko so it can resume
// any pending pointer lock requests, otherwise exit fullscreen; the user denied
// the fullscreen request.
if (isApproved)
Services.obs.notifyObservers(this.fullscreenDoc, "fullscreen-approved", "");
else
if (isApproved) {
gBrowser.selectedBrowser
.messageManager
.sendAsyncMessage("DOMFullscreen:Approved");
} else {
document.mozCancelFullScreen();
}
},
warningBox: null,
warningFadeOutTimeout: null,
fullscreenDoc: null,
// Shows the fullscreen approval UI, or if the domain has already been approved
// for fullscreen, shows a warning that the site has entered fullscreen for a short
// duration.
showWarning: function(targetDoc) {
showWarning: function(aOrigin) {
if (!document.mozFullScreen ||
!gPrefService.getBoolPref("full-screen-api.approval-required"))
return;
// Set the strings on the fullscreen approval UI.
this.fullscreenDoc = targetDoc;
let uri = this.fullscreenDoc.nodePrincipal.URI;
this.fullscreenOrigin = aOrigin;
let uri = BrowserUtils.makeURI(aOrigin);
let host = null;
try {
host = uri.host;

View File

@ -1294,17 +1294,7 @@ var gBrowserInit = {
if (Win7Features)
Win7Features.onOpenWindow();
// called when we go into full screen, even if initiated by a web page script
window.addEventListener("fullscreen", onFullScreen, true);
// Called when we enter DOM full-screen mode. Note we can already be in browser
// full-screen mode when we enter DOM full-screen mode.
window.addEventListener("MozEnteredDomFullscreen", onMozEnteredDomFullscreen, true);
if (window.fullScreen)
onFullScreen();
if (document.mozFullScreen)
onMozEnteredDomFullscreen();
FullScreen.init();
#ifdef MOZ_SERVICES_SYNC
// initialize the sync UI
@ -1435,7 +1425,7 @@ var gBrowserInit = {
gHistorySwipeAnimation.uninit();
FullScreen.cleanup();
FullScreen.uninit();
#ifdef MOZ_SERVICES_SYNC
gFxAccounts.uninit();
@ -2762,14 +2752,6 @@ function SwitchToMetro() {
#endif
}
function onFullScreen(event) {
FullScreen.toggle(event);
}
function onMozEnteredDomFullscreen(event) {
FullScreen.enterDomFullscreen(event);
}
function getWebNavigation()
{
return gBrowser.webNavigation;

View File

@ -578,3 +578,40 @@ if (Services.prefs.getBoolPref("browser.translation.detectLanguage")) {
Cu.import("resource:///modules/translation/TranslationContentHandler.jsm");
trHandler = new TranslationContentHandler(global, docShell);
}
let DOMFullscreenHandler = {
_fullscreenDoc: null,
init: function() {
addMessageListener("DOMFullscreen:Approved", this);
addMessageListener("DOMFullscreen:CleanUp", this);
addEventListener("MozEnteredDomFullscreen", this);
},
receiveMessage: function(aMessage) {
switch(aMessage.name) {
case "DOMFullscreen:Approved": {
if (this._fullscreenDoc) {
Services.obs.notifyObservers(this._fullscreenDoc,
"fullscreen-approved",
"");
}
break;
}
case "DOMFullscreen:CleanUp": {
this._fullscreenDoc = null;
break;
}
}
},
handleEvent: function(aEvent) {
if (aEvent.type == "MozEnteredDomFullscreen") {
this._fullscreenDoc = aEvent.target;
sendAsyncMessage("MozEnteredDomFullscreen", {
origin: this._fullscreenDoc.nodePrincipal.origin,
});
}
}
};
DOMFullscreenHandler.init();

View File

@ -198,6 +198,7 @@
#include "mozilla/dom/HTMLInputElement.h"
#include "mozilla/dom/NodeFilterBinding.h"
#include "mozilla/dom/OwningNonNull.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/UndoManager.h"
#include "mozilla/dom/WebComponentsBinding.h"
#include "nsFrame.h"
@ -10543,8 +10544,9 @@ nsIDocument::ExitFullscreen(nsIDocument* aDoc, bool aRunAsync)
}
// Returns true if the document is a direct child of a cross process parent
// mozbrowser iframe. This is the case when the document has a null parent,
// and its DocShell reports that it is a browser frame.
// mozbrowser iframe or TabParent. This is the case when the document has
// a null parent and its DocShell reports that it is a browser frame, or
// we can get a TabChild from it.
static bool
HasCrossProcessParent(nsIDocument* aDocument)
{
@ -10562,7 +10564,12 @@ HasCrossProcessParent(nsIDocument* aDocument)
if (!docShell) {
return false;
}
return docShell->GetIsBrowserOrApp();
TabChild* tabChild(TabChild::GetFrom(docShell));
if (!tabChild) {
return false;
}
return true;
}
static bool

View File

@ -61,6 +61,7 @@ public class AppConstants {
* If our MAX_SDK_VERSION is lower than ICS, we must not be an ICS device.
* Otherwise, we need a range check.
*/
public static final boolean preJBMR2 = MAX_SDK_VERSION < 18 || (MIN_SDK_VERSION < 18 && Build.VERSION.SDK_INT < 18);
public static final boolean preJB = MAX_SDK_VERSION < 16 || (MIN_SDK_VERSION < 16 && Build.VERSION.SDK_INT < 16);
public static final boolean preICS = MAX_SDK_VERSION < 14 || (MIN_SDK_VERSION < 14 && Build.VERSION.SDK_INT < 14);
public static final boolean preHCMR2 = MAX_SDK_VERSION < 13 || (MIN_SDK_VERSION < 13 && Build.VERSION.SDK_INT < 13);

View File

@ -27,11 +27,15 @@ import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.favicons.OnFaviconLoadedListener;
import org.mozilla.gecko.favicons.decoders.FaviconDecoder;
@ -92,12 +96,14 @@ import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.os.SystemClock;
import android.os.UserManager;
import android.os.Vibrator;
import android.provider.Settings;
import android.telephony.TelephonyManager;
@ -153,9 +159,6 @@ public class GeckoAppShell
* sVibrationMaybePlaying is true. */
private static long sVibrationEndTime;
/* Default value of how fast we should hint the Android sensors. */
private static int sDefaultSensorHint = 100;
private static Sensor gAccelerometerSensor;
private static Sensor gLinearAccelerometerSensor;
private static Sensor gGyroscopeSensor;
@ -680,14 +683,14 @@ public class GeckoAppShell
if(gOrientationSensor == null)
gOrientationSensor = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);
if (gOrientationSensor != null)
sm.registerListener(gi.getSensorEventListener(), gOrientationSensor, sDefaultSensorHint);
sm.registerListener(gi.getSensorEventListener(), gOrientationSensor, SensorManager.SENSOR_DELAY_GAME);
break;
case GeckoHalDefines.SENSOR_ACCELERATION:
if(gAccelerometerSensor == null)
gAccelerometerSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (gAccelerometerSensor != null)
sm.registerListener(gi.getSensorEventListener(), gAccelerometerSensor, sDefaultSensorHint);
sm.registerListener(gi.getSensorEventListener(), gAccelerometerSensor, SensorManager.SENSOR_DELAY_GAME);
break;
case GeckoHalDefines.SENSOR_PROXIMITY:
@ -708,14 +711,14 @@ public class GeckoAppShell
if(gLinearAccelerometerSensor == null)
gLinearAccelerometerSensor = sm.getDefaultSensor(10 /* API Level 9 - TYPE_LINEAR_ACCELERATION */);
if (gLinearAccelerometerSensor != null)
sm.registerListener(gi.getSensorEventListener(), gLinearAccelerometerSensor, sDefaultSensorHint);
sm.registerListener(gi.getSensorEventListener(), gLinearAccelerometerSensor, SensorManager.SENSOR_DELAY_GAME);
break;
case GeckoHalDefines.SENSOR_GYROSCOPE:
if(gGyroscopeSensor == null)
gGyroscopeSensor = sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
if (gGyroscopeSensor != null)
sm.registerListener(gi.getSensorEventListener(), gGyroscopeSensor, sDefaultSensorHint);
sm.registerListener(gi.getSensorEventListener(), gGyroscopeSensor, SensorManager.SENSOR_DELAY_GAME);
break;
default:
Log.w(LOGTAG, "Error! Can't enable unknown SENSOR type " + aSensortype);
@ -2528,6 +2531,39 @@ public class GeckoAppShell
return "DIRECT";
}
@WrapElementForJNI
public static boolean isUserRestricted() {
if (Versions.preJBMR2) {
return false;
}
UserManager mgr = (UserManager)getContext().getSystemService(Context.USER_SERVICE);
Bundle restrictions = mgr.getUserRestrictions();
return !restrictions.isEmpty();
}
@WrapElementForJNI
public static String getUserRestrictions() {
if (Versions.preJBMR2) {
return "{}";
}
JSONObject json = new JSONObject();
UserManager mgr = (UserManager)getContext().getSystemService(Context.USER_SERVICE);
Bundle restrictions = mgr.getUserRestrictions();
Set<String> keys = restrictions.keySet();
for (String key : keys) {
try {
json.put(key, restrictions.get(key));
} catch (JSONException e) {
}
}
return json.toString();
}
/* Downloads the uri pointed to by a share intent, and alters the intent to point to the locally stored file.
*/
public static void downloadImageForIntent(final Intent intent) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B

After

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 866 B

After

Width:  |  Height:  |  Size: 921 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 594 B

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 B

After

Width:  |  Height:  |  Size: 355 B

View File

@ -105,6 +105,7 @@ skip-if = android_version == "10"
[testNativeWindow]
[testOrderedBroadcast]
[testResourceSubstitutions]
[testRestrictedProfiles]
[testSharedPreferences]
[testSimpleDiscovery]
[testUITelemetry]

View File

@ -0,0 +1,9 @@
package org.mozilla.gecko.tests;
public class testRestrictedProfiles extends JavascriptTest {
public testRestrictedProfiles() {
super("testRestrictedProfiles.js");
}
}

View File

@ -0,0 +1,45 @@
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
/* 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/. */
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://gre/modules/JNI.jsm");
add_task(function test_isUserRestricted() {
// Make sure the parental controls service is available
do_check_true("@mozilla.org/parental-controls-service;1" in Cc);
let pc = Cc["@mozilla.org/parental-controls-service;1"].createInstance(Ci.nsIParentalControlsService);
// In an admin profile, like the tests: enabled = false
// In a restricted profile: enabled = true
do_check_false(pc.parentalControlsEnabled);
//run_next_test();
});
/*
// NOTE: JNI.jsm has no way to call a string method yet
add_task(function test_getUserRestrictions() {
// In an admin profile, like the tests: {}
// In a restricted profile: {"no_modify_accounts":true,"no_share_location":true}
let restrictions = "{}";
let jni = null;
try {
jni = new JNI();
let cls = jni.findClass("org/mozilla/gecko/GeckoAppShell");
let method = jni.getStaticMethodID(cls, "getUserRestrictions", "()Ljava/lang/String;");
restrictions = jni.callStaticStringMethod(cls, method);
} finally {
if (jni != null) {
jni.close();
}
}
do_check_eq(restrictions, "{}");
});
*/
run_next_test();

View File

@ -8,6 +8,7 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/SimpleServiceDiscovery.jsm");
function ok(passed, text) {
do_report_result(passed, text, Components.stack.caller, false);
@ -26,14 +27,38 @@ function middle(element) {
return [x, y];
}
// We must register a target and make a "mock" service for the target
var testTarget = {
target: "test:service",
factory: function(service) { /* dummy */ },
types: ["video/mp4", "video/webm"],
extensions: ["mp4", "webm"]
};
add_test(function setup_browser() {
chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
let BrowserApp = chromeWin.BrowserApp;
do_register_cleanup(function cleanup() {
BrowserApp.closeTab(BrowserApp.getTabForBrowser(browser));
SimpleServiceDiscovery.unregisterTarget(testTarget);
});
// We need to register a target or processService will ignore us
SimpleServiceDiscovery.registerTarget(testTarget);
// Create a pretend service
let service = {
location: "http://mochi.test:8888/tests/robocop/simpleservice.xml",
target: "test:service"
};
do_print("Force a detailed ping from a pretend service");
// Poke the service directly to get the discovery to happen
SimpleServiceDiscovery._processService(service);
// Load our test web page with <video> elements
let url = "http://mochi.test:8888/tests/robocop/video_discovery.html";
browser = BrowserApp.addTab(url, { selected: true, parentId: BrowserApp.selectedTab.id }).browser;
browser.addEventListener("load", function startTests(event) {

View File

@ -458,6 +458,10 @@ var CastingApps = {
}
});
if (items.length == 0) {
return;
}
let prompt = new Prompt({
title: Strings.browser.GetStringFromName("casting.prompt")
}).setSingleChoiceItems(items).show(function(data) {

View File

@ -246,8 +246,8 @@ var SimpleServiceDiscovery = {
getSupportedExtensions: function() {
let extensions = [];
this._targets.forEach(function(target) {
extensions = extensions.concat(target.extensions);
this.services.forEach(function(service) {
extensions = extensions.concat(service.extensions);
}, this);
return extensions.filter(function(extension, pos) {
return extensions.indexOf(extension) == pos;
@ -256,8 +256,8 @@ var SimpleServiceDiscovery = {
getSupportedMimeTypes: function() {
let types = [];
this._targets.forEach(function(target) {
types = types.concat(target.types);
this.services.forEach(function(service) {
types = types.concat(service.types);
}, this);
return types.filter(function(type, pos) {
return types.indexOf(type) == pos;

View File

@ -19,6 +19,10 @@ if not CONFIG['MOZ_DISABLE_PARENTAL_CONTROLS']:
UNIFIED_SOURCES += [
'nsParentalControlsServiceCocoa.mm',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
UNIFIED_SOURCES += [
'nsParentalControlsServiceAndroid.cpp',
]
else:
SOURCES += [
'nsParentalControlsServiceDefault.cpp',

View File

@ -0,0 +1,67 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "nsParentalControlsService.h"
#include "AndroidBridge.h"
#include "nsString.h"
#include "nsIFile.h"
NS_IMPL_ISUPPORTS(nsParentalControlsService, nsIParentalControlsService)
nsParentalControlsService::nsParentalControlsService() :
mEnabled(false)
{
if (mozilla::AndroidBridge::HasEnv()) {
mEnabled = mozilla::widget::android::GeckoAppShell::IsUserRestricted();
}
}
nsParentalControlsService::~nsParentalControlsService()
{
}
NS_IMETHODIMP
nsParentalControlsService::GetParentalControlsEnabled(bool *aResult)
{
*aResult = mEnabled;
return NS_OK;
}
NS_IMETHODIMP
nsParentalControlsService::GetBlockFileDownloadsEnabled(bool *aResult)
{
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsParentalControlsService::GetLoggingEnabled(bool *aResult)
{
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsParentalControlsService::Log(int16_t aEntryType,
bool aBlocked,
nsIURI *aSource,
nsIFile *aTarget)
{
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsParentalControlsService::RequestURIOverride(nsIURI *aTarget,
nsIInterfaceRequestor *aWindowContext,
bool *_retval)
{
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsParentalControlsService::RequestURIOverrides(nsIArray *aTargets,
nsIInterfaceRequestor *aWindowContext,
bool *_retval)
{
return NS_ERROR_NOT_AVAILABLE;
}

View File

@ -375,6 +375,48 @@ addMessageListener("NetworkPrioritizer:AdjustPriority", (msg) => {
loadGroup.adjustPriority(msg.data.adjustment);
});
let DOMFullscreenManager = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
init: function() {
Services.obs.addObserver(this, "ask-parent-to-exit-fullscreen", false);
Services.obs.addObserver(this, "ask-parent-to-rollback-fullscreen", false);
addMessageListener("DOMFullscreen:ChildrenMustExit", () => {
let utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
utils.exitFullscreen();
});
addEventListener("unload", () => {
Services.obs.removeObserver(this, "ask-parent-to-exit-fullscreen");
Services.obs.removeObserver(this, "ask-parent-to-rollback-fullscreen");
});
},
observe: function(aSubject, aTopic, aData) {
// Observer notifications are global, which means that these notifications
// might be coming from elements that are not actually children within this
// windows' content. We should ignore those. This will not be necessary once
// we fix bug 1053413 and stop using observer notifications for this stuff.
if (aSubject.defaultView.top !== content) {
return;
}
switch (aTopic) {
case "ask-parent-to-exit-fullscreen": {
sendAsyncMessage("DOMFullscreen:RequestExit");
break;
}
case "ask-parent-to-rollback-fullscreen": {
sendAsyncMessage("DOMFullscreen:RequestRollback");
break;
}
}
},
};
DOMFullscreenManager.init();
let AutoCompletePopup = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompletePopup]),

View File

@ -209,6 +209,8 @@
this.messageManager.addMessageListener("DocumentInserted", this);
this.messageManager.addMessageListener("FullZoomChange", this);
this.messageManager.addMessageListener("TextZoomChange", this);
this.messageManager.addMessageListener("DOMFullscreen:RequestExit", this);
this.messageManager.addMessageListener("DOMFullscreen:RequestRollback", this);
this.messageManager.loadFrameScript("chrome://global/content/browser-child.js", true);
if (this.hasAttribute("selectpopup")) {
@ -221,9 +223,17 @@
let RemoteController = Components.utils.import(jsm, {}).RemoteController;
this._controller = new RemoteController(this);
this.controllers.appendController(this._controller);
Services.obs.addObserver(this, "ask-children-to-exit-fullscreen", false);
]]>
</constructor>
<destructor>
<![CDATA[
Services.obs.removeObserver(this, "ask-children-to-exit-fullscreen");
]]>
</destructor>
<method name="receiveMessage">
<parameter name="aMessage"/>
<body><![CDATA[
@ -276,6 +286,20 @@
break;
}
case "DOMFullscreen:RequestExit": {
let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
windowUtils.exitFullscreen();
break;
}
case "DOMFullscreen:RequestRollback": {
let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
windowUtils.remoteFrameFullscreenReverted();
break;
}
default:
// Delegate to browser.xml.
return this._receiveMessage(aMessage);
@ -284,6 +308,19 @@
]]></body>
</method>
<method name="observe">
<parameter name="aSubject"/>
<parameter name="aTopic"/>
<parameter name="aData"/>
<body><![CDATA[
if (aTopic == "ask-children-to-exit-fullscreen") {
if (aSubject == window.document) {
this.messageManager.sendAsyncMessage("DOMFullscreen:ChildrenMustExit");
}
}
]]></body>
</method>
<!--
For out-of-process code, event.screen[XY] is relative to the
left/top of the content view. For in-process code,

View File

@ -55,6 +55,7 @@ jmethodID GeckoAppShell::jGetScreenDepthWrapper = 0;
jmethodID GeckoAppShell::jGetScreenOrientationWrapper = 0;
jmethodID GeckoAppShell::jGetShowPasswordSetting = 0;
jmethodID GeckoAppShell::jGetSystemColoursWrapper = 0;
jmethodID GeckoAppShell::jGetUserRestrictions = 0;
jmethodID GeckoAppShell::jHandleGeckoMessageWrapper = 0;
jmethodID GeckoAppShell::jHandleUncaughtException = 0;
jmethodID GeckoAppShell::jHideProgressDialog = 0;
@ -62,6 +63,7 @@ jmethodID GeckoAppShell::jInitCameraWrapper = 0;
jmethodID GeckoAppShell::jIsNetworkLinkKnown = 0;
jmethodID GeckoAppShell::jIsNetworkLinkUp = 0;
jmethodID GeckoAppShell::jIsTablet = 0;
jmethodID GeckoAppShell::jIsUserRestricted = 0;
jmethodID GeckoAppShell::jKillAnyZombies = 0;
jmethodID GeckoAppShell::jLoadPluginClass = 0;
jmethodID GeckoAppShell::jLockScreenOrientation = 0;
@ -142,6 +144,7 @@ void GeckoAppShell::InitStubs(JNIEnv *jEnv) {
jGetScreenOrientationWrapper = getStaticMethod("getScreenOrientation", "()S");
jGetShowPasswordSetting = getStaticMethod("getShowPasswordSetting", "()Z");
jGetSystemColoursWrapper = getStaticMethod("getSystemColors", "()[I");
jGetUserRestrictions = getStaticMethod("getUserRestrictions", "()Ljava/lang/String;");
jHandleGeckoMessageWrapper = getStaticMethod("handleGeckoMessage", "(Lorg/mozilla/gecko/util/NativeJSContainer;)V");
jHandleUncaughtException = getStaticMethod("handleUncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
jHideProgressDialog = getStaticMethod("hideProgressDialog", "()V");
@ -149,6 +152,7 @@ void GeckoAppShell::InitStubs(JNIEnv *jEnv) {
jIsNetworkLinkKnown = getStaticMethod("isNetworkLinkKnown", "()Z");
jIsNetworkLinkUp = getStaticMethod("isNetworkLinkUp", "()Z");
jIsTablet = getStaticMethod("isTablet", "()Z");
jIsUserRestricted = getStaticMethod("isUserRestricted", "()Z");
jKillAnyZombies = getStaticMethod("killAnyZombies", "()V");
jLoadPluginClass = getStaticMethod("loadPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;");
jLockScreenOrientation = getStaticMethod("lockScreenOrientation", "(I)V");
@ -780,6 +784,19 @@ jintArray GeckoAppShell::GetSystemColoursWrapper() {
return ret;
}
jstring GeckoAppShell::GetUserRestrictions() {
JNIEnv *env = AndroidBridge::GetJNIEnv();
if (env->PushLocalFrame(1) != 0) {
AndroidBridge::HandleUncaughtException(env);
MOZ_CRASH("Exception should have caused crash.");
}
jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetUserRestrictions);
AndroidBridge::HandleUncaughtException(env);
jstring ret = static_cast<jstring>(env->PopLocalFrame(temp));
return ret;
}
void GeckoAppShell::HandleGeckoMessageWrapper(jobject a0) {
JNIEnv *env = AndroidBridge::GetJNIEnv();
if (env->PushLocalFrame(1) != 0) {
@ -872,6 +889,19 @@ bool GeckoAppShell::IsTablet() {
return temp;
}
bool GeckoAppShell::IsUserRestricted() {
JNIEnv *env = AndroidBridge::GetJNIEnv();
if (env->PushLocalFrame(0) != 0) {
AndroidBridge::HandleUncaughtException(env);
MOZ_CRASH("Exception should have caused crash.");
}
bool temp = env->CallStaticBooleanMethod(mGeckoAppShellClass, jIsUserRestricted);
AndroidBridge::HandleUncaughtException(env);
env->PopLocalFrame(nullptr);
return temp;
}
void GeckoAppShell::KillAnyZombies() {
JNIEnv *env = AndroidBridge::GetJNIEnv();
if (env->PushLocalFrame(0) != 0) {

View File

@ -62,6 +62,7 @@ public:
static int16_t GetScreenOrientationWrapper();
static bool GetShowPasswordSetting();
static jintArray GetSystemColoursWrapper();
static jstring GetUserRestrictions();
static void HandleGeckoMessageWrapper(jobject a0);
static void HandleUncaughtException(jobject a0, jthrowable a1);
static void HideProgressDialog();
@ -69,6 +70,7 @@ public:
static bool IsNetworkLinkKnown();
static bool IsNetworkLinkUp();
static bool IsTablet();
static bool IsUserRestricted();
static void KillAnyZombies();
static jclass LoadPluginClass(const nsAString& a0, const nsAString& a1);
static void LockScreenOrientation(int32_t a0);
@ -148,6 +150,7 @@ protected:
static jmethodID jGetScreenOrientationWrapper;
static jmethodID jGetShowPasswordSetting;
static jmethodID jGetSystemColoursWrapper;
static jmethodID jGetUserRestrictions;
static jmethodID jHandleGeckoMessageWrapper;
static jmethodID jHandleUncaughtException;
static jmethodID jHideProgressDialog;
@ -155,6 +158,7 @@ protected:
static jmethodID jIsNetworkLinkKnown;
static jmethodID jIsNetworkLinkUp;
static jmethodID jIsTablet;
static jmethodID jIsUserRestricted;
static jmethodID jKillAnyZombies;
static jmethodID jLoadPluginClass;
static jmethodID jLockScreenOrientation;