Skip to content

RewardedAds for Android #741

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 12 commits into from
Nov 16, 2021

Conversation

DellaBitta
Copy link
Contributor

@DellaBitta DellaBitta commented Nov 9, 2021

Description

Provide details of the change, and generalize the change in the PR title above.

  • Implemented RewardedAd on Android, and created stubs for iOS and Desktop builds.
  • Revamped C++ JNI function signatures to have much shorter names, and to reuse functions common to interstitial and rewarded ads.
  • Created a new internal base class for full screen event listeners to share its implementation across RewardedAds and InsterstitialAds. This allows us to reuse some JNI callback functions.
  • Grouped those integration tests which require user interaction so that they execute one after the next, and front load them to the start of the itest flow (after a few quick sanity checks). This should make running the manual tests easier.

Testing

iTest Run
Expanded AdMob integration tests.
Executed tests manually on Android phones.
Validated (via logs) that the SetServerSideVerificationOption strings are properly reaching the Android SDK space.


Type of Change

Place an x the applicable box:

  • Bug fix. Add the issue # below if applicable.
  • New feature. A non-breaking change which adds functionality.
  • Other, such as a build process or documentation change.

@@ -489,6 +506,229 @@ TEST_F(FirebaseAdMobTest, TestRequestConfigurationSetGet) {
retrieved_configuration.test_device_ids.end(), "3"));
}

// Simple Load Tests as a sanity check. These don't show the ad, just
Copy link
Contributor Author

@DellaBitta DellaBitta Nov 9, 2021

Choose a reason for hiding this comment

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

Moved some BannerView and Interstitial tests around. Will call out the new tests via comments below so that you need not waste your time reviewing unchanged tests.

delete interstitial;
}

TEST_F(FirebaseAdMobTest, TestRewardedAdLoad) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

New test.

delete interstitial;
}

TEST_F(FirebaseAdMobTest, TestRewardedAdLoadAndShow) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

New test.

@@ -1148,6 +1214,200 @@ TEST_F(FirebaseAdMobTest, TestInterstitialAdErrorBadExtrasClassName) {
delete interstitial_ad;
}

// Other RewardedAd Tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

New tests from here downwards.

@DellaBitta DellaBitta changed the title Android builds and runs. Desktop and iOS stubs. RewardedAds for Android Nov 9, 2021
@@ -53,61 +50,6 @@ InterstitialAdInternal* InterstitialAdInternal::CreateInstance(
// FIREBASE_PLATFORM_TVOS
}

