Merge b2g-inbound to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-08-01 15:29:14 -04:00
Родитель 19e5d2d26c e7e1275ed0
Коммит 288b4db73c
54 изменённых файлов: 1797 добавлений и 459 удалений

248
b2g/app/B2GLoader.cpp Normal file
Просмотреть файл

@ -0,0 +1,248 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 autoindent cindent expandtab: */
/* 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 "nsXULAppAPI.h"
#include "application.ini.h"
#include "nsXPCOMGlue.h"
#include "nsStringGlue.h"
#include "nsCOMPtr.h"
#include "nsIFile.h"
#include "BinaryPath.h"
#include "nsAutoPtr.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <dlfcn.h>
#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
#define ASSERT(x) if (!(x)) { MOZ_CRASH(); }
// Functions being loaded by XPCOMGlue
XRE_ProcLoaderServiceRunType XRE_ProcLoaderServiceRun;
XRE_ProcLoaderClientInitType XRE_ProcLoaderClientInit;
XRE_ProcLoaderPreloadType XRE_ProcLoaderPreload;
extern XRE_CreateAppDataType XRE_CreateAppData;
extern XRE_GetFileFromPathType XRE_GetFileFromPath;
static const nsDynamicFunctionLoad kXULFuncs[] = {
{ "XRE_ProcLoaderServiceRun", (NSFuncPtr*) &XRE_ProcLoaderServiceRun },
{ "XRE_ProcLoaderClientInit", (NSFuncPtr*) &XRE_ProcLoaderClientInit },
{ "XRE_ProcLoaderPreload", (NSFuncPtr*) &XRE_ProcLoaderPreload },
{ "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
{ nullptr, nullptr }
};
static int
GetDirnameSlash(const char *aPath, char *aOutDir, int aMaxLen)
{
char *lastSlash = strrchr(aPath, XPCOM_FILE_PATH_SEPARATOR[0]);
if (lastSlash == nullptr) {
return 0;
}
int cpsz = lastSlash - aPath + 1; // include slash
if (aMaxLen <= cpsz) {
return 0;
}
strncpy(aOutDir, aPath, cpsz);
aOutDir[cpsz] = 0;
return cpsz;
}
static bool
GetXPCOMPath(const char *aProgram, char *aOutPath, int aMaxLen)
{
nsAutoArrayPtr<char> progBuf(new char[aMaxLen]);
nsresult rv = mozilla::BinaryPath::Get(aProgram, progBuf);
NS_ENSURE_SUCCESS(rv, false);
int len = GetDirnameSlash(progBuf, aOutPath, aMaxLen);
NS_ENSURE_TRUE(!!len, false);
NS_ENSURE_TRUE((len + sizeof(XPCOM_DLL)) < aMaxLen, false);
char *afterSlash = aOutPath + len;
strcpy(afterSlash, XPCOM_DLL);
return true;
}
static bool
LoadLibxul(const char *aXPCOMPath)
{
nsresult rv;
XPCOMGlueEnablePreload();
rv = XPCOMGlueStartup(aXPCOMPath);
NS_ENSURE_SUCCESS(rv, false);
rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
NS_ENSURE_SUCCESS(rv, false);
return true;
}
/**
* Return true if |arg| matches the given argument name.
*/
static bool
IsArg(const char* arg, const char* s)
{
if (*arg == '-') {
if (*++arg == '-') {
++arg;
}
return !strcasecmp(arg, s);
}
#if defined(XP_WIN)
if (*arg == '/') {
return !strcasecmp(++arg, s);
}
#endif
return false;
}
static already_AddRefed<nsIFile>
GetAppIni(int argc, const char *argv[])
{
nsCOMPtr<nsIFile> appini;
nsresult rv;
// Allow firefox.exe to launch XULRunner apps via -app <application.ini>
// Note that -app must be the *first* argument.
const char *appDataFile = getenv("XUL_APP_FILE");
if (appDataFile && *appDataFile) {
rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
NS_ENSURE_SUCCESS(rv, nullptr);
} else if (argc > 1 && IsArg(argv[1], "app")) {
if (argc == 2) {
return nullptr;
}
rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
NS_ENSURE_SUCCESS(rv, nullptr);
char appEnv[MAXPATHLEN];
snprintf(appEnv, MAXPATHLEN, "XUL_APP_FILE=%s", argv[2]);
if (putenv(appEnv)) {
return nullptr;
}
}
return appini.forget();
}
static bool
LoadStaticData(int argc, const char *argv[])
{
char xpcomPath[MAXPATHLEN];
bool ok = GetXPCOMPath(argv[0], xpcomPath, MAXPATHLEN);
NS_ENSURE_TRUE(ok, false);
ok = LoadLibxul(xpcomPath);
NS_ENSURE_TRUE(ok, false);
char progDir[MAXPATHLEN];
ok = GetDirnameSlash(xpcomPath, progDir, MAXPATHLEN);
NS_ENSURE_TRUE(ok, false);
nsCOMPtr<nsIFile> appini = GetAppIni(argc, argv);
const nsXREAppData *appData;
if (appini) {
nsresult rv =
XRE_CreateAppData(appini, const_cast<nsXREAppData**>(&appData));
NS_ENSURE_SUCCESS(rv, false);
} else {
appData = &sAppData;
}
XRE_ProcLoaderPreload(progDir, appData);
if (appini) {
XRE_FreeAppData(const_cast<nsXREAppData*>(appData));
}
return true;
}
/**
* Fork and run parent and child process.
*
* The parent is the b2g process and child for Nuwa.
*/
static int
RunProcesses(int argc, const char *argv[])
{
/*
* The original main() of the b2g process. It is renamed to
* b2g_main() for the b2g loader.
*/
int b2g_main(int argc, const char *argv[]);
int ipcSockets[2] = {-1, -1};
int r = socketpair(AF_LOCAL, SOCK_STREAM, 0, ipcSockets);
ASSERT(r == 0);
int parentSock = ipcSockets[0];
int childSock = ipcSockets[1];
r = fcntl(parentSock, F_SETFL, O_NONBLOCK);
ASSERT(r != -1);
r = fcntl(childSock, F_SETFL, O_NONBLOCK);
ASSERT(r != -1);
pid_t pid = fork();
ASSERT(pid >= 0);
bool isChildProcess = pid == 0;
close(isChildProcess ? parentSock : childSock);
if (isChildProcess) {
/* The Nuwa process */
/* This provides the IPC service of loading Nuwa at the process.
* The b2g process would send a IPC message of loading Nuwa
* as the replacement of forking and executing plugin-container.
*/
return XRE_ProcLoaderServiceRun(getppid(), childSock, argc, argv);
}
// The b2g process
int childPid = pid;
XRE_ProcLoaderClientInit(childPid, parentSock);
return b2g_main(argc, argv);
}
/**
* B2G Loader is responsible for loading the b2g process and the
* Nuwa process. It forks into the parent process, for the b2g
* process, and the child process, for the Nuwa process.
*
* The loader loads libxul and performs initialization of static data
* before forking, so relocation of libxul and static data can be
* shared between the b2g process, the Nuwa process, and the content
* processes.
*/
int
main(int argc, const char* argv[])
{
const char *program = argv[0];
/*
* Before fork(), libxul and static data of Gecko are loaded for
* sharing.
*/
bool ok = LoadStaticData(argc, argv);
if (!ok) {
return 255;
}
return RunProcesses(argc, argv);
}

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

@ -9,6 +9,11 @@ if not CONFIG['LIBXUL_SDK']:
PROGRAM = CONFIG['MOZ_APP_NAME'] + "-bin"
else:
PROGRAM = CONFIG['MOZ_APP_NAME']
if CONFIG['MOZ_B2G_LOADER']:
SOURCES += [
'B2GLoader.cpp',
]
SOURCES += [
'nsBrowserApp.cpp',
]

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

