Bug 561464 - Add support for XPCOM on Android, patch mostly by vlad, r=bsmedberg
authorMichael Wu <mwu@mozilla.com>
Tue, 01 Jun 2010 12:02:42 -0700
changeset 42994 193499688f7e44b412eb710e1288ede73ad48b9b
parent 42993 9d40cce434865515df81912ce22d2fdfa6e80a61
child 42995 fc0f91d19dbf9ef5131d4358c503c1f0c4f3c50c
push idunknown
push userunknown
push dateunknown
reviewersbsmedberg
bugs561464
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 561464 - Add support for XPCOM on Android, patch mostly by vlad, r=bsmedberg
xpcom/base/nsDebugImpl.cpp
xpcom/base/nsUUIDGenerator.cpp
xpcom/base/nsUUIDGenerator.h
xpcom/build/nsXPComInit.cpp
xpcom/glue/nsCRTGlue.cpp
xpcom/io/SpecialSystemDirectory.cpp
xpcom/io/nsLocalFileUnix.cpp
xpcom/io/nsNativeCharsetUtils.cpp
xpcom/io/nsNativeCharsetUtils.h
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp
xpcom/typelib/xpidl/Makefile.in
--- a/xpcom/base/nsDebugImpl.cpp
+++ b/xpcom/base/nsDebugImpl.cpp
@@ -45,16 +45,20 @@
 #include "prinit.h"
 #include "plstr.h"
 #include "nsError.h"
 #include "prerror.h"
 #include "prerr.h"
 #include "prenv.h"
 #include "pratom.h"
 
+#ifdef ANDROID
+#include <android/log.h>
+#endif
+
 #if defined(XP_BEOS)
 /* For DEBUGGER macros */
 #include <Debug.h>
 #endif
 
 #if defined(XP_UNIX) || defined(_WIN32) || defined(XP_OS2) || defined(XP_BEOS)
 /* for abort() and getenv() */
 #include <stdlib.h>
