Skip to content

Internal Updates #1595

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 9 commits into from
May 30, 2024
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
1 change: 1 addition & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ if (IOS)
${FIREBASE_SOURCE_DIR}/gma/src/include/firebase/gma/ad_view.h
${FIREBASE_SOURCE_DIR}/gma/src/include/firebase/gma/interstitial_ad.h
${FIREBASE_SOURCE_DIR}/gma/src/include/firebase/gma/internal/native_ad.h
${FIREBASE_SOURCE_DIR}/gma/src/include/firebase/gma/internal/query_info.h
${FIREBASE_SOURCE_DIR}/gma/src/include/firebase/gma/rewarded_ad.h
${FIREBASE_SOURCE_DIR}/gma/src/include/firebase/gma/types.h
${FIREBASE_SOURCE_DIR}/gma/src/include/firebase/gma/ump.h
Expand Down
4 changes: 4 additions & 0 deletions gma/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ set(common_SRCS
src/common/full_screen_ad_event_listener.cc
src/common/native_ad.cc
src/common/native_ad_internal.cc
src/common/query_info.cc
src/common/query_info_internal.cc
src/common/rewarded_ad.cc
src/common/rewarded_ad_internal.cc)

Expand All @@ -49,6 +51,7 @@ set(android_SRCS
src/android/interstitial_ad_internal_android.cc
src/android/native_ad_image_android.cc
src/android/native_ad_internal_android.cc
src/android/query_info_internal_android.cc
src/android/response_info_android.cc
src/android/rewarded_ad_internal_android.cc)

Expand All @@ -68,6 +71,7 @@ set(ios_SRCS
src/ios/interstitial_ad_internal_ios.mm
src/ios/native_ad_image_ios.mm
src/ios/native_ad_internal_ios.mm
src/ios/query_info_internal_ios.mm
src/ios/response_info_ios.mm
src/ios/rewarded_ad_internal_ios.mm)

Expand Down
66 changes: 66 additions & 0 deletions gma/integration_test/src/integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,72 @@ TEST_F(FirebaseGmaTest, TestNativeAdLoad) {
delete native_ad;
}

TEST_F(FirebaseGmaTest, TestCreateQueryInfo) {
SKIP_TEST_ON_DESKTOP;
SKIP_TEST_ON_SIMULATOR;

firebase::gma::QueryInfo* query_info = new firebase::gma::QueryInfo();

WaitForCompletion(query_info->Initialize(app_framework::GetWindowContext()),
"Initialize");

firebase::gma::AdRequest request = GetAdRequest();
// Set the requester type to 8. QueryInfo gets generated without a
// query_info_type set, but throws a warning that it is missing.
request.add_extra(kAdNetworkExtrasClassName, "query_info_type",
"requester_type_8");
// When the QueryInfo is initialized, generate a query info string.
firebase::Future<firebase::gma::QueryInfoResult> create_query_info_future =
query_info->CreateQueryInfo(firebase::gma::kAdFormatNative, request);

WaitForCompletion(create_query_info_future, "CreateQueryInfo");

if (create_query_info_future.error() == firebase::gma::kAdErrorCodeNone) {
const firebase::gma::QueryInfoResult* result_ptr =
create_query_info_future.result();
ASSERT_NE(result_ptr, nullptr);
EXPECT_TRUE(result_ptr->is_successful());
EXPECT_FALSE(result_ptr->query_info().empty());
}

create_query_info_future.Release();
delete query_info;
}

TEST_F(FirebaseGmaTest, TestCreateQueryInfoWithAdUnit) {
SKIP_TEST_ON_DESKTOP;
SKIP_TEST_ON_SIMULATOR;

firebase::gma::QueryInfo* query_info = new firebase::gma::QueryInfo();

WaitForCompletion(query_info->Initialize(app_framework::GetWindowContext()),
"Initialize");

firebase::gma::AdRequest request = GetAdRequest();
// Set the requester type to 8. QueryInfo gets generated without a
// query_info_type set, but throws a warning that it is missing.
request.add_extra(kAdNetworkExtrasClassName, "query_info_type",
"requester_type_8");
// When the QueryInfo is initialized, generate a query info string.
// Providing a bad/empty ad unit does not affect the query info generation.
firebase::Future<firebase::gma::QueryInfoResult> create_query_info_future =
query_info->CreateQueryInfoWithAdUnit(firebase::gma::kAdFormatNative,
request, kNativeAdUnit);

WaitForCompletion(create_query_info_future, "CreateQueryInfoWithAdUnit");

if (create_query_info_future.error() == firebase::gma::kAdErrorCodeNone) {
const firebase::gma::QueryInfoResult* result_ptr =
create_query_info_future.result();
ASSERT_NE(result_ptr, nullptr);
EXPECT_TRUE(result_ptr->is_successful());
EXPECT_FALSE(result_ptr->query_info().empty());
}

create_query_info_future.Release();
delete query_info;
}

