]> git.tdb.fi Git - libs/core.git/blob - source/core/android/mainthread.cpp
Provide access to the Java VM on Android
[libs/core.git] / source / core / android / mainthread.cpp
1 #include <cstring>
2 #include <cstdlib>
3 #include <android/window.h>
4 #include <msp/fs/dir.h>
5 #include <msp/fs/path.h>
6 #include <msp/fs/utils.h>
7 #include "application.h"
8 #include "errorlogger.h"
9 #include "mainthread.h"
10
11 using namespace std;
12
13 namespace Msp {
14 namespace Android {
15
16 MainThread::MainThread(ANativeActivity *a):
17         asset_manager(a->assetManager),
18         int_data_path(a->internalDataPath),
19         starting_up(true)
20 {
21         attach_to_activity(a);
22         startup_mutex.lock();
23         launch();
24 }
25
26 void MainThread::attach_to_activity(ANativeActivity *a)
27 {
28         activity = a;
29         activity->callbacks->onDestroy = &activity_destroyed;
30         activity->callbacks->onNativeWindowCreated = &native_window_created;
31         activity->callbacks->onNativeWindowResized = &native_window_resized;
32         activity->callbacks->onNativeWindowDestroyed = &native_window_destroyed;
33         activity->callbacks->onInputQueueCreated = &input_queue_created;
34         activity->callbacks->onInputQueueDestroyed = &input_queue_destroyed;
35         activity->instance = this;
36
37         set_window_flags(AWINDOW_FLAG_FULLSCREEN, 0);
38 }
39
40 void MainThread::wait_for_app_created()
41 {
42         MutexLock lock(startup_mutex);
43 }
44
45 void MainThread::resume_startup()
46 {
47         if(starting_up)
48         {
49                 starting_up = false;
50                 startup_mutex.unlock();
51         }
52 }
53
54 JavaVM *MainThread::get_java_vm() const
55 {
56         if(!activity)
57                 return 0;
58
59         return activity->vm;
60 }
61
62 void MainThread::set_window_flags(unsigned set, unsigned clear)
63 {
64         ANativeActivity_setWindowFlags(activity, set, clear);
65 }
66
67 void MainThread::main()
68 {
69         /* I have no idea how dependable this is, but it seems to be the only way
70         to get the package name aside from making a Java call through JNI */
71         char *appname = strdup(int_data_path[-2].c_str());
72         char *argv[] = { appname, 0 };
73         Msp::Android::ErrorLogger err_logger;
74         FS::chdir(FS::dirname(int_data_path));
75         Msp::Application::run(1, argv, this, &app_created);
76         free(appname);
77         if(activity)
78         {
79                 activity->callbacks->onDestroy = &end_process;
80                 ANativeActivity_finish(activity);
81         }
82         else
83                 end_process(0);
84 }
85
86 void MainThread::app_created(void *data)
87 {
88         reinterpret_cast<MainThread *>(data)->resume_startup();
89 }
90
91 void MainThread::activity_destroyed(ANativeActivity *activity)
92 {
93         reinterpret_cast<MainThread *>(activity->instance)->activity = 0;
94 }
95
96 void MainThread::native_window_created(ANativeActivity *activity, ANativeWindow *window)
97 {
98         reinterpret_cast<MainThread *>(activity->instance)->signal_native_window_created.emit(window);
99 }
100
101 void MainThread::native_window_resized(ANativeActivity *activity, ANativeWindow *window)
102 {
103         reinterpret_cast<MainThread *>(activity->instance)->signal_native_window_resized.emit(window);
104 }
105
106 void MainThread::native_window_destroyed(ANativeActivity *activity, ANativeWindow *window)
107 {
108         reinterpret_cast<MainThread *>(activity->instance)->signal_native_window_destroyed.emit(window);
109 }
110
111 void MainThread::input_queue_created(ANativeActivity *activity, AInputQueue *queue)
112 {
113         reinterpret_cast<MainThread *>(activity->instance)->signal_input_queue_created.emit(queue);
114 }
115
116 void MainThread::input_queue_destroyed(ANativeActivity *activity, AInputQueue *queue)
117 {
118         reinterpret_cast<MainThread *>(activity->instance)->signal_input_queue_destroyed.emit(queue);
119 }
120
121 void MainThread::end_process(ANativeActivity *)
122 {
123         exit(0);
124 }
125
126 } // namespace Android
127 } // namespace Msp