Skip to content

Remove LoadAdResult from new Admob. #723

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

Merged
merged 69 commits into from
Nov 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
db93aaa
Android AdResult prototype
DellaBitta Sep 27, 2021
8116de4
linter fixes
DellaBitta Sep 27, 2021
0eb306e
cause becomes smart ptr. iOS and Desktop impls
DellaBitta Sep 27, 2021
15c7b55
linter fixes
DellaBitta Sep 27, 2021
41c9aed
Added AdapterResponseInfo & AdResponseInfo | AdResult fixes
DellaBitta Sep 29, 2021
903abd8
linter fixes
DellaBitta Sep 29, 2021
9fd06d2
load_ad_result | response info iOS
DellaBitta Sep 30, 2021
42643cd
draft LoadAdResult future on Android
DellaBitta Oct 3, 2021
0f9125f
successful load ad, need to trim debug info
DellaBitta Oct 4, 2021
ee2a38d
removed debug logs
DellaBitta Oct 4, 2021
693435e
Safe Futures
DellaBitta Oct 4, 2021
f740e43
stubs build, reworked futures to use safe API
DellaBitta Oct 5, 2021
23bf809
merged feature/admob_2021 with RequestConfig changes
DellaBitta Oct 5, 2021
89db0b3
Banner View Android Tests
DellaBitta Oct 6, 2021
a8543d9
Android, Desktop Interstitial tests
DellaBitta Oct 7, 2021
eb97f88
CreateAndCompleteFuture, enabled TestBannerViewMultithreadDeletion
DellaBitta Oct 7, 2021
8d2f2b9
ios and Android LoadAdResult rework
DellaBitta Oct 11, 2021
4476e68
linter fixes
DellaBitta Oct 12, 2021
fa2e305
added more comments
DellaBitta Oct 12, 2021
32865b9
no lint on JNI function signatures
DellaBitta Oct 12, 2021
4062d9a
skip loading in progress tests on desktop
DellaBitta Oct 12, 2021
d8e2e58
multithread test
DellaBitta Oct 12, 2021
19a50b2
Upgrade to GMA 8.12 for iOS
DellaBitta Oct 13, 2021
663adee
Merge branch 'feature/admob_ios_version_update' into feature/admob_20…
DellaBitta Oct 13, 2021
c89f0eb
lint fix
DellaBitta Oct 13, 2021
531d924
add inherited linker flags to xcodeproject
DellaBitta Oct 13, 2021
4e1f165
exclude i386 in Admob itest project
DellaBitta Oct 14, 2021
5519a0f
review fixes
DellaBitta Oct 18, 2021
a269f07
Android bannerview listeners
DellaBitta Oct 22, 2021
33bd11a
most bannerview operations use c++ runonmainthread
DellaBitta Oct 22, 2021
2e0e0a2
Android admob interstitial tests pass
DellaBitta Oct 25, 2021
d3fbdb6
itest name typo
DellaBitta Oct 25, 2021
4b577f3
bannerview init assertions and memory cleanup
DellaBitta Oct 25, 2021
7870632
stability fixes, added stress test
DellaBitta Oct 26, 2021
da5a3c1
desktop stubs
DellaBitta Oct 26, 2021
1138457
Android/iOS both work for fullscreen and adlistener callbacks.
DellaBitta Oct 28, 2021
a7c0617
BannerView destroy, added to itests
DellaBitta Oct 29, 2021
0351c5d
lint fixes
DellaBitta Oct 29, 2021
09c41f6
Documentation comments for PrecisionType enum
DellaBitta Oct 29, 2021
425316c
admob/integration_test/src/integration_test.cc
DellaBitta Oct 29, 2021
736d198
remove flake from alreadyinitialized test
DellaBitta Oct 29, 2021
88a642a
format
DellaBitta Oct 29, 2021
fb65071
assert on null future result ptr
DellaBitta Oct 30, 2021
fa9ff2d
double init logging
DellaBitta Oct 30, 2021
d79ba4a
mutex inits
DellaBitta Oct 30, 2021
8c6c4d6
bannerview mutex
DellaBitta Oct 30, 2021
2bfb6db
revert itest debug output
DellaBitta Oct 31, 2021
dbdc38e
interstitial mutex
DellaBitta Oct 31, 2021
d6e1050
comment / formatting pass
DellaBitta Oct 31, 2021
4e5c7b9
interstitial uninitialized checks
DellaBitta Nov 1, 2021
633d167
fixed missing itest line.
DellaBitta Nov 1, 2021
53ba827
guard bannerview getlastresult use from returning a faulty loadAdResult
DellaBitta Nov 1, 2021
0afef99
AdResult::kUndefinedDomain now const char* const
DellaBitta Nov 1, 2021
352a790
Format .java files
DellaBitta Nov 1, 2021
cd95460
Removed LoadAdResultInternal. Now simply shares AdResultInternal struct
DellaBitta Nov 1, 2021
e87ae0a
load_ad_result_stub save error
DellaBitta Nov 1, 2021
db7c046
remove accidental change to reference_counted_future_impl.h
DellaBitta Nov 1, 2021
051d3e8
use of stringWithFormat in adapter_response. CompleteFuture now uses…
DellaBitta Nov 1, 2021
8cf3960
merge feature/admob_2021_adresult
DellaBitta Nov 1, 2021
16837e0
merged feature/admob_2021
DellaBitta Nov 1, 2021
88fe274
Android impl
DellaBitta Nov 2, 2021
a818ede
stub implementation
DellaBitta Nov 2, 2021
71e687a
stub cmake update
DellaBitta Nov 2, 2021
480e4b4
iOS implementation
DellaBitta Nov 2, 2021
d228167
removed log header include
DellaBitta Nov 2, 2021
04e83a7
missing symbol for stubs
DellaBitta Nov 2, 2021
2949156
build fix for stub
DellaBitta Nov 2, 2021
f8ffed7
Clarified response_info() method comment
DellaBitta Nov 3, 2021
4fcd79a
merged feature/admob_2021
DellaBitta Nov 8, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions admob/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ set(android_SRCS
src/android/admob_android.cc
src/android/banner_view_internal_android.cc
src/android/interstitial_ad_internal_android.cc
src/android/load_ad_result_android.cc
src/android/response_info_android.cc)

