mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge b2g-inbound to m-c. a=merge
This commit is contained in:
commit
95a1497ee2
248
b2g/app/B2GLoader.cpp
Normal file
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,32 +49,34 @@ 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) {
|
||||
cacheEntry.setMetaDataElement('request-method', 'GET');
|
||||
cacheEntry.setMetaDataElement('response-head', 'HTTP/1.1 200 OK\r\n');
|
||||
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');
|
||||
|
||||
let outputStream = cacheEntry.openOutputStream(0);
|
||||
let outputStream = cacheEntry.openOutputStream(0);
|
||||
|
||||
// Input-Output stream machinery in order to push nsIFile content into cache
|
||||
let inputStream = Cc['@mozilla.org/network/file-input-stream;1']
|
||||
.createInstance(Ci.nsIFileInputStream);
|
||||
inputStream.init(file, 1, -1, null);
|
||||
let bufferedOutputStream = Cc['@mozilla.org/network/buffered-output-stream;1']
|
||||
.createInstance(Ci.nsIBufferedOutputStream);
|
||||
bufferedOutputStream.init(outputStream, 1024);
|
||||
bufferedOutputStream.writeFrom(inputStream, inputStream.available());
|
||||
bufferedOutputStream.flush();
|
||||
bufferedOutputStream.close();
|
||||
inputStream.close();
|
||||
// Input-Output stream machinery in order to push nsIFile content into cache
|
||||
let inputStream = Cc['@mozilla.org/network/file-input-stream;1']
|
||||
.createInstance(Ci.nsIFileInputStream);
|
||||
inputStream.init(file, 1, -1, null);
|
||||
let bufferedOutputStream = Cc['@mozilla.org/network/buffered-output-stream;1']
|
||||
.createInstance(Ci.nsIBufferedOutputStream);
|
||||
bufferedOutputStream.init(outputStream, 1024);
|
||||
bufferedOutputStream.writeFrom(inputStream, inputStream.available());
|
||||
bufferedOutputStream.flush();
|
||||
bufferedOutputStream.close();
|
||||
inputStream.close();
|
||||
|
||||
cacheEntry.markValid();
|
||||
debug (file.path + ' -> ' + url + ' (' + itemType + ')');
|
||||
applicationCache.markEntry(url, itemType);
|
||||
cacheEntry.close();
|
||||
}
|
||||
cacheEntry.markValid();
|
||||
debug (file.path + ' -> ' + url + ' (' + itemType + ')');
|
||||
applicationCache.markEntry(url, itemType);
|
||||
cacheEntry.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
var tests = [
|
||||
{
|
||||
name: "init-failure",
|
||||
key: "init-failure",
|
||||
func: function testInitFailure(test) {
|
||||
function onSuccess(camera, config) {
|
||||
ok(false, "onSuccess called incorrectly");
|
||||
camera.release();
|
||||
test.next();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "onError called correctly on init failure");
|
||||
test.next();
|
||||
}
|
||||
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) {
|
||||
test.set("init-failure", function(type) {
|
||||
function onSuccess(camera, config) {
|
||||
ok(false, "onSuccess called incorrectly");
|
||||
camera.release();
|
||||
test.done(end);
|
||||
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;
|
||||
}
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "onError called correctly on init failure");
|
||||
test.done(end);
|
||||
}
|
||||
info("Running test: " + type);
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
|
||||
});
|
||||
};
|
||||
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
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',
|
||||
]
|
151
ipc/contentproc/plugin-container.cpp
Normal file
151
ipc/contentproc/plugin-container.cpp
Normal file
@ -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
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
vendored
1
media/mtransport/third_party/moz.build
vendored
@ -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;
|
||||
|
24
widget/gonk/PowerWakeLock.cpp
Normal file
24
widget/gonk/PowerWakeLock.cpp
Normal file
@ -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
|
25
widget/gonk/PowerWakeLock.h
Normal file
25
widget/gonk/PowerWakeLock.h
Normal file
@ -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,9 +568,10 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn
|
||||
for (const ManifestDirective* d = kParsingTable;
|
||||
d < ArrayEnd(kParsingTable);
|
||||
++d) {
|
||||
if (!strcmp(d->directive, token)) {
|
||||
directive = d;
|
||||
break;
|
||||
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,
|
||||
FileLocation &aFile,
|
||||
bool aChromeOnly)
|
||||
static void
|
||||
DoRegisterManifest(NSLocationType aType,
|
||||
FileLocation &aFile,
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user