@@ -304,16 +308,20 @@ NS_DebugBreak(PRUint32 aSeverity, const 
    PR_LogFlush();
 
    // errors on platforms without a debugdlg ring a bell on stderr
 #if !defined(XP_WIN) && !defined(XP_OS2)
    if (ll != PR_LOG_WARNING)
      fprintf(stderr, "\07");
 #endif
 
+#ifdef ANDROID
+   __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", buf.buffer);
+#endif
+
    // Write the message to stderr
    fprintf(stderr, "%s\n", buf.buffer);
    fflush(stderr);
 
    switch (aSeverity) {
    case NS_DEBUG_WARNING:
      return;
 
--- a/xpcom/base/nsUUIDGenerator.cpp
+++ b/xpcom/base/nsUUIDGenerator.cpp
@@ -71,17 +71,17 @@ nsUUIDGenerator::Init()
 {
     mLock = PR_NewLock();
 
     NS_ENSURE_TRUE(mLock, NS_ERROR_OUT_OF_MEMORY);
 
     // We're a service, so we're guaranteed that Init() is not going
     // to be reentered while we're inside Init().
     
-#if !defined(XP_WIN) && !defined(XP_MACOSX)
+#if !defined(XP_WIN) && !defined(XP_MACOSX) && !defined(ANDROID)
     /* initialize random number generator using NSPR random noise */
     unsigned int seed;
 
     PRSize bytes = 0;
     while (bytes < sizeof(seed)) {
         PRSize nbytes = PR_GetRandomNoise(((unsigned char *)&seed)+bytes,
                                           sizeof(seed)-bytes);
         if (nbytes == 0) {
@@ -166,21 +166,29 @@ nsUUIDGenerator::GenerateUUIDInPlace(nsI
     memcpy(id, &bytes, sizeof(nsID));
 
     CFRelease(uuid);
 #else /* not windows or OS X; generate randomness using random(). */
     /* XXX we should be saving the return of setstate here and switching
      * back to it; instead, we use the value returned when we called
      * initstate, since older glibc's have broken setstate() return values
      */
+#ifndef ANDROID
     setstate(mState);
+#endif
 
     PRSize bytesLeft = sizeof(nsID);
     while (bytesLeft > 0) {
+#ifdef ANDROID
+        long rval = arc4random();
+        const int mRBytes = 4;
+#else
         long rval = random();
+#endif
+
 
         PRUint8 *src = (PRUint8*)&rval;
         // We want to grab the mRBytes least significant bytes of rval, since
         // mRBytes less than sizeof(rval) means the high bytes are 0.
 #ifdef IS_BIG_ENDIAN
         src += sizeof(rval) - mRBytes;
 #endif
         PRUint8 *dst = ((PRUint8*) id) + (sizeof(nsID) - bytesLeft);
@@ -194,14 +202,16 @@ nsUUIDGenerator::GenerateUUIDInPlace(nsI
     /* Put in the version */
     id->m2 &= 0x0fff;
     id->m2 |= 0x4000;
 
     /* Put in the variant */
     id->m3[0] &= 0x3f;
     id->m3[0] |= 0x80;
 
+#ifndef ANDROID
     /* Restore the previous RNG state */
     setstate(mSavedState);
 #endif
+#endif
 
     return NS_OK;
 }
--- a/xpcom/base/nsUUIDGenerator.h
+++ b/xpcom/base/nsUUIDGenerator.h
@@ -54,17 +54,17 @@ public:
 
 private:
     ~nsUUIDGenerator();
 
 protected:
 
     PRLock* mLock;
 #if defined(WINCE)
-#elif !defined(XP_WIN) && !defined(XP_MACOSX)
+#elif !defined(XP_WIN) && !defined(XP_MACOSX) && !defined(ANDROID)
     char mState[128];
     char *mSavedState;
     PRUint8 mRBytes;
 #endif
 };
 
 #define NS_UUID_GENERATOR_CONTRACTID "@mozilla.org/uuid-generator;1"
 #define NS_UUID_GENERATOR_CLASSNAME "UUID Generator"
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -531,17 +531,17 @@ NS_InitXPCOM3(nsIServiceManager* *result
     if (NS_FAILED(rv)) return rv;
 
     NS_TIME_FUNCTION_MARK("Next: timer startup");
 
     // Set up the timer globals/timer thread
     rv = nsTimerImpl::Startup();
     NS_ENSURE_SUCCESS(rv, rv);
 
-#ifndef WINCE
+#if !defined(WINCE) && !defined(ANDROID)
     NS_TIME_FUNCTION_MARK("Next: setlocale");
 
     // If the locale hasn't already been setup by our embedder,
     // get us out of the "C" locale and into the system 
     if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
         setlocale(LC_ALL, "");
 #endif
 
--- a/xpcom/glue/nsCRTGlue.cpp
+++ b/xpcom/glue/nsCRTGlue.cpp
@@ -44,16 +44,20 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdarg.h>
 
 #ifdef XP_WIN
 #include <io.h>
 #endif
 
+#ifdef ANDROID
+#include <android/log.h>
+#endif
+
 const char*
 NS_strspnp(const char *delims, const char *str)
 {
   const char *d;
   do {
     for (d = delims; *d != '\0'; ++d) {
       if (*str == *d) {
         ++str;
@@ -274,16 +278,25 @@ printf_stderr(const char *fmt, ...)
 
   va_list args;
   va_start(args, fmt);
   vfprintf(fp, fmt, args);
   va_end(args);
 
   fclose(fp);
 }
+#elif defined(ANDROID)
+void
+printf_stderr(const char *fmt, ...)
+{
+  va_list args;
+  va_start(args, fmt);
+  __android_log_vprint(ANDROID_LOG_INFO, "Gecko", fmt, args);
+  va_end(args);
+}
 #else
 void
 printf_stderr(const char *fmt, ...)
 {
   va_list args;
   va_start(args, fmt);
   vfprintf(stderr, fmt, args);
   va_end(args);
--- a/xpcom/io/SpecialSystemDirectory.cpp
+++ b/xpcom/io/SpecialSystemDirectory.cpp
@@ -286,16 +286,19 @@ GetUnixHomeDir(nsILocalFile** aFile)
         return NS_NewNativeLocalFile(nsDependentCString(pHome),
                                      PR_TRUE,
                                      aFile);
     } else {
         return NS_NewNativeLocalFile(nsDependentCString(decc$translate_vms(pHome)),
                                      PR_TRUE,
                                      aFile);
     }
+#elif defined(ANDROID)
+    // XXX no home dir on android; maybe we should return the sdcard if present?
+    return NS_ERROR_FAILURE;
 #else
     return NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")),
                                  PR_TRUE, aFile);
 #endif
 }
 
 /*
   The following license applies to the xdg_user_dir_lookup function:
--- a/xpcom/io/nsLocalFileUnix.cpp
+++ b/xpcom/io/nsLocalFileUnix.cpp
@@ -1100,17 +1100,28 @@ nsLocalFile::GetFileSize(PRInt64 *aFileS
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsLocalFile::SetFileSize(PRInt64 aFileSize)
 {
     CHECK_mPath();
 
-#ifdef HAVE_TRUNCATE64
+#if defined(ANDROID)
+    /* no truncate on bionic */
+    int fd = open(mPath.get(), O_WRONLY);
+    if (fd == -1)
+        return NSRESULT_FOR_ERRNO();
+
+    int ret = ftruncate(fd, (off_t)aFileSize);
+    close(fd);
+
+    if (ret == -1)
+        return NSRESULT_FOR_ERRNO();
+#elif defined(HAVE_TRUNCATE64)
     if (truncate64(mPath.get(), (off64_t)aFileSize) == -1)
         return NSRESULT_FOR_ERRNO();
 #else
     off_t size = (off_t)aFileSize;
     if (truncate(mPath.get(), size) == -1)
         return NSRESULT_FOR_ERRNO();
 #endif
     return NS_OK;
--- a/xpcom/io/nsNativeCharsetUtils.cpp
+++ b/xpcom/io/nsNativeCharsetUtils.cpp
@@ -38,19 +38,19 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "xpcom-private.h"
 
 //-----------------------------------------------------------------------------
-// XP_MACOSX or XP_BEOS
+// XP_MACOSX or XP_BEOS or ANDROID
 //-----------------------------------------------------------------------------
-#if defined(XP_BEOS) || defined(XP_MACOSX)
+#if defined(XP_BEOS) || defined(XP_MACOSX) || defined(ANDROID)
 
 #include "nsAString.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
 
 NS_COM nsresult
 NS_CopyNativeToUnicode(const nsACString &input, nsAString  &output)
 {
--- a/xpcom/io/nsNativeCharsetUtils.h
+++ b/xpcom/io/nsNativeCharsetUtils.h
@@ -65,22 +65,22 @@ NS_COM nsresult NS_CopyUnicodeToNative(c
  * name in UTF-8 out of nsILocalFile, we can just use |GetNativeLeafName| rather
  * than using |GetLeafName| and converting the result to UTF-8 if the file 
  * system  encoding is UTF-8.
  * On Unix (but not on Mac OS X), it depends on the locale and is not known
  * in advance (at the compilation time) so that this function needs to be 
  * a real function. On Mac OS X and BeOS, it's always UTF-8 while on Windows 
  * and other platforms (e.g. OS2), it's never UTF-8.  
  */
-#if defined(XP_UNIX) && !defined(XP_MACOSX)
+#if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(ANDROID)
 NS_COM PRBool NS_IsNativeUTF8();
 #else
 inline PRBool NS_IsNativeUTF8()
 {
-#if defined(XP_MACOSX) || defined(XP_BEOS)
+#if defined(XP_MACOSX) || defined(XP_BEOS) || defined(ANDROID)
     return PR_TRUE;
 #else
     return PR_FALSE;
 #endif
 }
 #endif
 
 
--- a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp
+++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp
@@ -35,17 +35,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* Platform specific code to invoke XPCOM methods on native objects */
 
 #include "xptcprivate.h"
 
-#if !defined(LINUX) || !defined(__arm__)
+#if !defined(__arm__) && !(defined(LINUX) || defined(ANDROID))
 #error "This code is for Linux ARM only. Check that it works on your system, too.\nBeware that this code is highly compiler dependent."
 #endif
 
 /* This function copies a 64-bits word from dw to the given pointer in
  * a buffer delimited by start and end, possibly wrapping around the
  * buffer boundaries, and/or properly aligning the data at 64-bits word
  * boundaries (for EABI).
  * start and end are both assumed to be 64-bits aligned.
--- a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp
+++ b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp
@@ -36,17 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* Implement shared vtbl methods. */
 
 #include "xptcprivate.h"
 #include "xptiprivate.h"
 
-#if !defined(LINUX) || !defined(__arm__)
+#if !defined(__arm__) && !(defined(LINUX) || defined(ANDROID))
 #error "This code is for Linux ARM only. Please check if it works for you, too.\nDepends strongly on gcc behaviour."
 #endif
 
 #if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
 /* This tells gcc3.4+ not to optimize away symbols.
  * @see http://gcc.gnu.org/gcc-3.4/changes.html
  */
 #define DONT_DROP_OR_WARN __attribute__((used))
--- a/xpcom/typelib/xpidl/Makefile.in
+++ b/xpcom/typelib/xpidl/Makefile.in
@@ -39,18 +39,20 @@ DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= xpcom
 
-ifneq (,$(filter-out WINCE SYMBIAN,$(OS_ARCH)))
-# Sadly, the code here is too smart for the WinCE/Symbian compiler's brain
+# there's no reason to build a target xpidl, why do we do this at all?
+##ifneq (,$(filter-out WINCE SYMBIAN,$(OS_ARCH)))
+### Sadly, the code here is too smart for the WinCE/Symbian compiler's brain
+ifndef CROSS_COMPILE
 PROGRAM		= xpidl$(BIN_SUFFIX)
 SDK_BINARY  = $(PROGRAM)
 endif
 
 INTERNAL_TOOLS	= 1
 
 # glib and libIDL link against the non-debug msvcrt
 MOZ_NO_DEBUG_RTL=1