@ -17,6 +17,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "nsCOMPtr.h"
#include "nsIFile.h"
@ -163,9 +164,22 @@ static int do_main(int argc, char* argv[])
return XRE_main(argc, argv, &sAppData, 0);
}
int main(int argc, char* argv[])
#ifdef MOZ_B2G_LOADER
/*
* The main() in B2GLoader.cpp is the new main function instead of the
* main() here if it is enabled. So, rename it to b2g_man().
*/
#define main b2g_main
#define _CONST const
#else
#define _CONST
#endif
int main(int argc, _CONST char* argv[])
{
#ifndef MOZ_B2G_LOADER
char exePath[MAXPATHLEN];
#endif
#ifdef MOZ_WIDGET_GONK
// This creates a ThreadPool for binder ipc. A ThreadPool is necessary to
@ -175,7 +189,9 @@ int main(int argc, char* argv[])
android::ProcessState::self()->startThreadPool();
#endif
nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
nsresult rv;
#ifndef MOZ_B2G_LOADER
rv = mozilla::BinaryPath::Get(argv[0], exePath);
if (NS_FAILED(rv)) {
Output("Couldn't calculate the application directory.\n");
return 255;
@ -186,6 +202,7 @@ int main(int argc, char* argv[])
return 255;
strcpy(++lastSlash, XPCOM_DLL);
#endif // MOZ_B2G_LOADER
#if defined(XP_UNIX)
// If the b2g app is launched from adb shell, then the shell will wind
@ -209,6 +226,9 @@ int main(int argc, char* argv[])
DllBlocklist_Initialize();
#endif
// B2G loader has already initialized Gecko so we can't initialize
// it again here.
#ifndef MOZ_B2G_LOADER
// We do this because of data in bug 771745
XPCOMGlueEnablePreload();
@ -219,6 +239,7 @@ int main(int argc, char* argv[])
}
// Reset exePath so that it is the directory name and not the xpcom dll name
*lastSlash = 0;
#endif // MOZ_B2G_LOADER
rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
if (NS_FAILED(rv)) {
@ -253,7 +274,25 @@ int main(int argc, char* argv[])
int result;
{
ScopedLogging log;
result = do_main(argc, argv);
char **_argv;
/*
* Duplicate argument vector to conform non-const argv of
* do_main() since XRE_main() is very stupid with non-const argv.
*/
_argv = new char *[argc + 1];
for (int i = 0; i < argc; i++) {
_argv[i] = strdup(argv[i]);
MOZ_ASSERT(_argv[i] != nullptr);
}
_argv[argc] = nullptr;
result = do_main(argc, _argv);
for (int i = 0; i < argc; i++) {
free(_argv[i]);
}
delete[] _argv;
}
return result;

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="71f5a35e3bc1801847413cff1f14fc3b5cd991ca"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="999e945b85c578c503ad445c2285940f16aacdae">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

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

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="71f5a35e3bc1801847413cff1f14fc3b5cd991ca"/>

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

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "3842156466e71f41748f86777a1b8fbd379441c0",
"revision": "92b742f333b1f695de3de7c10316bc5ee652d084",
"repo_path": "/integration/gaia-central"
}

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

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="71f5a35e3bc1801847413cff1f14fc3b5cd991ca"/>

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

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9689218473b6fc4dd927ad6aa7b06c05f0843824"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1f20f326f317feda0ec59aff011b54a7c62cb9bf"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d61daef8fca7d6f335f659a8967bad423770e634"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -59,6 +59,7 @@ MOZ_B2G=1
if test "$OS_TARGET" = "Android"; then
MOZ_NUWA_PROCESS=1
MOZ_B2G_LOADER=1
fi
MOZ_FOLD_LIBS=1

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

@ -8614,6 +8614,14 @@ if test "$MOZ_WIDGET_TOOLKIT" = gonk -a -n "$MOZ_NUWA_PROCESS"; then
AC_DEFINE(MOZ_NUWA_PROCESS)
fi
AC_SUBST(MOZ_NUWA_PROCESS)
if test "$MOZ_WIDGET_TOOLKIT" = gonk -a -n "$MOZ_B2G_LOADER"; then
if test -z "$MOZ_NUWA_PROCESS"; then
AC_MSG_ERROR([B2G loader works with Nuwa]);
fi
export MOZ_B2G_LOADER
AC_DEFINE(MOZ_B2G_LOADER)
fi
AC_SUBST(MOZ_B2G_LOADER)
AC_SUBST(NSPR_CFLAGS)
AC_SUBST(NSPR_LIBS)

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

@ -23,7 +23,9 @@ let makeFile = CC('@mozilla.org/file/local;1',
'initWithPath');
let MutableArray = CC('@mozilla.org/array;1', 'nsIMutableArray');
const nsICache = Ci.nsICache;
let {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", {});
const nsICacheStorage = Ci.nsICacheStorage;
const nsIApplicationCache = Ci.nsIApplicationCache;
const applicationCacheService =
Cc['@mozilla.org/network/application-cache-service;1']
@ -47,10 +49,12 @@ function enableOfflineCacheForApp(origin, appId) {
function storeCache(applicationCache, url, file, itemType) {
let session = Services.cache.createSession(applicationCache.clientID,
nsICache.STORE_OFFLINE, true);
session.asyncOpenCacheEntry(url, nsICache.ACCESS_WRITE, {
onCacheEntryAvailable: function (cacheEntry, accessGranted, status) {
let storage =
Services.cache2.appCacheStorage(LoadContextInfo.default, applicationCache);
let uri = Services.io.newURI(url, null, null);
storage.asyncOpenURI(uri, "", nsICacheStorage.OPEN_TRUNCATE, {
onCacheEntryAvailable:
function (cacheEntry, isNew, appCache, result) {
cacheEntry.setMetaDataElement('request-method', 'GET');
cacheEntry.setMetaDataElement('response-head', 'HTTP/1.1 200 OK\r\n');

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

@ -234,6 +234,7 @@ GonkCameraHardware::Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCam
nsresult rv = cameraHardware->Init();
if (NS_FAILED(rv)) {
DOM_CAMERA_LOGE("Failed to initialize camera hardware (0x%X)\n", rv);
cameraHardware->Close();
return nullptr;
}

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

@ -17,6 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=940424
<script class="testbody" type="text/javascript;version=1.7">
SimpleTest.waitForExplicitFinish();
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
var initialConfig = {
mode: 'picture',
@ -27,24 +29,65 @@ var initialConfig = {
}
};
function end() {
CameraTest.end();
}
CameraTest.begin("hardware", function(test) {
test.set("init-failure", function(type) {
var tests = [
{
name: "init-failure",
key: "init-failure",
func: function testInitFailure(test) {
function onSuccess(camera, config) {
ok(false, "onSuccess called incorrectly");
camera.release();
test.done(end);
test.next();
}
function onError(error) {
ok(true, "onError called correctly on init failure");
test.done(end);
test.next();
}
info("Running test: " + type);
info("Running test: init-failure");
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
});
}
},
/* This test case (init-success) *must* follow the preceeding test case
(init-failure) in order for the desired condition to be verified */
{
name: "init-success",
key: "",
func: function(test) {
function onSuccess(camera, config) {
ok(true, "onSuccess called correctly");
camera.release();
test.next();
}
function onError(error) {
ok(false, "onError called incorrectly: " + error);
test.next();
}
info("Running test: init-success");
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError)
}
}
];
var testGenerator = function() {
for (var i = 0; i < tests.length; ++i ) {
yield tests[i];
}
}();
CameraTest.begin("hardware", function(test) {
CameraTest.next = function() {
try {
var t = testGenerator.next();
test.set(t.key, t.func.bind(undefined, CameraTest));
} catch(e) {
if (e instanceof StopIteration) {
CameraTest.end();
} else {
throw e;
}
}
};
CameraTest.next();
});
</script>

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

@ -68,6 +68,7 @@
#include "UeventPoller.h"
#include "nsIWritablePropertyBag2.h"
#include <algorithm>
#include "PowerWakeLock.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
#define NsecPerMsec 1000000LL
@ -667,6 +668,7 @@ void
SetScreenEnabled(bool aEnabled)
{
GetGonkDisplay()->SetEnabled(aEnabled);
gPowerWakelock = nullptr;
sScreenEnabled = aEnabled;
}

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

@ -37,6 +37,10 @@ include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk
ifneq ($(MOZ_WIDGET_TOOLKIT),android)
#LIBS += ../contentproc/$(LIB_PREFIX)plugin-container.$(LIB_SUFFIX)
endif
ifeq ($(OS_ARCH),WINNT) #{
# Note the manifest file exists in the tree, so we use the explicit filename
# here.

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

@ -4,148 +4,9 @@
* 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 "nsXPCOM.h"
#include "nsXULAppAPI.h"
// FIXME/cjones testing
#if !defined(OS_WIN)
#include <unistd.h>
#endif
#ifdef XP_WIN
#include <windows.h>
// we want a wmain entry point
// but we don't want its DLL load protection, because we'll handle it here
#define XRE_DONT_PROTECT_DLL_LOAD
#include "nsWindowsWMain.cpp"
#include "nsSetDllDirectory.h"
#endif
#if defined(XP_WIN)
#include "sandbox/chromium/base/basictypes.h"
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "mozilla/sandboxTarget.h"
#endif
#ifdef MOZ_WIDGET_GONK
# include <sys/time.h>
# include <sys/resource.h>
# include <binder/ProcessState.h>
# ifdef LOGE_IF
# undef LOGE_IF
# endif
# include <android/log.h>
# define LOGE_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)__android_log_print(ANDROID_LOG_ERROR, \
"Gecko:MozillaRntimeMain", __VA_ARGS__)) \
: (void)0 )
#endif
#ifdef MOZ_NUWA_PROCESS
#include <binder/ProcessState.h>
#include "ipc/Nuwa.h"
#endif
#ifdef MOZ_WIDGET_GONK
static void
InitializeBinder(void *aDummy) {
// Change thread priority to 0 only during calling ProcessState::self().
// The priority is registered to binder driver and used for default Binder
// Thread's priority.
// To change the process's priority to small value need's root permission.
int curPrio = getpriority(PRIO_PROCESS, 0);
int err = setpriority(PRIO_PROCESS, 0, 0);
MOZ_ASSERT(!err);
LOGE_IF(err, "setpriority failed. Current process needs root permission.");
android::ProcessState::self()->startThreadPool();
setpriority(PRIO_PROCESS, 0, curPrio);
}
#endif
#if defined(XP_WIN)
static bool gIsSandboxEnabled = false;
void StartSandboxCallback()
{
if (gIsSandboxEnabled) {
sandbox::TargetServices* target_service =
sandbox::SandboxFactory::GetTargetServices();
target_service->LowerToken();
}
}
#endif
#include "../contentproc/plugin-container.cpp"
int
main(int argc, char* argv[])
{
bool isNuwa = false;
for (int i = 1; i < argc; i++) {
isNuwa |= strcmp(argv[i], "-nuwa") == 0;
#if defined(XP_WIN)
gIsSandboxEnabled |= strcmp(argv[i], "-sandbox") == 0;
#endif
}
#ifdef MOZ_NUWA_PROCESS
if (isNuwa) {
PrepareNuwaProcess();
}
#endif
#ifdef MOZ_WIDGET_GONK
// This creates a ThreadPool for binder ipc. A ThreadPool is necessary to
// receive binder calls, though not necessary to send binder calls.
// ProcessState::Self() also needs to be called once on the main thread to
// register the main thread with the binder driver.
#ifdef MOZ_NUWA_PROCESS
if (!isNuwa) {
InitializeBinder(nullptr);
} else {
NuwaAddFinalConstructor(&InitializeBinder, nullptr);
}
#else
InitializeBinder(nullptr);
#endif
#endif
// Check for the absolute minimum number of args we need to move
// forward here. We expect the last arg to be the child process type.
if (argc < 1)
return 3;
GeckoProcessType proctype = XRE_StringToChildProcessType(argv[--argc]);
#ifdef XP_WIN
// For plugins, this is done in PluginProcessChild::Init, as we need to
// avoid it for unsupported plugins. See PluginProcessChild::Init for
// the details.
if (proctype != GeckoProcessType_Plugin) {
mozilla::SanitizeEnvironmentVariables();
SetDllDirectory(L"");
}
if (gIsSandboxEnabled) {
sandbox::TargetServices* target_service =
sandbox::SandboxFactory::GetTargetServices();
if (!target_service) {
return 1;
}
sandbox::ResultCode result = target_service->Init();
if (result != sandbox::SBOX_ALL_OK) {
return 2;
}
mozilla::SandboxTarget::Instance()->SetStartSandboxCallback(StartSandboxCallback);
}
#endif
nsresult rv = XRE_InitChildProcess(argc, argv, proctype);
NS_ENSURE_SUCCESS(rv, 1);
return 0;
main(int argc, char *argv[]) {
return content_process_main(argc, argv);
}

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

@ -1,3 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 autoindent cindent expandtab: */
// Copyright (c) 2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@ -18,6 +20,13 @@
#include "base/logging.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
#include "nsLiteralString.h"
#ifdef MOZ_B2G_LOADER
#include "ProcessUtils.h"
using namespace mozilla::ipc;
#endif // MOZ_B2G_LOADER
#ifdef MOZ_WIDGET_GONK
/*
@ -188,12 +197,71 @@ bool LaunchApp(const std::vector<std::string>& argv,
wait, process_handle);
}
#ifdef MOZ_B2G_LOADER
/**
* Launch an app using B2g Loader.
*/
static bool
LaunchAppProcLoader(const std::vector<std::string>& argv,
const file_handle_mapping_vector& fds_to_remap,
const environment_map& env_vars_to_set,
ChildPrivileges privs,
ProcessHandle* process_handle) {
size_t i;
scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
for (i = 0; i < argv.size(); i++) {
argv_cstr[i] = const_cast<char*>(argv[i].c_str());
}
argv_cstr[argv.size()] = nullptr;
scoped_array<char*> env_cstr(new char*[env_vars_to_set.size() + 1]);
i = 0;
for (environment_map::const_iterator it = env_vars_to_set.begin();
it != env_vars_to_set.end(); ++it) {
env_cstr[i++] = strdup((it->first + "=" + it->second).c_str());
}
env_cstr[env_vars_to_set.size()] = nullptr;
bool ok = ProcLoaderLoad((const char **)argv_cstr.get(),
(const char **)env_cstr.get(),
fds_to_remap, privs,
process_handle);
MOZ_ASSERT(ok, "ProcLoaderLoad() failed");
for (size_t i = 0; i < env_vars_to_set.size(); i++) {
free(env_cstr[i]);
}
return ok;
}
static bool
IsLaunchingNuwa(const std::vector<std::string>& argv) {
std::vector<std::string>::const_iterator it;
for (it = argv.begin(); it != argv.end(); ++it) {
if (*it == std::string("-nuwa")) {
return true;
}
}
return false;
}
#endif // MOZ_B2G_LOADER
bool LaunchApp(const std::vector<std::string>& argv,
const file_handle_mapping_vector& fds_to_remap,
const environment_map& env_vars_to_set,
ChildPrivileges privs,
bool wait, ProcessHandle* process_handle,
ProcessArchitecture arch) {
#ifdef MOZ_B2G_LOADER
static bool beforeFirstNuwaLaunch = true;
if (!wait && beforeFirstNuwaLaunch && IsLaunchingNuwa(argv)) {
beforeFirstNuwaLaunch = false;
return LaunchAppProcLoader(argv, fds_to_remap, env_vars_to_set,
privs, process_handle);
}
#endif // MOZ_B2G_LOADER
scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
// Illegal to allocate memory after fork and before execvp
InjectiveMultimap fd_shuffle1, fd_shuffle2;

29
ipc/contentproc/moz.build Normal file
Просмотреть файл

@ -0,0 +1,29 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
LIBRARY_NAME = 'plugin-container'
if CONFIG['MOZ_B2G_LOADER']:
FINAL_LIBRARY = 'xul'
SOURCES += [
'plugin-container.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
if CONFIG['OS_ARCH'] == 'WINNT':
LOCAL_INCLUDES += [
'/toolkit/xre',
'/xpcom/base',
]
if CONFIG['OS_ARCH'] == 'WINNT':
# For sandbox includes and the include dependencies those have
LOCAL_INCLUDES += [
'/security',
'/security/sandbox',
'/security/sandbox/chromium',
]

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

@ -0,0 +1,151 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=4 et :
* 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 "nsXPCOM.h"
#include "nsXULAppAPI.h"
// FIXME/cjones testing
#if !defined(OS_WIN)
#include <unistd.h>
#endif
#ifdef XP_WIN
#include <windows.h>
// we want a wmain entry point
// but we don't want its DLL load protection, because we'll handle it here
#define XRE_DONT_PROTECT_DLL_LOAD
#include "nsWindowsWMain.cpp"
#include "nsSetDllDirectory.h"
#endif
#if defined(XP_WIN)
#include "sandbox/chromium/base/basictypes.h"
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "mozilla/sandboxTarget.h"
#endif
#ifdef MOZ_WIDGET_GONK
# include <sys/time.h>
# include <sys/resource.h>
# include <binder/ProcessState.h>
# ifdef LOGE_IF
# undef LOGE_IF
# endif
# include <android/log.h>
# define LOGE_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)__android_log_print(ANDROID_LOG_ERROR, \
"Gecko:MozillaRntimeMain", __VA_ARGS__)) \
: (void)0 )
#endif
#ifdef MOZ_NUWA_PROCESS
#include <binder/ProcessState.h>
#include "ipc/Nuwa.h"
#endif
#ifdef MOZ_WIDGET_GONK
static void
InitializeBinder(void *aDummy) {
// Change thread priority to 0 only during calling ProcessState::self().
// The priority is registered to binder driver and used for default Binder
// Thread's priority.
// To change the process's priority to small value need's root permission.
int curPrio = getpriority(PRIO_PROCESS, 0);
int err = setpriority(PRIO_PROCESS, 0, 0);
MOZ_ASSERT(!err);
LOGE_IF(err, "setpriority failed. Current process needs root permission.");
android::ProcessState::self()->startThreadPool();
setpriority(PRIO_PROCESS, 0, curPrio);
}
#endif
#if defined(XP_WIN)
static bool gIsSandboxEnabled = false;
void StartSandboxCallback()
{
if (gIsSandboxEnabled) {
sandbox::TargetServices* target_service =
sandbox::SandboxFactory::GetTargetServices();
target_service->LowerToken();
}
}
#endif
int
content_process_main(int argc, char* argv[])
{
bool isNuwa = false;
for (int i = 1; i < argc; i++) {
isNuwa |= strcmp(argv[i], "-nuwa") == 0;
#if defined(XP_WIN)
gIsSandboxEnabled |= strcmp(argv[i], "-sandbox") == 0;
#endif
}
#ifdef MOZ_NUWA_PROCESS
if (isNuwa) {
PrepareNuwaProcess();
}
#endif
#ifdef MOZ_WIDGET_GONK
// This creates a ThreadPool for binder ipc. A ThreadPool is necessary to
// receive binder calls, though not necessary to send binder calls.
// ProcessState::Self() also needs to be called once on the main thread to
// register the main thread with the binder driver.
#ifdef MOZ_NUWA_PROCESS
if (!isNuwa) {
InitializeBinder(nullptr);
} else {
NuwaAddFinalConstructor(&InitializeBinder, nullptr);
}
#else
InitializeBinder(nullptr);
#endif
#endif
// Check for the absolute minimum number of args we need to move
// forward here. We expect the last arg to be the child process type.
if (argc < 1)
return 3;
GeckoProcessType proctype = XRE_StringToChildProcessType(argv[--argc]);
#ifdef XP_WIN
// For plugins, this is done in PluginProcessChild::Init, as we need to
// avoid it for unsupported plugins. See PluginProcessChild::Init for
// the details.
if (proctype != GeckoProcessType_Plugin) {
mozilla::SanitizeEnvironmentVariables();
SetDllDirectory(L"");
}
if (gIsSandboxEnabled) {
sandbox::TargetServices* target_service =
sandbox::SandboxFactory::GetTargetServices();
if (!target_service) {
return 1;
}
sandbox::ResultCode result = target_service->Init();
if (result != sandbox::SBOX_ALL_OK) {
return 2;
}
mozilla::SandboxTarget::Instance()->SetStartSandboxCallback(StartSandboxCallback);
}
#endif
nsresult rv = XRE_InitChildProcess(argc, argv, proctype);
NS_ENSURE_SUCCESS(rv, 1);
return 0;
}

35
ipc/glue/PProcLoader.ipdl Normal file
Просмотреть файл

@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 autoindent cindent expandtab: */
/* 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/. */
namespace mozilla {
namespace ipc {
struct FDRemap {
FileDescriptor fd;
int mapto;
};
protocol PProcLoader
{
child:
/**
* Request B2G loader service to load content process.
*
* It actually calls the main() function of plugin-container.
*/
async Load(nsCString[] argv, nsCString[] env,
FDRemap[] fdsRemap, uint32_t privs,
int32_t cookie);
parent:
/**
* The acknowledgement of Load().
*/
async LoadComplete(int32_t pid, int32_t cookie);
};
}
}

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

@ -1,3 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 autoindent cindent expandtab: */
/* 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/. */
@ -5,6 +7,10 @@
#ifndef mozilla_ipc_ProcessUtils_h
#define mozilla_ipc_ProcessUtils_h
#ifdef MOZ_B2G_LOADER
#include "base/process_util.h"
#endif
namespace mozilla {
namespace ipc {
@ -12,6 +18,17 @@ namespace ipc {
// this directly.
void SetThisProcessName(const char *aName);
#ifdef MOZ_B2G_LOADER
// see ProcessUtils_linux.cpp for explaination.
void ProcLoaderClientGeckoInit();
bool ProcLoaderLoad(const char *aArgv[],
const char *aEnvp[],
const base::file_handle_mapping_vector &aFdsRemap,
const base::ChildPrivileges aPrivs,
base::ProcessHandle *aProcessHandle);
#endif /* MOZ_B2G_LOADER */
} // namespace ipc
} // namespace mozilla

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

@ -1,3 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 autoindent cindent expandtab: */
/* 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/. */
@ -8,6 +10,37 @@
#include <sys/prctl.h>
#ifdef MOZ_B2G_LOADER
#include <sys/types.h>
#include <unistd.h>
#include "nsAutoPtr.h"
#include "mozilla/Assertions.h"
#include "mozilla/ipc/PProcLoaderParent.h"
#include "mozilla/ipc/PProcLoaderChild.h"
#include "mozilla/ipc/Transport.h"
#include "mozilla/ipc/FileDescriptorUtils.h"
#include "mozilla/ipc/IOThreadChild.h"
#include "mozilla/dom/ContentProcess.h"
#include "base/file_descriptor_shuffle.h"
#include "mozilla/BackgroundHangMonitor.h"
#include "mozilla/DebugOnly.h"
#include "base/process_util.h"
#include "prenv.h"
#include "nsXULAppAPI.h" // export XRE_* functions
#include "nsAppRunner.h"
int content_process_main(int argc, char *argv[]);
extern bool gDisableAndroidLog;
#endif /* MOZ_B2G_LOADER */
namespace mozilla {
namespace ipc {
@ -16,5 +49,522 @@ void SetThisProcessName(const char *aName)
prctl(PR_SET_NAME, (unsigned long)aName, 0uL, 0uL, 0uL);
}
#ifdef MOZ_B2G_LOADER
/**
* How does B2G Loader Work?
*
* <<parent process>> <<child process>>
* ProcLoaderParent -----> ProcLoaderChild
* ^ |
* | load() | content_process_main()
* | V
* ProcLoaderClient Nuwa/plugin-container
* ^
* | ProcLoaderLoad()
* ...
* ContentParent
*
*
* B2G loader includes an IPC protocol PProcLoader for communication
* between client (parent) and server (child). The b2g process is the
* client. It requests the server to load/start the Nuwa process with
* the given arguments, env variables, and file descriptors.
*
* ProcLoaderClientInit() is called by B2G loader to initialize the
* client side, the b2g process. Then the b2g_main() is called to
* start b2g process.
*
* ProcLoaderClientGeckoInit() is called by XRE_main() to create the
* parent actor, |ProcLoaderParent|, of PProcLoader for servicing the
* request to run Nuwa process later once Gecko has been initialized.
*
* ProcLoaderServiceRun() is called by the server process. It starts
* an IOThread and event loop to serve the |ProcLoaderChild|
* implmentation of PProcLoader protocol as the child actor. Once it
* recieves a load() request, it stops the IOThread and event loop,
* then starts running the main function of the content process with
* the given arguments.
*
* NOTE: The server process serves at most one load() request.
*/
using namespace base;
using namespace mozilla::dom;
static bool sProcLoaderClientOnDeinit = false;
static DebugOnly<bool> sProcLoaderClientInitialized = false;
static DebugOnly<bool> sProcLoaderClientGeckoInitialized = false;
static pid_t sProcLoaderPid = 0;
static int sProcLoaderChannelFd = -1;
static PProcLoaderParent *sProcLoaderParent = nullptr;
static MessageLoop *sProcLoaderLoop = nullptr;
static void ProcLoaderClientDeinit();
class ProcLoaderParent : public PProcLoaderParent
{
private:
nsAutoPtr<FileDescriptor> mChannelFd; // To keep a reference.
public:
ProcLoaderParent(FileDescriptor *aFd) : mChannelFd(aFd) {}
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool RecvLoadComplete(const int32_t &aPid,
const int32_t &aCookie) MOZ_OVERRIDE;
virtual void OnChannelError() MOZ_OVERRIDE;
};
void
ProcLoaderParent::ActorDestroy(ActorDestroyReason aWhy)
{
}
static void
_ProcLoaderParentDestroy(PProcLoaderParent *aLoader)
{
aLoader->Close();
delete aLoader;
sProcLoaderClientOnDeinit = false;
}
bool
ProcLoaderParent::RecvLoadComplete(const int32_t &aPid,
const int32_t &aCookie)
{
ProcLoaderClientDeinit();
return true;
}
void
ProcLoaderParent::OnChannelError()
{
if (sProcLoaderClientOnDeinit) {
// Get error for closing while the channel is already error.
return;
}
NS_WARNING("ProcLoaderParent is in channel error");
ProcLoaderClientDeinit();
}
/**
* Initialize the client of B2G loader for loader itself.
*
* The initialization of B2G loader are divided into two stages. First
* stage is to collect child info passed from the main program of the
* loader. Second stage is to initialize Gecko according to info from the
* first stage and make the client of loader service ready.
*
* \param aPeerPid is the pid of the child.
* \param aChannelFd is the file descriptor of the socket used for IPC.
*/
static void
ProcLoaderClientInit(pid_t aPeerPid, int aChannelFd)
{
MOZ_ASSERT(!sProcLoaderClientInitialized, "call ProcLoaderClientInit() more than once");
MOZ_ASSERT(aPeerPid != 0 && aChannelFd != -1, "invalid argument");
sProcLoaderPid = aPeerPid;
sProcLoaderChannelFd = aChannelFd;
sProcLoaderClientInitialized = true;
}
/**
* Initialize the client of B2G loader for Gecko.
*/
void
ProcLoaderClientGeckoInit()
{
MOZ_ASSERT(sProcLoaderClientInitialized, "call ProcLoaderClientInit() at first");
MOZ_ASSERT(!sProcLoaderClientGeckoInitialized,
"call ProcLoaderClientGeckoInit() more than once");
sProcLoaderClientGeckoInitialized = true;
FileDescriptor *fd = new FileDescriptor(sProcLoaderChannelFd);
close(sProcLoaderChannelFd);
sProcLoaderChannelFd = -1;
Transport *transport = OpenDescriptor(*fd, Transport::MODE_CLIENT);
sProcLoaderParent = new ProcLoaderParent(fd);
sProcLoaderParent->Open(transport,
sProcLoaderPid,
XRE_GetIOMessageLoop(),
ParentSide);
sProcLoaderLoop = MessageLoop::current();
}
/**
* Shutdown and destroy the client of B2G loader service.
*/
static void
ProcLoaderClientDeinit()
{
MOZ_ASSERT(sProcLoaderClientGeckoInitialized && sProcLoaderClientInitialized);
sProcLoaderClientGeckoInitialized = false;
sProcLoaderClientInitialized = false;
sProcLoaderClientOnDeinit = true;
MOZ_ASSERT(sProcLoaderParent != nullptr);
PProcLoaderParent *procLoaderParent = sProcLoaderParent;
sProcLoaderParent = nullptr;
sProcLoaderLoop = nullptr;
MessageLoop::current()->
PostTask(FROM_HERE,
NewRunnableFunction(&_ProcLoaderParentDestroy,
procLoaderParent));
}
struct AsyncSendLoadData
{
nsTArray<nsCString> mArgv;
nsTArray<nsCString> mEnv;
nsTArray<FDRemap> mFdsremap;
ChildPrivileges mPrivs;
int mCookie;
};
static void
AsyncSendLoad(AsyncSendLoadData *aLoad)
{
PProcLoaderParent *loader = sProcLoaderParent;
DebugOnly<bool> ok =
loader->SendLoad(aLoad->mArgv, aLoad->mEnv, aLoad->mFdsremap,
aLoad->mPrivs, aLoad->mCookie);
MOZ_ASSERT(ok);
delete aLoad;
}
/**
* Request the loader service, the server, to load Nuwa.
*/
bool
ProcLoaderLoad(const char *aArgv[],
const char *aEnvp[],
const file_handle_mapping_vector &aFdsRemap,
const ChildPrivileges aPrivs,
ProcessHandle *aProcessHandle)
{
static int cookie=0;
int i;
if (sProcLoaderParent == nullptr || sProcLoaderPid == 0) {
return false;
}
AsyncSendLoadData *load = new AsyncSendLoadData();
nsTArray<nsCString> &argv = load->mArgv;
for (i = 0; aArgv[i] != nullptr; i++) {
argv.AppendElement(nsCString(aArgv[i]));
}
nsTArray<nsCString> &env = load->mEnv;
for (i = 0; aEnvp[i] != nullptr; i++) {
env.AppendElement(nsCString(aEnvp[i]));
}
nsTArray<FDRemap> &fdsremap = load->mFdsremap;
for (file_handle_mapping_vector::const_iterator fdmap =
aFdsRemap.begin();
fdmap != aFdsRemap.end();
fdmap++) {
fdsremap.AppendElement(FDRemap(FileDescriptor(fdmap->first), fdmap->second));
}
load->mPrivs = aPrivs;
load->mCookie = cookie++;
*aProcessHandle = sProcLoaderPid;
sProcLoaderPid = 0;
sProcLoaderLoop->PostTask(FROM_HERE,
NewRunnableFunction(AsyncSendLoad, load));
return true;
}
class ProcLoaderRunnerBase;
static bool sProcLoaderServing = false;
static ProcLoaderRunnerBase *sProcLoaderDispatchedTask = nullptr;
class ProcLoaderRunnerBase
{
public:
virtual int DoWork() = 0;
};
class ProcLoaderNoopRunner : public ProcLoaderRunnerBase {
public:
virtual int DoWork();
};
int
ProcLoaderNoopRunner::DoWork() {
return 0;
}
/**
* The runner to load Nuwa at the current process.
*/
class ProcLoaderLoadRunner : public ProcLoaderRunnerBase {
private:
const nsTArray<nsCString> mArgv;
const nsTArray<nsCString> mEnv;
const nsTArray<FDRemap> mFdsRemap;
const ChildPrivileges mPrivs;
void ShuffleFds();
public:
ProcLoaderLoadRunner(const InfallibleTArray<nsCString>& aArgv,
const InfallibleTArray<nsCString>& aEnv,
const InfallibleTArray<FDRemap>& aFdsRemap,
const ChildPrivileges aPrivs)
: mArgv(aArgv)
, mEnv(aEnv)
, mFdsRemap(aFdsRemap)
, mPrivs(aPrivs) {}
int DoWork();
};
void
ProcLoaderLoadRunner::ShuffleFds()
{
unsigned int i;
InjectiveMultimap fd_shuffle1, fd_shuffle2;
fd_shuffle1.reserve(mFdsRemap.Length());
fd_shuffle2.reserve(mFdsRemap.Length());
for (i = 0; i < mFdsRemap.Length(); i++) {
const FDRemap *map = &mFdsRemap[i];
int fd = map->fd().PlatformHandle();
int tofd = map->mapto();
fd_shuffle1.push_back(InjectionArc(fd, tofd, false));
fd_shuffle2.push_back(InjectionArc(fd, tofd, false));
}
DebugOnly<bool> ok = ShuffleFileDescriptors(&fd_shuffle1);
MOZ_ASSERT(ok, "ShuffleFileDescriptors failed");
CloseSuperfluousFds(fd_shuffle2);
}
int
ProcLoaderLoadRunner::DoWork()
{
unsigned int i;
ShuffleFds();
unsigned int argc = mArgv.Length();
char **argv = new char *[argc + 1];
for (i = 0; i < argc; i++) {
argv[i] = ::strdup(mArgv[i].get());
}
argv[argc] = nullptr;
unsigned int envc = mEnv.Length();
for (i = 0; i < envc; i++) {
PR_SetEnv(mEnv[i].get());
}
SetCurrentProcessPrivileges(mPrivs);
MOZ_ASSERT(content_process_main != nullptr,
"content_process_main not found");
// Start Nuwa (main function)
int ret = content_process_main(argc, argv);
for (i = 0; i < argc; i++) {
free(argv[i]);
}
delete[] argv;
return ret;
}
class ProcLoaderChild : public PProcLoaderChild
{
pid_t mPeerPid;
public:
ProcLoaderChild(pid_t aPeerPid) : mPeerPid(aPeerPid) {}
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool RecvLoad(const InfallibleTArray<nsCString>& aArgv,
const InfallibleTArray<nsCString>& aEnv,
const InfallibleTArray<FDRemap>& aFdsremap,
const uint32_t& aPrivs,
const int32_t& aCookie);
virtual void OnChannelError();
};
void
ProcLoaderChild::ActorDestroy(ActorDestroyReason aWhy)
{
}
static void
_ProcLoaderChildDestroy(ProcLoaderChild *aChild)
{
aChild->Close();
delete aChild;
MessageLoop::current()->Quit();
}
bool
ProcLoaderChild::RecvLoad(const InfallibleTArray<nsCString>& aArgv,
const InfallibleTArray<nsCString>& aEnv,
const InfallibleTArray<FDRemap>& aFdsRemap,
const uint32_t& aPrivs,
const int32_t& aCookie) {
if (!sProcLoaderServing) {
return true;
}
sProcLoaderServing = false;
MOZ_ASSERT(sProcLoaderDispatchedTask == nullptr);
ChildPrivileges privs = static_cast<ChildPrivileges>(aPrivs);
sProcLoaderDispatchedTask =
new ProcLoaderLoadRunner(aArgv, aEnv, aFdsRemap, privs);
SendLoadComplete(mPeerPid, aCookie);
MessageLoop::current()->PostTask(FROM_HERE,
NewRunnableFunction(_ProcLoaderChildDestroy,
this));
return true;
}
void
ProcLoaderChild::OnChannelError()
{
if (!sProcLoaderServing) {
return;
}
sProcLoaderServing = false;
PProcLoaderChild::OnChannelError();
MOZ_ASSERT(sProcLoaderDispatchedTask == nullptr);
sProcLoaderDispatchedTask = new ProcLoaderNoopRunner();
MessageLoop::current()->PostTask(FROM_HERE,
NewRunnableFunction(_ProcLoaderChildDestroy,
this));
}
/**
* A helper class which calls NS_LogInit/NS_LogTerm in its scope.
*/
class ScopedLogging
{
public:
ScopedLogging() { NS_LogInit(); }
~ScopedLogging() { NS_LogTerm(); }
};
/**
* Run service of ProcLoader.
*
* \param aPeerPid is the pid of the parent.
* \param aFd is the file descriptor of the socket for IPC.
*
* See the comment near the head of this file.
*/
static int
ProcLoaderServiceRun(pid_t aPeerPid, int aFd,
int aArgc, const char *aArgv[])
{
ScopedLogging logging;
char **_argv;
_argv = new char *[aArgc + 1];
for (int i = 0; i < aArgc; i++) {
_argv[i] = ::strdup(aArgv[i]);
MOZ_ASSERT(_argv[i] != nullptr);
}
_argv[aArgc] = nullptr;
gArgv = _argv;
gArgc = aArgc;
{
gDisableAndroidLog = true;
nsresult rv = XRE_InitCommandLine(aArgc, _argv);
if (NS_FAILED(rv)) {
gDisableAndroidLog = false;
MOZ_CRASH();
}
FileDescriptor fd(aFd);
close(aFd);
MOZ_ASSERT(!sProcLoaderServing);
MessageLoop loop;
nsAutoPtr<ContentProcess> process;
process = new ContentProcess(aPeerPid);
ChildThread *iothread = process->child_thread();
Transport *transport = OpenDescriptor(fd, Transport::MODE_CLIENT);
ProcLoaderChild *loaderChild = new ProcLoaderChild(aPeerPid);
// Pass a message loop to initialize (connect) the channel
// (connection).
loaderChild->Open(transport, aPeerPid, iothread->message_loop());
BackgroundHangMonitor::Prohibit();
sProcLoaderServing = true;
loop.Run();
BackgroundHangMonitor::Allow();
XRE_DeinitCommandLine();
gDisableAndroidLog = false;
}
MOZ_ASSERT(sProcLoaderDispatchedTask != nullptr);
ProcLoaderRunnerBase *task = sProcLoaderDispatchedTask;
sProcLoaderDispatchedTask = nullptr;
int ret = task->DoWork();
delete task;
for (int i = 0; i < aArgc; i++) {
free(_argv[i]);
}
delete[] _argv;
return ret;
}
#endif /* MOZ_B2G_LOADER */
} // namespace ipc
} // namespace mozilla
#ifdef MOZ_B2G_LOADER
void
XRE_ProcLoaderClientInit(pid_t aPeerPid, int aChannelFd)
{
mozilla::ipc::ProcLoaderClientInit(aPeerPid, aChannelFd);
}
int
XRE_ProcLoaderServiceRun(pid_t aPeerPid, int aFd,
int aArgc, const char *aArgv[])
{
return mozilla::ipc::ProcLoaderServiceRun(aPeerPid, aFd,
aArgc, aArgv);
}
#endif /* MOZ_B2G_LOADER */

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

@ -130,12 +130,14 @@ IPDL_SOURCES = [
'PBackground.ipdl',
'PBackgroundSharedTypes.ipdlh',
'PBackgroundTest.ipdl',
'PProcLoader.ipdl',
'ProtocolTypes.ipdlh',
'URIParams.ipdlh',
]
LOCAL_INCLUDES += [
'/toolkit/xre',
'/xpcom/threads',
]

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

@ -26,4 +26,7 @@ if CONFIG['MOZ_B2G_RIL'] or CONFIG['MOZ_B2G_BT'] or CONFIG['MOZ_NFC'] or CONFIG[
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
DIRS += ['keystore', 'netd']
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
DIRS += ['contentproc']
DIRS += ['app']

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

@ -15,7 +15,8 @@
// See http://www.w3.org/TR/AERT#color-contrast
#define NS_SUFFICIENT_LUMINOSITY_DIFFERENCE 125000
#define NS_LUMINOSITY_DIFFERENCE(a, b) \
int32_t(mozilla::Abs(NS_GetLuminosity(a) - NS_GetLuminosity(b)))
int32_t(mozilla::Abs( \
NS_GetLuminosity(a | 0xff000000) - NS_GetLuminosity(b | 0xff000000)))
// To determine colors based on the background brightness and border color
void NS_GetSpecial3DColors(nscolor aResult[2],

1
media/mtransport/third_party/moz.build поставляемый
Просмотреть файл

@ -50,7 +50,6 @@ nrappkit_non_unified_sources = [
'nrappkit/src/util/hex.c',
'nrappkit/src/util/libekr/debug.c',
'nrappkit/src/util/libekr/r_assoc.c',
'nrappkit/src/util/libekr/r_bitfield.c',
'nrappkit/src/util/libekr/r_crc32.c',
'nrappkit/src/util/libekr/r_data.c',
'nrappkit/src/util/libekr/r_errors.c',

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

@ -10,8 +10,6 @@
src/util/libekr/debug.h
src/util/libekr/r_assoc.c
src/util/libekr/r_assoc.h
src/util/libekr/r_bitfield.c
src/util/libekr/r_bitfield.h
src/util/libekr/r_common.h
src/util/libekr/r_crc32.c
src/util/libekr/r_crc32.h

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

@ -42,8 +42,6 @@
'./src/util/libekr/r_assoc.c',
'./src/util/libekr/r_assoc.h',
# './src/util/libekr/r_assoc_test.c',
'./src/util/libekr/r_bitfield.c',
'./src/util/libekr/r_bitfield.h',
'./src/util/libekr/r_common.h',
'./src/util/libekr/r_crc32.c',
'./src/util/libekr/r_crc32.h',

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

@ -1,152 +0,0 @@
/**
r_bitfield.c
Copyright (C) 2002-2003, Network Resonance, Inc.
Copyright (C) 2006, Network Resonance, Inc.
All Rights Reserved
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of Network Resonance, Inc. nor the name of any
contributors to this software may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/**
r_bitfield.c
Copyright (C) 2001 RTFM, Inc.
All Rights Reserved.
ekr@rtfm.com Wed Oct 3 11:15:23 2001
*/
static char *RCSSTRING __UNUSED__ ="$Id: r_bitfield.c,v 1.2 2006/08/16 19:39:17 adamcain Exp $";
#include <string.h>
#include <r_common.h>
#include <string.h>
#include "r_bitfield.h"
int r_bitfield_create(setp,size)
r_bitfield **setp;
UINT4 size;
{
r_bitfield *set=0;
int _status;
int num_words=size/32+!!(size%32);
if(!(set=(r_bitfield *)RMALLOC(sizeof(r_bitfield))))
ABORT(R_NO_MEMORY);
if(!(set->data=(UINT4 *)RMALLOC(num_words*4)))
ABORT(R_NO_MEMORY);
memset(set->data,0,4*num_words);
set->base=0;
set->len=num_words;
*setp=set;
_status=0;
abort:
if(_status){
r_bitfield_destroy(&set);
}
return(_status);
}
int r_bitfield_destroy(setp)
r_bitfield **setp;
{
r_bitfield *set;
if(!setp || !*setp)
return(0);
set=*setp;
RFREE(set->data);
RFREE(set);
*setp=0;
return(0);
}
int r_bitfield_set(set,bit)
r_bitfield *set;
int bit;
{
int word=(bit-set->base)/32;
int bbit=(bit-set->base)%32;
int _status;
/* Resize? */
if(word>set->len){
UINT4 newlen=set->len;
UINT4 *tmp;
while(newlen<word)
newlen*=2;
if(!(tmp=(UINT4 *)RMALLOC(newlen)))
ABORT(R_NO_MEMORY);
memcpy(tmp,set->data,set->len*4);
memset(tmp+set->len*4,0,(newlen-set->len)*4);
RFREE(set->data);
set->data=tmp;
}
set->data[word]|=1<<bbit;
_status=0;
abort:
return(_status);
}
int r_bitfield_isset(set,bit)
r_bitfield *set;
int bit;
{
int word=(bit-set->base)/32;
int bbit=(bit-set->base)%32;
int _status;
if(bit<set->base)
return(0);
/* Resize? */
if(word>set->len)
return(0);
return(set->data[word]&(1<<bbit));
_status=0;
return(_status);
}

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

@ -1,63 +0,0 @@
/**
r_bitfield.h
Copyright (C) 2002-2003, Network Resonance, Inc.
Copyright (C) 2006, Network Resonance, Inc.
All Rights Reserved
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of Network Resonance, Inc. nor the name of any
contributors to this software may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/**
r_bitfield.h
Copyright (C) 2001 RTFM, Inc.
All Rights Reserved.
ekr@rtfm.com Wed Oct 3 10:43:50 2001
*/
#ifndef _r_bitfield_h
#define _r_bitfield_h
typedef struct r_bitfield_ {
UINT4 *data;
UINT4 len;
UINT4 base;
} r_bitfield;
int r_bitfield_set(r_bitfield *,int bit);
int r_bitfield_isset(r_bitfield *,int bit);
int r_bitfield_create(r_bitfield **setp,UINT4 size);
int r_bitfield_destroy(r_bitfield **setp);
#endif

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

@ -99,18 +99,70 @@ ARTPAssembler::AssemblyStatus AH263Assembler::addPacket(
return MALFORMED_PACKET;
}
// RFC 4629, Sec. 5.1 General H.263+ Payload Header.
// The H.263+ payload header is structured as follows:
// 0 1
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | RR |P|V| PLEN |PEBIT|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// RR: 5 bits
// Reserved bits. It SHALL be zero and MUST be ignored by receivers.
// P: 1 bit
// Indicates the picture start or a picture segment (GOB/Slice) start or
// a video sequence end (EOS or EOSBS). Two bytes of zero bits then have
// to be prefixed to the payload of such a packet to compose a complete
// picture/GOB/slice/EOS/EOSBS start code. This bit allows the omission
// of the two first bytes of the start code, thus improving the
// compression ratio.
// V: 1 bit
// Indicates the presence of an 8-bit field containing information for
// Video Redundancy Coding (VRC), which follows immediately after the
// initial 16 bits of the payload header.
// PLEN: 6 bits
// Length, in bytes, of the extra picture header. If no extra picture
// header is attached, PLEN is 0. If PLEN>0, the extra picture header is
// attached immediately following the rest of the payload header. Note
// that the length reflects the omission of the first two bytes of the
// picture start code (PSC).
// PEBIT: 3 bits
// Indicates the number of bits that shall be ignored in the last byte
// of the picture header. If PLEN is not zero, the ignored bits shall be
// the least significant bits of the byte. If PLEN is zero, then PEBIT
// shall also be zero.
unsigned payloadHeader = U16_AT(buffer->data());
CHECK_EQ(payloadHeader >> 11, 0u); // RR=0
unsigned P = (payloadHeader >> 10) & 1;
CHECK_EQ((payloadHeader >> 9) & 1, 0u); // V=0
CHECK_EQ((payloadHeader >> 3) & 0x3f, 0u); // PLEN=0
CHECK_EQ(payloadHeader & 7, 0u); // PEBIT=0
unsigned V = (payloadHeader >> 9) & 1;
unsigned PLEN = (payloadHeader >> 3) & 0x3f;
unsigned PEBIT = payloadHeader & 7;
// V = 0
// We do not support VRC header extension for now, so just discard it if
// present.
if (V != 0u) {
queue->erase(queue->begin());
++mNextExpectedSeqNo;
ALOGW("Packet discarded due to VRC (V != 0)");
return MALFORMED_PACKET;
}
// If PLEN is zero, then PEBIT shall also be zero.
if (PLEN == 0u && PEBIT != 0u) {
queue->erase(queue->begin());
++mNextExpectedSeqNo;
ALOGW("Packet discarded (PEBIT != 0)");
return MALFORMED_PACKET;
}
size_t skip = PLEN + (P ? 0: 2);
buffer->setRange(buffer->offset() + skip, buffer->size() - skip);
if (P) {
buffer->data()[0] = 0x00;
buffer->data()[1] = 0x00;
} else {
buffer->setRange(buffer->offset() + 2, buffer->size() - 2);
}
mPackets.push_back(buffer);

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

@ -215,12 +215,21 @@ static sp<ABuffer> MakeAVCCodecSpecificData(
}
sp<ABuffer> MakeAACCodecSpecificData(const char *params) {
if (!params || !strlen(params)) {
return NULL;
}
AString val;
CHECK(GetAttribute(params, "config", &val));
if (!GetAttribute(params, "config", &val)) {
return NULL;
}
sp<ABuffer> config = decodeHex(val);
CHECK(config != NULL);
CHECK_GE(config->size(), 4u);
if (!config.get()) {
return NULL;
}
if (config->size() < 4u) {
return NULL;
}
const uint8_t *data = config->data();
uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
@ -476,6 +485,10 @@ APacketSource::APacketSource(
sp<ABuffer> codecSpecificData =
MakeAACCodecSpecificData(params.c_str());
if (!codecSpecificData.get()) {
mInitCheck = ERROR_UNSUPPORTED;
return;
}
mFormat->setData(
kKeyESDS, 0,

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

@ -160,6 +160,8 @@ if CONFIG['MOZ_ENABLE_XREMOTE']:
'/widget/xremoteclient',
]
if CONFIG['MOZ_B2G_LOADER']:
DEFINES['OMNIJAR_NAME'] = CONFIG['OMNIJAR_NAME']
CXXFLAGS += CONFIG['TK_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']

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

@ -185,6 +185,10 @@
#include "GTestRunner.h"
#endif
#ifdef MOZ_B2G_LOADER
#include "ProcessUtils.h"
#endif
#ifdef MOZ_WIDGET_ANDROID
#include "AndroidBridge.h"
#endif
@ -3772,6 +3776,10 @@ XREMain::XRE_mainRun()
nsresult rv = NS_OK;
NS_ASSERTION(mScopedXPCom, "Scoped xpcom not initialized.");
#ifdef MOZ_B2G_LOADER
mozilla::ipc::ProcLoaderClientGeckoInit();
#endif
#ifdef NS_FUNCTION_TIMER
// initialize some common services, so we don't pay the cost for these at odd times later on;
// SetWindowCreator -> ChromeRegistry -> IOService -> SocketTransportService -> (nspr wspm init), Prefs

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

@ -81,6 +81,11 @@
using mozilla::_ipdltest::IPDLUnitTestProcessChild;
#endif // ifdef MOZ_IPDL_TESTS
#ifdef MOZ_B2G_LOADER
#include "nsLocalFile.h"
#include "nsXREAppData.h"
#endif
using namespace mozilla;
using mozilla::ipc::BrowserProcessSubThread;
@ -815,3 +820,38 @@ XRE_GetWindowsEnvironment()
}
#endif // XP_WIN
#ifdef MOZ_B2G_LOADER
extern const nsXREAppData* gAppData;
/**
* Preload static data of Gecko for B2G loader.
*
* This function is supposed to be called before XPCOM is initialized.
* For now, this function preloads
* - XPT interface Information
*/
void
XRE_ProcLoaderPreload(const char* aProgramDir, const nsXREAppData* aAppData)
{
void PreloadXPT(nsIFile *);
nsresult rv;
nsCOMPtr<nsIFile> omnijarFile;
rv = NS_NewNativeLocalFile(nsCString(aProgramDir),
true,
getter_AddRefs(omnijarFile));
MOZ_ASSERT(NS_SUCCEEDED(rv));
rv = omnijarFile->AppendNative(NS_LITERAL_CSTRING(NS_STRINGIFY(OMNIJAR_NAME)));
MOZ_ASSERT(NS_SUCCEEDED(rv));
/*
* gAppData is required by nsXULAppInfo. The manifest parser
* evaluate flags with the information from nsXULAppInfo.
*/
gAppData = aAppData;
PreloadXPT(omnijarFile);
gAppData = nullptr;
}
#endif /* MOZ_B2G_LOADER */

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

@ -878,6 +878,10 @@ void mozilla_sampler_unlock()
bool mozilla_sampler_register_thread(const char* aName, void* stackTop)
{
if (sInitCount == 0) {
return false;
}
#if defined(MOZ_WIDGET_GONK) && !defined(MOZ_PROFILING)
// The only way to profile secondary threads on b2g
// is to build with profiling OR have the profiler
@ -895,6 +899,10 @@ bool mozilla_sampler_register_thread(const char* aName, void* stackTop)
void mozilla_sampler_unregister_thread()
{
if (sInitCount == 0) {
return;
}
Sampler::UnregisterCurrentThread();
PseudoStack *stack = tlsPseudoStack.get();
@ -906,6 +914,10 @@ void mozilla_sampler_unregister_thread()
}
void mozilla_sampler_sleep_start() {
if (sInitCount == 0) {
return;
}
PseudoStack *stack = tlsPseudoStack.get();
if (stack == nullptr) {
return;
@ -914,6 +926,10 @@ void mozilla_sampler_sleep_start() {
}
void mozilla_sampler_sleep_end() {
if (sInitCount == 0) {
return;
}
PseudoStack *stack = tlsPseudoStack.get();
if (stack == nullptr) {
return;

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

@ -0,0 +1,24 @@
/* -*- Mode: C++; tab-width: 40; 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 "PowerWakeLock.h"
#include <hardware_legacy/power.h>
const char* kPower_WAKE_LOCK_ID = "PowerKeyEvent";
namespace mozilla {
namespace hal_impl {
StaticRefPtr <PowerWakelock> gPowerWakelock;
PowerWakelock::PowerWakelock()
{
acquire_wake_lock(PARTIAL_WAKE_LOCK, kPower_WAKE_LOCK_ID);
}
PowerWakelock::~PowerWakelock()
{
release_wake_lock(kPower_WAKE_LOCK_ID);
}
} // hal_impl
} // mozilla

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

@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 40; 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/. */
#ifndef __POWERWAKELOCK_H_
#define __POWERWAKELOCK_H_
#include "mozilla/StaticPtr.h"
#include "nsISupportsImpl.h"
namespace mozilla {
namespace hal_impl {
class PowerWakelock
{
public:
NS_INLINE_DECL_REFCOUNTING(PowerWakelock);
PowerWakelock();
private:
~PowerWakelock();
};
extern StaticRefPtr <PowerWakelock> gPowerWakelock;
} // hal_impl
} // mozilla
#endif /* __POWERWAKELOCK_H_ */

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

@ -51,6 +51,12 @@
#include <sys/limits.h>
#include <sha1.h>
#include "PowerWakeLock.h"
#include "mozilla/Hal.h"
using namespace mozilla;
using namespace mozilla::hal;
using namespace mozilla::hal_impl;
/* this macro is used to tell if "bit" is set in "array"
* it selects a byte from the array, and does a boolean AND
* operation with a byte that only has the relevant bit set.
@ -855,6 +861,10 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz
event->type = iev.type;
event->code = iev.code;
event->value = iev.value;
if (event->code == KEY_POWER && event->value
&& !hal::GetScreenEnabled()) {
gPowerWakelock = new PowerWakelock();
}
event += 1;
capacity -= 1;
}

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

@ -17,6 +17,7 @@
EXPORTS += [
'GonkPermission.h',
'OrientationObserver.h',
'PowerWakeLock.h',
]
DIRS += ['libdisplay', 'nativewindow']
@ -57,6 +58,7 @@ SOURCES += [
'nsWindow.cpp',
'OrientationObserver.cpp',
'ParentProcessController.cpp',
'PowerWakeLock.cpp',
'ProcessOrientation.cpp',
'WidgetTraceEvent.cpp'
]

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

@ -92,6 +92,8 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
aColor = TEXT_NORMAL_COLOR;
break;
case eColorID_TextSelectBackground:
aColor = NS_RGBA(0x33,0xb5,0xe5,0x66);
break;
case eColorID_IMESelectedRawTextBackground:
case eColorID_IMESelectedConvertedTextBackground:
// still used

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

@ -101,6 +101,13 @@ Break(const char* aMsg);
#include <stdlib.h>
#endif
#ifdef MOZ_B2G_LOADER
/* Avoid calling Android logger/logd temporarily while running
* B2GLoader to start the child process.
*/
bool gDisableAndroidLog = false;
#endif
using namespace mozilla;
static const char* sMultiprocessDescription = nullptr;
@ -392,6 +399,9 @@ NS_DebugBreak(uint32_t aSeverity, const char* aStr, const char* aExpr,
#endif
#ifdef ANDROID
#ifdef MOZ_B2G_LOADER
if (!gDisableAndroidLog)
#endif
__android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", buf.buffer);
#endif

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

@ -467,6 +467,16 @@ XRE_API(WindowsEnvironmentType,
XRE_GetWindowsEnvironment, ())
#endif // XP_WIN
#ifdef MOZ_B2G_LOADER
XRE_API(int,
XRE_ProcLoaderServiceRun, (pid_t, int, int argc, const char *argv[]));
XRE_API(void,
XRE_ProcLoaderClientInit, (pid_t, int));
XRE_API(void,
XRE_ProcLoaderPreload, (const char* aProgramDir,
const nsXREAppData* aAppData));
#endif // MOZ_B2G_LOADER
XRE_API(int,
XRE_XPCShellMain, (int argc, char** argv, char** envp))

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

@ -36,6 +36,18 @@
#include "nsIScriptError.h"
#include "nsIXULAppInfo.h"
#include "nsIXULRuntime.h"
#ifdef MOZ_B2G_LOADER
#include "mozilla/XPTInterfaceInfoManager.h"
#endif
#ifdef MOZ_B2G_LOADER
#define XPTONLY_MANIFEST &nsComponentManagerImpl::XPTOnlyManifestManifest
#define XPTONLY_XPT &nsComponentManagerImpl::XPTOnlyManifestXPT
#else
#define XPTONLY_MANIFEST nullptr
#define XPTONLY_XPT nullptr
#endif
using namespace mozilla;
@ -64,36 +76,43 @@ struct ManifestDirective
(nsChromeRegistry::ManifestProcessingContext& cx,
int lineno, char *const *argv,
bool platform, bool contentaccessible);
#ifdef MOZ_B2G_LOADER
// The function to handle the directive for XPT Only parsing.
void (*xptonlyfunc)(nsComponentManagerImpl::XPTOnlyManifestProcessingContext& cx,
int lineno, char *const * argv);
#else
void *xptonlyfunc;
#endif
bool isContract;
};
static const ManifestDirective kParsingTable[] = {
{ "manifest", 1, false, true, true, false,
&nsComponentManagerImpl::ManifestManifest, nullptr },
&nsComponentManagerImpl::ManifestManifest, nullptr, XPTONLY_MANIFEST },
{ "binary-component", 1, true, false, false, false,
&nsComponentManagerImpl::ManifestBinaryComponent, nullptr },
&nsComponentManagerImpl::ManifestBinaryComponent, nullptr, nullptr },
{ "interfaces", 1, true, false, false, false,
&nsComponentManagerImpl::ManifestXPT, nullptr },
&nsComponentManagerImpl::ManifestXPT, nullptr, XPTONLY_XPT },
{ "component", 2, true, false, false, false,
&nsComponentManagerImpl::ManifestComponent, nullptr },
&nsComponentManagerImpl::ManifestComponent, nullptr, nullptr },
{ "contract", 2, true, false, false, false,
&nsComponentManagerImpl::ManifestContract, nullptr, true},
&nsComponentManagerImpl::ManifestContract, nullptr, nullptr, true},
{ "category", 3, true, false, false, false,
&nsComponentManagerImpl::ManifestCategory, nullptr },
&nsComponentManagerImpl::ManifestCategory, nullptr, nullptr },
{ "content", 2, true, true, true, true,
nullptr, &nsChromeRegistry::ManifestContent },
nullptr, &nsChromeRegistry::ManifestContent, nullptr },
{ "locale", 3, true, true, true, false,
nullptr, &nsChromeRegistry::ManifestLocale },
nullptr, &nsChromeRegistry::ManifestLocale, nullptr },
{ "skin", 3, false, true, true, false,
nullptr, &nsChromeRegistry::ManifestSkin },
nullptr, &nsChromeRegistry::ManifestSkin, nullptr },
{ "overlay", 2, true, true, false, false,
nullptr, &nsChromeRegistry::ManifestOverlay },
nullptr, &nsChromeRegistry::ManifestOverlay, nullptr },
{ "style", 2, false, true, false, false,
nullptr, &nsChromeRegistry::ManifestStyle },
nullptr, &nsChromeRegistry::ManifestStyle, nullptr },
{ "override", 2, true, true, true, false,
nullptr, &nsChromeRegistry::ManifestOverride },
nullptr, &nsChromeRegistry::ManifestOverride, nullptr },
{ "resource", 2, true, true, false, false,
nullptr, &nsChromeRegistry::ManifestResource }
nullptr, &nsChromeRegistry::ManifestResource, nullptr }
};
static const char kWhitespace[] = "\t ";
@ -126,8 +145,16 @@ struct AutoPR_smprintf_free
} // anonymous namespace
/**
* If we are pre-loading XPTs, this method may do nothing because the
* console service is not initialized.
*/
void LogMessage(const char* aMsg, ...)
{
if (!nsComponentManagerImpl::gComponentManager) {
return;
}
nsCOMPtr<nsIConsoleService> console =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (!console)
@ -143,6 +170,10 @@ void LogMessage(const char* aMsg, ...)
console->LogMessage(error);
}
/**
* If we are pre-loading XPTs, this method may do nothing because the
* console service is not initialized.
*/
void LogMessageWithContext(FileLocation &aFile,
uint32_t aLineNumber, const char* aMsg, ...)
{
@ -153,6 +184,10 @@ void LogMessageWithContext(FileLocation &aFile,
if (!formatted)
return;
if (!nsComponentManagerImpl::gComponentManager) {
return;
}
nsCString file;
aFile.GetURIString(file);
@ -388,11 +423,23 @@ struct CachedDirective
} // anonymous namespace
/**
* For XPT-Only mode, the parser handles only directives of "manifest"
* and "interfaces", and always call the function given by |xptonlyfunc|
* variable of struct |ManifestDirective|.
*
* This function is safe to be called before the component manager is
* ready if aXPTOnly is true for it don't invoke any component during
* parsing.
*/
void
ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOnly)
ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOnly, bool aXPTOnly)
{
nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, file, aChromeOnly);
nsChromeRegistry::ManifestProcessingContext chromecx(type, file);
#ifdef MOZ_B2G_LOADER
nsComponentManagerImpl::XPTOnlyManifestProcessingContext xptonlycx(file);
#endif
nsresult rv;
NS_NAMED_LITERAL_STRING(kPlatform, "platform");
@ -416,7 +463,12 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn
nsAutoString osTarget;
nsAutoString abi;
nsCOMPtr<nsIXULAppInfo> xapp (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
nsCOMPtr<nsIXULAppInfo> xapp;
if (!aXPTOnly) {
// Avoid to create any component for XPT only mode.
// No xapp means no ID, version, ..., modifiers checking.
xapp = do_GetService(XULAPPINFO_SERVICE_CONTRACTID);
}
if (xapp) {
nsAutoCString s;
rv = xapp->GetID(s);
@ -516,7 +568,8 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn
for (const ManifestDirective* d = kParsingTable;
d < ArrayEnd(kParsingTable);
++d) {
if (!strcmp(d->directive, token)) {
if (!strcmp(d->directive, token) &&
(!aXPTOnly || d->xptonlyfunc)) {
directive = d;
break;
}
@ -577,8 +630,9 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn
CheckStringFlag(kABI, wtoken, abi, stABI) ||
CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) ||
CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, stGeckoVersion))
CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, stGeckoVersion)) {
continue;
}
#if defined(MOZ_WIDGET_ANDROID)
bool tablet = false;
@ -619,6 +673,11 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn
stABI == eBad)
continue;
#ifdef MOZ_B2G_LOADER
if (aXPTOnly) {
directive->xptonlyfunc(xptonlycx, line, argv);
} else
#endif /* MOZ_B2G_LOADER */
if (directive->regfunc) {
if (GeckoProcessType_Default != XRE_GetProcessType())
continue;
@ -636,7 +695,7 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn
(nsChromeRegistry::gChromeRegistry->*(directive->regfunc))
(chromecx, line, argv, platform, contentAccessible);
}
else if (directive->ischrome || !aChromeOnly) {
else if (directive->mgrfunc && (directive->ischrome || !aChromeOnly)) {
if (directive->isContract) {
CachedDirective* cd = contracts.AppendElement();
cd->lineno = line;
@ -646,6 +705,9 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn
else
(nsComponentManagerImpl::gComponentManager->*(directive->mgrfunc))
(mgrcx, line, argv);
} else {
LogMessageWithContext(file, line,
"No valid manifest directive.");
}
}

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

@ -13,7 +13,7 @@
class nsIFile;
void ParseManifest(NSLocationType type, mozilla::FileLocation &file,
char* buf, bool aChromeOnly);
char* buf, bool aChromeOnly, bool aXPTOnly=false);
void LogMessage(const char* aMsg, ...);

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

