11/*
2- * Copyright (C) 2019 HERE Europe B.V.
2+ * Copyright (C) 2019-2023 HERE Europe B.V.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
3333#include < jni.h>
3434#endif
3535
36+ #include " ContextInternal.h"
37+
3638namespace {
3739std::atomic_flag gDeInitializing = ATOMIC_FLAG_INIT;
3840}
3941
4042namespace olp {
4143namespace 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- }
6544
6645void initialize () {
67- const auto data = instance ();
46+ const auto data = Instance ();
6847
6948 // Fire all initializations.
70- for (const olp::context::Context::InitializedCallback& cb : data->initVector )
49+ for (const olp::context::Context::InitializedCallback& cb : data->init_vector )
7150 cb ();
7251}
7352
7453void deinitialize () {
7554 if (!atomic_flag_test_and_set (&gDeInitializing )) {
76- const auto data = instance ();
55+ const auto data = Instance ();
7756
7857 // Fire all deinitializeds.
7958 for (const olp::context::Context::DeinitializedCallback& cb :
80- data->deinitVector )
59+ data->deinit_vector )
8160 cb ();
8261
8362 atomic_flag_clear (&gDeInitializing );
@@ -86,16 +65,16 @@ void deinitialize() {
8665
8766void Context::addInitializeCallbacks (InitializedCallback initCallback,
8867 DeinitializedCallback deinitCalback) {
89- auto cd = instance ();
68+ auto cd = Instance ();
9069
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));
9372}
9473
9574void Context::init () {
96- auto cd = instance ();
75+ auto cd = Instance ();
9776#ifdef ANDROID
98- cd->javaVM = nullptr ;
77+ cd->java_vm = nullptr ;
9978#else
10079 (void )cd;
10180#endif
@@ -104,16 +83,16 @@ void Context::init() {
10483
10584void Context::deinit () {
10685#ifdef ANDROID
107- auto cd = instance ();
86+ auto cd = Instance ();
10887 // Release the global reference of Context.
10988 // Technically not needed if we took the application context,
11089 // but good to release just in case.
111- if (cd->javaVM ) {
90+ if (cd->java_vm ) {
11291 JNIEnv* env = nullptr ;
11392 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) !=
11594 JNI_OK) {
116- if (cd->javaVM ->AttachCurrentThread (&env, nullptr ) != JNI_OK) {
95+ if (cd->java_vm ->AttachCurrentThread (&env, nullptr ) != JNI_OK) {
11796 env = nullptr ;
11897 } else {
11998 attached = true ;
@@ -122,20 +101,20 @@ void Context::deinit() {
122101 if (env) {
123102 env->DeleteGlobalRef (cd->context );
124103 if (attached) {
125- cd->javaVM ->DetachCurrentThread ();
104+ cd->java_vm ->DetachCurrentThread ();
126105 }
127106 }
128107 }
129108
130- cd->javaVM = nullptr ;
109+ cd->java_vm = nullptr ;
131110#endif
132111 deinitialize ();
133112}
134113
135114#if defined(ANDROID)
136115void Context::init (JavaVM* vm, jobject context) {
137- auto cd = instance ();
138- cd->javaVM = vm;
116+ auto cd = Instance ();
117+ cd->java_vm = vm;
139118
140119 JNIEnv* env = nullptr ;
141120 if (vm->GetEnv (reinterpret_cast <void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
@@ -148,46 +127,84 @@ void Context::init(JavaVM* vm, jobject context) {
148127}
149128
150129JavaVM* Context::getJavaVM () {
151- auto cd = instance ();
152- if (!cd->javaVM ) {
130+ auto cd = Instance ();
131+ if (!cd->java_vm ) {
153132 assert (false );
154133 }
155134
156- return cd->javaVM ;
135+ return cd->java_vm ;
157136}
158137
159138jobject Context::getAndroidContext () {
160- auto cd = instance ();
139+ auto cd = Instance ();
161140 if (!cd->context ) {
162141 assert (false );
163142 }
164143 return cd->context ;
165144}
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__
167184
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 ) {
172189 Context::init ();
173190 }
174191}
175192#ifdef ANDROID
176193// / 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 ) {
181198 Context::init (vm, application);
182199 }
183200}
184201#endif
185202
186203// / see Context::deinit()
187204Context::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 ) {
191208 Context::deinit ();
192209 }
193210}
0 commit comments