Skip to content

Commit dc62717

Browse files
authored
Merge pull request #769 from firebase/feature/admob_2021_neighboring_content
AdMob AdRequest Neighboring Content URLS
2 parents f11ef67 + 0080b28 commit dc62717

File tree

10 files changed

+116
-10
lines changed

10 files changed

+116
-10
lines changed

admob/integration_test/src/integration_test.cc

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ static const char* kAdNetworkExtrasInvalidClassName = "abc123321cba";
120120

121121
static const char* kContentUrl = "http://www.firebase.com";
122122

123+
static const std::vector<std::string> kNeighboringContentURLs = {
124+
"test_url1", "test_url2", "test_url3"};
125+
123126
using app_framework::LogDebug;
124127
using app_framework::ProcessEvents;
125128

@@ -235,8 +238,12 @@ firebase::admob::AdRequest FirebaseAdMobTest::GetAdRequest() {
235238
extras_iter->second.c_str());
236239
}
237240

241+
// Content URL
238242
request.set_content_url(kContentUrl);
239243

244+
// Neighboring Content URLs
245+
request.add_neighboring_content_urls(kNeighboringContentURLs);
246+
240247
return request;
241248
}
242249

@@ -285,7 +292,7 @@ TEST_F(FirebaseAdMobTest, TestGetAdRequest) { GetAdRequest(); }
285292
TEST_F(FirebaseAdMobTest, TestGetAdRequestValues) {
286293
SKIP_TEST_ON_DESKTOP;
287294

288-
const firebase::admob::AdRequest request = GetAdRequest();
295+
firebase::admob::AdRequest request = GetAdRequest();
289296

290297
// Content URL.
291298
EXPECT_TRUE(request.content_url() == std::string(kContentUrl));
@@ -324,6 +331,16 @@ TEST_F(FirebaseAdMobTest, TestGetAdRequestValues) {
324331
EXPECT_TRUE(configured_keywords.find(*keyword_iter) !=
325332
configured_keywords.end());
326333
}
334+
335+
const std::unordered_set<std::string> configured_neighboring_content_urls =
336+
request.neighboring_content_urls();
337+
EXPECT_EQ(configured_neighboring_content_urls.size(),
338+
kNeighboringContentURLs.size());
339+
for (auto url_iter = kNeighboringContentURLs.begin();
340+
url_iter != kNeighboringContentURLs.end(); ++url_iter) {
341+
EXPECT_TRUE(configured_neighboring_content_urls.find(*url_iter) !=
342+
configured_neighboring_content_urls.end());
343+
}
327344
}
328345

329346
// A simple listener to help test changes to a AdViews.

admob/src/android/ad_request_converter.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,20 @@ jobject GetJavaAdRequestFromCPPAdRequest(const AdRequest& request,
124124
env->DeleteLocalRef(content_url);
125125
}
126126

127+
// Neighboring Content Urls.
128+
if (!request.neighboring_content_urls().empty()) {
129+
jobject url_list = util::StdUnorderedSetToJavaList(
130+
env, request.neighboring_content_urls());
131+
builder = util::ContinueBuilder(
132+
env, builder,
133+
env->CallObjectMethod(
134+
builder,
135+
ad_request_builder::GetMethodId(
136+
ad_request_builder::kSetNeighboringContentUrls),
137+
url_list));
138+
env->DeleteLocalRef(url_list);
139+
}
140+
127141
// Set the request agent string so requests originating from this library can
128142
// be tracked and reported on as a group.
129143
jstring agent_str =

admob/src/android/admob_android.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ namespace admob {
3838
"Lcom/google/android/gms/ads/AdRequest$Builder;"), \
3939
X(SetContentUrl, "setContentUrl", \
4040
"(Ljava/lang/String;)Lcom/google/android/gms/ads/AdRequest$Builder;"), \
41+
X(SetNeighboringContentUrls, "setNeighboringContentUrls", \
42+
"(Ljava/util/List;)Lcom/google/android/gms/ads/AdRequest$Builder;"), \
4143
X(SetRequestAgent, "setRequestAgent", \
4244
"(Ljava/lang/String;)Lcom/google/android/gms/ads/AdRequest$Builder;")
4345
// clang-format on

admob/src/common/admob_common.cc

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,12 @@ AdRequest::AdRequest() {}
132132
AdRequest::~AdRequest() {}
133133