@ -69,6 +69,7 @@
#include "nsStringEnumerator.h"
#include "mozilla/FileUtils.h"
#include "nsNetUtil.h"
#include "nsDataHashtable.h"
#include <new> // for placement new
@ -104,6 +105,36 @@ NS_DEFINE_CID(kCategoryManagerCID, NS_CATEGORYMANAGER_CID);
#define UID_STRING_LENGTH 39
#ifdef MOZ_B2G_LOADER
typedef nsDataHashtable<nsCStringHashKey, bool> XPTIInfosBookType;
static XPTIInfosBookType *sXPTIInfosBook = nullptr;
static XPTIInfosBookType *
GetXPTIInfosBook()
{
if (sXPTIInfosBook == nullptr) {
sXPTIInfosBook = new XPTIInfosBookType;
}
return sXPTIInfosBook;
}
static bool
IsRegisteredXPTIInfo(FileLocation &aFile)
{
nsAutoCString uri;
aFile.GetURIString(uri);
return GetXPTIInfosBook()->Get(uri);
}
static void
MarkRegisteredXPTIInfo(FileLocation &aFile)
{
nsAutoCString uri;
aFile.GetURIString(uri);
GetXPTIInfosBook()->Put(uri, true);
}
#endif /* MOZ_B2G_LOADER */
nsresult
nsGetServiceFromCategory::operator()(const nsIID& aIID, void** aInstancePtr) const
{
@ -524,11 +555,14 @@ CutExtension(nsCString& path)
path.Cut(0, dotPos + 1);
}
void
nsComponentManagerImpl::RegisterManifest(NSLocationType aType,
static void
DoRegisterManifest(NSLocationType aType,
FileLocation &aFile,
bool aChromeOnly)
bool aChromeOnly,
bool aXPTOnly)
{
MOZ_ASSERT(!aXPTOnly ||
nsComponentManagerImpl::gComponentManager == nullptr);
uint32_t len;
FileLocation::Data data;
nsAutoArrayPtr<char> buf;
@ -542,7 +576,7 @@ nsComponentManagerImpl::RegisterManifest(NSLocationType aType,
}
if (NS_SUCCEEDED(rv)) {
buf[len] = '\0';
ParseManifest(aType, aFile, buf, aChromeOnly);
ParseManifest(aType, aFile, buf, aChromeOnly, aXPTOnly);
} else if (NS_BOOTSTRAPPED_LOCATION != aType) {
nsCString uri;
aFile.GetURIString(uri);
@ -550,6 +584,14 @@ nsComponentManagerImpl::RegisterManifest(NSLocationType aType,
}
}
void
nsComponentManagerImpl::RegisterManifest(NSLocationType aType,
FileLocation &aFile,
bool aChromeOnly)
{
DoRegisterManifest(aType, aFile, aChromeOnly, false);
}
void
nsComponentManagerImpl::ManifestManifest(ManifestProcessingContext& cx, int lineno, char *const * argv)
{
@ -587,14 +629,19 @@ nsComponentManagerImpl::ManifestBinaryComponent(ManifestProcessingContext& cx, i
RegisterModule(m, &f);
}
void
nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& cx, int lineno, char *const * argv)
static void
DoRegisterXPT(FileLocation &aFile)
{
FileLocation f(cx.mFile, argv[0]);
#ifdef MOZ_B2G_LOADER
if (IsRegisteredXPTIInfo(aFile)) {
return;
}
#endif
uint32_t len;
FileLocation::Data data;
nsAutoArrayPtr<char> buf;
nsresult rv = f.GetData(data);
nsresult rv = aFile.GetData(data);
if (NS_SUCCEEDED(rv)) {
rv = data.GetSize(&len);
}
@ -604,13 +651,23 @@ nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& cx, int lineno, c
}
if (NS_SUCCEEDED(rv)) {
XPTInterfaceInfoManager::GetSingleton()->RegisterBuffer(buf, len);
#ifdef MOZ_B2G_LOADER
MarkRegisteredXPTIInfo(aFile);
#endif
} else {
nsCString uri;
f.GetURIString(uri);
aFile.GetURIString(uri);
LogMessage("Could not read '%s'.", uri.get());
}
}
void
nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& cx, int lineno, char *const * argv)
{
FileLocation f(cx.mFile, argv[0]);
DoRegisterXPT(f);
}
void
nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& cx, int lineno, char *const * argv)
{
@ -794,6 +851,10 @@ nsresult nsComponentManagerImpl::Shutdown(void)
delete sStaticModules;
delete sModuleLocations;
#ifdef MOZ_B2G_LOADER
delete sXPTIInfosBook;
sXPTIInfosBook = nullptr;
#endif
// Unload libraries
mNativeModuleLoader.UnloadLibraries();
@ -1942,6 +2003,54 @@ nsComponentManagerImpl::GetManifestLocations(nsIArray **aLocations)
return NS_OK;
}
#ifdef MOZ_B2G_LOADER
/* static */
void
nsComponentManagerImpl::XPTOnlyManifestManifest(XPTOnlyManifestProcessingContext &aCx,
int aLineno,
char * const * aArgv)
{
char* file = aArgv[0];
FileLocation f(aCx.mFile, file);
DoRegisterManifest(NS_COMPONENT_LOCATION, f, false, true);
}
/* static */
void
nsComponentManagerImpl::XPTOnlyManifestXPT(XPTOnlyManifestProcessingContext &aCx,
int aLineno,
char * const * aArgv)
{
FileLocation f(aCx.mFile, aArgv[0]);
DoRegisterXPT(f);
}
/**
* To load XPT Interface Information before the component manager is ready.
*
* With this function, B2G loader could XPT interface info. as earier
* as possible to gain benefit of shared memory model of the kernel.
*/
/* static */ void
nsComponentManagerImpl::PreloadXPT(nsIFile *aFile)
{
MOZ_ASSERT(nsComponentManagerImpl::gComponentManager == nullptr);
FileLocation location(aFile, "chrome.manifest");
DoRegisterManifest(NS_COMPONENT_LOCATION, location,
false, true /* aXPTOnly */);
}
void
PreloadXPT(nsIFile *aOmnijarFile)
{
nsComponentManagerImpl::PreloadXPT(aOmnijarFile);
}
#endif /* MOZ_B2G_LOADER */
EXPORT_XPCOM_API(nsresult)
XRE_AddManifestLocation(NSLocationType aType, nsIFile* aLocation)
{

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

@ -38,6 +38,10 @@
#include "mozilla/Omnijar.h"
#include "mozilla/Attributes.h"
#ifdef MOZ_B2G_LOADER
#include "mozilla/FileLocation.h"
#endif
struct nsFactoryEntry;
class nsIServiceManager;
struct PRThread;
@ -316,6 +320,30 @@ public:
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
#ifdef MOZ_B2G_LOADER
// Preload XPT interface info for B2G loader.
// This function is called before XPCOM has been initialized.
static void PreloadXPT(nsIFile *aFile);
#endif
#ifdef MOZ_B2G_LOADER
// Parsing functions of directives of manifest for XPT only parsing.
struct XPTOnlyManifestProcessingContext
{
XPTOnlyManifestProcessingContext(mozilla::FileLocation &aFile)
: mFile(aFile)
{ }
~XPTOnlyManifestProcessingContext() { }
mozilla::FileLocation mFile;
};
static void XPTOnlyManifestManifest(XPTOnlyManifestProcessingContext& aCx,
int aLineno, char * const *aArgv);
static void XPTOnlyManifestXPT(XPTOnlyManifestProcessingContext& aCx,
int aLineno, char * const *aArgv);
#endif
private:
~nsComponentManagerImpl();
};

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

