-
Notifications
You must be signed in to change notification settings - Fork 122
Feature/admob 2021 stability in future usage #762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4eabdf0
b4251c9
6673e59
e2cea9d
c03e414
591a658
40ef248
9c19e08
d73c995
37be813
7c1c6cf
ef47ba6
e79a87f
5cd408e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,6 @@ | |
#include "admob/src/include/firebase/admob/banner_view.h" | ||
#include "admob/src/include/firebase/admob/types.h" | ||
#include "app/src/assert.h" | ||
#include "app/src/semaphore.h" | ||
#include "app/src/util_android.h" | ||
|
||
namespace firebase { | ||
|
@@ -142,23 +141,17 @@ BannerViewInternalAndroid::BannerViewInternalAndroid(BannerView* base) | |
env->DeleteLocalRef(helper_ref); | ||
} | ||
|
||
void DestroyOnDeleteCallback(const Future<void>& result, void* sem_data) { | ||
if (sem_data != nullptr) { | ||
Semaphore* semaphore = static_cast<Semaphore*>(sem_data); | ||
semaphore->Post(); | ||
} | ||
} | ||
|
||
BannerViewInternalAndroid::~BannerViewInternalAndroid() { | ||
firebase::MutexLock lock(mutex_); | ||
|
||
Semaphore semaphore(0); | ||
InvokeNullary(kBannerViewFnDestroyOnDelete, banner_view_helper::kDestroy) | ||
.OnCompletion(DestroyOnDeleteCallback, &semaphore); | ||
semaphore.Wait(); | ||
|
||
JNIEnv* env = ::firebase::admob::GetJNI(); | ||
|
||
// The application should have invoked Destroy already, but | ||
// invoke it now just in case they haven't in the hope that | ||
// we can prevent leaking memory. | ||
env->CallVoidMethod( | ||
helper_, banner_view_helper::GetMethodId(banner_view_helper::kDestroy), | ||
/*callbackDataPtr=*/nullptr, /*destructor_invocation=*/true); | ||
|
||
env->DeleteGlobalRef(ad_view_); | ||
ad_view_ = nullptr; | ||
|
||
|
@@ -257,16 +250,19 @@ Future<void> BannerViewInternalAndroid::Initialize(AdParent parent, | |
if (initialized_) { | ||
const SafeFutureHandle<void> future_handle = | ||
future_data_.future_impl.SafeAlloc<void>(kBannerViewFnInitialize); | ||
Future<void> future = MakeFuture(&future_data_.future_impl, future_handle); | ||
CompleteFuture(kAdMobErrorAlreadyInitialized, | ||
kAdAlreadyInitializedErrorMessage, future_handle, | ||
&future_data_); | ||
return MakeFuture(&future_data_.future_impl, future_handle); | ||
return future; | ||
} | ||
|
||
initialized_ = true; | ||
|
||
FutureCallbackData<void>* callback_data = | ||
CreateVoidFutureCallbackData(kBannerViewFnSetPosition, &future_data_); | ||
Future<void> future = | ||
MakeFuture(&future_data_.future_impl, callback_data->future_handle); | ||
|
||
JNIEnv* env = ::firebase::admob::GetJNI(); | ||
FIREBASE_ASSERT(env); | ||
|
@@ -281,8 +277,7 @@ Future<void> BannerViewInternalAndroid::Initialize(AdParent parent, | |
call_data->callback_data = callback_data; | ||
util::RunOnMainThread(env, activity, InitializeBannerViewOnMainThread, | ||
call_data); | ||
|
||
return MakeFuture(&future_data_.future_impl, callback_data->future_handle); | ||
return future; | ||
} | ||
|
||
// This function is run on the main thread and is called in the | ||
|
@@ -324,7 +319,8 @@ Future<AdResult> BannerViewInternalAndroid::LoadAd(const AdRequest& request) { | |
|
||
FutureCallbackData<AdResult>* callback_data = | ||
CreateAdResultFutureCallbackData(kBannerViewFnLoadAd, &future_data_); | ||
SafeFutureHandle<AdResult> future_handle = callback_data->future_handle; | ||
Future<AdResult> future = | ||
MakeFuture(&future_data_.future_impl, callback_data->future_handle); | ||
|
||
LoadAdOnMainThreadData* call_data = new LoadAdOnMainThreadData(); | ||
call_data->ad_request = request; | ||
|
@@ -334,7 +330,7 @@ Future<AdResult> BannerViewInternalAndroid::LoadAd(const AdRequest& request) { | |
jobject activity = ::firebase::admob::GetActivity(); | ||
util::RunOnMainThread(env, activity, LoadAdOnMainThread, call_data); | ||
|
||
return MakeFuture(&future_data_.future_impl, future_handle); | ||
return future; | ||
} | ||
|
||
BoundingBox BannerViewInternalAndroid::bounding_box() const { | ||
|
@@ -390,21 +386,29 @@ Future<void> BannerViewInternalAndroid::Resume() { | |
|
||
Future<void> BannerViewInternalAndroid::Destroy() { | ||
firebase::MutexLock lock(mutex_); | ||
return InvokeNullary(kBannerViewFnDestroy, banner_view_helper::kDestroy); | ||
FutureCallbackData<void>* callback_data = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No longer use futures to track the destruction as the ReferenceCountedFutureImpl may be destroyed before the operation attempts to complete the future. This had caused a crash on some Android runs which was responsible for a lot of flake. TBH, the Application should have already invoked In theory this code could be removed, but I'll keep it anyway. But moving forward there doesn't seem to be a good reason to block the destructor and wait, though. Instead I'll start an asynchronous attempt to destroy the Java resources, if they haven't been destroyed already, and then return immediately from here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I think there's no reason to actually wait for the Java destruction to complete. |
||
CreateVoidFutureCallbackData(kBannerViewFnDestroy, &future_data_); | ||
Future<void> future = | ||
MakeFuture(&future_data_.future_impl, callback_data->future_handle); | ||
::firebase::admob::GetJNI()->CallVoidMethod( | ||
helper_, banner_view_helper::GetMethodId(banner_view_helper::kDestroy), | ||
reinterpret_cast<jlong>(callback_data), /*destructor_invocation=*/false); | ||
return future; | ||
} | ||
|
||
Future<void> BannerViewInternalAndroid::SetPosition(int x, int y) { | ||
firebase::MutexLock lock(mutex_); | ||
|
||
FutureCallbackData<void>* callback_data = | ||
CreateVoidFutureCallbackData(kBannerViewFnSetPosition, &future_data_); | ||
SafeFutureHandle<void> future_handle = callback_data->future_handle; | ||
Future<void> future = | ||
MakeFuture(&future_data_.future_impl, callback_data->future_handle); | ||
|
||
::firebase::admob::GetJNI()->CallVoidMethod( | ||
helper_, banner_view_helper::GetMethodId(banner_view_helper::kMoveToXY), | ||
reinterpret_cast<jlong>(callback_data), x, y); | ||
|
||
return MakeFuture(&future_data_.future_impl, future_handle); | ||
return future; | ||
} | ||
|
||
Future<void> BannerViewInternalAndroid::SetPosition( | ||
|
@@ -413,14 +417,15 @@ Future<void> BannerViewInternalAndroid::SetPosition( | |
|
||
FutureCallbackData<void>* callback_data = | ||
CreateVoidFutureCallbackData(kBannerViewFnSetPosition, &future_data_); | ||
SafeFutureHandle<void> future_handle = callback_data->future_handle; | ||
Future<void> future = | ||
MakeFuture(&future_data_.future_impl, callback_data->future_handle); | ||
|
||
::firebase::admob::GetJNI()->CallVoidMethod( | ||
helper_, | ||
banner_view_helper::GetMethodId(banner_view_helper::kMoveToPosition), | ||
reinterpret_cast<jlong>(callback_data), static_cast<int>(position)); | ||
|
||
return MakeFuture(&future_data_.future_impl, future_handle); | ||
return future; | ||
} | ||
|
||
// This function is run on the main thread and is called in the | ||
|
@@ -449,7 +454,8 @@ Future<void> BannerViewInternalAndroid::InvokeNullary( | |
|
||
FutureCallbackData<void>* callback_data = | ||
CreateVoidFutureCallbackData(fn, &future_data_); | ||
SafeFutureHandle<void> future_handle = callback_data->future_handle; | ||
Future<void> future = | ||
MakeFuture(&future_data_.future_impl, callback_data->future_handle); | ||
|
||
NulleryInvocationOnMainThreadData* call_data = | ||
new NulleryInvocationOnMainThreadData(); | ||
|
@@ -459,7 +465,7 @@ Future<void> BannerViewInternalAndroid::InvokeNullary( | |
|
||
util::RunOnMainThread(env, activity, InvokeNulleryOnMainThread, call_data); | ||
|
||
return MakeFuture(&future_data_.future_impl, future_handle); | ||
return future; | ||
} | ||
|
||
} // namespace internal | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -227,7 +227,9 @@ const char* GetRequestAgentString() { | |
// Mark a future as complete. | ||
void CompleteFuture(int error, const char* error_msg, | ||
SafeFutureHandle<void> handle, FutureData* future_data) { | ||
future_data->future_impl.Complete(handle, error, error_msg); | ||
if (future_data->future_impl.ValidFuture(handle)) { | ||
future_data->future_impl.Complete(handle, error, error_msg); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just an extra safety check. |
||
} | ||
} | ||
|
||
// For calls that aren't asynchronous, we can create and complete at the | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait to ensure that any callback attempts have time to complete before we start testing the listener.