// Interactive test section. These have been placed up front so that the
// tester doesn't get bored waiting for them.
TEST_F(FirebaseGmaUITest, TestAdViewAdOpenedAdClosed) {
Expand Down
45 changes: 45 additions & 0 deletions gma/src/android/gma_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "gma/src/android/interstitial_ad_internal_android.h"
#include "gma/src/android/native_ad_image_android.h"
#include "gma/src/android/native_ad_internal_android.h"
#include "gma/src/android/query_info_internal_android.h"
#include "gma/src/android/response_info_android.h"
#include "gma/src/android/rewarded_ad_internal_android.h"
#include "gma/src/common/gma_common.h"
Expand Down Expand Up @@ -363,6 +364,9 @@ Future<AdapterInitializationStatus> Initialize(JNIEnv* env, jobject activity,
download_helper::CacheClassFromFiles(env, activity, &embedded_files) !=
nullptr &&
download_helper::CacheMethodIds(env, activity) &&
query_info_helper::CacheClassFromFiles(env, activity,
&embedded_files) != nullptr &&
query_info_helper::CacheMethodIds(env, activity) &&
rewarded_ad_helper::CacheClassFromFiles(env, activity,
&embedded_files) != nullptr &&
rewarded_ad_helper::CacheMethodIds(env, activity) &&
Expand Down Expand Up @@ -705,6 +709,7 @@ void ReleaseClasses(JNIEnv* env) {
native_ad_helper::ReleaseClass(env);
native_image::ReleaseClass(env);
download_helper::ReleaseClass(env);
query_info_helper::ReleaseClass(env);
rewarded_ad_helper::ReleaseClass(env);
load_ad_error::ReleaseClass(env);
}
Expand Down Expand Up @@ -917,6 +922,35 @@ void JNI_completeLoadedAd(JNIEnv* env, jclass clazz, jlong data_ptr,
env->DeleteLocalRef(j_response_info);
}

void JNI_completeCreateQueryInfoSuccess(JNIEnv* env, jclass clazz,
jlong data_ptr, jstring j_query_info) {
FIREBASE_ASSERT(env);
FIREBASE_ASSERT(data_ptr);
FIREBASE_ASSERT(j_query_info);

std::string query_info = util::JStringToString(env, j_query_info);
FutureCallbackData<QueryInfoResult>* callback_data =
reinterpret_cast<FutureCallbackData<QueryInfoResult>*>(data_ptr);
GmaInternal::CompleteCreateQueryInfoFutureSuccess(callback_data, query_info);
env->DeleteLocalRef(j_query_info);
}

void JNI_completeQueryInfoError(JNIEnv* env, jclass clazz, jlong data_ptr,
jint j_error_code, jstring j_error_message) {
FIREBASE_ASSERT(env);
FIREBASE_ASSERT(data_ptr);
FIREBASE_ASSERT(j_error_message);

// QueryInfo errors return only internal AdErrorCode values.
const AdErrorCode error_code = static_cast<AdErrorCode>(j_error_code);
std::string error_message = util::JStringToString(env, j_error_message);

FutureCallbackData<QueryInfoResult>* callback_data =
reinterpret_cast<FutureCallbackData<QueryInfoResult>*>(data_ptr);
GmaInternal::CompleteCreateQueryInfoFutureFailure(callback_data, error_code,
error_message);
}

void JNI_NativeAd_completeLoadedAd(JNIEnv* env, jclass clazz, jlong data_ptr,
jlong native_internal_data_ptr,
jobject j_icon, jobjectArray j_images,
Expand Down Expand Up @@ -1307,6 +1341,15 @@ bool RegisterNatives() {
reinterpret_cast<void*>(&JNI_NativeAd_notifyAdOpened)},
};

static const JNINativeMethod kQueryInfoMethods[] = {
{"completeQueryInfoFutureCallback", "(JILjava/lang/String;)V",
reinterpret_cast<void*>(&JNI_completeAdFutureCallback)},
{"completeCreateQueryInfoSuccess", "(JLjava/lang/String;)V",
reinterpret_cast<void*>(&JNI_completeCreateQueryInfoSuccess)},
{"completeCreateQueryInfoError", "(JILjava/lang/String;)V",
reinterpret_cast<void*>(&JNI_completeQueryInfoError)},
};

static const JNINativeMethod kNativeImageMethods[] = {
{"completeNativeImageFutureCallback", "(JILjava/lang/String;)V",
reinterpret_cast<void*>(&JNI_completeAdFutureCallback)},
Expand Down Expand Up @@ -1370,6 +1413,8 @@ bool RegisterNatives() {
download_helper::RegisterNatives(
env, kNativeImageMethods,
FIREBASE_ARRAYSIZE(kNativeImageMethods)) &&
query_info_helper::RegisterNatives(
env, kQueryInfoMethods, FIREBASE_ARRAYSIZE(kQueryInfoMethods)) &&
rewarded_ad_helper::RegisterNatives(
env, kRewardedAdMethods, FIREBASE_ARRAYSIZE(kRewardedAdMethods)) &&
gma_initialization_helper::RegisterNatives(
Expand Down
192 changes: 192 additions & 0 deletions gma/src/android/query_info_internal_android.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "gma/src/android/query_info_internal_android.h"

#include <assert.h>
#include <jni.h>

#include <cstdarg>
#include <cstddef>

#include "app/src/assert.h"
#include "app/src/util_android.h"
#include "gma/src/android/ad_request_converter.h"
#include "gma/src/android/gma_android.h"
#include "gma/src/common/gma_common.h"
#include "gma/src/include/firebase/gma.h"
#include "gma/src/include/firebase/gma/internal/query_info.h"
#include "gma/src/include/firebase/gma/types.h"

namespace firebase {
namespace gma {

METHOD_LOOKUP_DEFINITION(query_info_helper,
"com/google/firebase/gma/internal/cpp/QueryInfoHelper",
QUERYINFOHELPER_METHODS);

namespace internal {

QueryInfoInternalAndroid::QueryInfoInternalAndroid(QueryInfo* base)
: QueryInfoInternal(base), helper_(nullptr), initialized_(false) {
firebase::MutexLock lock(mutex_);
JNIEnv* env = ::firebase::gma::GetJNI();
jobject helper_ref = env->NewObject(
query_info_helper::GetClass(),
query_info_helper::GetMethodId(query_info_helper::kConstructor),
reinterpret_cast<jlong>(this));
util::CheckAndClearJniExceptions(env);

FIREBASE_ASSERT(helper_ref);
helper_ = env->NewGlobalRef(helper_ref);
FIREBASE_ASSERT(helper_);
env->DeleteLocalRef(helper_ref);
}

QueryInfoInternalAndroid::~QueryInfoInternalAndroid() {
firebase::MutexLock lock(mutex_);
JNIEnv* env = ::firebase::gma::GetJNI();

env->CallVoidMethod(
helper_, query_info_helper::GetMethodId(query_info_helper::kDisconnect));
util::CheckAndClearJniExceptions(env);
env->DeleteGlobalRef(helper_);
helper_ = nullptr;
}

Future<void> QueryInfoInternalAndroid::Initialize(AdParent parent) {
firebase::MutexLock lock(mutex_);

if (initialized_) {
const SafeFutureHandle<void> future_handle =
future_data_.future_impl.SafeAlloc<void>(kQueryInfoFnInitialize);
Future<void> future = MakeFuture(&future_data_.future_impl, future_handle);
CompleteFuture(kAdErrorCodeAlreadyInitialized,
kAdAlreadyInitializedErrorMessage, future_handle,
&future_data_);
return future;
}

initialized_ = true;
JNIEnv* env = ::firebase::gma::GetJNI();
FIREBASE_ASSERT(env);

FutureCallbackData<void>* callback_data =
CreateVoidFutureCallbackData(kQueryInfoFnInitialize, &future_data_);
Future<void> future =
MakeFuture(&future_data_.future_impl, callback_data->future_handle);
env->CallVoidMethod(
helper_, query_info_helper::GetMethodId(query_info_helper::kInitialize),
reinterpret_cast<jlong>(callback_data), parent);
util::CheckAndClearJniExceptions(env);
return future;
}

Future<QueryInfoResult> QueryInfoInternalAndroid::CreateQueryInfo(
AdFormat format, const AdRequest& request) {
firebase::MutexLock lock(mutex_);

if (!initialized_) {
SafeFutureHandle<QueryInfoResult> future_handle =
CreateFuture<QueryInfoResult>(kQueryInfoFnCreateQueryInfo,
&future_data_);
Future<QueryInfoResult> future =
MakeFuture(&future_data_.future_impl, future_handle);
CompleteFuture(kAdErrorCodeUninitialized, kAdUninitializedErrorMessage,
future_handle, &future_data_, QueryInfoResult());
return future;
}

gma::AdErrorCode error = kAdErrorCodeNone;
jobject j_request = GetJavaAdRequestFromCPPAdRequest(request, &error);
if (j_request == nullptr) {
if (error == kAdErrorCodeNone) {
error = kAdErrorCodeInternalError;
}
return CreateAndCompleteFutureWithQueryInfoResult(
kQueryInfoFnCreateQueryInfo, error,
kAdCouldNotParseAdRequestErrorMessage, &future_data_,
QueryInfoResult());
}
JNIEnv* env = GetJNI();
FIREBASE_ASSERT(env);
FutureCallbackData<QueryInfoResult>* callback_data =
CreateQueryInfoResultFutureCallbackData(kQueryInfoFnCreateQueryInfo,
&future_data_);
Future<QueryInfoResult> future =
MakeFuture(&future_data_.future_impl, callback_data->future_handle);

jstring j_ad_unit_str = env->NewStringUTF("");
::firebase::gma::GetJNI()->CallVoidMethod(
helper_,
query_info_helper::GetMethodId(query_info_helper::kCreateQueryInfo),
reinterpret_cast<jlong>(callback_data), static_cast<int>(format),
j_ad_unit_str, j_request);
util::CheckAndClearJniExceptions(env);
env->DeleteLocalRef(j_ad_unit_str);
env->DeleteLocalRef(j_request);
return future;
}

Future<QueryInfoResult> QueryInfoInternalAndroid::CreateQueryInfoWithAdUnit(
AdFormat format, const AdRequest& request, const char* ad_unit_id) {
firebase::MutexLock lock(mutex_);

if (!initialized_) {
SafeFutureHandle<QueryInfoResult> future_handle =
CreateFuture<QueryInfoResult>(kQueryInfoFnCreateQueryInfoWithAdUnit,
&future_data_);
Future<QueryInfoResult> future =
MakeFuture(&future_data_.future_impl, future_handle);
CompleteFuture(kAdErrorCodeUninitialized, kAdUninitializedErrorMessage,
future_handle, &future_data_, QueryInfoResult());
return future;
}

gma::AdErrorCode error = kAdErrorCodeNone;
jobject j_request = GetJavaAdRequestFromCPPAdRequest(request, &error);
if (j_request == nullptr) {
if (error == kAdErrorCodeNone) {
error = kAdErrorCodeInternalError;
}
return CreateAndCompleteFutureWithQueryInfoResult(
kQueryInfoFnCreateQueryInfoWithAdUnit, error,
kAdCouldNotParseAdRequestErrorMessage, &future_data_,
QueryInfoResult());
}
JNIEnv* env = GetJNI();
FIREBASE_ASSERT(env);
FutureCallbackData<QueryInfoResult>* callback_data =
CreateQueryInfoResultFutureCallbackData(
kQueryInfoFnCreateQueryInfoWithAdUnit, &future_data_);
Future<QueryInfoResult> future =
MakeFuture(&future_data_.future_impl, callback_data->future_handle);

jstring j_ad_unit_str = env->NewStringUTF(ad_unit_id);
::firebase::gma::GetJNI()->CallVoidMethod(
helper_,
query_info_helper::GetMethodId(query_info_helper::kCreateQueryInfo),
reinterpret_cast<jlong>(callback_data), static_cast<int>(format),
j_ad_unit_str, j_request);
util::CheckAndClearJniExceptions(env);
env->DeleteLocalRef(j_ad_unit_str);
env->DeleteLocalRef(j_request);
return future;
}

} // namespace internal
} // namespace gma
} // namespace firebase
Loading
Loading