1
1
/*
2
- * Copyright (C) 2019 HERE Europe B.V.
2
+ * Copyright (C) 2019-2023 HERE Europe B.V.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
33
33
#include < jni.h>
34
34
#endif
35
35
36
+ #include " ContextInternal.h"
37
+
36
38
namespace {
37
39
std::atomic_flag gDeInitializing = ATOMIC_FLAG_INIT;
38
40
}
39
41
40
42
namespace olp {
41
43
namespace context {
42
- // Because of static initializer orders, we need to have this on the heap.
43
- struct ContextData {
44
- std::vector<olp::context::Context::InitializedCallback> initVector;
45
- std::vector<olp::context::Context::DeinitializedCallback> deinitVector;
46
-
47
- std::mutex contextMutex;
48
- size_t contextInstanceCounter = 0 ;
49
- #ifdef ANDROID
50
- JavaVM* javaVM = nullptr ;
51
- jobject context = nullptr ;
52
- #endif
53
- };
54
-
55
- #define LOGTAG " Context"
56
-
57
- std::shared_ptr<ContextData> instance () {
58
- // Static initialization is thread safe.
59
- // Shared pointer allows to extend the life of ContextData
60
- // until all Scope objects are destroyed.
61
- static std::shared_ptr<ContextData> gSetupVectors =
62
- std::make_shared<ContextData>();
63
- return gSetupVectors ;
64
- }
65
44
66
45
void initialize () {
67
- const auto data = instance ();
46
+ const auto data = Instance ();
68
47
69
48
// Fire all initializations.
70
- for (const olp::context::Context::InitializedCallback& cb : data->initVector )
49
+ for (const olp::context::Context::InitializedCallback& cb : data->init_vector )
71
50
cb ();
72
51
}
73
52
74
53
void deinitialize () {
75
54
if (!atomic_flag_test_and_set (&gDeInitializing )) {
76
- const auto data = instance ();
55
+ const auto data = Instance ();
77
56
78
57
// Fire all deinitializeds.
79
58
for (const olp::context::Context::DeinitializedCallback& cb :
80
- data->deinitVector )
59
+ data->deinit_vector )
81
60
cb ();
82
61
83
62
atomic_flag_clear (&gDeInitializing );
@@ -86,16 +65,16 @@ void deinitialize() {
86
65
87
66
void Context::addInitializeCallbacks (InitializedCallback initCallback,
88
67
DeinitializedCallback deinitCalback) {
89
- auto cd = instance ();
68
+ auto cd = Instance ();
90
69
91
- cd->initVector .emplace_back (std::move (initCallback));
92
- cd->deinitVector .emplace_back (std::move (deinitCalback));
70
+ cd->init_vector .emplace_back (std::move (initCallback));
71
+ cd->deinit_vector .emplace_back (std::move (deinitCalback));
93
72
}
94
73
95
74
void Context::init () {
96
- auto cd = instance ();
75
+ auto cd = Instance ();
97
76
#ifdef ANDROID
98
- cd->javaVM = nullptr ;
77
+ cd->java_vm = nullptr ;
99
78
#else
100
79
(void )cd;
101
80
#endif
@@ -104,16 +83,16 @@ void Context::init() {
104
83
105
84
void Context::deinit () {
106
85
#ifdef ANDROID
107
- auto cd = instance ();
86
+ auto cd = Instance ();
108
87
// Release the global reference of Context.
109
88
// Technically not needed if we took the application context,
110
89
// but good to release just in case.
111
- if (cd->javaVM ) {
90
+ if (cd->java_vm ) {
112
91
JNIEnv* env = nullptr ;
113
92
bool attached = false ;
114
- if (cd->javaVM ->GetEnv (reinterpret_cast <void **>(&env), JNI_VERSION_1_6) !=
93
+ if (cd->java_vm ->GetEnv (reinterpret_cast <void **>(&env), JNI_VERSION_1_6) !=
115
94
JNI_OK) {
116
- if (cd->javaVM ->AttachCurrentThread (&env, nullptr ) != JNI_OK) {
95
+ if (cd->java_vm ->AttachCurrentThread (&env, nullptr ) != JNI_OK) {
117
96
env = nullptr ;
118
97
} else {
119
98
attached = true ;
@@ -122,20 +101,20 @@ void Context::deinit() {
122
101
if (env) {
123
102
env->DeleteGlobalRef (cd->context );
124
103
if (attached) {
125
- cd->javaVM ->DetachCurrentThread ();
104
+ cd->java_vm ->DetachCurrentThread ();
126
105
}
127
106
}
128
107
}
129
108
130
- cd->javaVM = nullptr ;
109
+ cd->java_vm = nullptr ;
131
110
#endif
132
111
deinitialize ();
133
112
}
134
113
135
114
#if defined(ANDROID)
136
115
void Context::init (JavaVM* vm, jobject context) {
137
- auto cd = instance ();
138
- cd->javaVM = vm;
116
+ auto cd = Instance ();
117
+ cd->java_vm = vm;
139
118
140
119
JNIEnv* env = nullptr ;
141
120
if (vm->GetEnv (reinterpret_cast <void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
@@ -148,46 +127,84 @@ void Context::init(JavaVM* vm, jobject context) {
148
127
}
149
128
150
129
JavaVM* Context::getJavaVM () {
151
- auto cd = instance ();
152
- if (!cd->javaVM ) {
130
+ auto cd = Instance ();
131
+ if (!cd->java_vm ) {
153
132
assert (false );
154
133
}
155
134
156
- return cd->javaVM ;
135
+ return cd->java_vm ;
157
136
}
158
137
159
138
jobject Context::getAndroidContext () {
160
- auto cd = instance ();
139
+ auto cd = Instance ();
161
140
if (!cd->context ) {
162
141
assert (false );
163
142
}
164
143
return cd->context ;
165
144
}
166
- #endif
145
+ #elif defined(__APPLE__)
146
+ void Context::EnterBackground () {
147
+ auto cd = Instance ();
148
+ std::lock_guard<std::mutex> lock (cd->context_mutex );
149
+
150
+ auto & clients = cd->enter_background_subscibers ;
151
+ std::for_each (clients.begin (), clients.end (),
152
+ [&](std::weak_ptr<EnterBackgroundSubscriber> weak) {
153
+ auto strong = weak.lock ();
154
+ if (strong) {
155
+ strong->OnEnterBackground ();
156
+ }
157
+ });
158
+ }
159
+
160
+ void Context::ExitBackground () {
161
+ auto cd = Instance ();
162
+ std::lock_guard<std::mutex> lock (cd->context_mutex );
163
+
164
+ auto & clients = cd->enter_background_subscibers ;
165
+ std::for_each (clients.begin (), clients.end (),
166
+ [&](std::weak_ptr<EnterBackgroundSubscriber> weak) {
167
+ auto strong = weak.lock ();
168
+ if (strong) {
169
+ strong->OnExitBackground ();
170
+ }
171
+ });
172
+ }
173
+
174
+ void Context::StoreBackgroundSessionCompletionHandler (
175
+ const std::string& session_name,
176
+ std::function<void (void )> completion_handler) {
177
+ auto cd = Instance ();
178
+ std::lock_guard<std::mutex> lock (cd->context_mutex );
179
+
180
+ auto & completion_handlers = cd->completion_handlers ;
181
+ completion_handlers.emplace (session_name, std::move (completion_handler));
182
+ }
183
+ #endif // __APPLE__
167
184
168
- Context::Scope::Scope () : m_cd(instance ()) {
169
- std::lock_guard<std::mutex> lock (m_cd->contextMutex );
170
- assert (m_cd->contextInstanceCounter != std::numeric_limits<size_t >::max ());
171
- if (m_cd->contextInstanceCounter ++ == 0 ) {
185
+ Context::Scope::Scope () : m_cd(Instance ()) {
186
+ std::lock_guard<std::mutex> lock (m_cd->context_mutex );
187
+ assert (m_cd->context_instance_counter != std::numeric_limits<size_t >::max ());
188
+ if (m_cd->context_instance_counter ++ == 0 ) {
172
189
Context::init ();
173
190
}
174
191
}
175
192
#ifdef ANDROID
176
193
// / see Context::init()
177
- Context::Scope::Scope (JavaVM* vm, jobject application) : m_cd(instance ()) {
178
- std::lock_guard<std::mutex> lock (m_cd->contextMutex );
179
- assert (m_cd->contextInstanceCounter != std::numeric_limits<size_t >::max ());
180
- if (m_cd->contextInstanceCounter ++ == 0 ) {
194
+ Context::Scope::Scope (JavaVM* vm, jobject application) : m_cd(Instance ()) {
195
+ std::lock_guard<std::mutex> lock (m_cd->context_mutex );
196
+ assert (m_cd->context_instance_counter != std::numeric_limits<size_t >::max ());
197
+ if (m_cd->context_instance_counter ++ == 0 ) {
181
198
Context::init (vm, application);
182
199
}
183
200
}
184
201
#endif
185
202
186
203
// / see Context::deinit()
187
204
Context::Scope::~Scope () {
188
- std::lock_guard<std::mutex> lock (m_cd->contextMutex );
189
- assert (m_cd->contextInstanceCounter != std::numeric_limits<size_t >::min ());
190
- if (--m_cd->contextInstanceCounter == 0 ) {
205
+ std::lock_guard<std::mutex> lock (m_cd->context_mutex );
206
+ assert (m_cd->context_instance_counter != std::numeric_limits<size_t >::min ());
207
+ if (--m_cd->context_instance_counter == 0 ) {
191
208
Context::deinit ();
192
209
}
193
210
}
0 commit comments