Skip to content

Commit a00b2da

Browse files
authored
Admob - AdSize and AdRequest updates (#679)
Updated the AdSize and AdRequest structures: - Converted them to classes. - AdRequest now has methods to manipulate the content url, keywords and network extras. - Extras are are now collections with mediation class names keys. The class names now dynamically resolved to jclasses on on Android and GADSize objects on iOS, as these objects are required as part of the Admob phone SDK API when setting extras. - AdSize now provides methods for Adaptive sizes, and includes constants for common ad sizes. Banner and Interstitial ads were updated to use these new structures. Updated Itests - Some unit testing is done on these structures. - Added pauses between banner ad move commands as they were moving too quickly for Android phones to properly render them (they flashed as blank black boxes.) [iTest execution](https://github.com/firebase/firebase-cpp-sdk/actions/runs/1271413043) [Packaging execution 1](https://github.com/firebase/firebase-cpp-sdk/actions/runs/1293182830) [Packaging execution 2, expanded](https://github.com/firebase/firebase-cpp-sdk/actions/runs/1295146882) - builds fine, some test failures in unrelated storage and messaging code.
1 parent 80f50ff commit a00b2da

23 files changed

+876
-196
lines changed

admob/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ set(android_SRCS
4040

4141
# Source files used by the iOS implementation.
4242
set(ios_SRCS
43+
src/ios/FADAdSize.mm
4344
src/ios/FADBannerView.mm
4445
src/ios/FADInterstitialDelegate.mm
4546
src/ios/FADRequest.mm

admob/integration_test/src/integration_test.cc

Lines changed: 195 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
#include <cstdlib>
2020
#include <cstring>
2121
#include <ctime>
22+
#include <map>
2223
#include <vector>
2324

2425
#include "app_framework.h" // NOLINT
2526
#include "firebase/admob.h"
27+
#include "firebase/admob/types.h"
2628
#include "firebase/app.h"
2729
#include "firebase/util.h"
2830
#include "firebase_test_framework.h" // NOLINT
@@ -72,6 +74,28 @@ const char* kInterstitialAdUnit = "ca-app-pub-3940256099942544/4411468910";
7274
const std::vector<std::string> kTestDeviceIDs = {
7375
"2077ef9a63d2b398840261c8221a0c9b", "098fe087d987c9a878965454a65654d7"};
7476

77+
// Sample keywords to use in making the request.
78+
static const std::vector<std::string> kKeywords({"AdMob", "C++", "Fun"});
79+
80+
// "Extra" key value pairs can be added to the request as well. Typically
81+
// these are used when testing new features.
82+
static const std::map<std::string, std::string> kAdMobAdapterExtras = {
83+
{"the_name_of_an_extra", "the_value_for_that_extra"},
84+
{"heres", "a second example"}};
85+
86+
#if defined(__ANDROID__)
87+
static const char* kAdNetworkExtrasClassName =
88+
"com/google/ads/mediation/admob/AdMobAdapter";
89+
#else
90+
static const char* kAdNetworkExtrasClassName = "GADExtras";
91+
#endif
92+
93+
// Used to detect kAdMobErrorAdNetworkClassLoadErrors when loading
94+
// ads.
95+
static const char* kAdNetworkExtrasInvalidClassName = "abc123321cba";
96+
97+
static const char* kContentUrl = "http://www.firebase.com";
98+
7599
using app_framework::LogDebug;
76100
using app_framework::ProcessEvents;
77101

@@ -96,6 +120,8 @@ class FirebaseAdMobTest : public FirebaseTest {
96120

97121
firebase::App* FirebaseAdMobTest::shared_app_ = nullptr;
98122

123+
void BrieflyPauseForVisualInspection() { app_framework::ProcessEvents(100); }
124+
99125
void FirebaseAdMobTest::SetUpTestSuite() {
100126
LogDebug("Initialize Firebase App.");
101127

@@ -161,28 +187,72 @@ void FirebaseAdMobTest::SetUp() {
161187
void FirebaseAdMobTest::TearDown() { FirebaseTest::TearDown(); }
162188

163189
firebase::admob::AdRequest FirebaseAdMobTest::GetAdRequest() {
164-
// Sample keywords to use in making the request.
165-
static const char* kKeywords[] = {"AdMob", "C++", "Fun"};
166-
167190
firebase::admob::AdRequest request;
168191

169192
// Additional keywords to be used in targeting.
170-
request.keyword_count = sizeof(kKeywords) / sizeof(kKeywords[0]);
171-
request.keywords = kKeywords;
193+
for (auto keyword_iter = kKeywords.begin(); keyword_iter != kKeywords.end();
194+
++keyword_iter) {
195+
request.add_keyword((*keyword_iter).c_str());
196+
}
172197

173-
// "Extra" key value pairs can be added to the request as well. Typically
174-
// these are used when testing new features.
175-
static const firebase::admob::KeyValuePair kRequestExtras[] = {
176-
{"the_name_of_an_extra", "the_value_for_that_extra"}};
177-
request.extras_count = sizeof(kRequestExtras) / sizeof(kRequestExtras[0]);
178-
request.extras = kRequestExtras;
198+
for (auto extras_iter = kAdMobAdapterExtras.begin();
199+
extras_iter != kAdMobAdapterExtras.end(); ++extras_iter) {
200+
request.add_extra(kAdNetworkExtrasClassName, extras_iter->first.c_str(),
201+
extras_iter->second.c_str());
202+
}
203+
204+
request.set_content_url(kContentUrl);
179205

180206
return request;
181207
}
182208

183209
// Test cases below.
184210
TEST_F(FirebaseAdMobTest, TestGetAdRequest) { GetAdRequest(); }
185211

212+
TEST_F(FirebaseAdMobTest, TestGetAdRequestValues) {
213+
SKIP_TEST_ON_DESKTOP;
214+
215+
const firebase::admob::AdRequest request = GetAdRequest();
216+
217+
// Content URL.
218+
EXPECT_TRUE(request.content_url() == std::string(kContentUrl));
219+
220+
// Extras.
221+
std::map<std::string, std::map<std::string, std::string> > configured_extras =
222+
request.extras();
223+
224+
EXPECT_EQ(configured_extras.size(), 1);
225+
for (auto extras_name_iter = configured_extras.begin();
226+
extras_name_iter != configured_extras.end(); ++extras_name_iter) {
227+
// Confirm class name.
228+
const std::string class_name = extras_name_iter->first;
229+
EXPECT_EQ(class_name, kAdNetworkExtrasClassName);
230+
231+
// Grab the extras.
232+
const std::map<std::string, std::string>& configured_extras =
233+
extras_name_iter->second;
234+
EXPECT_EQ(configured_extras.size(), kAdMobAdapterExtras.size());
235+
236+
// Check the extra key value pairs.
237+
for (auto constant_extras_iter = kAdMobAdapterExtras.begin();
238+
constant_extras_iter != kAdMobAdapterExtras.end();
239+
++constant_extras_iter) {
240+
// Ensure the configured value matches the constant for the same key.
241+
EXPECT_EQ(configured_extras.at(constant_extras_iter->first),
242+
constant_extras_iter->second);
243+
}
244+
}
245+
246+
const std::unordered_set<std::string> configured_keywords =
247+
request.keywords();
248+
EXPECT_EQ(configured_keywords.size(), kKeywords.size());
249+
for (auto keyword_iter = kKeywords.begin(); keyword_iter != kKeywords.end();
250+
++keyword_iter) {
251+
EXPECT_TRUE(configured_keywords.find(*keyword_iter) !=
252+
configured_keywords.end());
253+
}
254+
}
255+
186256
// A simple listener to help test changes to a BannerView.
187257
class TestBannerViewListener : public firebase::admob::BannerView::Listener {
188258
public:
@@ -200,6 +270,71 @@ class TestBannerViewListener : public firebase::admob::BannerView::Listener {
200270
std::vector<firebase::admob::BoundingBox> bounding_box_changes_;
201271
};
202272

273+
TEST_F(FirebaseAdMobTest, TestAdSize) {
274+
uint32_t kWidth = 50;
275+
uint32_t kHeight = 10;
276+
277+
using firebase::admob::AdSize;
278+
279+
const AdSize adaptive_landscape =
280+
AdSize::GetLandscapeAnchoredAdaptiveBannerAdSize(kWidth);
281+
EXPECT_EQ(adaptive_landscape.width(), kWidth);
282+
EXPECT_EQ(adaptive_landscape.height(), 0);
283+
EXPECT_EQ(adaptive_landscape.type(), AdSize::kTypeAnchoredAdaptive);
284+
EXPECT_EQ(adaptive_landscape.orientation(), AdSize::kOrientationLandscape);
285+
286+
const AdSize adaptive_portrait =
287+
AdSize::GetPortraitAnchoredAdaptiveBannerAdSize(kWidth);
288+
EXPECT_EQ(adaptive_portrait.width(), kWidth);
289+
EXPECT_EQ(adaptive_portrait.height(), 0);
290+
EXPECT_EQ(adaptive_portrait.type(), AdSize::kTypeAnchoredAdaptive);
291+
EXPECT_EQ(adaptive_portrait.orientation(), AdSize::kOrientationPortrait);
292+
293+
EXPECT_FALSE(adaptive_portrait == adaptive_landscape);
294+
EXPECT_TRUE(adaptive_portrait != adaptive_landscape);
295+
296+
const firebase::admob::AdSize adaptive_current =
297+
AdSize::GetCurrentOrientationAnchoredAdaptiveBannerAdSize(kWidth);
298+
EXPECT_EQ(adaptive_current.width(), kWidth);
299+
EXPECT_EQ(adaptive_current.height(), 0);
300+
EXPECT_EQ(adaptive_current.type(), AdSize::kTypeAnchoredAdaptive);
301+
EXPECT_EQ(adaptive_current.orientation(), AdSize::kOrientationCurrent);
302+
303+
const firebase::admob::AdSize custom_ad_size(kWidth, kHeight);
304+
EXPECT_EQ(custom_ad_size.width(), kWidth);
305+
EXPECT_EQ(custom_ad_size.height(), kHeight);
306+
EXPECT_EQ(custom_ad_size.type(), AdSize::kTypeStandard);
307+
EXPECT_EQ(custom_ad_size.orientation(), AdSize::kOrientationCurrent);
308+
309+
const AdSize custom_ad_size_2(kWidth, kHeight);
310+
EXPECT_TRUE(custom_ad_size == custom_ad_size_2);
311+
EXPECT_FALSE(custom_ad_size != custom_ad_size_2);
312+
313+
const AdSize banner = AdSize::kBanner;
314+
EXPECT_EQ(banner.width(), 320);
315+
EXPECT_EQ(banner.height(), 50);
316+
EXPECT_EQ(banner.type(), AdSize::kTypeStandard);
317+
EXPECT_EQ(banner.orientation(), AdSize::kOrientationCurrent);
318+
319+
const AdSize fullbanner = AdSize::kFullBanner;
320+
EXPECT_EQ(fullbanner.width(), 468);
321+
EXPECT_EQ(fullbanner.height(), 60);
322+
EXPECT_EQ(fullbanner.type(), AdSize::kTypeStandard);
323+
EXPECT_EQ(fullbanner.orientation(), AdSize::kOrientationCurrent);
324+
325+
const AdSize leaderboard = AdSize::kLeaderBoard;
326+
EXPECT_EQ(leaderboard.width(), 728);
327+
EXPECT_EQ(leaderboard.height(), 90);
328+
EXPECT_EQ(leaderboard.type(), AdSize::kTypeStandard);
329+
EXPECT_EQ(leaderboard.orientation(), AdSize::kOrientationCurrent);
330+
331+
const AdSize medium_rectangle = AdSize::kMediumRectangle;
332+
EXPECT_EQ(medium_rectangle.width(), 300);
333+
EXPECT_EQ(medium_rectangle.height(), 250);
334+
EXPECT_EQ(medium_rectangle.type(), AdSize::kTypeStandard);
335+
EXPECT_EQ(medium_rectangle.orientation(), AdSize::kOrientationCurrent);
336+
}
337+
203338
TEST_F(FirebaseAdMobTest, TestRequestConfigurationSetGetEmptyConfig) {
204339
SKIP_TEST_ON_DESKTOP;
205340

@@ -273,11 +408,7 @@ TEST_F(FirebaseAdMobTest, TestBannerView) {
273408
static const int kBannerWidth = 320;
274409
static const int kBannerHeight = 50;
275410

276-
firebase::admob::AdSize banner_ad_size;
277-
banner_ad_size.ad_size_type = firebase::admob::kAdSizeStandard;
278-
banner_ad_size.width = kBannerWidth;
279-
banner_ad_size.height = kBannerHeight;
280-
411+
const firebase::admob::AdSize banner_ad_size(kBannerWidth, kBannerHeight);
281412
firebase::admob::BannerView* banner = new firebase::admob::BannerView();
282413
WaitForCompletion(banner->Initialize(app_framework::GetWindowContext(),
283414
kBannerAdUnit, banner_ad_size),
@@ -301,81 +432,106 @@ TEST_F(FirebaseAdMobTest, TestBannerView) {
301432
firebase::admob::BannerView::kPresentationStateVisibleWithAd);
302433
expected_num_bounding_box_changes++;
303434

304-
// Move to each of the six pre-defined positions.
435+
BrieflyPauseForVisualInspection();
305436

437+
// Move to each of the six pre-defined positions.
306438
WaitForCompletion(banner->MoveTo(firebase::admob::BannerView::kPositionTop),
307439
"MoveTo(Top)");
308440
expected_presentation_states.push_back(
309441
firebase::admob::BannerView::kPresentationStateVisibleWithAd);
310442
expected_num_bounding_box_changes++;
311443

444+
BrieflyPauseForVisualInspection();
445+
312446
WaitForCompletion(
313447
banner->MoveTo(firebase::admob::BannerView::kPositionTopLeft),
314448
"MoveTo(TopLeft)");
315449
expected_presentation_states.push_back(
316450
firebase::admob::BannerView::kPresentationStateVisibleWithAd);
317451
expected_num_bounding_box_changes++;
318452

453+
BrieflyPauseForVisualInspection();
454+
319455
WaitForCompletion(
320456
banner->MoveTo(firebase::admob::BannerView::kPositionTopRight),
321457
"MoveTo(TopRight)");
322458
expected_presentation_states.push_back(
323459
firebase::admob::BannerView::kPresentationStateVisibleWithAd);
324460
expected_num_bounding_box_changes++;
325461

462+
BrieflyPauseForVisualInspection();
463+
326464
WaitForCompletion(
327465
banner->MoveTo(firebase::admob::BannerView::kPositionBottom),
328466
"Moveto(Bottom)");
329467
expected_presentation_states.push_back(
330468
firebase::admob::BannerView::kPresentationStateVisibleWithAd);
331469
expected_num_bounding_box_changes++;
332470

471+
BrieflyPauseForVisualInspection();
472+
333473
WaitForCompletion(
334474
banner->MoveTo(firebase::admob::BannerView::kPositionBottomLeft),
335475
"MoveTo(BottomLeft)");
336476
expected_presentation_states.push_back(
337477
firebase::admob::BannerView::kPresentationStateVisibleWithAd);
338478
expected_num_bounding_box_changes++;
339479

480+
BrieflyPauseForVisualInspection();
481+
340482
WaitForCompletion(
341483
banner->MoveTo(firebase::admob::BannerView::kPositionBottomRight),
342484
"MoveTo(BottomRight)");
343485
expected_presentation_states.push_back(
344486
firebase::admob::BannerView::kPresentationStateVisibleWithAd);
345487
expected_num_bounding_box_changes++;
346488

489+
BrieflyPauseForVisualInspection();
490+
347491
// Move to some coordinates.
348492
WaitForCompletion(banner->MoveTo(100, 300), "MoveTo(x0, y0)");
349493
expected_presentation_states.push_back(
350494
firebase::admob::BannerView::kPresentationStateVisibleWithAd);
351495
expected_num_bounding_box_changes++;
352496

497+
BrieflyPauseForVisualInspection();
498+
353499
WaitForCompletion(banner->MoveTo(100, 400), "MoveTo(x1, y1)");
354500
expected_presentation_states.push_back(
355501
firebase::admob::BannerView::kPresentationStateVisibleWithAd);
356502
expected_num_bounding_box_changes++;
357503

504+
BrieflyPauseForVisualInspection();
505+
358506
// Try hiding and showing the BannerView.
359507
WaitForCompletion(banner->Hide(), "Hide 1");
360508
expected_presentation_states.push_back(
361509
firebase::admob::BannerView::kPresentationStateHidden);
362510

511+
BrieflyPauseForVisualInspection();
512+
363513
WaitForCompletion(banner->Show(), "Show 1");
364514
expected_presentation_states.push_back(
365515
firebase::admob::BannerView::kPresentationStateVisibleWithAd);
366516
expected_num_bounding_box_changes++;
367517

518+
BrieflyPauseForVisualInspection();
519+
368520
// Move again after hiding/showing.
369521
WaitForCompletion(banner->MoveTo(100, 300), "MoveTo(x2, y2)");
370522
expected_presentation_states.push_back(
371523
firebase::admob::BannerView::kPresentationStateVisibleWithAd);
372524
expected_num_bounding_box_changes++;
373525

526+
BrieflyPauseForVisualInspection();
527+
374528
WaitForCompletion(banner->MoveTo(100, 400), "Moveto(x3, y3)");
375529
expected_presentation_states.push_back(
376530
firebase::admob::BannerView::kPresentationStateVisibleWithAd);
377531
expected_num_bounding_box_changes++;
378532

533+
BrieflyPauseForVisualInspection();
534+
379535
WaitForCompletion(banner->Hide(), "Hide 2");
380536
expected_presentation_states.push_back(
381537
firebase::admob::BannerView::kPresentationStateHidden);
@@ -429,11 +585,7 @@ TEST_F(FirebaseAdMobTest, TestBannerViewAlreadyInitialized) {
429585
static const int kBannerWidth = 320;
430586
static const int kBannerHeight = 50;
431587

432-
firebase::admob::AdSize banner_ad_size;
433-
banner_ad_size.ad_size_type = firebase::admob::kAdSizeStandard;
434-
banner_ad_size.width = kBannerWidth;
435-
banner_ad_size.height = kBannerHeight;
436-
588+
const firebase::admob::AdSize banner_ad_size(kBannerWidth, kBannerHeight);
437589
firebase::admob::BannerView* banner = new firebase::admob::BannerView();
438590

439591
{
@@ -464,6 +616,26 @@ TEST_F(FirebaseAdMobTest, TestBannerViewAlreadyInitialized) {
464616
}
465617
}
466618

619+
TEST_F(FirebaseAdMobTest, TestBannerViewWithBadExtrasClassName) {
620+
SKIP_TEST_ON_DESKTOP;
621+
622+
static const int kBannerWidth = 320;
623+
static const int kBannerHeight = 50;
624+
625+
const firebase::admob::AdSize banner_ad_size(kBannerWidth, kBannerHeight);
626+
firebase::admob::BannerView* banner = new firebase::admob::BannerView();
627+
WaitForCompletion(banner->Initialize(app_framework::GetWindowContext(),
628+
kBannerAdUnit, banner_ad_size),
629+
"Initialize");
630+
631+
// Load the banner ad.
632+
firebase::admob::AdRequest request = GetAdRequest();
633+
request.add_extra(kAdNetworkExtrasInvalidClassName, "shouldnot", "work");
634+
WaitForCompletion(banner->LoadAd(request), "LoadAd",
635+
firebase::admob::kAdMobErrorAdNetworkClassLoadError);
636+
delete banner;
637+
}
638+
467639
// A simple listener to help test changes to a InterstitialAd.
468640
class TestInterstitialAdListener
469641
: public firebase::admob::InterstitialAd::Listener {
@@ -543,10 +715,7 @@ TEST_F(FirebaseAdMobTest, TestBannerViewMultithreadDeletion) {
543715
static const int kBannerWidth = 320;
544716
static const int kBannerHeight = 50;
545717

546-
firebase::admob::AdSize banner_ad_size;
547-
banner_ad_size.ad_size_type = firebase::admob::kAdSizeStandard;
548-
banner_ad_size.width = kBannerWidth;
549-
banner_ad_size.height = kBannerHeight;
718+
const firebase::admob::AdSize banner_ad_size(kBannerWidth, kBannerHeight);
550719

551720
for (int i = 0; i < 5; ++i) {
552721
firebase::admob::BannerView* banner = new firebase::admob::BannerView();

0 commit comments

Comments
 (0)