michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: michael@0: #include michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include "nsTArray.h" michael@0: #include "nsString.h" michael@0: #include "nsIFile.h" michael@0: #include "nsAppRunner.h" michael@0: #include "AndroidBridge.h" michael@0: #include "APKOpen.h" michael@0: #include "nsExceptionHandler.h" michael@0: michael@0: #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, MOZ_APP_NAME, args) michael@0: michael@0: // We need to put Gecko on a even more separate thread, because michael@0: // otherwise this JNI method never returns; this leads to problems michael@0: // with local references overrunning the local refs table, among michael@0: // other things, since GC can't ever run on them. michael@0: michael@0: // Note that we don't have xpcom initialized yet, so we can't use the michael@0: // thread manager for this. Instead, we use pthreads directly. michael@0: michael@0: struct AutoAttachJavaThread { michael@0: AutoAttachJavaThread() { michael@0: attached = mozilla_AndroidBridge_SetMainThread(pthread_self()); michael@0: } michael@0: ~AutoAttachJavaThread() { michael@0: mozilla_AndroidBridge_SetMainThread(-1); michael@0: attached = false; michael@0: } michael@0: michael@0: bool attached; michael@0: }; michael@0: michael@0: extern "C" NS_EXPORT void michael@0: GeckoStart(void *data, const nsXREAppData *appData) michael@0: { michael@0: #ifdef MOZ_CRASHREPORTER michael@0: const struct mapping_info *info = getLibraryMapping(); michael@0: while (info->name) { michael@0: CrashReporter::AddLibraryMapping(info->name, info->base, michael@0: info->len, info->offset); michael@0: info++; michael@0: } michael@0: #endif michael@0: michael@0: AutoAttachJavaThread attacher; michael@0: if (!attacher.attached) michael@0: return; michael@0: michael@0: if (!data) { michael@0: LOG("Failed to get arguments for GeckoStart\n"); michael@0: return; michael@0: } michael@0: michael@0: nsTArray targs; michael@0: char *arg = strtok(static_cast(data), " "); michael@0: while (arg) { michael@0: targs.AppendElement(arg); michael@0: arg = strtok(nullptr, " "); michael@0: } michael@0: targs.AppendElement(static_cast(nullptr)); michael@0: michael@0: int result = XRE_main(targs.Length() - 1, targs.Elements(), appData, 0); michael@0: michael@0: if (result) michael@0: LOG("XRE_main returned %d", result); michael@0: michael@0: mozilla::widget::android::GeckoAppShell::NotifyXreExit(); michael@0: michael@0: free(targs[0]); michael@0: nsMemory::Free(data); michael@0: return; michael@0: }