Merge mozilla-central and fx-team
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
Before Width: | Height: | Size: 279 B After Width: | Height: | Size: 311 B |
Before Width: | Height: | Size: 866 B After Width: | Height: | Size: 921 B |
Before Width: | Height: | Size: 594 B After Width: | Height: | Size: 633 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 221 B After Width: | Height: | Size: 254 B |
Before Width: | Height: | Size: 325 B After Width: | Height: | Size: 355 B |
@ -105,6 +105,7 @@ skip-if = android_version == "10"
|
||||
[testNativeWindow]
|
||||
[testOrderedBroadcast]
|
||||
[testResourceSubstitutions]
|
||||
[testRestrictedProfiles]
|
||||
[testSharedPreferences]
|
||||
[testSimpleDiscovery]
|
||||
[testUITelemetry]
|
||||
|
9
mobile/android/base/tests/testRestrictedProfiles.java
Normal file
@ -0,0 +1,9 @@
|
||||
package org.mozilla.gecko.tests;
|
||||
|
||||
|
||||
|
||||
public class testRestrictedProfiles extends JavascriptTest {
|
||||
public testRestrictedProfiles() {
|
||||
super("testRestrictedProfiles.js");
|
||||
}
|
||||
}
|
45
mobile/android/base/tests/testRestrictedProfiles.js
Normal 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();
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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',
|
||||
|
@ -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;
|
||||
}
|
@ -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]),
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|