134134
AdRequest::AdRequest(const char* content_url) { set_content_url(content_url); }
135-
void AdRequest::add_extra(const char* ad_network, const char* extra_key,
135+
136+
void AdRequest::add_extra(const char* adapter_class_name, const char* extra_key,
136137
const char* extra_value) {
137-
if (ad_network != nullptr && extra_key != nullptr && extra_value != nullptr) {
138-
extras_[std::string(ad_network)][std::string(extra_key)] =
138+
if (adapter_class_name != nullptr && extra_key != nullptr &&
139+
extra_value != nullptr) {
140+
extras_[std::string(adapter_class_name)][std::string(extra_key)] =
139141
std::string(extra_value);
140142
}
141143
}
@@ -156,6 +158,14 @@ void AdRequest::set_content_url(const char* content_url) {
156158
}
157159
}
158160

161+
void AdRequest::add_neighboring_content_urls(
162+
const std::vector<std::string>& neighboring_content_urls) {
163+
for (auto urls = neighboring_content_urls.begin();
164+
urls != neighboring_content_urls.end(); ++urls) {
165+
neighboring_content_urls_.insert(*urls);
166+
}
167+
}
168+
159169
// AdView
160170
// Method implementations of AdView which are platform independent.
161171
void AdView::SetAdListener(AdListener* listener) { ad_listener_ = listener; }

admob/src/include/firebase/admob/types.h

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ class AdRequest {
466466
/// if no content URL has been configured.
467467
const std::string& content_url() const { return content_url_; }
468468

469-
/// A Map of ad network adapters to their collection of extra parameters, as
469+
/// A Map of adapter class names to their collection of extra parameters, as
470470
/// configured via @ref add_extra.
471471
const std::map<std::string, std::map<std::string, std::string> >& extras()
472472
const {
@@ -477,16 +477,23 @@ class AdRequest {
477477
/// @ref add_keyword.
478478
const std::unordered_set<std::string>& keywords() const { return keywords_; }
479479

480+
/// Returns the set of neighboring content URLs or an empty set if no URLs
481+
/// were set via @ref add_neighboring_content_urls().
482+
const std::unordered_set<std::string>& neighboring_content_urls() const {
483+
return neighboring_content_urls_;
484+
}
485+
480486
/// Add a network extra for the associated ad_network.
481487
///
482488
/// Appends an extra to the corresponding list of extras for the ad_network.
483489
/// Each ad network can have multiple extra strings.
484490
///
485-
/// @param[in] ad_network the ad network for which to add the extra.
491+
/// @param[in] adapter_class_name the ad network adapter for which to add the
492+
/// extra.
486493
/// @param[in] extra_key a key which will be passed to the corresponding ad
487494
/// network adapter.
488495
/// @param[in] extra_value the value associated with extra_key.
489-
void add_extra(const char* ad_network, const char* extra_key,
496+
void add_extra(const char* adapter_class_name, const char* extra_key,
490497
const char* extra_value);
491498

492499
/// Adds a keyword for targeting purposes.
@@ -504,10 +511,23 @@ class AdRequest {
504511
/// @param[in] content_url the url of the content being viewed.
505512
void set_content_url(const char* content_url);
506513

514+
/// Adds to the list of URLs which represent web content near an ad.
515+
///
516+
/// Promotes brand safety and allows displayed ads to have an app level
517+
/// rating (MA, T, PG, etc) that is more appropriate to neighboring content.
518+
///
519+
/// Subsequent invocations append to the existing list.
520+
///
521+
/// @param[in] neighboring_content_urls neighboring content URLs to be
522+
/// attached to the existing neighboring content URLs.
523+
void add_neighboring_content_urls(
524+
const std::vector<std::string>& neighboring_content_urls);
525+
507526
private:
508527
std::string content_url_;
509528
std::map<std::string, std::map<std::string, std::string> > extras_;
510529
std::unordered_set<std::string> keywords_;
530+
std::unordered_set<std::string> neighboring_content_urls_;
511531
};
512532

513533
/// Describes a reward credited to a user for interacting with a RewardedAd.

admob/src/ios/FADRequest.mm

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@
9393
gadRequest.contentURL = util::StringToNSString(adRequest.content_url());
9494
}
9595

96+
// Neighboring Content URLs
97+
if (!adRequest.neighboring_content_urls().empty()) {
98+
gadRequest.neighboringContentURLStrings =
99+
util::StringUnorderedSetToNSMutableArray(adRequest.neighboring_content_urls());
100+
}
101+
96102
// Set the request agent string so requests originating from this library can
97103
// be tracked and reported on as a group.
98104
gadRequest.requestAgent = @(GetRequestAgentString());

app/src/util_android.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,23 @@ jobject StdVectorToJavaList(JNIEnv* env,
679679
return java_list;
680680
}
681681

682+
// Converts a `std::unordered_set<std::string>` to a
683+
// `java.util.ArrayList<String>` Returns a local ref to a List.
684+
jobject StdUnorderedSetToJavaList(
685+
JNIEnv* env, const std::unordered_set<std::string>& string_set) {
686+
jobject java_list =
687+
env->NewObject(array_list::GetClass(),
688+
array_list::GetMethodId(array_list::kConstructor));
689+
jmethodID add_method = array_list::GetMethodId(array_list::kAdd);
690+
for (auto it = string_set.begin(); it != string_set.end(); ++it) {
691+
jstring value = env->NewStringUTF(it->c_str());
692+
env->CallBooleanMethod(java_list, add_method, value);
693+
CheckAndClearJniExceptions(env);
694+
env->DeleteLocalRef(value);
695+
}
696+
return java_list;
697+
}
698+
682699
// Converts a `std::map<Variant, Variant>` to a `java.util.Map<Object, Object>`.
683700
// Returns a local ref to a Map.
684701
jobject VariantMapToJavaMap(JNIEnv* env,

app/src/util_android.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <map>
2424
#include <string>
25+
#include <unordered_set>
2526
#include <vector>
2627

2728
#include "app/src/assert.h"
@@ -817,6 +818,11 @@ std::string JObjectClassName(JNIEnv* env, jobject obj);
817818
jobject StdVectorToJavaList(JNIEnv* env,
818819
const std::vector<std::string>& string_vector);
819820

821+
// Converts a `std::unordered_set<std::string>` to a `java.util.ArrayList<String>`
822+
// Returns a local ref to a List.
823+
jobject StdUnorderedSetToJavaList(JNIEnv* env,
824+
const std::unordered_set<std::string>& string_set);
825+
820826
// Converts an `std::map<const char*, const char*>` to a
821827
// `java.util.Map<String, String>`.
822828
void StdMapToJavaMap(JNIEnv* env, jobject* to,

app/src/util_ios.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include <map>
2626
#include <string>
27+
#include <unordered_set>
2728
#include <vector>
2829

2930
#include "app/src/include/firebase/variant.h"
@@ -193,10 +194,14 @@ void ForEachAppDelegateClass(void (^block)(Class));
193194
NSMutableArray *StringVectorToNSMutableArray(
194195
const std::vector<std::string> &vector);
195196

197+
// Convert a unordered_set of strings into an NSMutableArray.
198+
NSMutableArray *StringUnorderedSetToNSMutableArray(
199+
const std::unordered_set<std::string> &set);
200+
196201
// Convert a NSArray into a vector of strings. Asserts if a non NSString
197202
// object is found in the array.
198-
void NSArrayOfNSStringToVectorOfString(NSArray *array,
199-
std::vector<std::string> *string_vector);
203+
void NSArrayOfNSStringToVectorOfString(
204+
NSArray *array, std::vector<std::string> *string_vector);
200205

201206
// Convert a string map to NSDictionary.
202207
NSDictionary *StringMapToNSDictionary(

app/src/util_ios.mm

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,16 @@ void ForEachAppDelegateClass(void (^block)(Class)) {
161161
return array;
162162
}
163163

164-
void NSArrayOfNSStringToVectorOfString(NSArray *array, std::vector<std::string> *string_vector) {
164+
NSMutableArray *StringUnorderedSetToNSMutableArray(
165+
const std::unordered_set<std::string> &set) {
166+
NSMutableArray<NSString *> *array = [[NSMutableArray alloc] initWithCapacity:set.size()];
167+
for (auto &element : set) {
168+
[array addObject:StringToNSString(element)];
169+
}
170+
return array;
171+
}
172+
173+
void NSArrayOfNSStringToVectorOfString(NSArray* array, std::vector<std::string>* string_vector) {
165174
string_vector->reserve(array.count);
166175
for (id object in array) {
167176
if (![object isKindOfClass:[NSString class]]) {

0 commit comments

Comments
 (0)