Skip to content

Commit f655518

Browse files
authored
Functions to Disable AdMob Automatic Services on iOS (#772)
Add iOS-specific functions to disable some automatic services: - `DisableSDKCrashReporting()` - `DisableMediationInitialization()` These functions have no behavior on Android.
1 parent dc62717 commit f655518

File tree

8 files changed

+141
-36
lines changed

8 files changed

+141
-36
lines changed

admob/integration_test/src/integration_test.cc

Lines changed: 94 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,15 @@ static const char* kAdNetworkExtrasClassName =
114114
static const char* kAdNetworkExtrasClassName = "GADExtras";
115115
#endif
116116

117+
// Class nname of the GMA SDK returned in initialization results.
118+
#if defined(ANDROID)
119+
const char kAdMobClassName[] = "com.google.android.gms.ads.MobileAds";
120+
#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
121+
const char kAdMobClassName[] = "GADMobileAds";
122+
#else // desktop
123+
const char kAdMobClassName[] = "stub";
124+
#endif
125+
117126
// Used to detect kAdMobErrorAdNetworkClassLoadErrors when loading
118127
// ads.
119128
static const char* kAdNetworkExtrasInvalidClassName = "abc123321cba";
@@ -151,43 +160,60 @@ class FirebaseAdMobTest : public FirebaseTest {
151160
static firebase::App* shared_app_;
152161
};
153162

163+
// Runs AdMob Tests on methods and functions that should be run
164+
// before AdMob initializes.
165+
class FirebaseAdMobPreInitializationTests : public FirebaseAdMobTest {
166+
public:
167+
FirebaseAdMobPreInitializationTests();
168+
~FirebaseAdMobPreInitializationTests() override;
169+
170+
static void SetUpTestSuite();
171+
172+
void SetUp() override;
173+
};
174+
154175
firebase::App* FirebaseAdMobTest::shared_app_ = nullptr;
155176

156177
void PauseForVisualInspectionAndCallbacks() {
157178
app_framework::ProcessEvents(300);
158179
}
159180

160-
void FirebaseAdMobTest::SetUpTestSuite() {
161-
LogDebug("Initialize Firebase App.");
162-
163-
FindFirebaseConfig(FIREBASE_CONFIG_STRING);
164-
165-
#if defined(ANDROID)
166-
shared_app_ = ::firebase::App::Create(app_framework::GetJniEnv(),
167-
app_framework::GetActivity());
168-
#else
169-
shared_app_ = ::firebase::App::Create();
170-
#endif // defined(ANDROID)
171-
181+
void InitializeAdMob(firebase::App* shared_app) {
172182
LogDebug("Initializing AdMob.");
173183

174184
::firebase::ModuleInitializer initializer;
175-
initializer.Initialize(shared_app_, nullptr,
185+
initializer.Initialize(shared_app, nullptr,
176186
[](::firebase::App* app, void* /* userdata */) {
177187
LogDebug("Try to initialize AdMob");
178188
firebase::InitResult result;
179189
::firebase::admob::Initialize(*app, &result);
180190
return result;
181191
});
182192

183-
WaitForCompletion(initializer.InitializeLastResult(), "Initialize");
193+
FirebaseAdMobTest::WaitForCompletion(initializer.InitializeLastResult(),
194+
"Initialize");
184195

185196
ASSERT_EQ(initializer.InitializeLastResult().error(), 0)
186197
<< initializer.InitializeLastResult().error_message();
187198

188199
LogDebug("Successfully initialized AdMob.");
189200
}
190201

202+
void FirebaseAdMobTest::SetUpTestSuite() {
203+
LogDebug("Initialize Firebase App.");
204+
205+
FindFirebaseConfig(FIREBASE_CONFIG_STRING);
206+
207+
#if defined(ANDROID)
208+
shared_app_ = ::firebase::App::Create(app_framework::GetJniEnv(),
209+
app_framework::GetActivity());
210+
#else
211+
shared_app_ = ::firebase::App::Create();
212+
#endif // defined(ANDROID)
213+
214+
InitializeAdMob(shared_app_);
215+
}
216+
191217
void FirebaseAdMobTest::TearDownTestSuite() {
192218
// Workaround: AdMob does some of its initialization in the main
193219
// thread, so if you terminate it too quickly after initialization
@@ -247,7 +273,54 @@ firebase::admob::AdRequest FirebaseAdMobTest::GetAdRequest() {
247273
return request;
248274
}
249275

276+
FirebaseAdMobPreInitializationTests::FirebaseAdMobPreInitializationTests() {}
277+
278+
FirebaseAdMobPreInitializationTests::~FirebaseAdMobPreInitializationTests() {}
279+
280+
void FirebaseAdMobPreInitializationTests::SetUp() { FirebaseTest::SetUp(); }
281+
282+
void FirebaseAdMobPreInitializationTests::SetUpTestSuite() {
283+
LogDebug("Initialize Firebase App.");
284+
FindFirebaseConfig(FIREBASE_CONFIG_STRING);
285+
#if defined(ANDROID)
286+
shared_app_ = ::firebase::App::Create(app_framework::GetJniEnv(),
287+
app_framework::GetActivity());
288+
#else
289+
shared_app_ = ::firebase::App::Create();
290+
#endif // defined(ANDROID)
291+
}
292+
250293
// Test cases below.
294+
295+
TEST_F(FirebaseAdMobPreInitializationTests,
296+
TestDisableMediationInitialization) {
297+
// Note: This test should be disabled or put in an entirely different test
298+
// binrary if we ever wish to test mediation in this application.
299+
firebase::admob::DisableMediationInitialization();
300+
301+
// Ensure that AdMob can initialize.
302+
InitializeAdMob(shared_app_);
303+
auto initialize_future = firebase::admob::InitializeLastResult();
304+
WaitForCompletion(initialize_future, "admob::Initialize");
305+
ASSERT_NE(initialize_future.result(), nullptr);
306+
EXPECT_EQ(*initialize_future.result(),
307+
firebase::admob::GetInitializationStatus());
308+
309+
#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
310+
// Check to see that only one Adapter was initialized, the base GMA adapter.
311+
// Note: DisableMediationInitialization is only implemented on iOS.
312+
std::map<std::string, firebase::admob::AdapterStatus> adapter_status =
313+
firebase::admob::GetInitializationStatus().GetAdapterStatusMap();
314+
EXPECT_EQ(adapter_status.size(), 1);
315+
EXPECT_THAT(
316+
adapter_status,
317+
Contains(Pair(
318+
kAdMobClassName,
319+
Property(&firebase::admob::AdapterStatus::is_initialized, true))))
320+
<< "Expected adapter class '" << kAdMobClassName << "' is not loaded.";
321+
#endif
322+
}
323+
251324
TEST_F(FirebaseAdMobTest, TestInitializationStatus) {
252325
// Ensure Initialize()'s result matches GetInitializationStatus().
253326
auto initialize_future = firebase::admob::InitializeLastResult();
@@ -265,14 +338,6 @@ TEST_F(FirebaseAdMobTest, TestInitializationStatus) {
265338
adapter_status.second.description().c_str());
266339
}
267340

268-
#if defined(ANDROID)
269-
const char kAdMobClassName[] = "com.google.android.gms.ads.MobileAds";
270-
#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
271-
const char kAdMobClassName[] = "GADMobileAds";
272-
#else // desktop
273-
const char kAdMobClassName[] = "stub";
274-
#endif
275-
276341
// Confirm that the default Google Mobile Ads SDK class name shows up in the
277342
// list. It should either be is_initialized = true, or description should say
278343
// "Timeout" (this is a special case we are using to deflake this test on
@@ -287,6 +352,13 @@ TEST_F(FirebaseAdMobTest, TestInitializationStatus) {
287352
<< "Expected adapter class '" << kAdMobClassName << "' is not loaded.";
288353
}
289354

355+
TEST_F(FirebaseAdMobPreInitializationTests, TestDisableSDKCrashReporting) {
356+
// We can't test to see if this method successfully reconfigures crash
357+
// reporting, but we're still calling it as a sanity check and to ensure
358+
// the symbol exists in the library.
359+
firebase::admob::DisableSDKCrashReporting();
360+
}
361+
290362
TEST_F(FirebaseAdMobTest, TestGetAdRequest) { GetAdRequest(); }
291363

292364
TEST_F(FirebaseAdMobTest, TestGetAdRequestValues) {

admob/src/android/admob_android.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,10 @@ AdapterInitializationStatus GetInitializationStatus() {
374374
}
375375
}
376376

377+
void DisableSDKCrashReporting() {}
378+
379+
void DisableMediationInitialization() {}
380+
377381
void SetRequestConfiguration(
378382
const RequestConfiguration& request_configuration) {
379383
JNIEnv* env = ::firebase::admob::GetJNI();

admob/src/include/firebase/admob.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,24 @@ Future<AdapterInitializationStatus> InitializeLastResult();
117117
/// check which adapters have been initialized.
118118
AdapterInitializationStatus GetInitializationStatus();
119119

120+
/// Disables automated SDK crash reporting on iOS. If not called, the SDK
121+
/// records the original exception handler if available and registers a new
122+
/// exception handler. The new exception handler only reports SDK related
123+
/// exceptions and calls the recorded original exception handler.
124+
///
125+
/// This method has no effect on Android.
126+
void DisableSDKCrashReporting();
127+
128+
/// Disables mediation adapter initialization on iOS during initialization of
129+
/// the AdMob SDK. Calling this method may negatively impact your ad
130+
/// performance and should only be called if you will not use AdMob SDK
131+
/// controlled mediation during this app session. This method must be called
132+
/// before initializing the AdMob SDK or loading ads and has no effect once the
133+
/// SDK has been initialized.
134+
///
135+
/// This method has no effect on Android.
136+
void DisableMediationInitialization();
137+
120138
/// Sets the global @ref RequestConfiguration that will be used for
121139
/// every @ref AdRequest during the app's session.
122140
///

admob/src/ios/admob_ios.mm

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,14 @@ static AdapterInitializationStatus PopulateAdapterInitializationStatus(
126126

127127
bool IsInitialized() { return g_initialized; }
128128

129+
void DisableSDKCrashReporting() {
130+
[GADMobileAds.sharedInstance disableSDKCrashReporting];
131+
}
132+
133+
void DisableMediationInitialization() {
134+
[GADMobileAds.sharedInstance disableMediationInitialization];
135+
}
136+
129137
void SetRequestConfiguration(const RequestConfiguration& request_configuration)
130138
{
131139
GADMobileAds.sharedInstance.requestConfiguration.testDeviceIdentifiers =

admob/src/stub/admob_stub.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ AdapterInitializationStatus GetInitializationStatus() {
100100
}
101101
}
102102

103+
void DisableSDKCrashReporting() {}
104+
105+
void DisableMediationInitialization() {}
106+
103107
bool IsInitialized() { return g_initialized; }
104108

105109
void SetRequestConfiguration(

app/src/util_android.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -818,10 +818,10 @@ std::string JObjectClassName(JNIEnv* env, jobject obj);
818818
jobject StdVectorToJavaList(JNIEnv* env,
819819
const std::vector<std::string>& string_vector);
820820

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);
821+
// Converts a `std::unordered_set<std::string>` to a
822+
// `java.util.ArrayList<String>` Returns a local ref to a List.
823+
jobject StdUnorderedSetToJavaList(
824+
JNIEnv* env, const std::unordered_set<std::string>& string_set);
825825

826826
// Converts an `std::map<const char*, const char*>` to a
827827
// `java.util.Map<String, String>`.

app/src/util_ios.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@
1717
#ifndef FIREBASE_APP_SRC_UTIL_IOS_H_
1818
#define FIREBASE_APP_SRC_UTIL_IOS_H_
1919

20-
#ifdef __OBJC__
21-
22-
#import <Foundation/Foundation.h>
23-
#import <UIKit/UIKit.h>
24-
2520
#include <map>
2621
#include <string>
2722
#include <unordered_set>
2823
#include <vector>
2924

25+
#ifdef __OBJC__
26+
27+
#import <Foundation/Foundation.h>
28+
#import <UIKit/UIKit.h>
29+
3030
#include "app/src/include/firebase/variant.h"
3131

3232
namespace firebase {
@@ -200,8 +200,8 @@ NSMutableArray *StringUnorderedSetToNSMutableArray(
200200

201201
// Convert a NSArray into a vector of strings. Asserts if a non NSString
202202
// object is found in the array.
203-
void NSArrayOfNSStringToVectorOfString(
204-
NSArray *array, std::vector<std::string> *string_vector);
203+
void NSArrayOfNSStringToVectorOfString(NSArray *array,
204+
std::vector<std::string> *string_vector);
205205

206206
// Convert a string map to NSDictionary.
207207
NSDictionary *StringMapToNSDictionary(

app/src/util_ios.mm

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,15 @@ void ForEachAppDelegateClass(void (^block)(Class)) {
161161
return array;
162162
}
163163

164-
NSMutableArray *StringUnorderedSetToNSMutableArray(
165-
const std::unordered_set<std::string> &set) {
164+
NSMutableArray *StringUnorderedSetToNSMutableArray(const std::unordered_set<std::string> &set) {
166165
NSMutableArray<NSString *> *array = [[NSMutableArray alloc] initWithCapacity:set.size()];
167166
for (auto &element : set) {
168167
[array addObject:StringToNSString(element)];
169168
}
170169
return array;
171170
}
172171

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

0 commit comments

Comments
 (0)