# Source files used by the iOS implementation.
Expand All @@ -53,15 +52,13 @@ set(ios_SRCS
src/ios/admob_ios.mm
src/ios/banner_view_internal_ios.mm
src/ios/interstitial_ad_internal_ios.mm
src/ios/load_ad_result_ios.mm
src/ios/response_info_ios.mm)

# Source files used by the stub implementation.
set(stub_SRCS
src/stub/ad_result_stub.cc
src/stub/adapter_response_info_stub.cc
src/stub/admob_stub.cc
src/stub/load_ad_result_stub.cc
src/stub/response_info_stub.cc)

if(ANDROID)
Expand Down
33 changes: 13 additions & 20 deletions admob/integration_test/src/integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -509,12 +509,12 @@ TEST_F(FirebaseAdMobTest, TestBannerView) {

// Load the banner ad.
firebase::admob::AdRequest request = GetAdRequest();
firebase::Future<firebase::admob::LoadAdResult> load_ad_future =
firebase::Future<firebase::admob::AdResult> load_ad_future =
banner->LoadAd(request);
WaitForCompletion(load_ad_future, "LoadAd");
EXPECT_EQ(expected_num_bounding_box_changes,
bounding_box_listener.bounding_box_changes_.size());
const firebase::admob::LoadAdResult* result_ptr = load_ad_future.result();
const firebase::admob::AdResult* result_ptr = load_ad_future.result();
ASSERT_NE(result_ptr, nullptr);
EXPECT_TRUE(result_ptr->is_successful());
EXPECT_EQ(result_ptr->code(), firebase::admob::kAdMobErrorNone);
Expand Down Expand Up @@ -636,9 +636,6 @@ TEST_F(FirebaseAdMobTest, TestBannerView) {
app_framework::ProcessEvents(2000);

WaitForCompletion(banner->Destroy(), "Destroy BannerView");

LogDebug("And again to ensure destruction callbacks are recorded.");
app_framework::ProcessEvents(2000);
banner->SetBoundingBoxListener(nullptr);
delete banner;

Expand Down Expand Up @@ -718,7 +715,7 @@ TEST_F(FirebaseAdMobTest, TestBannerViewAdOpenedAdClosed) {

// Load the banner ad.
firebase::admob::AdRequest request = GetAdRequest();
firebase::Future<firebase::admob::LoadAdResult> load_ad_future =
firebase::Future<firebase::admob::AdResult> load_ad_future =
banner->LoadAd(request);
WaitForCompletion(load_ad_future, "LoadAd");
WaitForCompletion(banner->Show(), "Show 0");
Expand All @@ -737,9 +734,6 @@ TEST_F(FirebaseAdMobTest, TestBannerViewAdOpenedAdClosed) {
app_framework::ProcessEvents(1000);
}

LogDebug("Waiting for a moment to ensure all callbacks are recorded.");
app_framework::ProcessEvents(2000);

// Ensure all of the expected events were triggered on Android.
EXPECT_EQ(ad_listener.num_on_ad_clicked_, 1);
EXPECT_EQ(ad_listener.num_on_ad_impression_, 1);
Expand Down Expand Up @@ -853,16 +847,16 @@ TEST_F(FirebaseAdMobTest, TestBannerViewErrorLoadInProgress) {
// successful ad loads instead of the expected
// kAdMobErrorLoadInProgress error.
firebase::admob::AdRequest request = GetAdRequest();
firebase::Future<firebase::admob::LoadAdResult> first_load_ad =
firebase::Future<firebase::admob::AdResult> first_load_ad =
banner->LoadAd(request);
firebase::Future<firebase::admob::LoadAdResult> second_load_ad =
firebase::Future<firebase::admob::AdResult> second_load_ad =
banner->LoadAd(request);

WaitForCompletion(second_load_ad, "Second LoadAd",
firebase::admob::kAdMobErrorLoadInProgress);
WaitForCompletion(first_load_ad, "First LoadAd");

const firebase::admob::LoadAdResult* result_ptr = second_load_ad.result();
const firebase::admob::AdResult* result_ptr = second_load_ad.result();
ASSERT_NE(result_ptr, nullptr);
EXPECT_FALSE(result_ptr->is_successful());
EXPECT_EQ(result_ptr->code(), firebase::admob::kAdMobErrorLoadInProgress);
Expand Down Expand Up @@ -890,12 +884,11 @@ TEST_F(FirebaseAdMobTest, TestBannerViewErrorBadAdUnitId) {

// Load the banner ad.
firebase::admob::AdRequest request = GetAdRequest();
firebase::Future<firebase::admob::LoadAdResult> load_ad =
banner->LoadAd(request);
firebase::Future<firebase::admob::AdResult> load_ad = banner->LoadAd(request);
WaitForCompletion(load_ad, "LoadAd",
firebase::admob::kAdMobErrorInvalidRequest);

const firebase::admob::LoadAdResult* result_ptr = load_ad.result();
const firebase::admob::AdResult* result_ptr = load_ad.result();
ASSERT_NE(result_ptr, nullptr);
EXPECT_FALSE(result_ptr->is_successful());
EXPECT_EQ(result_ptr->code(), firebase::admob::kAdMobErrorInvalidRequest);
Expand Down Expand Up @@ -1088,16 +1081,16 @@ TEST_F(FirebaseAdMobTest, TestInterstitialAdErrorLoadInProgress) {
// successful ad loads instead of the expected
// kAdMobErrorLoadInProgress error.
firebase::admob::AdRequest request = GetAdRequest();
firebase::Future<firebase::admob::LoadAdResult> first_load_ad =
firebase::Future<firebase::admob::AdResult> first_load_ad =
interstitial_ad->LoadAd(kInterstitialAdUnit, request);
firebase::Future<firebase::admob::LoadAdResult> second_load_ad =
firebase::Future<firebase::admob::AdResult> second_load_ad =
interstitial_ad->LoadAd(kInterstitialAdUnit, request);

WaitForCompletion(second_load_ad, "Second LoadAd",
firebase::admob::kAdMobErrorLoadInProgress);
WaitForCompletion(first_load_ad, "First LoadAd");

const firebase::admob::LoadAdResult* result_ptr = second_load_ad.result();
const firebase::admob::AdResult* result_ptr = second_load_ad.result();
ASSERT_NE(result_ptr, nullptr);
EXPECT_FALSE(result_ptr->is_successful());
EXPECT_EQ(result_ptr->code(), firebase::admob::kAdMobErrorLoadInProgress);
Expand All @@ -1120,12 +1113,12 @@ TEST_F(FirebaseAdMobTest, TestInterstitialAdErrorBadAdUnitId) {

// Load the interstitial ad.
firebase::admob::AdRequest request = GetAdRequest();
firebase::Future<firebase::admob::LoadAdResult> load_ad =
firebase::Future<firebase::admob::AdResult> load_ad =
interstitial_ad->LoadAd(kBadAdUnit, request);
WaitForCompletion(load_ad, "LoadAd",
firebase::admob::kAdMobErrorInvalidRequest);

const firebase::admob::LoadAdResult* result_ptr = load_ad.result();
const firebase::admob::AdResult* result_ptr = load_ad.result();
ASSERT_NE(result_ptr, nullptr);
EXPECT_FALSE(result_ptr->is_successful());
EXPECT_EQ(result_ptr->code(), firebase::admob::kAdMobErrorInvalidRequest);
Expand Down
83 changes: 68 additions & 15 deletions admob/src/android/ad_result_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "admob/src/android/ad_request_converter.h"
#include "admob/src/android/admob_android.h"
#include "admob/src/android/response_info_android.h"
#include "admob/src/common/admob_common.h"
#include "admob/src/include/firebase/admob.h"

Expand All @@ -34,6 +35,11 @@ METHOD_LOOKUP_DEFINITION(ad_error,
"com/google/android/gms/ads/AdError",
ADERROR_METHODS);

METHOD_LOOKUP_DEFINITION(load_ad_error,
PROGUARD_KEEP_CLASS
"com/google/android/gms/ads/LoadAdError",
LOADADERROR_METHODS);

const char* const AdResult::kUndefinedDomain = "undefined";

AdResult::AdResult() {
Expand All @@ -43,11 +49,17 @@ AdResult::AdResult() {
internal_ = new AdResultInternal();
internal_->is_successful = false;
internal_->is_wrapper_error = true;
internal_->is_load_ad_error = false;
internal_->code = kAdMobErrorUninitialized;
internal_->domain = "SDK";
internal_->message = "This AdResult has not be initialized.";
internal_->to_string = internal_->message;
internal_->j_ad_error = nullptr;

// While most data is passed into this object through the AdResultInternal
// structure (above), the response_info_ is constructed when parsing
// the j_ad_error itself.
response_info_ = new ResponseInfo();
}

AdResult::AdResult(const AdResultInternal& ad_result_internal) {
Expand All @@ -57,7 +69,9 @@ AdResult::AdResult(const AdResultInternal& ad_result_internal) {
internal_ = new AdResultInternal();
internal_->is_successful = ad_result_internal.is_successful;
internal_->is_wrapper_error = ad_result_internal.is_wrapper_error;
internal_->is_load_ad_error = ad_result_internal.is_load_ad_error;
internal_->j_ad_error = nullptr;
response_info_ = new ResponseInfo();

// AdResults can be returned on success, or for errors encountered in the C++
// SDK wrapper, or in the Android AdMob SDK. The structure is populated
Expand Down Expand Up @@ -104,17 +118,44 @@ AdResult::AdResult(const AdResultInternal& ad_result_internal) {
internal_->message = util::JStringToString(env, j_message);
env->DeleteLocalRef(j_message);

// To string.
jobject j_to_string = env->CallObjectMethod(
internal_->j_ad_error, ad_error::GetMethodId(ad_error::kToString));
FIREBASE_ASSERT(j_to_string);
internal_->to_string = util::JStringToString(env, j_to_string);
env->DeleteLocalRef(j_to_string);
// Differentiate between a com.google.android.gms.ads.AdError or its
// com.google.android.gms.ads.LoadAdError subclass.
if (!internal_->is_load_ad_error) {
// AdError.
jobject j_to_string = env->CallObjectMethod(
internal_->j_ad_error, ad_error::GetMethodId(ad_error::kToString));
FIREBASE_ASSERT(j_to_string);
internal_->to_string = util::JStringToString(env, j_to_string);
env->DeleteLocalRef(j_to_string);
} else {
// LoadAdError.
jobject j_response_info = env->CallObjectMethod(
internal_->j_ad_error,
load_ad_error::GetMethodId(load_ad_error::kGetResponseInfo));

if (j_response_info != nullptr) {
ResponseInfoInternal response_info_internal;
response_info_internal.j_response_info = j_response_info;
*response_info_ = ResponseInfo(response_info_internal);
env->DeleteLocalRef(j_response_info);
}

// A to_string value of this LoadAdError. Invoke the set_to_string
// protected method of the AdResult parent class to overwrite whatever
// it parsed.
jobject j_to_string = env->CallObjectMethod(
internal_->j_ad_error,
load_ad_error::GetMethodId(load_ad_error::kToString));
internal_->to_string = util::JStringToString(env, j_to_string);
env->DeleteLocalRef(j_to_string);
}
}
}

AdResult::AdResult(const AdResult& ad_result) : AdResult() {
FIREBASE_ASSERT(ad_result.response_info_ != nullptr);
// Reuse the assignment operator.
this->response_info_ = new ResponseInfo();
*this = ad_result;
}

Expand All @@ -127,46 +168,57 @@ AdResult& AdResult::operator=(const AdResult& ad_result) {
FIREBASE_ASSERT(env);
FIREBASE_ASSERT(internal_);
FIREBASE_ASSERT(ad_result.internal_);
FIREBASE_ASSERT(response_info_);
FIREBASE_ASSERT(ad_result.response_info_);

AdResultInternal* preexisting_internal = internal_;
{
// Lock the parties so they're not deleted while the copying takes place.
MutexLock(ad_result.internal_->mutex);
MutexLock(internal_->mutex);
MutexLock ad_result_lock(ad_result.internal_->mutex);
MutexLock lock(internal_->mutex);
internal_ = new AdResultInternal();

internal_->is_successful = ad_result.internal_->is_successful;
internal_->is_wrapper_error = ad_result.internal_->is_wrapper_error;
internal_->is_load_ad_error = ad_result.internal_->is_load_ad_error;
internal_->code = ad_result.internal_->code;
internal_->domain = ad_result.internal_->domain;
internal_->message = ad_result.internal_->message;
if (ad_result.internal_->j_ad_error != nullptr) {
internal_->j_ad_error =
env->NewGlobalRef(ad_result.internal_->j_ad_error);
}

if (preexisting_internal->j_ad_error) {
env->DeleteGlobalRef(preexisting_internal->j_ad_error);
preexisting_internal->j_ad_error = nullptr;
}

*response_info_ = *ad_result.response_info_;
}

// Deleting the internal_ deletes the mutex within it, so we wait for
// complete deletion until after the mutex lock leaves scope.
delete preexisting_internal;

return *this;
}

AdResult::~AdResult() {
FIREBASE_ASSERT(internal_);
FIREBASE_ASSERT(response_info_);

if (internal_->j_ad_error != nullptr) {
JNIEnv* env = GetJNI();
FIREBASE_ASSERT(env);
env->DeleteGlobalRef(internal_->j_ad_error);
internal_->j_ad_error = nullptr;
}

delete internal_;
internal_ = nullptr;

delete response_info_;
response_info_ = nullptr;
}

bool AdResult::is_successful() const {
Expand All @@ -193,7 +245,9 @@ std::unique_ptr<AdResult> AdResult::GetCause() const {

AdResultInternal ad_result_internal;
ad_result_internal.is_wrapper_error = false;
ad_result_internal.is_load_ad_error = false;
ad_result_internal.j_ad_error = j_ad_error;

std::unique_ptr<AdResult> ad_result =
std::unique_ptr<AdResult>(new AdResult(ad_result_internal));
env->DeleteLocalRef(j_ad_error);
Expand All @@ -219,17 +273,16 @@ const std::string& AdResult::message() const {
return internal_->message;
}

const ResponseInfo& AdResult::response_info() const {
FIREBASE_ASSERT(response_info_ != nullptr);
return *response_info_;
}

/// Returns a log friendly string version of this object.
const std::string& AdResult::ToString() const {
FIREBASE_ASSERT(internal_);
return internal_->to_string;
}

/// Protected method used by LoadAdResult, a subclass which constructs its
/// to_string representation programatically after the AdResult construction.
void AdResult::set_to_string(std::string to_string) {
FIREBASE_ASSERT(internal_);
internal_->to_string = to_string;
}
} // namespace admob
} // namespace firebase
16 changes: 13 additions & 3 deletions admob/src/android/ad_result_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,14 @@ namespace admob {
X(ToString, "toString", "()Ljava/lang/String;")
// clang-format on

#define LOADADERROR_METHODS(X) \
X(GetResponseInfo, "getResponseInfo", \
"()Lcom/google/android/gms/ads/ResponseInfo;"), \
X(ToString, "toString", "()Ljava/lang/String;")
// clang-format on

METHOD_LOOKUP_DECLARATION(ad_error, ADERROR_METHODS);
METHOD_LOOKUP_DECLARATION(load_ad_error, LOADADERROR_METHODS);

struct AdResultInternal {
// True if the result contains an error originating from C++/Java wrapper
Expand All @@ -48,13 +55,16 @@ struct AdResultInternal {
// True if this was a successful result.
bool is_successful;

// An error code
// True if this error data represents a result from a LoadAd request.
bool is_load_ad_error;

// An error code.
AdMobError code;

// A cached value of com.google.android.gms.ads.AdError.domain
// A cached value of com.google.android.gms.ads.AdError.domain.
std::string domain;

// A cached value of com.google.android.gms.ads.AdError.message
// A cached value of com.google.android.gms.ads.AdError.message.
std::string message;

// A cached result from invoking com.google.android.gms.ads.AdError.ToString.
Expand Down
1 change: 1 addition & 0 deletions admob/src/android/adapter_response_info_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ AdapterResponseInfo::AdapterResponseInfo(

// Construct an AdResultInternal from the AdError in the AdapterResponseInfo.
AdResultInternal ad_result_internal;
ad_result_internal.is_load_ad_error = false;
ad_result_internal.j_ad_error = env->CallObjectMethod(
j_adapter_response_info,
adapter_response_info::GetMethodId(adapter_response_info::kGetAdError));
Expand Down
Loading