Minimalistic port for Android
authorMikko Rasa <tdb@tdb.fi>
Sat, 11 Oct 2014 10:32:23 +0000 (13:32 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 11 Oct 2014 10:32:23 +0000 (13:32 +0300)
Application startup through NativeActivity is provided and uncaught
exceptions are logged.  A number of things are still in need of proper
implementations.

Build
source/core/android/errorlogger.cpp [new file with mode: 0644]
source/core/android/errorlogger.h [new file with mode: 0644]
source/core/android/main.cpp [new file with mode: 0644]
source/core/android/mainthread.cpp [new file with mode: 0644]
source/core/android/mainthread.h [new file with mode: 0644]
source/fs/android/stat_owner.cpp [new file with mode: 0644]
source/fs/unix/stat.cpp
source/fs/unix/stat_owner.cpp [new file with mode: 0644]

diff --git a/Build b/Build
index aea04a16e0a12b39f8e30d3b945cfffa058d14c6..fb10fd448ee77676890b733a5553d3c61e5763e3 100644 (file)
--- a/Build
+++ b/Build
@@ -15,6 +15,14 @@ package "mspcore"
                        library "dl";
                };
        };
+       if_arch "android"
+       {
+               build_info
+               {
+                       library "android";
+                       library "log";
+               };
+       };
 
        feature "zlib" "Support compression with zlib"
        {
@@ -42,6 +50,14 @@ package "mspcore"
                {
                        overlay "osx";
                };
+               if_arch "android"
+               {
+                       overlay "android";
+                       build_info
+                       {
+                               keep_symbol "ANativeActivity_onCreate";
+                       };
+               };
                if_arch "!windows"
                {
                        overlay "unix";
diff --git a/source/core/android/errorlogger.cpp b/source/core/android/errorlogger.cpp
new file mode 100644 (file)
index 0000000..5fadc1a
--- /dev/null
@@ -0,0 +1,20 @@
+#include <typeinfo>
+#include <android/log.h>
+#include <msp/debug/demangle.h>
+#include "errorlogger.h"
+
+using namespace std;
+
+namespace Msp {
+namespace Android {
+
+bool ErrorLogger::report_uncaught_exception(const exception &e) const
+{
+       __android_log_write(ANDROID_LOG_ERROR, "Msp", "An uncaught exception occurred.");
+       __android_log_print(ANDROID_LOG_ERROR, "Msp", "  type:   %s", Debug::demangle(typeid(e).name()).c_str());
+       __android_log_print(ANDROID_LOG_ERROR, "Msp", "  what(): %s", e.what());
+       return true;
+}
+
+} // namespace Android
+} // namespace Msp
diff --git a/source/core/android/errorlogger.h b/source/core/android/errorlogger.h
new file mode 100644 (file)
index 0000000..4512f09
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef MSP_CORE_ERRORLOGGER_ANDROID_H_
+#define MSP_CORE_ERRORLOGGER_ANDROID_H_
+
+#include <msp/debug/errorreporter.h>
+
+namespace Msp {
+namespace Android {
+
+class ErrorLogger: public Debug::ErrorReporter
+{
+public:
+       virtual bool report_uncaught_exception(const std::exception &) const;
+};
+
+} // namespace Android
+} // namespace Msp
+
+#endif
diff --git a/source/core/android/main.cpp b/source/core/android/main.cpp
new file mode 100644 (file)
index 0000000..86ed5be
--- /dev/null
@@ -0,0 +1,6 @@
+#include "mainthread.h"
+
+extern "C" void ANativeActivity_onCreate(ANativeActivity *activity, void * /*saved_state*/, size_t /*state_size*/)
+{
+       new Msp::Android::MainThread(activity);
+}
diff --git a/source/core/android/mainthread.cpp b/source/core/android/mainthread.cpp
new file mode 100644 (file)
index 0000000..51fcafc
--- /dev/null
@@ -0,0 +1,31 @@
+#include <cstring>
+#include <msp/fs/path.h>
+#include "application.h"
+#include "errorlogger.h"
+#include "mainthread.h"
+
+using namespace std;
+
+namespace Msp {
+namespace Android {
+
+MainThread::MainThread(ANativeActivity *a):
+       activity(a)
+{
+       launch();
+}
+
+void MainThread::main()
+{
+       /* I have no idea how dependable this is, but it seems to be the only way
+       to get the package name aside from making a Java call through JNI */
+       char *appname = strdup(FS::Path(activity->internalDataPath)[-2].c_str());
+       char *argv[] = { appname, 0 };
+       Msp::Android::ErrorLogger err_logger;
+       Msp::Application::run(1, argv, activity);
+       free(appname);
+       ANativeActivity_finish(activity);
+}
+
+} // namespace Android
+} // namespace Msp
diff --git a/source/core/android/mainthread.h b/source/core/android/mainthread.h
new file mode 100644 (file)
index 0000000..9d139bc
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef MSP_CORE_ANDROID_MAINTHREAD_H_
+#define MSP_CORE_ANDROID_MAINTHREAD_H_
+
+#include <android/native_activity.h>
+#include "thread.h"
+
+namespace Msp {
+namespace Android {
+
+class MainThread: public Thread
+{
+private:
+       ANativeActivity *activity;
+
+public:
+       MainThread(ANativeActivity *);
+
+private:
+       virtual void main();
+};
+
+} // namespace Android
+} // namespace Msp
+
+#endif
diff --git a/source/fs/android/stat_owner.cpp b/source/fs/android/stat_owner.cpp
new file mode 100644 (file)
index 0000000..45fba30
--- /dev/null
@@ -0,0 +1,26 @@
+#include <grp.h>
+#include <pwd.h>
+#include <msp/strings/format.h>
+#include "stat.h"
+#include "stat_private.h"
+
+namespace Msp {
+namespace FS {
+
+void Stat::Private::fill_owner_info(Stat::OwnerInfo &result)
+{
+       struct passwd *owner;
+       if((owner = getpwuid(owner_id)))
+               result.owner = owner->pw_name;
+       else
+               result.owner = format("%d", owner_id);
+
+       struct group *group;
+       if((group = getgrgid(group_id)))
+               result.group = group->gr_name;
+       else
+               result.group = format("%d", group_id);
+}
+
+} // namespace FS
+} // namespace Msp
index 1404fede5c030b462fa410c38adb9de0dd0cb568..1ba62cd1c3f8a752032c6f1a1baca95ce9a28051 100644 (file)
@@ -2,10 +2,7 @@
 #include <cerrno>
 #include <unistd.h>
 #include <sys/stat.h>
-#include <grp.h>
-#include <pwd.h>
 #include <msp/core/systemerror.h>
-#include <msp/strings/format.h>
 #include "stat.h"
 #include "stat_private.h"
 
@@ -43,25 +40,6 @@ Stat Stat::Private::from_struct_stat(const struct stat &st)
        return result;
 }
 
-void Stat::Private::fill_owner_info(Stat::OwnerInfo &result)
-{
-       char buf[1024];
-
-       struct passwd pw;
-       struct passwd *owner;
-       if(!getpwuid_r(owner_id, &pw, buf, sizeof(buf), &owner) && owner)
-               result.owner = owner->pw_name;
-       else
-               result.owner = format("%d", owner_id);
-
-       struct group gr;
-       struct group *group;
-       if(!getgrgid_r(group_id, &gr, buf, sizeof(buf), &group) && group)
-               result.group = group->gr_name;
-       else
-               result.group = format("%d", group_id);
-}
-
 
 Stat Stat::stat(const Path &path)
 {
diff --git a/source/fs/unix/stat_owner.cpp b/source/fs/unix/stat_owner.cpp
new file mode 100644 (file)
index 0000000..1a33d74
--- /dev/null
@@ -0,0 +1,30 @@
+#include <grp.h>
+#include <pwd.h>
+#include <msp/strings/format.h>
+#include "stat.h"
+#include "stat_private.h"
+
+namespace Msp {
+namespace FS {
+
+void Stat::Private::fill_owner_info(Stat::OwnerInfo &result)
+{
+       char buf[1024];
+
+       struct passwd pw;
+       struct passwd *owner;
+       if(!getpwuid_r(owner_id, &pw, buf, sizeof(buf), &owner) && owner)
+               result.owner = owner->pw_name;
+       else
+               result.owner = format("%d", owner_id);
+
+       struct group gr;
+       struct group *group;
+       if(!getgrgid_r(group_id, &gr, buf, sizeof(buf), &group) && group)
+               result.group = group->gr_name;
+       else
+               result.group = format("%d", group_id);
+}
+
+} // namespace FS
+} // namespace Msp