@ -65,6 +65,7 @@ private:
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BackgroundHangManager)
static StaticRefPtr<BackgroundHangManager> sInstance;
static bool sProhibited;
// Lock for access to members of this class
Monitor mLock;
@ -162,6 +163,7 @@ public:
StaticRefPtr<BackgroundHangManager> BackgroundHangManager::sInstance;
bool BackgroundHangManager::sProhibited = false;
ThreadLocal<BackgroundHangThread*> BackgroundHangThread::sTlsKey;
@ -413,8 +415,16 @@ BackgroundHangThread*
BackgroundHangThread::FindThread()
{
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
if (BackgroundHangManager::sInstance == nullptr) {
MOZ_ASSERT(BackgroundHangManager::sProhibited,
"BackgroundHandleManager is not initialized");
return nullptr;
}
if (sTlsKey.initialized()) {
// Use TLS if available
MOZ_ASSERT(!BackgroundHangManager::sProhibited,
"BackgroundHandleManager is not initialized");
return sTlsKey.get();
}
// If TLS is unavailable, we can search through the thread list
@ -440,6 +450,7 @@ void
BackgroundHangMonitor::Startup()
{
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
MOZ_ASSERT(!BackgroundHangManager::sProhibited, "Prohibited");
MOZ_ASSERT(!BackgroundHangManager::sInstance, "Already initialized");
ThreadStackHelper::Startup();
BackgroundHangThread::Startup();
@ -451,6 +462,7 @@ void
BackgroundHangMonitor::Shutdown()
{
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
MOZ_ASSERT(!BackgroundHangManager::sProhibited, "Prohibited");
MOZ_ASSERT(BackgroundHangManager::sInstance, "Not initialized");
/* Scope our lock inside Shutdown() because the sInstance object can
be destroyed as soon as we set sInstance to nullptr below, and
@ -467,7 +479,8 @@ BackgroundHangMonitor::BackgroundHangMonitor(const char* aName,
: mThread(BackgroundHangThread::FindThread())
{
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
if (!mThread) {
if (!BackgroundHangManager::sProhibited && !mThread) {
// If sProhibit is true, mThread would be null, and no monitoring.
mThread = new BackgroundHangThread(aName, aTimeoutMs, aMaxTimeoutMs);
}
#endif
@ -477,7 +490,8 @@ BackgroundHangMonitor::BackgroundHangMonitor()
: mThread(BackgroundHangThread::FindThread())
{
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
MOZ_ASSERT(mThread, "Thread not initialized for hang monitoring");
MOZ_ASSERT(!BackgroundHangManager::sProhibited || mThread,
"This thread is not initialized for hang monitoring");
#endif
}
@ -489,6 +503,11 @@ void
BackgroundHangMonitor::NotifyActivity()
{
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
if (mThread == nullptr) {
MOZ_ASSERT(BackgroundHangManager::sProhibited,
"This thread is not initialized for hang monitoring");
return;
}
mThread->NotifyActivity();
#endif
}
@ -497,18 +516,49 @@ void
BackgroundHangMonitor::NotifyWait()
{
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
if (mThread == nullptr) {
MOZ_ASSERT(BackgroundHangManager::sProhibited,
"This thread is not initialized for hang monitoring");
return;
}
mThread->NotifyWait();
#endif
}
void
BackgroundHangMonitor::Prohibit()
{
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
MOZ_ASSERT(BackgroundHangManager::sInstance == nullptr,
"The background hang monitor is already initialized");
BackgroundHangManager::sProhibited = true;
#endif
}
void
BackgroundHangMonitor::Allow()
{
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
MOZ_ASSERT(BackgroundHangManager::sInstance == nullptr,
"The background hang monitor is already initialized");
BackgroundHangManager::sProhibited = false;
#endif
}
/* Because we are iterating through the BackgroundHangThread linked list,
we need to take a lock. Using MonitorAutoLock as a base class makes
sure all of that is taken care of for us. */
BackgroundHangMonitor::ThreadHangStatsIterator::ThreadHangStatsIterator()
: MonitorAutoLock(BackgroundHangManager::sInstance->mLock)
, mThread(BackgroundHangManager::sInstance->mHangThreads.getFirst())
, mThread(BackgroundHangManager::sInstance ?
BackgroundHangManager::sInstance->mHangThreads.getFirst() :
nullptr)
{
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
MOZ_ASSERT(BackgroundHangManager::sInstance || BackgroundHangManager::sProhibited,
"Inconsistent state");
#endif
}
Telemetry::ThreadHangStats*

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

@ -107,6 +107,8 @@ class BackgroundHangThread;
* }
* }
*
* Prohibit() and Allow() make the background hang monitor work safely
* before Startup().
*/
class BackgroundHangMonitor
{
@ -204,6 +206,27 @@ public:
* NotifyActivity when subsequently exiting the wait state.
*/
void NotifyWait();
/**
* Prohibit the hang monitor from activating.
*
* Startup() should not be called between Prohibit() and Allow().
* This function makes the background hang monitor stop monitoring
* threads.
*
* Prohibit() and Allow() can be called before XPCOM is ready. If
* we don't stop monitoring threads it could case errors.
*/
static void Prohibit();
/**
* Allow the hang monitor to run.
*
* Allow() and Prohibit() should be called in pair.
*
* \see Prohibit()
*/
static void Allow();
};
} // namespace mozilla