void InterstitialAdInternal::SetFullScreenContentListener(
Copy link
Contributor Author

@DellaBitta DellaBitta Nov 9, 2021

Choose a reason for hiding this comment

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

Moved to a new internal full screen event listener base class which is shared with RewardedAds. This allows us to cast the nativepointer to a listener base class in the JNI callbacks, coalescing the two different JNI callback method sets into one.

@@ -0,0 +1,70 @@
/*
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Stub implementation for now.

@DellaBitta DellaBitta marked this pull request as ready for review November 10, 2021 16:50
TestUserEarnedRewardListener user_earned_reward_listener;
WaitForCompletion(rewarded->Show(&user_earned_reward_listener), "Show");

LogDebug(
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you get credit for the ad even if you just watch it through, you don't have to install the thing.

Copy link
Contributor Author

@DellaBitta DellaBitta Nov 15, 2021

Choose a reason for hiding this comment

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

While you get the reward the ad doesn't produce the ad clicked event that we're also looking for.

Clicking Install just brings you to the app store. I'll update the comment that you don't actually have to go through with the installation of the app, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

// Stress tests. These take a while so run them near the end.
TEST_F(FirebaseAdMobTest, TestBannerViewStress) {
// AdMob cannot be tested on Firebase Test Lab, so disable tests on FTL.
TEST_REQUIRES_USER_INTERACTION;
Copy link
Contributor

Choose a reason for hiding this comment

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

AdMob cannot be tested on Firebase Test Lab, so disable tests on FTL.

What's the deal with this?

Also, even if we can't run this test on FTL, it would be better here to just ensure that you are specifically not running on FTL - the automated tests should still run on simulator, no?

Let's talk to @sunmou99 about seeing if there's a way to add a SKIP_TEST_ON_FIREBASE_TEST_LAB macro.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've enabled this test successfully in testing another PR, so I'll just remove it here.

I think that this TEST_REQUIRES_USER_INTERACTION was originally for the main BannerView tests that required you to click things but I was confused by the comment that was there, which seems to make it sound like the tests don't run at all. I hadn't tested this until recentlly and it works fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

}

extern "C" JNIEXPORT void JNICALL
Java_com_google_firebase_admob_internal_cpp_InterstitialAdHelper_notifyAdImpressionEvent( // NOLINT
extern "C" JNIEXPORT void JNICALL JNI_notifyAdImpressionEvent(JNIEnv* env,
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe you don't need any of the "extern "C" JNIEXPORT JNICALL stuff since we are registering natives directly - also it would probably be best to put these in an unnamed namespace. (along with the one I added!)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

void FullScreenAdEventListener::NotifyListenerOfAdClickedFullScreenContent() {
MutexLock lock(listener_mutex_);
if (full_screen_content_listener_ != nullptr) {
full_screen_content_listener_->OnAdClicked();
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a question: is it safe to keep the mutex locked the whole time the user's callback is running? This could potentially be a long time. Typically if there's any way to avoid locking a mutex while a user callback runs we try not to lock it. Not really sure how you'd safely do this here though, to avoid the listener itself being deleted, so maybe never mind,.

Copy link
Contributor Author

@DellaBitta DellaBitta Nov 15, 2021

Choose a reason for hiding this comment

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

Yes, I see your point.

I feel like tackling it this way: If this mutex lock is a problem then we'll have safe customer reports saying that it's in their way. But if we take the mutex out there, then we could have crazy crash reports due to corrupted memory somewhere later in the runtime. For now I'd like to play it safe and open up to dangers later, but only if we need to. WDYT?

internal_ = internal::RewardedAdInternal::CreateInstance(this);

GetOrCreateCleanupNotifier()->RegisterObject(this, [](void* object) {
FIREBASE_ASSERT_MESSAGE(
Copy link
Contributor

Choose a reason for hiding this comment

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

The idea of CleanupNotifier is to invalidate the objects and WARN the user they did the wrong thing, not assert.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted. This was from the older implementation. Will fix it in banner and interstitial, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

private RewardedAd mRewarded;

// Synchronization object for thread safe access to:
// * mRewarded
Copy link
Contributor

Choose a reason for hiding this comment

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

It doesn't actually seem to be locking when mRewarded is used, is this because mRewarded is only ever used in the UI thread? If so you can mention that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding it for other operations...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@@ -937,6 +937,9 @@ TEST_F(FirebaseAdMobTest, TestBannerView) {
bounding_box_listener.bounding_box_changes_.size());

#if defined(ANDROID) || TARGET_OS_IPHONE
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of disabling this test, is it possible to just add some wiggle room to the aspect ratio check on simulator?

@DellaBitta DellaBitta merged commit d852f3c into feature/admob_2021 Nov 16, 2021
@DellaBitta DellaBitta deleted the feature/admob_2021_android_rewardedad branch November 16, 2021 18:18
@github-actions github-actions bot added the tests: in-progress This PR's integration tests are in progress. label Nov 16, 2021
@github-actions
Copy link

github-actions bot commented Nov 16, 2021

❌  Integration test FAILED

Requested by @DellaBitta on commit d852f3c
Last updated: Tue Nov 16 12:51 PST 2021
View integration test log & download artifacts

Failures Configs
messaging [TEST] [ERROR] [Android] [All os] [android_target]
storage [TEST] [FAILURE] [iOS] [macos] [simulator_target]
(1 failed tests)  FirebaseStorageTest.TestLargeFilePauseResumeAndDownloadCancel

Add flaky tests to go/fpl-cpp-flake-tracker

@github-actions github-actions bot added the tests: failed This PR's integration tests failed. label Nov 16, 2021
@firebase-workflow-trigger firebase-workflow-trigger bot removed the tests: in-progress This PR's integration tests are in progress. label Nov 16, 2021
@firebase firebase locked and limited conversation to collaborators Dec 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla: yes tests: failed This PR's integration tests failed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants