Skip to content

AdMob AdRequest Neighboring Content URLS #769

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
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 18 additions & 1 deletion admob/integration_test/src/integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ static const char* kAdNetworkExtrasInvalidClassName = "abc123321cba";

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

static const std::vector<std::string> kNeighboringContentURLs = {
"test_url1", "test_url2", "test_url3"};

using app_framework::LogDebug;
using app_framework::ProcessEvents;

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

// Content URL
request.set_content_url(kContentUrl);

// Neighboring Content URLs
request.add_neighboring_content_urls(kNeighboringContentURLs);

return request;
}

Expand Down Expand Up @@ -285,7 +292,7 @@ TEST_F(FirebaseAdMobTest, TestGetAdRequest) { GetAdRequest(); }
TEST_F(FirebaseAdMobTest, TestGetAdRequestValues) {
SKIP_TEST_ON_DESKTOP;

const firebase::admob::AdRequest request = GetAdRequest();
firebase::admob::AdRequest request = GetAdRequest();

// Content URL.
EXPECT_TRUE(request.content_url() == std::string(kContentUrl));
Expand Down Expand Up @@ -324,6 +331,16 @@ TEST_F(FirebaseAdMobTest, TestGetAdRequestValues) {
EXPECT_TRUE(configured_keywords.find(*keyword_iter) !=
configured_keywords.end());
}

const std::unordered_set<std::string> configured_neighboring_content_urls =
request.neighboring_content_urls();
EXPECT_EQ(configured_neighboring_content_urls.size(),
kNeighboringContentURLs.size());
for (auto url_iter = kNeighboringContentURLs.begin();
url_iter != kNeighboringContentURLs.end(); ++url_iter) {
EXPECT_TRUE(configured_neighboring_content_urls.find(*url_iter) !=
configured_neighboring_content_urls.end());
}
}

// A simple listener to help test changes to a AdViews.
Expand Down
14 changes: 14 additions & 0 deletions admob/src/android/ad_request_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,20 @@ jobject GetJavaAdRequestFromCPPAdRequest(const AdRequest& request,
env->DeleteLocalRef(content_url);
}

// Neighboring Content Urls.
if (!request.neighboring_content_urls().empty()) {
jobject url_list = util::StdUnorderedSetToJavaList(
env, request.neighboring_content_urls());
builder = util::ContinueBuilder(
env, builder,
env->CallObjectMethod(
builder,
ad_request_builder::GetMethodId(
ad_request_builder::kSetNeighboringContentUrls),
url_list));
env->DeleteLocalRef(url_list);
}

// Set the request agent string so requests originating from this library can
// be tracked and reported on as a group.
jstring agent_str =
Expand Down
2 changes: 2 additions & 0 deletions admob/src/android/admob_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ namespace admob {
"Lcom/google/android/gms/ads/AdRequest$Builder;"), \
X(SetContentUrl, "setContentUrl", \
"(Ljava/lang/String;)Lcom/google/android/gms/ads/AdRequest$Builder;"), \
X(SetNeighboringContentUrls, "setNeighboringContentUrls", \
"(Ljava/util/List;)Lcom/google/android/gms/ads/AdRequest$Builder;"), \
X(SetRequestAgent, "setRequestAgent", \
"(Ljava/lang/String;)Lcom/google/android/gms/ads/AdRequest$Builder;")
// clang-format on
Expand Down
16 changes: 13 additions & 3 deletions admob/src/common/admob_common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,12 @@ AdRequest::AdRequest() {}
AdRequest::~AdRequest() {}

AdRequest::AdRequest(const char* content_url) { set_content_url(content_url); }
void AdRequest::add_extra(const char* ad_network, const char* extra_key,

void AdRequest::add_extra(const char* adapter_class_name, const char* extra_key,
const char* extra_value) {
if (ad_network != nullptr && extra_key != nullptr && extra_value != nullptr) {
extras_[std::string(ad_network)][std::string(extra_key)] =
if (adapter_class_name != nullptr && extra_key != nullptr &&
extra_value != nullptr) {
extras_[std::string(adapter_class_name)][std::string(extra_key)] =
std::string(extra_value);
}
}
Expand All @@ -156,6 +158,14 @@ void AdRequest::set_content_url(const char* content_url) {
}
}

void AdRequest::add_neighboring_content_urls(
const std::vector<std::string>& neighboring_content_urls) {
for (auto urls = neighboring_content_urls.begin();
urls != neighboring_content_urls.end(); ++urls) {
neighboring_content_urls_.insert(*urls);
}
}

// AdView
// Method implementations of AdView which are platform independent.
void AdView::SetAdListener(AdListener* listener) { ad_listener_ = listener; }
Expand Down
26 changes: 23 additions & 3 deletions admob/src/include/firebase/admob/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ class AdRequest {
/// if no content URL has been configured.
const std::string& content_url() const { return content_url_; }

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

/// Returns the set of neighboring content URLs or an empty set if no URLs
/// were set via @ref add_neighboring_content_urls().
const std::unordered_set<std::string>& neighboring_content_urls() const {
return neighboring_content_urls_;
}

/// Add a network extra for the associated ad_network.
///
/// Appends an extra to the corresponding list of extras for the ad_network.
/// Each ad network can have multiple extra strings.
///
/// @param[in] ad_network the ad network for which to add the extra.
/// @param[in] adapter_class_name the ad network adapter for which to add the
/// extra.
/// @param[in] extra_key a key which will be passed to the corresponding ad
/// network adapter.
/// @param[in] extra_value the value associated with extra_key.
void add_extra(const char* ad_network, const char* extra_key,
void add_extra(const char* adapter_class_name, const char* extra_key,
const char* extra_value);

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

/// Adds to the list of URLs which represent web content near an ad.
///
/// Promotes brand safety and allows displayed ads to have an app level
/// rating (MA, T, PG, etc) that is more appropriate to neighboring content.
///
/// Subsequent invocations append to the existing list.
///
/// @param[in] neighboring_content_urls neighboring content URLs to be
/// attached to the existing neighboring content URLs.
void add_neighboring_content_urls(
const std::vector<std::string>& neighboring_content_urls);

private:
std::string content_url_;
std::map<std::string, std::map<std::string, std::string> > extras_;
std::unordered_set<std::string> keywords_;
std::unordered_set<std::string> neighboring_content_urls_;
};

/// Describes a reward credited to a user for interacting with a RewardedAd.
Expand Down
6 changes: 6 additions & 0 deletions admob/src/ios/FADRequest.mm
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@
gadRequest.contentURL = util::StringToNSString(adRequest.content_url());
}

// Neighboring Content URLs
if (!adRequest.neighboring_content_urls().empty()) {
gadRequest.neighboringContentURLStrings =
util::StringUnorderedSetToNSMutableArray(adRequest.neighboring_content_urls());
}

// Set the request agent string so requests originating from this library can
// be tracked and reported on as a group.
gadRequest.requestAgent = @(GetRequestAgentString());
Expand Down
17 changes: 17 additions & 0 deletions app/src/util_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,23 @@ jobject StdVectorToJavaList(JNIEnv* env,
return java_list;
}

// Converts a `std::unordered_set<std::string>` to a
// `java.util.ArrayList<String>` Returns a local ref to a List.
jobject StdUnorderedSetToJavaList(
JNIEnv* env, const std::unordered_set<std::string>& string_set) {
jobject java_list =
env->NewObject(array_list::GetClass(),
array_list::GetMethodId(array_list::kConstructor));
jmethodID add_method = array_list::GetMethodId(array_list::kAdd);
for (auto it = string_set.begin(); it != string_set.end(); ++it) {
jstring value = env->NewStringUTF(it->c_str());
env->CallBooleanMethod(java_list, add_method, value);
CheckAndClearJniExceptions(env);
env->DeleteLocalRef(value);
}
return java_list;
}

// Converts a `std::map<Variant, Variant>` to a `java.util.Map<Object, Object>`.
// Returns a local ref to a Map.
jobject VariantMapToJavaMap(JNIEnv* env,
Expand Down
6 changes: 6 additions & 0 deletions app/src/util_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <map>
#include <string>
#include <unordered_set>
#include <vector>

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

// Converts a `std::unordered_set<std::string>` to a `java.util.ArrayList<String>`
// Returns a local ref to a List.
jobject StdUnorderedSetToJavaList(JNIEnv* env,
const std::unordered_set<std::string>& string_set);

// Converts an `std::map<const char*, const char*>` to a
// `java.util.Map<String, String>`.
void StdMapToJavaMap(JNIEnv* env, jobject* to,
Expand Down
9 changes: 7 additions & 2 deletions app/src/util_ios.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <map>
#include <string>
#include <unordered_set>
#include <vector>

#include "app/src/include/firebase/variant.h"
Copy link
Contributor

@jonsimantov jonsimantov Dec 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can fix the lint error if you move the system #includes above the #ifdef __OBJC__.

Expand Down Expand Up @@ -193,10 +194,14 @@ void ForEachAppDelegateClass(void (^block)(Class));
NSMutableArray *StringVectorToNSMutableArray(
const std::vector<std::string> &vector);

// Convert a unordered_set of strings into an NSMutableArray.
NSMutableArray *StringUnorderedSetToNSMutableArray(
const std::unordered_set<std::string> &set);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#include <unordered_set> is indeed at the top of the file.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Lint warning: Add #include <unordered_set> for unordered_set<>


// Convert a NSArray into a vector of strings. Asserts if a non NSString
// object is found in the array.
void NSArrayOfNSStringToVectorOfString(NSArray *array,
std::vector<std::string> *string_vector);
void NSArrayOfNSStringToVectorOfString(
NSArray *array, std::vector<std::string> *string_vector);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#include <vector> is indeed at the top of the file.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Lint warning: Add #include <vector> for vector<>


// Convert a string map to NSDictionary.
NSDictionary *StringMapToNSDictionary(
Expand Down
11 changes: 10 additions & 1 deletion app/src/util_ios.mm
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,16 @@ void ForEachAppDelegateClass(void (^block)(Class)) {
return array;
}

void NSArrayOfNSStringToVectorOfString(NSArray *array, std::vector<std::string> *string_vector) {
NSMutableArray *StringUnorderedSetToNSMutableArray(
const std::unordered_set<std::string> &set) {
NSMutableArray<NSString *> *array = [[NSMutableArray alloc] initWithCapacity:set.size()];
for (auto &element : set) {
[array addObject:StringToNSString(element)];
}
return array;
}

void NSArrayOfNSStringToVectorOfString(NSArray* array, std::vector<std::string>* string_vector) {
string_vector->reserve(array.count);
for (id object in array) {
if (![object isKindOfClass:[NSString class]]) {
Expand Down