diff --git a/.github/workflows/cpp-packaging.yml b/.github/workflows/cpp-packaging.yml index d31257572a..585e8f591c 100644 --- a/.github/workflows/cpp-packaging.yml +++ b/.github/workflows/cpp-packaging.yml @@ -889,7 +889,7 @@ jobs: -w integration_tests.yml \ -p test_packaged_sdk ${{ github.run_id }} \ -p use_expanded_matrix ${USE_EXPANDED_MATRIX} \ - -p apis "analytics,app_check,auth,database,dynamic_links,functions,installations,messaging,remote_config,storage" \ + -p apis "analytics,app_check,auth,database,functions,installations,messaging,remote_config,storage" \ -p test_pull_request nightly-packaging \ -s 10 \ -A ${verbose_flag} diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 05c93a6188..e5ecd08909 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -17,7 +17,7 @@ on: required: true apis: description: 'CSV of apis to build and test' - default: 'analytics,app_check,auth,database,dynamic_links,firestore,functions,gma,installations,messaging,remote_config,storage,ump' + default: 'analytics,app_check,auth,database,firestore,functions,gma,installations,messaging,remote_config,storage,ump' required: true operating_systems: description: 'CSV of VMs to run on' @@ -186,7 +186,7 @@ jobs: # list. Then we can use fromJson to define the field in the matrix for the tests job. if [[ "${{ github.event.schedule }}" == "0 9 * * *" ]]; then # at 1am PST/2am PDT. Running integration tests and generate test report for all testapps except firestore - apis="analytics,app_check,auth,database,dynamic_links,functions,gma,installations,messaging,remote_config,storage,ump" + apis="analytics,app_check,auth,database,functions,gma,installations,messaging,remote_config,storage,ump" echo "::warning ::Running main nightly tests" elif [[ "${{ github.event.schedule }}" == "0 10 * * *" || "${{ github.event.schedule }}" == "0 11 * * *" ]]; then # at 2am PST/3am PDT and 3am PST/4am PDT. Running integration tests for firestore and generate test report. diff --git a/Android/firebase_dependencies.gradle b/Android/firebase_dependencies.gradle index 94b39ec52c..6b84ec465f 100644 --- a/Android/firebase_dependencies.gradle +++ b/Android/firebase_dependencies.gradle @@ -24,7 +24,6 @@ def firebaseDependenciesMap = [ 'analytics' : ['com.google.firebase:firebase-analytics'], 'auth' : ['com.google.firebase:firebase-auth'], 'database' : ['com.google.firebase:firebase-database'], - 'dynamic_links' : ['com.google.firebase:firebase-dynamic-links'], 'firestore' : ['com.google.firebase:firebase-firestore'], 'functions' : ['com.google.firebase:firebase-functions'], 'gma' : ['com.google.android.gms:play-services-ads:23.0.0', @@ -46,8 +45,7 @@ def firebaseDependenciesMap = [ // A map of library to the gradle resources that they depend upon. def firebaseResourceDependenciesMap = [ 'app' : [':app:app_resources', - ':app:google_api_resources', - ':app:invites_resources'], + ':app:google_api_resources'], 'app_check' : [':app_check:app_check_resources'], 'auth' : [':auth:auth_resources'], 'database' : [':database:database_resources'], @@ -88,9 +86,6 @@ class Dependencies { def getDatabase() { libSet.add('database') } - def getDynamicLinks() { - libSet.add('dynamic_links') - } def getFirestore() { libSet.add('firestore') } @@ -103,9 +98,6 @@ class Dependencies { def getInstallations() { libSet.add('installations') } - def getInvites() { - libSet.add('invites') - } def getMessaging() { libSet.add('messaging') } diff --git a/CMakeLists.txt b/CMakeLists.txt index aea6d80a34..1abb1b84ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,9 +39,6 @@ option(FIREBASE_INCLUDE_AUTH "Include the Firebase Authentication library." option(FIREBASE_INCLUDE_DATABASE "Include the Firebase Realtime Database library." ${FIREBASE_INCLUDE_LIBRARY_DEFAULT}) -option(FIREBASE_INCLUDE_DYNAMIC_LINKS - "Include the Firebase Dynamic Links library." - ${FIREBASE_INCLUDE_LIBRARY_DEFAULT}) option(FIREBASE_INCLUDE_FIRESTORE "Include the Cloud Firestore library." ${FIREBASE_INCLUDE_LIBRARY_DEFAULT}) @@ -125,8 +122,7 @@ if(FIREBASE_CPP_BUILD_TESTS OR FIREBASE_CPP_BUILD_STUB_TESTS) endif() if (PLATFORM STREQUAL TVOS OR PLATFORM STREQUAL SIMULATOR_TVOS) - # GMA, UMP, and FDL are not supported on tvOS. - set(FIREBASE_INCLUDE_DYNAMIC_LINKS OFF) + # GMA and UMP are not supported on tvOS. set(FIREBASE_INCLUDE_GMA OFF) set(FIREBASE_INCLUDE_UMP OFF) endif() @@ -625,9 +621,6 @@ endif() if (FIREBASE_INCLUDE_DATABASE) add_subdirectory(database) endif() -if (FIREBASE_INCLUDE_DYNAMIC_LINKS) - add_subdirectory(dynamic_links) -endif() if (FIREBASE_INCLUDE_FIRESTORE) add_subdirectory(firestore) add_dependencies(FIREBASE_GENERATED_HEADERS FIREBASE_FIRESTORE_GENERATED_HEADERS) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 9b2d0b333a..88ebe23674 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -33,13 +33,6 @@ binary_to_array("google_api_resources" "${CMAKE_CURRENT_LIST_DIR}/google_api_resources/build/google_api_resources_lib.jar" "google_api" "${FIREBASE_GEN_FILE_DIR}/app") -firebase_cpp_gradle(":app:invites_resources:generateDexJarRelease" - "${CMAKE_CURRENT_LIST_DIR}/invites_resources/build/invites_resources_lib.jar") -binary_to_array("invites_resources" - "${CMAKE_CURRENT_LIST_DIR}/invites_resources/build/invites_resources_lib.jar" - "firebase_invites" - "${FIREBASE_GEN_FILE_DIR}/app") - # Generate version.h set(version_header_dir ${FIREBASE_GEN_FILE_DIR}/app/src/include/firebase) set(version_header ${version_header_dir}/version.h) @@ -142,32 +135,21 @@ else() set(mutex_SRCS src/mutex_pthread.cc) endif() -set(invites_SRCS - src/invites/cached_receiver.cc - src/invites/invites_receiver_internal.cc) - set(app_android_SRCS src/app_android.cc src/google_play_services/availability_android.cc ${app_resources_source} ${google_api_resources_source} - ${invites_resources_source} - src/invites/android/invites_receiver_internal_android.cc - src/invites/android/invites_android_helper.cc src/uuid.cc) set(app_ios_SRCS src/app_ios.mm src/util_apple.mm src/util_ios.mm - src/invites/ios/invites_receiver_internal_ios.mm - src/invites/ios/invites_ios_startup.mm src/uuid_ios_darwin.mm) if (PLATFORM STREQUAL TVOS OR PLATFORM STREQUAL SIMULATOR_TVOS) # TVOS does not have a web browser and does not support dynamic links. # Remove these files if we are building for TVOS. - list(REMOVE_ITEM app_ios_SRCS - src/invites/ios/invites_receiver_internal_ios.mm - src/invites/ios/invites_ios_startup.mm) + # list(REMOVE_ITEM app_ios_SRCS) # No items to remove anymore endif() @@ -195,7 +177,6 @@ build_flatbuffers("${desktop_flatbuffers_schemas}" set(app_desktop_SRCS src/app_desktop.cc - src/invites/stub/invites_receiver_internal_stub.cc src/variant_util.cc src/heartbeat/date_provider.cc src/heartbeat/heartbeat_storage_desktop.cc @@ -286,11 +267,7 @@ set(utility_common_HDRS set(utility_android_HDRS) set(utility_ios_HDRS) set(utility_desktop_HDRS - src/variant_util.h - src/invites/cached_receiver.h - src/invites/invites_receiver_internal.h - src/invites/receiver_interface.h - src/invites/sender_receiver_interface.h) + src/variant_util.h) if(ANDROID) set(utility_HDRS "${utility_common_HDRS}" @@ -307,15 +284,10 @@ endif() set(app_android_HDRS ${app_resources_header} - ${google_api_resources_header} - ${invites_resources_header} - src/invites/android/invites_android_helper.h - src/invites/android/invites_receiver_internal_android.h) + ${google_api_resources_header}) set(app_ios_HDRS - src/app_ios.h - src/invites/ios/invites_receiver_internal_ios.h) -set(app_desktop_HDRS - src/invites/stub/invites_receiver_internal_stub.h) + src/app_ios.h) +set(app_desktop_HDRS) if(ANDROID) set(app_platform_HDRS "${app_android_HDRS}") @@ -344,7 +316,6 @@ add_library(firebase_app STATIC ${log_SRCS} ${log_HDRS} ${common_SRCS} - ${invites_SRCS} ${mutex_SRCS} ${app_platform_SRCS} ${internal_HDRS} @@ -419,7 +390,6 @@ elseif(IOS) POD_NAMES . FirebaseCore - FirebaseDynamicLinks FirebaseInstanceID ) else() @@ -504,9 +474,6 @@ if (IOS) ${FIREBASE_SOURCE_DIR}/database/src/include/firebase/database/mutable_data.h ${FIREBASE_SOURCE_DIR}/database/src/include/firebase/database/query.h ${FIREBASE_SOURCE_DIR}/database/src/include/firebase/database/transaction.h) - set(dynamic_links_HDRS - ${FIREBASE_SOURCE_DIR}/dynamic_links/src/include/firebase/dynamic_links.h - ${FIREBASE_SOURCE_DIR}/dynamic_links/src/include/firebase/dynamic_links/components.h) set(firestore_HDRS ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore.h ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/aggregate_query.h @@ -577,7 +544,6 @@ if (IOS) ${app_check_HDRS} ${auth_HDRS} ${database_HDRS} - ${dynamic_links_HDRS} ${firestore_HDRS} ${functions_HDRS} ${gma_HDRS} diff --git a/app/invites_resources/build.gradle b/app/invites_resources/build.gradle deleted file mode 100644 index 31f6d284b2..0000000000 --- a/app/invites_resources/build.gradle +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2018 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. - -buildscript { - repositories { - google() - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - classpath 'com.google.gms:google-services:4.4.1' - } -} -allprojects { - repositories { - google() - mavenCentral() - } -} - -apply plugin: 'com.android.library' - -android { - compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 - } - compileSdkVersion 34 - buildToolsVersion '32.0.0' - - defaultConfig { - minSdkVersion 23 - targetSdkVersion 34 - } - - sourceSets { - main { - manifest.srcFile '../../android_build_files/AndroidManifest.xml' - java { - srcDirs = ['../src_java/com/google/firebase/dynamiclinks/internal/cpp'] - } - } - } -} - -dependencies { - implementation platform('com.google.firebase:firebase-bom:33.15.0') - implementation 'com.google.firebase:firebase-analytics' - implementation 'com.google.firebase:firebase-dynamic-links' - implementation project(':app:app_resources') -} - -afterEvaluate { - generateReleaseBuildConfig.enabled = false - project.tasks.withType(com.android.build.gradle.internal.tasks.CheckAarMetadataTask) { - enabled = false - } -} - -apply from: "$rootDir/android_build_files/extract_and_dex.gradle" -extractAndDexAarFile('invites_resources') diff --git a/app/src/invites/android/invites_android_helper.cc b/app/src/invites/android/invites_android_helper.cc deleted file mode 100644 index 6efb26e941..0000000000 --- a/app/src/invites/android/invites_android_helper.cc +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2017 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 "app/src/invites/android/invites_android_helper.h" - -#include -#include - -#include "app/invites_resources.h" -#include "app/src/embedded_file.h" -#include "app/src/include/firebase/internal/common.h" -#include "app/src/invites/receiver_interface.h" -#include "app/src/invites/sender_receiver_interface.h" -#include "app/src/log.h" -#include "app/src/util_android.h" - -namespace firebase { -namespace invites { -namespace internal { - -Mutex AndroidHelper::init_mutex_; // NOLINT -int AndroidHelper::initialize_count_ = 0; - -METHOD_LOOKUP_DEFINITION( - dynamic_links_native_wrapper, - "com/google/firebase/dynamiclinks/internal/cpp/DynamicLinksNativeWrapper", - DYNAMIC_LINKS_NATIVE_WRAPPER_METHODS) - -extern "C" { - -JNIEXPORT void JNICALL -Java_com_google_firebase_dynamiclinks_internal_cpp_DynamicLinksNativeWrapper_receivedDynamicLinkCallback( - JNIEnv* env, jclass clazz, jlong data_ptr, jstring deep_link_url_java, - jint result, jstring error_string_java); - -} // extern "C" - -AndroidHelper::AndroidHelper(const ::firebase::App& app, - SenderReceiverInterface* sender_receiver) - : app_(&app), wrapper_obj_(nullptr) { - { - MutexLock init_lock(init_mutex_); - if (initialize_count_ == 0) { - JNIEnv* env = app_->GetJNIEnv(); - if (!util::Initialize(env, app.activity())) { - app_ = nullptr; - return; - } - - static const JNINativeMethod kNativeMethods[] = { - {"receivedDynamicLinkCallback", - "(JLjava/lang/String;ILjava/lang/String;)V", - reinterpret_cast( - &Java_com_google_firebase_dynamiclinks_internal_cpp_DynamicLinksNativeWrapper_receivedDynamicLinkCallback)} // NOLINT - }; - const std::vector embedded_files = - util::CacheEmbeddedFiles( - env, app_->activity(), - firebase::internal::EmbeddedFile::ToVector( - firebase_invites::invites_resources_filename, - firebase_invites::invites_resources_data, - firebase_invites::invites_resources_size)); - if (!(dynamic_links_native_wrapper::CacheClassFromFiles( - env, app_->activity(), &embedded_files) && - // Prepare to instantiate the DynamicLinksNativeWrapper Java class, - // which we will use to talk to the Firebase Dynamic Links Java - // library. Note that we need global references to everything - // because, again, we may be running from different threads. - dynamic_links_native_wrapper::CacheMethodIds(env, - app_->activity()) && - dynamic_links_native_wrapper::RegisterNatives( - env, kNativeMethods, FIREBASE_ARRAYSIZE(kNativeMethods)))) { - util::Terminate(env); - app_ = nullptr; - return; - } - } - initialize_count_++; - } - // Actually create the DynamicLinksNativeWrapper object now. - CreateWrapperObject(sender_receiver); -} - -AndroidHelper::~AndroidHelper() { - // If initialization failed there is nothing to clean up. - if (app_ == nullptr) return; - - // Ensure that no further JNI callbacks refer to deleted instances. - CallMethod(dynamic_links_native_wrapper::kDiscardNativePointer); - - JNIEnv* env = app_->GetJNIEnv(); - env->DeleteGlobalRef(wrapper_obj_); - wrapper_obj_ = nullptr; - { - MutexLock init_lock(init_mutex_); - assert(initialize_count_ > 0); - initialize_count_--; - if (initialize_count_ == 0) { - util::Terminate(env); - dynamic_links_native_wrapper::ReleaseClass(env); - } - } - app_ = nullptr; -} - -void AndroidHelper::CreateWrapperObject( - SenderReceiverInterface* sender_receiver) { - JNIEnv* env = app_->GetJNIEnv(); - jobject obj = env->NewObject(dynamic_links_native_wrapper::g_class, - dynamic_links_native_wrapper::GetMethodId( - dynamic_links_native_wrapper::kConstructor), - reinterpret_cast(sender_receiver), - app_->activity(), nullptr); - CheckJNIException(); - wrapper_obj_ = env->NewGlobalRef(obj); - env->DeleteLocalRef(obj); -} - -bool AndroidHelper::CallBooleanMethod( - dynamic_links_native_wrapper::Method method) { - JNIEnv* env = app_->GetJNIEnv(); - jboolean result = env->CallBooleanMethod( - wrapper_obj(), dynamic_links_native_wrapper::GetMethodId(method)); - CheckJNIException(); - return (result != JNI_FALSE); -} - -bool AndroidHelper::CallBooleanMethodString( - dynamic_links_native_wrapper::Method method, const char* strparam) { - JNIEnv* env = app_->GetJNIEnv(); - jstring param = env->NewStringUTF(strparam); - jboolean result = env->CallBooleanMethod( - wrapper_obj(), dynamic_links_native_wrapper::GetMethodId(method), param); - CheckJNIException(); - env->DeleteLocalRef(param); - - return (result != JNI_FALSE); -} - -int AndroidHelper::CallIntMethodString( - dynamic_links_native_wrapper::Method method, const char* strparam) { - JNIEnv* env = app_->GetJNIEnv(); - jstring param = env->NewStringUTF(strparam); - jint result = env->CallBooleanMethod( - wrapper_obj(), dynamic_links_native_wrapper::GetMethodId(method), param); - CheckJNIException(); - env->DeleteLocalRef(param); - - return result; -} - -void AndroidHelper::CallMethod(dynamic_links_native_wrapper::Method method) { - JNIEnv* env = app_->GetJNIEnv(); - env->CallVoidMethod(wrapper_obj(), - dynamic_links_native_wrapper::GetMethodId(method)); - CheckJNIException(); -} - -void AndroidHelper::CallMethodStringString( - dynamic_links_native_wrapper::Method method, const char* strparam1, - const char* strparam2) { - JNIEnv* env = app_->GetJNIEnv(); - jstring param1 = env->NewStringUTF(strparam1); - jstring param2 = env->NewStringUTF(strparam2); - env->CallVoidMethod(wrapper_obj(), - dynamic_links_native_wrapper::GetMethodId(method), param1, - param2); - CheckJNIException(); - - env->DeleteLocalRef(param2); - env->DeleteLocalRef(param1); -} - -void AndroidHelper::CheckJNIException() { - JNIEnv* env = app_->GetJNIEnv(); - if (env->ExceptionCheck()) { - // Get the exception text. - jthrowable exception = env->ExceptionOccurred(); - env->ExceptionClear(); - - // Convert the exception to a string. - jclass object_class = env->FindClass("java/lang/Object"); - jmethodID toString = - env->GetMethodID(object_class, "toString", "()Ljava/lang/String;"); - jstring s = (jstring)env->CallObjectMethod(exception, toString); - const char* exception_text = env->GetStringUTFChars(s, nullptr); - - // Log the exception text. - LogError("JNI exception: %s", exception_text); - - // Also, assert fail. - assert(false); - - // In the event we didn't assert fail, clean up. - env->ReleaseStringUTFChars(s, exception_text); - env->DeleteLocalRef(s); - env->DeleteLocalRef(exception); - } -} - -void AndroidHelper::ConnectionFailedCallback(int error_code) { - // TODO(jsimantov): Set a flag so the calling class can see an error occurred. - (void)error_code; -} - -extern "C" { - -// A function that receives the callback from the Java side. The -// "data_ptr" parameter is actually a pointer to our instance of -// InviteReceiverInternalAndroid, so we can call the proper -// ReceivedInviteCallback method. -JNIEXPORT void JNICALL -Java_com_google_firebase_dynamiclinks_internal_cpp_DynamicLinksNativeWrapper_receivedDynamicLinkCallback( - JNIEnv* env, jclass clazz, jlong data_ptr, jstring deep_link_url_java, - jint result, jstring error_string_java) { - if (data_ptr == 0) return; // test call only - - // Be careful - we are in a different thread now. No JNI calls are allowed - // except on the JNIEnv we were passed, and we have to take care changing the - // InvitesReceiverInternal data -- anything we touch needs a lock. - std::string invitation_id; // Will remain empty. - std::string deep_link_url; - std::string error_string; - if (result == 0) { - if (deep_link_url_java != nullptr) { - const char* chars = env->GetStringUTFChars(deep_link_url_java, nullptr); - deep_link_url = chars; - env->ReleaseStringUTFChars(deep_link_url_java, chars); - } - } else { - // result != 0 - if (error_string_java != nullptr) { - const char* chars = env->GetStringUTFChars(error_string_java, nullptr); - error_string = chars; - env->ReleaseStringUTFChars(error_string_java, chars); - } - } - firebase::invites::internal::SenderReceiverInterface* sender_receiver = - reinterpret_cast( - data_ptr); - - // On Android, we are always considered a perfect match. - sender_receiver->ReceivedInviteCallback(invitation_id, deep_link_url, - kLinkMatchStrengthPerfectMatch, - result, error_string); -} - -} // extern "C" - -} // namespace internal -} // namespace invites -} // namespace firebase diff --git a/app/src/invites/android/invites_android_helper.h b/app/src/invites/android/invites_android_helper.h deleted file mode 100644 index bfd0efaf05..0000000000 --- a/app/src/invites/android/invites_android_helper.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2017 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. - */ - -// Internal header file for shared Android functionality. - -#ifndef FIREBASE_APP_SRC_INVITES_ANDROID_INVITES_ANDROID_HELPER_H_ -#define FIREBASE_APP_SRC_INVITES_ANDROID_INVITES_ANDROID_HELPER_H_ - -#include - -#include "app/src/include/firebase/app.h" -#include "app/src/include/firebase/internal/mutex.h" -#include "app/src/invites/sender_receiver_interface.h" -#include "app/src/util_android.h" - -namespace firebase { -namespace invites { -namespace internal { - -// clang-format off -#define DYNAMIC_LINKS_NATIVE_WRAPPER_METHODS(X) \ - X(Constructor, \ - "", \ - "(JLandroid/app/Activity;)V"), \ - X(DiscardNativePointer, "discardNativePointer", "()V"), \ - X(FetchDynamicLink, "fetchDynamicLink", "()Z") -// clang-format on -METHOD_LOOKUP_DECLARATION(dynamic_links_native_wrapper, - DYNAMIC_LINKS_NATIVE_WRAPPER_METHODS) - -class AndroidHelper { - public: - AndroidHelper(const ::firebase::App& app, - SenderReceiverInterface* sender_receiver_interface); - ~AndroidHelper(); - - // The DynamicLinksNativeWrapper Java object we have instantiated. - jobject wrapper_obj() { return wrapper_obj_; } - - // JNI helper functions - - // Call a method returning boolean with no parameters. - bool CallBooleanMethod(dynamic_links_native_wrapper::Method method); - - // Call a method returning boolean with a string parameter. - bool CallBooleanMethodString(dynamic_links_native_wrapper::Method method, - const char* strparam); - - // Call a method returning integer with a string parameter. - int CallIntMethodString(dynamic_links_native_wrapper::Method method, - const char* strparam); - - // Call a method returning void, with no parameters. - void CallMethod(dynamic_links_native_wrapper::Method method); - - // Call a method returning void, with two string parameters. - void CallMethodStringString(dynamic_links_native_wrapper::Method method, - const char* strparam1, const char* strparam2); - - void CheckJNIException(); - - void ConnectionFailedCallback(int error_code); - - // Whether this object was successfully initialized by the constructor. - bool initialized() const { return app_ != nullptr; } - - private: - // The App contains a global reference to the Activity, as well as access to - // the JNIEnv. - const ::firebase::App* app_; - - // The instantiated DynamicLinksNativeWrapper object. This is a global - // reference, so we must destroy it when we are finished. - jobject wrapper_obj_; - - // Instantiate wrapper_obj_ by calling the wrapper class constructor. - void CreateWrapperObject(SenderReceiverInterface* sender_receiver_interface); - - static Mutex init_mutex_; // NOLINT - static int initialize_count_; -}; - -} // namespace internal -} // namespace invites -} // namespace firebase - -#endif // FIREBASE_APP_SRC_INVITES_ANDROID_INVITES_ANDROID_HELPER_H_ diff --git a/app/src/invites/android/invites_receiver_internal_android.cc b/app/src/invites/android/invites_receiver_internal_android.cc deleted file mode 100644 index 8255e02b71..0000000000 --- a/app/src/invites/android/invites_receiver_internal_android.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2017 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 "app/src/invites/android/invites_receiver_internal_android.h" - -#include - -#include "app/src/include/firebase/app.h" -#include "app/src/invites/android/invites_android_helper.h" -#include "app/src/invites/invites_receiver_internal.h" - -namespace firebase { -namespace invites { -namespace internal { - -InvitesReceiverInternalAndroid::InvitesReceiverInternalAndroid( - const ::firebase::App &app) - : InvitesReceiverInternal(app), android(app, this) { - if (!android.initialized()) app_ = nullptr; -} - -bool InvitesReceiverInternalAndroid::PerformFetch() { - return android.CallBooleanMethod( - dynamic_links_native_wrapper::kFetchDynamicLink); -} - -bool InvitesReceiverInternalAndroid::PerformConvertInvitation( - const char * /*invitation_id*/) { - LogWarning("ConvertInvitation is not implemented."); - return false; -} - -} // namespace internal -} // namespace invites -} // namespace firebase diff --git a/app/src/invites/android/invites_receiver_internal_android.h b/app/src/invites/android/invites_receiver_internal_android.h deleted file mode 100644 index 2a31652dac..0000000000 --- a/app/src/invites/android/invites_receiver_internal_android.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2017 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. - */ - -// Internal header file for Android Firebase invites sending functionality. - -#ifndef FIREBASE_APP_SRC_INVITES_ANDROID_INVITES_RECEIVER_INTERNAL_ANDROID_H_ -#define FIREBASE_APP_SRC_INVITES_ANDROID_INVITES_RECEIVER_INTERNAL_ANDROID_H_ - -#include - -#include "app/src/invites/android/invites_android_helper.h" -#include "app/src/invites/invites_receiver_internal.h" - -namespace firebase { -class App; - -namespace invites { -namespace internal { - -class InvitesReceiverInternalAndroid : public InvitesReceiverInternal { - public: - InvitesReceiverInternalAndroid(const ::firebase::App& app); - virtual ~InvitesReceiverInternalAndroid() {} - - virtual bool PerformFetch(); - - virtual bool PerformConvertInvitation(const char* invitation_id); - - private: - AndroidHelper android; -}; - -} // namespace internal -} // namespace invites -} // namespace firebase - -#endif // FIREBASE_APP_SRC_INVITES_ANDROID_INVITES_RECEIVER_INTERNAL_ANDROID_H_ diff --git a/app/src/invites/cached_receiver.cc b/app/src/invites/cached_receiver.cc deleted file mode 100644 index 0802fdc731..0000000000 --- a/app/src/invites/cached_receiver.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2017 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 "app/src/invites/cached_receiver.h" - -#include - -namespace firebase { -namespace invites { -namespace internal { - -CachedReceiver::CachedReceiver() - : match_strength_(kLinkMatchStrengthNoMatch), - result_code_(0), - has_pending_invite_(false), - receiver_(nullptr) {} - -CachedReceiver::~CachedReceiver() { SetReceiver(nullptr); } - -ReceiverInterface* CachedReceiver::SetReceiver(ReceiverInterface* receiver) { - MutexLock lock(lock_); - ReceiverInterface* prev_receiver = receiver_; - receiver_ = receiver; - SendCachedInvite(); - return prev_receiver; -} - -void CachedReceiver::SendCachedInvite() { - MutexLock lock(lock_); - if (receiver_) { - NotifyReceiver(receiver_); - has_pending_invite_ = false; - } -} - -void CachedReceiver::NotifyReceiver(ReceiverInterface* receiver) { - MutexLock lock(lock_); - if (has_pending_invite_ && receiver) { - receiver->ReceivedInviteCallback(invitation_id_, deep_link_url_, - match_strength_, result_code_, - error_message_); - } -} - -void CachedReceiver::ReceivedInviteCallback( - const std::string& invitation_id, const std::string& deep_link_url, - InternalLinkMatchStrength match_strength, int result_code, - const std::string& error_message) { - MutexLock lock(lock_); - // If there is already a pending invite, don't override it with an empty - // invite. - if (has_pending_invite_ && invitation_id.empty() && deep_link_url.empty() && - result_code == 0) { - return; - } - - has_pending_invite_ = true; - invitation_id_ = invitation_id; - deep_link_url_ = deep_link_url; - match_strength_ = match_strength; - - result_code_ = result_code; - error_message_ = error_message; - SendCachedInvite(); -} - -} // namespace internal -} // namespace invites -} // namespace firebase diff --git a/app/src/invites/cached_receiver.h b/app/src/invites/cached_receiver.h deleted file mode 100644 index a0a8166e5d..0000000000 --- a/app/src/invites/cached_receiver.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2017 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. - */ - -#ifndef FIREBASE_APP_SRC_INVITES_CACHED_RECEIVER_H_ -#define FIREBASE_APP_SRC_INVITES_CACHED_RECEIVER_H_ - -#include - -#include "app/src/include/firebase/internal/mutex.h" -#include "app/src/invites/receiver_interface.h" - -namespace firebase { -namespace invites { -namespace internal { - -// Receives and potentially caches invites / dynamic links until a receiver -// is registered with this class at which point all notifications are -// forwarded to the registered receiver. -class CachedReceiver : public ReceiverInterface { - public: - CachedReceiver(); - virtual ~CachedReceiver(); - - // Callback called when an invite is received. If an error occurred, - // result_code should be non-zero. Otherwise, either invitation_id should be - // set, or deep_link_url should be set, or both. - void ReceivedInviteCallback(const std::string& invitation_id, - const std::string& deep_link_url, - InternalLinkMatchStrength match_strength, - int result_code, - const std::string& error_message) override; - - // Set the receiver to forward invites / dynamic links to. - // If an invite / link is cached call the receiver immediately with the data. - ReceiverInterface* SetReceiver(ReceiverInterface* receiver); - - // Notify a receiver of any invites cached in this class. - void NotifyReceiver(ReceiverInterface* receiver); - - private: - // Send a cache data to the registered receiver. - void SendCachedInvite(); - - protected: - // Mutex to manage the state of this class. - Mutex lock_; - - // Last invite / dynamic link that was received. - // The Invitation ID, if any. - std::string invitation_id_; - // Deep Link URL, if any. - std::string deep_link_url_; - - // How strong or week the deep link match is, as defined by the Invites - // library. - InternalLinkMatchStrength match_strength_; - - // The error / result code, if an error occurred. - int result_code_; - // A description of the error, if one occurred. - std::string error_message_; - - // Is there a pending invite to send when a receiver is set. - bool has_pending_invite_; - // Receiver to forward invites to. - ReceiverInterface* receiver_; -}; - -} // namespace internal -} // namespace invites -} // namespace firebase - -#endif // FIREBASE_APP_SRC_INVITES_CACHED_RECEIVER_H_ diff --git a/app/src/invites/invites_receiver_internal.cc b/app/src/invites/invites_receiver_internal.cc deleted file mode 100644 index 3f0c498a6d..0000000000 --- a/app/src/invites/invites_receiver_internal.cc +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2017 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 "app/src/invites/invites_receiver_internal.h" - -#include - -#include - -#include "app/src/include/firebase/app.h" -#include "app/src/include/firebase/future.h" -#include "app/src/include/firebase/internal/platform.h" -#include "app/src/reference_counted_future_impl.h" -#if FIREBASE_PLATFORM_ANDROID -#include "app/src/invites/android/invites_receiver_internal_android.h" -#elif FIREBASE_PLATFORM_IOS -#include "app/src/invites/ios/invites_receiver_internal_ios.h" -#else -#include "app/src/invites/stub/invites_receiver_internal_stub.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS - -namespace firebase { -namespace invites { -namespace internal { - -static const int kFetchFailedCode = -1; -static const char kFetchFailedMessage[] = "Dynamic link fetch failed."; -static const int kConvertFailedCode = -1; -static const char kConvertFailedMessage[] = "Invite conversion failed."; -static const int kConvertInProgressCode = -2; -static const char kConvertInProgressMessage[] = - "Invite conversion already in progress"; - -// Used by testing and reference counting the receiver singleton. -// When testing this is used by SetNextCreatedInstance() to set the next -// instance returned by CreateInstance(). -static InvitesReceiverInternal* g_receiver = nullptr; - -InvitesReceiverInternal* InvitesReceiverInternal::CreateInstance( - const ::firebase::App& app, ReceiverInterface* receiver_implementation) { - InvitesReceiverInternal* receiver = g_receiver; - if (!receiver) { -#if FIREBASE_PLATFORM_ANDROID - receiver = new InvitesReceiverInternalAndroid(app); -#elif FIREBASE_PLATFORM_IOS - receiver = new InvitesReceiverInternalIos(app); -#else - receiver = new InvitesReceiverInternalStub(app); -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS - if (!receiver->initialized()) { - delete receiver; - return nullptr; - } - g_receiver = receiver; - } - receiver->receiver_implementations_.push_back(receiver_implementation); - receiver->ref_count_++; - // Notify the newly registered receiver of any cached notifications. - receiver->cached_receiver_.NotifyReceiver(receiver_implementation); - return receiver; -} - -void InvitesReceiverInternal::DestroyInstance( - InvitesReceiverInternal* receiver, - ReceiverInterface* receiver_implementation) { - assert(receiver && receiver == g_receiver); - assert(receiver->initialized()); - assert(receiver->ref_count_); - if (receiver_implementation) { - auto& receiver_implementations = receiver->receiver_implementations_; - auto it = - std::find(receiver_implementations.begin(), - receiver_implementations.end(), receiver_implementation); - if (it != receiver_implementations.end()) { - receiver_implementations.erase(it); - } - } - receiver->ref_count_--; - if (receiver->ref_count_ == 0) { - delete receiver; - g_receiver = nullptr; - } -} - -void InvitesReceiverInternal::SetNextCreatedInstance( - InvitesReceiverInternal* instance) { - g_receiver = instance; -} - -void InvitesReceiverInternal::Fetch() { - if (!PerformFetch()) { - ReceivedInviteCallback("", "", kLinkMatchStrengthNoMatch, kFetchFailedCode, - kFetchFailedMessage); - } -} - -void InvitesReceiverInternal::ReceivedInviteCallback( - const std::string& invitation_id, const std::string& deep_link_url, - InternalLinkMatchStrength match_strength, int result_code, - const std::string& error_message) { - LogDebug( - "Received link: invite_id=%s url=%s match_strength=%d result=%d " - "error=%s", - invitation_id.c_str(), deep_link_url.c_str(), - static_cast(match_strength), result_code, error_message.c_str()); - for (auto it = receiver_implementations_.begin(); - it != receiver_implementations_.end(); ++it) { - (*it)->ReceivedInviteCallback(invitation_id, deep_link_url, match_strength, - result_code, error_message); - } -} - -Future InvitesReceiverInternal::ConvertInvitation( - const char* invitation_id) { - if (!future_impl_.ValidFuture(future_handle_convert_)) { - future_handle_convert_ = future_impl_.SafeAlloc(kInvitesFnConvert); - if (!PerformConvertInvitation(invitation_id)) { - future_impl_.Complete(future_handle_convert_, kConvertFailedCode, - kConvertFailedMessage); - // This will tell all of the pending Futures that we have failed. Once all - // those futures are gone, the RefFuture will automatically be deleted. - future_handle_convert_ = SafeFutureHandle::kInvalidHandle; - } - } else { - // If there's already a convert in progress, fail. - const SafeFutureHandle handle = - future_impl_.SafeAlloc(kInvitesFnConvert); - future_impl_.Complete(handle, kConvertInProgressCode, - kConvertInProgressMessage); - } - return ConvertInvitationLastResult(); -} - -Future InvitesReceiverInternal::ConvertInvitationLastResult() { - return static_cast&>( - future_impl_.LastResult(kInvitesFnConvert)); -} - -void InvitesReceiverInternal::ConvertedInviteCallback( - const std::string& invitation_id, int result_code, - std::string error_message) { - future_impl_.Complete(future_handle_convert_, result_code, - error_message.c_str()); - future_handle_convert_ = SafeFutureHandle::kInvalidHandle; -} - -} // namespace internal -} // namespace invites -} // namespace firebase diff --git a/app/src/invites/invites_receiver_internal.h b/app/src/invites/invites_receiver_internal.h deleted file mode 100644 index b77e81aa7b..0000000000 --- a/app/src/invites/invites_receiver_internal.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2017 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. - */ - -// Internal header file for Android InvitesReceiver functionality. - -#ifndef FIREBASE_APP_SRC_INVITES_INVITES_RECEIVER_INTERNAL_H_ -#define FIREBASE_APP_SRC_INVITES_INVITES_RECEIVER_INTERNAL_H_ - -#include - -#include "app/src/include/firebase/app.h" -#include "app/src/include/firebase/future.h" -#include "app/src/include/firebase/internal/mutex.h" -#include "app/src/invites/cached_receiver.h" -#include "app/src/invites/receiver_interface.h" -#include "app/src/invites/sender_receiver_interface.h" -#include "app/src/reference_counted_future_impl.h" - -namespace firebase { -namespace invites { -namespace internal { - -// This class performs the general functionality of InvitesReceiver class, -// including setting up the Future results, and processing callbacks from Java. -// A subclass will handle platform-specific operations by implementing -// PerformFetch and PerformConvertInvitation. -class InvitesReceiverInternal : public SenderReceiverInterface { - public: - // Create an instance of whichever subclass of InvitesReceiverInternal is - // appropriate for our platform. - static InvitesReceiverInternal* CreateInstance( - const ::firebase::App& app, ReceiverInterface* receiver_implementation); - - // Decrement ref count / destroy instance of InvitesReceiverInternal. - static void DestroyInstance(InvitesReceiverInternal* receiver, - ReceiverInterface* receiver_implementation); - - // The next time an instance would be created via a call to CreateInstance(), - // return this instance instead. Use this for testing (to stub the - // platform-specific subclass of InvitesReceiverInternal). It will be deleted - // normally when the InvitesReceiver class is deleted. - static void SetNextCreatedInstance(InvitesReceiverInternal* new_instance); - - // Start checking to see if we've received an invite. This will call - // PerformFetch() which does the application-specific part. If PerformFetch() - // returns true, the invite will be sent to the Listener via - // ReceivedInviteCallback. Otherwise an error happened, and this will pass - // the error to the Listener. - void Fetch(); - - // If this returns true, we are currently checking for incoming invites. If - // this returns false, something went wrong. If it returns true, then - // ReceivedInviteCallback will eventually get called with the results. - virtual bool PerformFetch() = 0; - - // Not used by the receiver. - void SentInviteCallback(const std::vector& /*invitation_ids*/, - int /*result_code*/, - const std::string& /*error_message*/) override {} - - // Callback called when an invite is received. If an error occurred, - // result_code should be non-zero. Otherwise, either invitation_id should be - // set, or deep_link_url should be set, or both. - void ReceivedInviteCallback(const std::string& invitation_id, - const std::string& deep_link_url, - InternalLinkMatchStrength match_strength, - int result_code, - const std::string& error_message) override; - - // Start the process of conversion on this invitation ID. This will call - // PerformConvertInvitation() which does the application-specific part. If - // PerformConvertInvitation() returns true, the Future will complete once - // there is a call to ConvertedInviteCallback. Otherwise an error happened and - // the Future will complete immediately. - Future ConvertInvitation(const char* id); - - // Get an already existing future result. - Future ConvertInvitationLastResult(); - - // Start trying to mark the invitation as a "conversion" on the Firebase - // backend. If this returns false, something went wrong. If it returns true, - // then ConvertedInviteCallback will eventually get called with the results. - virtual bool PerformConvertInvitation(const char* invitation_id) = 0; - - // Callback called when an invite conversion occurs. If an error occurred, - // result_code will be non-zero. Otherwise, the conversion was successful. - void ConvertedInviteCallback(const std::string& invitation_id, - int result_code, - std::string error_message) override; - - // Get the app this is attached to. - const App* app() const { return app_; } - - protected: - enum InvitesFn { kInvitesFnConvert, kInvitesFnCount }; - - // Use CreateInstance() to create an appropriate one for the platform we are - // on. - explicit InvitesReceiverInternal(const ::firebase::App& app) - : app_(&app), - future_impl_(kInvitesFnCount), - future_handle_convert_(ReferenceCountedFutureImpl::kInvalidHandle), - ref_count_(0) { - receiver_implementations_.push_back(&cached_receiver_); - } - - // Virtual destructor is required. - virtual ~InvitesReceiverInternal() {} - - // Whether this object was successfully initialized by the constructor. - bool initialized() const { return app_ != nullptr; } - - protected: - // Keep a pointer to the App in case we need to call Initialize(). - const App* app_; - - private: - // Futures implementation, and the corresponding mutex. - ReferenceCountedFutureImpl future_impl_; - - // When a conversion begins, future_handle_convert_ will be non-0 - // until the conversion finishes. The future for the convert can be accessed - // via `future_impl_.LastResult(kInvitesFnConvert)`. - SafeFutureHandle future_handle_convert_; - - // Need to add a cache which stores the last invite and forwards it to the - // newly registered receiver. - CachedReceiver cached_receiver_; - - // Routes callbacks to library specific methods. - std::vector receiver_implementations_; - - // Number of references to this instance. - int ref_count_; -}; - -} // namespace internal -} // namespace invites -} // namespace firebase - -#endif // FIREBASE_APP_SRC_INVITES_INVITES_RECEIVER_INTERNAL_H_ diff --git a/app/src/invites/ios/.clang-format b/app/src/invites/ios/.clang-format deleted file mode 100644 index 9d159247d5..0000000000 --- a/app/src/invites/ios/.clang-format +++ /dev/null @@ -1,2 +0,0 @@ -DisableFormat: true -SortIncludes: false diff --git a/app/src/invites/ios/invites_ios_startup.h b/app/src/invites/ios/invites_ios_startup.h deleted file mode 100644 index eff85b3980..0000000000 --- a/app/src/invites/ios/invites_ios_startup.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2017 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. - */ - -#ifndef FIREBASE_APP_SRC_INVITES_IOS_INVITES_IOS_STARTUP_H_ -#define FIREBASE_APP_SRC_INVITES_IOS_INVITES_IOS_STARTUP_H_ - -#include - -#include - -namespace firebase { -namespace invites { -namespace internal { - -// Derive from this class and instance it to hook UIApplicationDelegate methods -// required to receive dynamic links or invites. -// This is handled via a class with virtual methods so that when the -// invites_ios_startup.mm module is linked into application all other -// dynamic links / modules (e.g invites_receiver_internal_ios.mm) can be dead -// stripped. -class InvitesIosStartup { - public: - // Create an object to hook swizzled UIApplicationDelegate methods. - // Priority is an arbitrary value used to determine the execution order - // of each method of this object. Lower values of priority are executed - // first (e.g 0 is executed before 1). - explicit InvitesIosStartup(int priority) : priority_(priority) { Register(); } - - virtual ~InvitesIosStartup() { Unregister(); } - - // Register this object with the set of instances that are called from - // static methods (e.g OpenUrl) of this class. - // This method does nothing if the object is already registered. - void Register(); - // Unregister this object from the set of instances that are called from - // static methods (e.g OpenUrl) of this class. - // This method does nothing if the object is already unregistered. - void Unregister(); - - // Call HandleDidBecomeActive methods of registered instances of this class. - static void DidBecomeActive(UIApplication *application); - - // Call HandleOpenUrl methods of registered instances of this class. - static BOOL OpenUrl(UIApplication *application, NSURL *url, - NSString *sourceApplication, id annotation); - static BOOL OpenUrl(UIApplication *application, NSURL *url, - NSDictionary *options); - - // Call HandleContinueUserActivity methods of registered instances of this - // class. - static BOOL ContinueUserActivity(UIApplication *application, - NSUserActivity *userActivity, - void (^restorationHandler)(NSArray *)); - - protected: - // Called from UIApplicationDelegate application:didBecomeActive. - // All registered methods are called. - virtual void HandleDidBecomeActive(UIApplication *application) = 0; - - // Called from - // UIApplicationDelegate openURL:application:url:sourceApplication:annotation - // If this method returns true methods of lower priority (e.g N+1) are not - // called. - virtual BOOL HandleOpenUrl(UIApplication *application, NSURL *url, - NSString *sourceApplication, id annotation) = 0; - // Called from - // UIApplicationDelegate openURL:application:url:options - // If this method returns true methods of lower priority (e.g N+1) are not - // called. - virtual BOOL HandleOpenUrl(UIApplication *application, NSURL *url, - NSDictionary *options) = 0; - // Called from - // UIApplicationDelegate - // continueUserActivity:application::userActivity:restorationHandler - // If this method returns true methods of lower priority (e.g N+1) are not - // called. - virtual BOOL HandleContinueUserActivity( - UIApplication *application, NSUserActivity *userActivity, - void (^restorationHandler)(NSArray *)) = 0; - - private: - int priority_; - - static std::vector *s_invites_ios_startups; -}; - -} // namespace internal -} // namespace invites -} // namespace firebase - -#endif // FIREBASE_APP_SRC_INVITES_IOS_INVITES_IOS_STARTUP_H_ diff --git a/app/src/invites/ios/invites_ios_startup.mm b/app/src/invites/ios/invites_ios_startup.mm deleted file mode 100644 index a99602ba79..0000000000 --- a/app/src/invites/ios/invites_ios_startup.mm +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright 2017 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 "app/src/invites/ios/invites_ios_startup.h" - -#include -#include - -#include "app/src/log.h" -#include "app/src/util_ios.h" - -#import -#import -#import - -namespace firebase { -namespace invites { - -static ::firebase::util::ClassMethodImplementationCache& SwizzledMethodCache() { - static ::firebase::util::ClassMethodImplementationCache *g_swizzled_method_cache; - return *::firebase::util::ClassMethodImplementationCache::GetCreateCache( - &g_swizzled_method_cache); -} - -extern "C" { - -static BOOL AppDelegateApplicationOpenUrlSourceApplicationAnnotation(id self, SEL selectorValue, - UIApplication *application, - NSURL *url, - NSString *sourceApplication, - id annotation) { - BOOL ret = internal::InvitesIosStartup::OpenUrl(application, url, sourceApplication, annotation); - - // Some applications / frameworks (like Unity) do not handle nil arguments for url, - // sourceApplication and annotation, so create empty objects to prevent them from failing. - if (!url) url = [[NSURL alloc] init]; - if (!sourceApplication) sourceApplication = @""; - if (!annotation) annotation = [[NSString alloc] init]; - IMP app_delegate_application_open_url_source_application_annotation = - SwizzledMethodCache().GetMethodForObject( - self, @selector(application:openURL:sourceApplication:annotation:)); - if (app_delegate_application_open_url_source_application_annotation) { - return ((util::AppDelegateApplicationOpenUrlSourceApplicationAnnotationFunc) - app_delegate_application_open_url_source_application_annotation)( - self, selectorValue, application, url, sourceApplication, annotation); - } else if ([self methodForSelector:@selector(forwardInvocation:)] != - [NSObject instanceMethodForSelector:@selector(forwardInvocation:)]) { - NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selectorValue]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:selectorValue]; - [invocation setTarget:self]; - [invocation setArgument:&application atIndex:2]; - [invocation setArgument:&url atIndex:3]; - [invocation setArgument:&sourceApplication atIndex:4]; - [invocation setArgument:&annotation atIndex:5]; - [self forwardInvocation:invocation]; - // Read the return value from the invocation. - [invocation getReturnValue:&ret]; - } - return ret; -} - -static BOOL AppDelegateApplicationContinueUserActivityRestorationHandler( - id self, SEL selectorValue, UIApplication *application, NSUserActivity *userActivity, - void (^restorationHandler)(NSArray *)) { - BOOL ret = internal::InvitesIosStartup::ContinueUserActivity(application, userActivity, - restorationHandler); - - // Some applications / frameworks may not handle nil arguments for userActivity, - // so create an empty object to prevent them from failing. - if (!userActivity) userActivity = [[NSUserActivity alloc] init]; - IMP app_delegate_application_continue_user_activity_restoration_handler = - SwizzledMethodCache().GetMethodForObject( - self, @selector(application:continueUserActivity:restorationHandler:)); - if (app_delegate_application_continue_user_activity_restoration_handler) { - return ((util::AppDelegateApplicationContinueUserActivityRestorationHandlerFunc) - app_delegate_application_continue_user_activity_restoration_handler)( - self, selectorValue, application, userActivity, restorationHandler); - } else if ([self methodForSelector:@selector(forwardInvocation:)] != - [NSObject instanceMethodForSelector:@selector(forwardInvocation:)]) { - NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selectorValue]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:selectorValue]; - [invocation setTarget:self]; - [invocation setArgument:&application atIndex:2]; - [invocation setArgument:&userActivity atIndex:3]; - [invocation setArgument:&restorationHandler atIndex:4]; - [self forwardInvocation:invocation]; - // Read the return value from the invocation. - [invocation getReturnValue:&ret]; - } - return ret; -} - -static BOOL AppDelegateApplicationOpenUrlOptions(id self, SEL selectorValue, - UIApplication *application, NSURL *url, - NSDictionary *options) { - BOOL ret = internal::InvitesIosStartup::OpenUrl(application, url, options); - - // Some applications / frameworks (like Unity) do not handle nil arguments for url and options - // so create empty objects to prevent them from failing. - if (!url) url = [[NSURL alloc] init]; - if (!options) options = @{}; - - IMP app_delegate_application_open_url_options = - SwizzledMethodCache().GetMethodForObject(self, @selector(application:openURL:options:)); - if (app_delegate_application_open_url_options) { - return ( - (util::AppDelegateApplicationOpenUrlOptionsFunc)app_delegate_application_open_url_options)( - self, selectorValue, application, url, options); - } else if ([self methodForSelector:@selector(forwardInvocation:)] != - [NSObject instanceMethodForSelector:@selector(forwardInvocation:)]) { - NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selectorValue]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:selectorValue]; - [invocation setTarget:self]; - [invocation setArgument:&application atIndex:2]; - [invocation setArgument:&url atIndex:3]; - [invocation setArgument:&options atIndex:4]; - [self forwardInvocation:invocation]; - // Read the return value from the invocation. - [invocation getReturnValue:&ret]; - } - return ret; -} - -// Fetch link when entering foreground. -static void AppDelegateApplicationDidBecomeActive(id self, SEL selectorValue, - UIApplication *application) { - internal::InvitesIosStartup::DidBecomeActive(application); - IMP app_delegate_application_did_become_active = - SwizzledMethodCache().GetMethodForObject(self, @selector(applicationDidBecomeActive:)); - if (app_delegate_application_did_become_active) { - ((util::AppDelegateApplicationDidBecomeActiveFunc)app_delegate_application_did_become_active)( - self, selectorValue, application); - } else if ([self methodForSelector:@selector(forwardInvocation:)] != - [NSObject instanceMethodForSelector:@selector(forwardInvocation:)]) { - NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selectorValue]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:selectorValue]; - [invocation setTarget:self]; - [invocation setArgument:&application atIndex:2]; - [self forwardInvocation:invocation]; - } -} - -// Hook all AppDelegate methods that Firebase Invites requires to intercept incoming invites and -// dynamic links. -// -// The user of the library provides the class which implements AppDelegate protocol so this method -// hooks methods of user's UIApplication class in order to intercept events required for Invites. -// The alternative to this procedure would require the user to implement boilerplate code in their -// UIApplication in order to plumb in Firebase Invites. -// -// The following methods are replaced in order to intercept AppDelegate events: -// - (BOOL)application:openURL:sourceApplication:annotation: -// - (BOOL)application:openURL:options: -// - (BOOL)application:continueUserActivity:restorationHandler: -static void HookAppDelegateMethods(Class clazz) { - Class method_encoding_class = [FIRSAMAppDelegate class]; - auto& method_cache = SwizzledMethodCache(); - // application:openURL:options: is called in preference to - // application:openURL:sourceApplication:annotation: so if the UIApplicationDelegate does not - // implement application:openURL:options:, do not hook it. - method_cache.ReplaceMethod( - clazz, @selector(application:openURL:options:), (IMP)AppDelegateApplicationOpenUrlOptions, - method_encoding_class); - method_cache.ReplaceOrAddMethod( - clazz, @selector(application:openURL:sourceApplication:annotation:), - (IMP)AppDelegateApplicationOpenUrlSourceApplicationAnnotation, method_encoding_class); - method_cache.ReplaceOrAddMethod( - clazz, @selector(application:continueUserActivity:restorationHandler:), - (IMP)AppDelegateApplicationContinueUserActivityRestorationHandler, method_encoding_class); - method_cache.ReplaceOrAddMethod( - clazz, @selector(applicationDidBecomeActive:), (IMP)AppDelegateApplicationDidBecomeActive, - method_encoding_class); -} - -} // extern "C" - -namespace internal { - -std::vector *InvitesIosStartup::s_invites_ios_startups = nullptr; - -// Register this object with the set of instances that are called from -// static methods (e.g OpenUrl) of this class. -// This method does nothing if the object is already registered. -void InvitesIosStartup::Register() { - if (s_invites_ios_startups) { - auto it = std::find(s_invites_ios_startups->begin(), - s_invites_ios_startups->end(), this); - if (it != s_invites_ios_startups->end()) return; - } else { - s_invites_ios_startups = new std::vector(); - } - s_invites_ios_startups->push_back(this); - std::sort(s_invites_ios_startups->begin(), s_invites_ios_startups->end(), - [](InvitesIosStartup *lhs, InvitesIosStartup *rhs) { - return lhs->priority_ < rhs->priority_; - }); -} - -// Unregister this object from the set of instances that are called from -// static methods (e.g OpenUrl) of this class. -// This method does nothing if the object is already unregistered. -void InvitesIosStartup::Unregister() { - if (!s_invites_ios_startups) return; - auto it = std::find(s_invites_ios_startups->begin(), - s_invites_ios_startups->end(), this); - // If the object isn't in the s_invites_ios_startups vector, do nothing. - if (it != s_invites_ios_startups->end()) { - s_invites_ios_startups->erase(it); - } - if (s_invites_ios_startups->size() == 0) { - delete s_invites_ios_startups; - s_invites_ios_startups = nullptr; - } -} - -// Call HandleDidBecomeActive methods of registered instances of this class. -void InvitesIosStartup::DidBecomeActive(UIApplication *application) { - if (s_invites_ios_startups) { - for (auto it = s_invites_ios_startups->begin(); it != s_invites_ios_startups->end(); ++it) { - (*it)->HandleDidBecomeActive(application); - } - } -} - -// Call OpenUrl methods of registered instances of this class. -BOOL InvitesIosStartup::OpenUrl(UIApplication *application, NSURL *url, - NSString *sourceApplication, id annotation) { - if (s_invites_ios_startups) { - for (auto it = s_invites_ios_startups->begin(); it != s_invites_ios_startups->end(); ++it) { - if ((*it)->HandleOpenUrl(application, url, sourceApplication, annotation)) return YES; - } - } - return NO; -} - -BOOL InvitesIosStartup::OpenUrl(UIApplication *application, NSURL *url, - NSDictionary *options) { - if (s_invites_ios_startups) { - for (auto it = s_invites_ios_startups->begin(); it != s_invites_ios_startups->end(); ++it) { - if ((*it)->HandleOpenUrl(application, url, options)) return YES; - } - } - return NO; -} - -// Call ContinueUserActivity methods of registered instances of this class. -BOOL InvitesIosStartup::ContinueUserActivity(UIApplication *application, - NSUserActivity *userActivity, - void (^restorationHandler)(NSArray *)) { - if (s_invites_ios_startups) { - for (auto it = s_invites_ios_startups->begin(); it != s_invites_ios_startups->end(); ++it) { - if ((*it)->HandleContinueUserActivity(application, userActivity, restorationHandler)) { - return YES; - } - } - } - return NO; -} - -} // namespace internal - -} // namespace invites -} // namespace firebase - -// Category for UIApplication that is used to hook methods in all classes. Category +load() methods -// are called after all class load methods in each Mach-O (see call_load_methods() in -// http://www.opensource.apple.com/source/objc4/objc4-274/runtime/objc-runtime.m) -@implementation UIApplication (FIRFBI) -+ (void)load { - // C++ constructors may not be called yet so call NSLog rather than LogDebug. - NSLog(@"Loading UIApplication category for Firebase App"); - ::firebase::util::RunOnAppDelegateClasses(^(Class clazz) { - ::firebase::invites::HookAppDelegateMethods(clazz); - }); -} -@end diff --git a/app/src/invites/ios/invites_receiver_internal_ios.h b/app/src/invites/ios/invites_receiver_internal_ios.h deleted file mode 100644 index a1f825a213..0000000000 --- a/app/src/invites/ios/invites_receiver_internal_ios.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2017 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. - */ - -// Internal header file for iOS Firebase invites sending functionality. - -#ifndef FIREBASE_APP_SRC_INVITES_IOS_INVITES_RECEIVER_INTERNAL_IOS_H_ -#define FIREBASE_APP_SRC_INVITES_IOS_INVITES_RECEIVER_INTERNAL_IOS_H_ - -#include - -#include "app/src/invites/invites_receiver_internal.h" - -#ifdef __OBJC__ -#include -#endif // __OBJC__ - -namespace firebase { -class App; -class Mutex; - -namespace invites { -namespace internal { - -// An internal class that performs the iOS-specific parts of receiving app -// invites and deep links. Because of the way iOS App Invites are implmented in -// the original library, the bulk of the work is done in the SetLaunchUrl() -// method. -// -// The general sequence of events when there's an incoming invite/deep link is: -// -// 1. SetLaunchUrl initializes and calls the dynamic links -// service to check for a deep link. -// -// 2. The dynamic links service, finding a link for the user, calls -// SetOpenUrl, passing in a special link that the app invites library will -// parse, which SetOpenUrl saves until later. -// -// 3. PerformFetch() checks the saved URL once it's present. If it matches the -// special format that the invites/DDL library uses, it parses out an invitation -// ID and/or deep link URL from it. -class InvitesReceiverInternalIos : public InvitesReceiverInternal { - public: - // Registers the startup class associated with this module. - // This can be used from a static object to ensure registration occurs before - // main(). - class StartupRegistration { - public: - // id must be valid for the lifetime of this class. - StartupRegistration(const char* id) : identifier_(id) { - InvitesReceiverInternalIos::RegisterStartup(this); - } - - // Identifier used to debug this object. - const char* identifier() const { return identifier_; } - - private: - const char* identifier_; - }; - - // Used to receive link data from Callbacks::FinishFetch() so that the - // InvitesReceiverInternalIos::Callbacks implementation can handle the - // URL link before InvitesReceiverInternalIos falls back to it's default - // behavior. - struct LinkInfo { - LinkInfo() : match_strength(kLinkMatchStrengthNoMatch) {} - - // ID of the invite derived from a URL link. - std::string invite_id; - // Deep link derived from a URL link. - std::string deep_link; - // How strong the match is. - InternalLinkMatchStrength match_strength; - }; - -#ifdef __OBJC__ - // Class used by the invites API to hook operations performed by the receiver. - class Callbacks { - public: - virtual ~Callbacks() {} - - // Used by Invites to complete Google Sign-in when sending an invite. - virtual bool OpenUrl(NSURL* url, NSString* source_application, - id annotation) = 0; - - // Called when a URL link (vs. universal link) is being processed by - // InvitesReceiverInternalIos::FinishFetch(). Dynamic link processing - // stops if this returns true. - virtual bool FinishFetch(NSURL* url, NSString* source_application, - id annotation, LinkInfo* link_info) = 0; - - // Called from InvitesReceiverInternalIos::PerformConvertInvitation() to - // convert an invite. - virtual void PerformConvertInvitation(const char* invitation_id) = 0; - }; -#else - // This header is also included by plain C++. - class Callbacks; -#endif // __OBJC__ - - // Work around a bug where null deep links cause Android clients to fail. - // TODO(jsimantov): Remove this constant when b/27612427 is fixed. - static const char* const kNullDeepLinkUrl; - - InvitesReceiverInternalIos(const ::firebase::App& app); - virtual ~InvitesReceiverInternalIos(); - - // This function consumes the URL previously set by open_url_. - virtual bool PerformFetch(); - - virtual bool PerformConvertInvitation(const char* invitation_id); - -#ifdef __OBJC__ - static void SetLaunchOptions(NSDictionary* launch_options); - static BOOL OpenUrl(NSURL* url, NSString* source_application, id annotation); - static BOOL OpenUniversalLink(NSURL* url); -#endif // __OBJC__ - - // Configure library specific callbacks, see Callbacks class for more - // information. - static void SetCallbacks(Callbacks* callbacks); - - // Register the component that handles app delegate callbacks. - static void RegisterStartup(StartupRegistration* registration); - - private: - void FinishFetch(); - - Mutex callback_mutex_; // Acquired when PerformFetch starts. - // Released after ReceivedInviteCallback is called. - bool fetch_in_progress_; // Whether a fetch is currently in progress. - Mutex fetch_mutex_; // Protects fetch_in_progress_. -}; - -} // namespace internal -} // namespace invites -} // namespace firebase - -#endif // FIREBASE_APP_SRC_INVITES_IOS_INVITES_RECEIVER_INTERNAL_IOS_H_ diff --git a/app/src/invites/ios/invites_receiver_internal_ios.mm b/app/src/invites/ios/invites_receiver_internal_ios.mm deleted file mode 100644 index 33550324f6..0000000000 --- a/app/src/invites/ios/invites_receiver_internal_ios.mm +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright 2017 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 "app/src/invites/ios/invites_receiver_internal_ios.h" - -#include -#include -#include -#include - -#include "app/src/assert.h" -#include "app/src/include/firebase/app.h" -#include "app/src/include/firebase/internal/mutex.h" -#include "app/src/invites/invites_receiver_internal.h" -#include "app/src/invites/ios/invites_ios_startup.h" -#include "app/src/log.h" -#include "app/src/util_ios.h" - -#include "FIRDynamicLink.h" -#include "FIRDynamicLinks.h" - -// We need access to the inviteId method of FIRDynamicLink. This is not in the -// public API yet, but will be added in a future release. -@interface FIRDynamicLink () -- (nullable NSString *)inviteId; -@end - -namespace firebase { -namespace invites { -namespace internal { - -// When fetching invites, we will time out after kFetchCheckUrlTimeoutSeconds. -const float kFetchCheckUrlTimeoutSeconds = 300.0f; -// When fetching invites, how often to check if the URL has been set. -const float kFetchCheckUrlInitialIntervalSeconds = 0.2f; -// Amount to increase polling interval per iteration. -const float kFetchCheckUrlIntervalIncreaseSeconds = 0.2f; - -enum LinkType { kLinkTypeNone, kLinkTypeUrl, kLinkTypeUniversal }; - -// Fetch dynamic link / invite using the currently instanced receiver object. -// Do nothing if a receiver isn't available. -static void FetchDynamicLink(); - -class InvitesIosStartupImpl : public InvitesIosStartup { - public: - explicit InvitesIosStartupImpl(int priority) : InvitesIosStartup(priority) {} - virtual ~InvitesIosStartupImpl() {} - - protected: - void HandleDidBecomeActive(UIApplication *application) override { - LogDebug("HandleDidBecomeActive 0x%08x", - static_cast(reinterpret_cast(application))); - FetchDynamicLink(); - } - - BOOL HandleOpenUrl(UIApplication *application, NSURL *url, - NSString *sourceApplication, id annotation) override { - LogDebug("HandleOpenUrl %s %s", url ? url.absoluteString.UTF8String : "(null)", - sourceApplication ? sourceApplication.UTF8String : "(null)"); - return InvitesReceiverInternalIos::OpenUrl( - url, sourceApplication, annotation) != NO; - } - - BOOL HandleOpenUrl(UIApplication *application, NSURL *url, - NSDictionary *options) override { - NSString *sourceApplication = options[UIApplicationOpenURLOptionsSourceApplicationKey]; - id annotation = options[UIApplicationOpenURLOptionsAnnotationKey]; - LogDebug("HandleOpenUrl(new) %s %s", url ? url.absoluteString.UTF8String : "(null)", - sourceApplication ? sourceApplication.UTF8String : "(null)"); - return InvitesReceiverInternalIos::OpenUrl( - url, sourceApplication, annotation) != NO; - } - - BOOL HandleContinueUserActivity( - UIApplication *application, NSUserActivity *userActivity, - void (^restorationHandler)(NSArray *)) override { - LogDebug("ContinueUserActivity %s", userActivity && userActivity.webpageURL ? - userActivity.webpageURL.absoluteString.UTF8String : "(null)"); - return userActivity ? - InvitesReceiverInternalIos::OpenUniversalLink(userActivity.webpageURL) != NO - : false; - } -}; - -static LinkType g_got_link_type = kLinkTypeNone; -static NSURL *g_open_url; -static NSString *g_source_application; -static id g_annotation = nil; -// Amount of time elapsed (in seconds) since the dynamic link URL poller started. -static float g_fetch_timer = 0.0f; -// Amount of time (in seconds) to wait between polling the dynamic link URL. -static float g_fetch_poll_interval = 0.0f; - -// Instance of this class. This is used to execute dynamic link fetches from swizzled methods of -// the app delegate. -static InvitesReceiverInternalIos* g_invites_receiver = nullptr; - -// Miscellaneous hooks that are overriden by the invites library if it's initialized. -static InvitesReceiverInternalIos::Callbacks* g_callbacks = nullptr; - -static InvitesIosStartupImpl g_ios_startup_impl(0); - -// Mutex for the static stuff. -static ::firebase::Mutex g_static_mutex; - -// Fetch dynamic link / invite using the currently instanced receiver object. -// Do nothing if a receiver isn't available. -static void FetchDynamicLink() { - // Spin up a thread to perform a fetch call, because the underlying Fetch - // call can potentially end up blocking if another callback is happening, - // and we don't want to delay the startup. - MutexLock lock(g_static_mutex); - if (g_invites_receiver) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), - ^{ - MutexLock lock(g_static_mutex); - if (g_invites_receiver) g_invites_receiver->Fetch(); - }); - } -} - -// Register the component that handles app delegate callbacks. -void InvitesReceiverInternalIos::RegisterStartup(StartupRegistration *registration) { - firebase::LogDebug("Registered dynamic links handler %s", registration->identifier()); - g_ios_startup_impl.Register(); -} - - -// TODO(jsimantov): Remove this constant when b/27612427 is fixed. -const char* const InvitesReceiverInternalIos::kNullDeepLinkUrl = "file:///dev/null"; - -BOOL InvitesReceiverInternalIos::OpenUrl(NSURL *url, NSString *source_application, id annotation) { - LogDebug("OpenURL(%s, %s, %s)", url.description.UTF8String, - source_application.description.UTF8String, [annotation description].UTF8String); - MutexLock lock(g_static_mutex); - if (g_callbacks && g_callbacks->OpenUrl(url, source_application, annotation)) { - return YES; - } - g_open_url = url; - g_source_application = source_application; - g_annotation = annotation; - g_got_link_type = kLinkTypeUrl; - FetchDynamicLink(); - return YES; // We are potentially handling this URL. -} - -BOOL InvitesReceiverInternalIos::OpenUniversalLink(NSURL *universal_link) { - LogDebug("OpenUniversalLink(%s)", universal_link.description.UTF8String); - MutexLock lock(g_static_mutex); - g_open_url = universal_link; - g_source_application = nil; - g_annotation = nil; - g_got_link_type = kLinkTypeUniversal; - FetchDynamicLink(); - return YES; // We are potentially handling this URL. -} - -InvitesReceiverInternalIos::InvitesReceiverInternalIos( - const ::firebase::App &app) - : InvitesReceiverInternal(app), - callback_mutex_(Mutex::kModeNonRecursive), - fetch_in_progress_(false) { - assert(!g_invites_receiver); - g_invites_receiver = this; - g_ios_startup_impl.Register(); - -} - -InvitesReceiverInternalIos::~InvitesReceiverInternalIos() { - { - MutexLock lock(fetch_mutex_); - fetch_in_progress_ = false; - } - { - MutexLock lock(g_static_mutex); - g_invites_receiver = nullptr; - } - { - // Wait for any pending callbacks to finish. - MutexLock lock(callback_mutex_); - } - g_ios_startup_impl.Unregister(); -} - -bool InvitesReceiverInternalIos::PerformFetch() { - { - MutexLock lock(g_static_mutex); - g_fetch_timer = 0.0f; - g_fetch_poll_interval = kFetchCheckUrlInitialIntervalSeconds; - } - { - MutexLock lock(fetch_mutex_); - if (fetch_in_progress_) return true; - fetch_in_progress_ = true; - } - callback_mutex_.Acquire(); // Released by FinishFetch() when the fetch is complete. - std::string url; - MutexLock lock(g_static_mutex); - // Check if g_open_url is set. When the app starts, g_open_url will be null while - // checkForPendingDynamicLink executes, and then it will receive a special URL parsed by - // [FIRInvite handleURL], whether or not there is an app invite or deep link. This means there - // will be a short delay the first time we check for invites/deep links when the app starts. - if (g_open_url != nil) { - // Finish fetching now. - FinishFetch(); // Releases callback_mutex_. - } else { - // Spin up a thread to check on the URL. - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - // Check if we have received a URL yet. We should get one approx a quarter to half second - // after the app starts. We'll check a few times a second, and after a few seconds we give up - // and time out. - while (true) { - float current_interval; - { - MutexLock lock(g_static_mutex); - if (g_fetch_timer >= kFetchCheckUrlTimeoutSeconds) break; - g_fetch_timer += g_fetch_poll_interval; - current_interval = g_fetch_poll_interval; - g_fetch_poll_interval += kFetchCheckUrlIntervalIncreaseSeconds; - } - [NSThread sleepForTimeInterval:current_interval]; - { - MutexLock fetch_lock(fetch_mutex_); - if (!fetch_in_progress_) break; // Time out immediately. - } - bool link_ready = false; - { - MutexLock static_lock(g_static_mutex); - link_ready = g_open_url != nil; - } - if (link_ready) { - FinishFetch(); // Releases callback_mutex_. - return; - } - } - LogDebug("Timed out waiting for a link (waited %.2f seconds).", kFetchCheckUrlTimeoutSeconds); - // Timed out waiting to receive the invite. Unfortunately, this happens in the Invites library - // in certain cases. We have to consider that as just meaning there is no invite or deep link. - ReceivedInviteCallback("", "", kLinkMatchStrengthNoMatch, 0, ""); - callback_mutex_.Release(); - }); - } - return true; -} - -static internal::InternalLinkMatchStrength MatchTypeToLinkStrength(FIRDLMatchType match_type) { - switch (match_type) { - case FIRDLMatchTypeNone: - return internal::kLinkMatchStrengthNoMatch; - case FIRDLMatchTypeWeak: - return internal::kLinkMatchStrengthWeakMatch; - case FIRDLMatchTypeDefault: - return internal::kLinkMatchStrengthStrongMatch; - case FIRDLMatchTypeUnique: - return internal::kLinkMatchStrengthPerfectMatch; - } -} - -void InvitesReceiverInternalIos::FinishFetch() { - NSURL *url; - NSString *source_application; - id annotation; - LinkType link_type; - { - MutexLock lock(g_static_mutex); - FIREBASE_ASSERT(g_open_url != nil); - // Consume the URL. - url = g_open_url; - g_open_url = nil; - source_application = g_source_application; - g_source_application = nil; - annotation = g_annotation ? g_annotation : @{}; // handleURL fails on nil, use empty instead. - g_annotation = nil; - link_type = g_got_link_type; - g_got_link_type = kLinkTypeNone; - } - - if (link_type == kLinkTypeUrl) { - LogDebug("URL link %s", url.absoluteString.UTF8String); - // Regular URL, handle it synchronously. - bool processed_link = false; - LinkInfo link_info; - { - MutexLock lock(g_static_mutex); - processed_link = g_callbacks && g_callbacks->FinishFetch(url, source_application, annotation, - &link_info); - } - - int error_code = 0; - const char* error_string = ""; - if (!processed_link) { - // If FIRInvites couldn't get a link, check via FIRDynamicLinks instead (required for iOS 8). - FIRDynamicLink *dynamicLink = - [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; - - if (dynamicLink) { - // Got a FIRDynamicLink. It may or may not have an inviteId, but it will have a link. - // TODO(jsimantov): when FIRDynamicLink has metadata implemented, switch inviteId to use - // that. - NSString *inviteId = [dynamicLink inviteId]; - if (inviteId) link_info.invite_id = inviteId.UTF8String; - if (dynamicLink.url) link_info.deep_link = [dynamicLink.url absoluteString].UTF8String; - // TODO(jsimantov): Remove this workaround when b/27612427 is fixed. - if (link_info.deep_link == InvitesReceiverInternalIos::kNullDeepLinkUrl) { - link_info.deep_link = ""; - } - link_info.match_strength = MatchTypeToLinkStrength(dynamicLink.matchType); - } else { - LogWarning("Failed to process %s", url.absoluteString.UTF8String); - error_string = "Unable to retrieve link"; - error_code = 1; - } - } - ReceivedInviteCallback(link_info.invite_id, link_info.deep_link, link_info.match_strength, - error_code, error_string); - } else if (link_type == kLinkTypeUniversal) { - LogDebug("Universal link %s", url.absoluteString.UTF8String); - // Keep a strong reference to the FIRDynamicLinks singleton in the completion block until - // the block is complete. - __block FIRDynamicLinks* dynamic_links_reference = [FIRDynamicLinks dynamicLinks]; - // iOS 9+ Universal Link, handle asynchronously. (dynamic links only) - BOOL handled = [dynamic_links_reference handleUniversalLink:url - completion:^( - FIRDynamicLink *_Nullable dynamic_link, - NSError *_Nullable error) { - MutexLock lock(g_static_mutex); - dynamic_links_reference = nil; - auto receiver = g_invites_receiver; - if (receiver) { - int error_code = 1; /* firebase::dynamic_links::kErrorCodeFailed */ - std::string error_string = "Unknown error occurred."; - if (dynamic_link) { - std::string invite_id = util::NSStringToString(dynamic_link.inviteId); - std::string url_string = util::NSStringToString( - dynamic_link.url.absoluteString); - if (!url_string.empty() || !invite_id.empty()) { - receiver->ReceivedInviteCallback( - invite_id, url_string, MatchTypeToLinkStrength(dynamic_link.matchType), - 0, ""); - return; - } - } - if (error) { - std::string error_description = - util::NSStringToString(error.localizedDescription); - if (!error_description.empty()) error_string = error_description; - if (error.code) error_code = static_cast(error.code); - } else { - error_string = "The short dynamic link references a scheme that does not " - "match this application's bundle ID."; - } - receiver->ReceivedInviteCallback("", "", kLinkMatchStrengthNoMatch, error_code, - error_string); - } - }]; - if (!handled) { - // Link wasn't handled, complete with no received link. - ReceivedInviteCallback("", "", kLinkMatchStrengthNoMatch, 0, ""); - } - } - { - MutexLock lock(fetch_mutex_); - fetch_in_progress_ = false; - } - callback_mutex_.Release(); -} - -bool InvitesReceiverInternalIos::PerformConvertInvitation(const char* invitation_id) { - { - MutexLock lock(g_static_mutex); - if (g_callbacks) g_callbacks->PerformConvertInvitation(invitation_id); - } - ConvertedInviteCallback(invitation_id, 0, ""); - return true; -} - -void InvitesReceiverInternalIos::SetCallbacks( - InvitesReceiverInternalIos::Callbacks* callbacks) { - MutexLock lock(g_static_mutex); - g_callbacks = callbacks; -} - - -} // namespace internal -} // namespace invites -} // namespace firebase diff --git a/app/src/invites/receiver_interface.h b/app/src/invites/receiver_interface.h deleted file mode 100644 index da070ab239..0000000000 --- a/app/src/invites/receiver_interface.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2017 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. - */ - -#ifndef FIREBASE_APP_SRC_INVITES_RECEIVER_INTERFACE_H_ -#define FIREBASE_APP_SRC_INVITES_RECEIVER_INTERFACE_H_ - -#include - -namespace firebase { -namespace invites { - -namespace internal { - -/// @brief Enum describing the strength of a dynamic links match. -/// -/// This version is only used internally, and is not exposed to the user. The -/// dynamic links and invites libraries both mirror this for a different version -/// that the dev can use. -enum InternalLinkMatchStrength { - /// No match has been achieved - kLinkMatchStrengthNoMatch = 0, - - /// The match between the Dynamic Link and device is not perfect. You should - /// not reveal any personal information related to the Dynamic Link. - kLinkMatchStrengthWeakMatch, - - /// The match between the Dynamic Link and this device has a high confidence, - /// but there is a small possibility of error. - kLinkMatchStrengthStrongMatch, - - /// The match between the Dynamic Link and the device is exact. You may - /// safely - /// reveal any personal information related to this Dynamic Link. - kLinkMatchStrengthPerfectMatch -}; - -class ReceiverInterface { - public: - virtual ~ReceiverInterface() {} - - // Callback called when an invite is received. If an error occurred, - // result_code should be non-zero. Otherwise, either invitation_id should be - // set, or deep_link_url should be set, or both. - virtual void ReceivedInviteCallback(const std::string& invitation_id, - const std::string& deep_link_url, - InternalLinkMatchStrength match_strength, - int result_code, - const std::string& error_message) = 0; -}; - -} // namespace internal -} // namespace invites -} // namespace firebase - -#endif // FIREBASE_APP_SRC_INVITES_RECEIVER_INTERFACE_H_ diff --git a/app/src/invites/sender_receiver_interface.h b/app/src/invites/sender_receiver_interface.h deleted file mode 100644 index ea83faa16e..0000000000 --- a/app/src/invites/sender_receiver_interface.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2017 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. - */ - -#ifndef FIREBASE_APP_SRC_INVITES_SENDER_RECEIVER_INTERFACE_H_ -#define FIREBASE_APP_SRC_INVITES_SENDER_RECEIVER_INTERFACE_H_ - -#include -#include - -#include "app/src/invites/receiver_interface.h" - -namespace firebase { -namespace invites { -namespace internal { - -// Called by AndroidHelper when operations complete. -// This is due to AndroidHelper implementing both invite send and dynamic link -// receive operations on Android. -// This interface is not implemented on iOS as the dynamic link receive logic -// is completely separate from the invite sending logic. -class SenderReceiverInterface : public ReceiverInterface { - public: - SenderReceiverInterface() {} - virtual ~SenderReceiverInterface() {} - - // Called when an invite has been sent. - virtual void SentInviteCallback( - const std::vector& invitation_ids, int result_code, - const std::string& error_message) = 0; - - // Callback called when an invite conversion occurs. If an error occurred, - // result_code will be non-zero. Otherwise, the conversion was successful. - virtual void ConvertedInviteCallback(const std::string& invitation_id, - int result_code, - std::string error_message) = 0; -}; - -} // namespace internal -} // namespace invites -} // namespace firebase - -#endif // FIREBASE_APP_SRC_INVITES_SENDER_RECEIVER_INTERFACE_H_ diff --git a/app/src/invites/stub/invites_receiver_internal_stub.cc b/app/src/invites/stub/invites_receiver_internal_stub.cc deleted file mode 100644 index 58156b0680..0000000000 --- a/app/src/invites/stub/invites_receiver_internal_stub.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2017 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 "app/src/invites/stub/invites_receiver_internal_stub.h" - -namespace firebase { -namespace invites { -namespace internal { - -InvitesReceiverInternalStub::~InvitesReceiverInternalStub() {} - -bool InvitesReceiverInternalStub::PerformFetch() { return true; } - -bool InvitesReceiverInternalStub::PerformConvertInvitation( - const char* /* unused */) { - return true; -} - -} // namespace internal -} // namespace invites -} // namespace firebase diff --git a/app/src/invites/stub/invites_receiver_internal_stub.h b/app/src/invites/stub/invites_receiver_internal_stub.h deleted file mode 100644 index 763139c105..0000000000 --- a/app/src/invites/stub/invites_receiver_internal_stub.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2017 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. - */ - -#ifndef FIREBASE_APP_SRC_INVITES_STUB_INVITES_RECEIVER_INTERNAL_STUB_H_ -#define FIREBASE_APP_SRC_INVITES_STUB_INVITES_RECEIVER_INTERNAL_STUB_H_ - -#include "app/src/invites/invites_receiver_internal.h" - -namespace firebase { -class App; -namespace invites { -namespace internal { - -// Stub version of InvitesReceiverInternal, for use on desktop platforms. This -// version will simply not be able to fetch or convert invitations, and will -// return an error if you try. -class InvitesReceiverInternalStub : public InvitesReceiverInternal { - public: - explicit InvitesReceiverInternalStub(const ::firebase::App& app) - : InvitesReceiverInternal(app) {} - virtual ~InvitesReceiverInternalStub(); // NOLINT - virtual bool PerformFetch(); // NOLINT - virtual bool PerformConvertInvitation(const char* /* unused */); // NOLINT -}; - -} // namespace internal -} // namespace invites -} // namespace firebase - -#endif // FIREBASE_APP_SRC_INVITES_STUB_INVITES_RECEIVER_INTERNAL_STUB_H_ diff --git a/build_scripts/ios/build.sh b/build_scripts/ios/build.sh index c466d35af7..8b8fb2fab5 100755 --- a/build_scripts/ios/build.sh +++ b/build_scripts/ios/build.sh @@ -27,7 +27,7 @@ readonly SUPPORTED_PLATFORMS=(device simulator) readonly SUPPORTED_ARCHITECTURES=(arm64 x86_64) readonly DEVICE_ARCHITECTURES=(arm64) readonly SIMULATOR_ARCHITECTURES=(arm64 x86_64) -readonly SUPPORTED_TARGETS=(firebase_analytics firebase_auth firebase_app_check firebase_database firebase_dynamic_links firebase_firestore firebase_functions firebase_gma firebase_installations firebase_messaging firebase_remote_config firebase_storage firebase_ump) +readonly SUPPORTED_TARGETS=(firebase_analytics firebase_auth firebase_app_check firebase_database firebase_firestore firebase_functions firebase_gma firebase_installations firebase_messaging firebase_remote_config firebase_storage firebase_ump) # build default value buildpath="ios_build" diff --git a/build_scripts/packaging.conf b/build_scripts/packaging.conf index 8f1ee6f401..b2e40da1c1 100644 --- a/build_scripts/packaging.conf +++ b/build_scripts/packaging.conf @@ -2,5 +2,5 @@ # List of all Firebase products to include in the binary SDK package. readonly -a product_list=(analytics app app_check auth database -dynamic_links firestore functions gma installations messaging +firestore functions gma installations messaging remote_config storage ump) diff --git a/dynamic_links/CMakeLists.txt b/dynamic_links/CMakeLists.txt deleted file mode 100644 index 01283f3f38..0000000000 --- a/dynamic_links/CMakeLists.txt +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright 2019 Google -# -# 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. - -# CMake file for the firebase_dynamic_links library - -# Common source files used by all platforms -set(common_SRCS - src/common.cc - src/common.h - src/listener.cc) - -# Source files used by the Android implementation. -set(android_SRCS - src/dynamic_links_android.cc) - -# Source files used by the iOS implementation. -set(ios_SRCS - src/dynamic_links_ios.mm) - -# Source files used by the stub implementation. -set(stub_SRCS - src/dynamic_links_stub.cc) - -if(ANDROID) - set(dynamic_links_platform_SRCS - "${android_SRCS}") -elseif(IOS) - set(dynamic_links_platform_SRCS - "${ios_SRCS}") -else() - set(dynamic_links_platform_SRCS - "${stub_SRCS}") -endif() - -add_library(firebase_dynamic_links STATIC - ${common_SRCS} - ${dynamic_links_platform_SRCS}) - -set_property(TARGET firebase_dynamic_links PROPERTY FOLDER "Firebase Cpp") - -# Set up the dependency on Firebase App. -target_link_libraries(firebase_dynamic_links - PUBLIC firebase_app) -# Public headers all refer to each other relative to the src/include directory, -# while private headers are relative to the entire C++ SDK directory. -target_include_directories(firebase_dynamic_links - PUBLIC - ${CMAKE_CURRENT_LIST_DIR}/src/include - PRIVATE - ${FIREBASE_CPP_SDK_ROOT_DIR} -) -target_compile_definitions(firebase_dynamic_links - PRIVATE - -DINTERNAL_EXPERIMENTAL=1 -) -# Automatically include headers that might not be declared. -if(MSVC) - add_definitions(/FI"assert.h" /FI"string.h" /FI"stdint.h") -else() - add_definitions(-include assert.h -include string.h) -endif() - -if(ANDROID) - firebase_cpp_proguard_file(dynamic_links) -elseif(IOS) - # Enable Automatic Reference Counting (ARC) and Bitcode. - target_compile_options(firebase_dynamic_links - PUBLIC "-fobjc-arc" "-fembed-bitcode") - target_link_libraries(firebase_dynamic_links - PUBLIC "-fembed-bitcode") - - setup_pod_headers( - firebase_dynamic_links - POD_NAMES - FirebaseDynamicLinks - ) - - if (FIREBASE_XCODE_TARGET_FORMAT STREQUAL "frameworks") - set_target_properties(firebase_dynamic_links PROPERTIES - FRAMEWORK TRUE - ) - endif() -endif() - -cpp_pack_library(firebase_dynamic_links "") -cpp_pack_public_headers() diff --git a/dynamic_links/build.gradle b/dynamic_links/build.gradle deleted file mode 100644 index 6fd8088c25..0000000000 --- a/dynamic_links/build.gradle +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2018 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. - -buildscript { - repositories { - google() - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - } -} -allprojects { - repositories { - google() - mavenCentral() - } -} - -apply plugin: 'com.android.library' - -android { - compileSdkVersion 34 - ndkPath System.getenv('ANDROID_NDK_HOME') - buildToolsVersion '32.0.0' - - sourceSets { - main { - manifest.srcFile '../android_build_files/AndroidManifest.xml' - } - } - - externalNativeBuild { - cmake { - path '../CMakeLists.txt' - } - } - - defaultConfig { - minSdkVersion 23 - targetSdkVersion 34 - versionCode 1 - versionName "1.0" - - buildTypes { - release { - minifyEnabled false - } - } - - externalNativeBuild { - cmake { - targets 'firebase_dynamic_links' - // Args are: Re-use app library prebuilt by app gradle project. - // Don't configure all the cmake subprojects. - // Only include needed project. - arguments '-DFIREBASE_CPP_USE_PRIOR_GRADLE_BUILD=ON', - '-DFIREBASE_INCLUDE_LIBRARY_DEFAULT=OFF', - '-DFIREBASE_INCLUDE_DYNAMIC_LINKS=ON' - } - } - } - - lintOptions { - abortOnError false - } -} - -dependencies { - implementation project(':app') -} -apply from: "$rootDir/android_build_files/android_abis.gradle" -apply from: "$rootDir/android_build_files/generate_proguard.gradle" -project.afterEvaluate { - generateProguardFile('dynamic_links') - preBuild.dependsOn(':app:build') - project.tasks.withType(com.android.build.gradle.internal.tasks.CheckAarMetadataTask) { - enabled = false - } -} diff --git a/dynamic_links/integration_test/AndroidManifest.xml b/dynamic_links/integration_test/AndroidManifest.xml deleted file mode 100644 index d737ea3ec6..0000000000 --- a/dynamic_links/integration_test/AndroidManifest.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/dynamic_links/integration_test/CMakeLists.txt b/dynamic_links/integration_test/CMakeLists.txt deleted file mode 100644 index 5286ceba8c..0000000000 --- a/dynamic_links/integration_test/CMakeLists.txt +++ /dev/null @@ -1,242 +0,0 @@ -# Copyright 2020 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. - -# Cmake file for a single C++ integration test build. - -cmake_minimum_required(VERSION 2.8) - -find_program(FIREBASE_PYTHON_EXECUTABLE - NAMES python3 python - DOC "The Python interpreter to use, such as one from a venv" - REQUIRED -) - -# User settings for Firebase integration tests. -# Path to Firebase SDK. -# Try to read the path to the Firebase C++ SDK from an environment variable. -if (NOT "$ENV{FIREBASE_CPP_SDK_DIR}" STREQUAL "") - set(DEFAULT_FIREBASE_CPP_SDK_DIR "$ENV{FIREBASE_CPP_SDK_DIR}") -else() - if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/../../cpp_sdk_version.json") - set(DEFAULT_FIREBASE_CPP_SDK_DIR "${CMAKE_CURRENT_LIST_DIR}/../..") - else() - set(DEFAULT_FIREBASE_CPP_SDK_DIR "firebase_cpp_sdk") - endif() -endif() -if ("${FIREBASE_CPP_SDK_DIR}" STREQUAL "") - set(FIREBASE_CPP_SDK_DIR ${DEFAULT_FIREBASE_CPP_SDK_DIR}) -endif() -if(NOT EXISTS ${FIREBASE_CPP_SDK_DIR}) - message(FATAL_ERROR "The Firebase C++ SDK directory does not exist: ${FIREBASE_CPP_SDK_DIR}. See the readme.md for more information") -endif() - -# Copy all prerequisite files for integration tests to run. -if(NOT ANDROID) - if (EXISTS ${CMAKE_CURRENT_LIST_DIR}/../../setup_integration_tests.py) - # If this is running from inside the SDK directory, run the setup script. - execute_process( - COMMAND - ${FIREBASE_PYTHON_EXECUTABLE} - "${CMAKE_CURRENT_LIST_DIR}/../../setup_integration_tests.py" - "${CMAKE_CURRENT_LIST_DIR}" - RESULT_VARIABLE - FIREBASE_PYTHON_EXECUTABLE_RESULT - ) - if(NOT FIREBASE_PYTHON_EXECUTABLE_RESULT EQUAL 0) - message(FATAL_ERROR "Failed to run setup_integration_tests.py") - endif() - endif() -endif() - -# Windows runtime mode, either MD or MT depending on whether you are using -# /MD or /MT. For more information see: -# https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx -set(MSVC_RUNTIME_MODE MD) - -project(firebase_testapp) - -# Integration test source files. -set(FIREBASE_APP_FRAMEWORK_SRCS - src/app_framework.cc - src/app_framework.h -) - -set(FIREBASE_TEST_FRAMEWORK_SRCS - src/firebase_test_framework.h - src/firebase_test_framework.cc -) - -set(FIREBASE_INTEGRATION_TEST_SRCS - src/integration_test.cc -) - -# The include directory for the testapp. -include_directories(src) - -# Firebase C++ SDK requires C++14. -set (CMAKE_CXX_STANDARD 14) -set (CMAKE_CXX_STANDARD_REQUIRED YES) # Don't fall back to an earlier version. - -# Download and unpack googletest (and googlemock) at configure time -set(GOOGLETEST_ROOT ${CMAKE_CURRENT_LIST_DIR}/external/googletest) -# Note: Once googletest is downloaded once, it won't be updated or -# downloaded again unless you delete the "external/googletest" -# directory. -if (NOT EXISTS ${GOOGLETEST_ROOT}/src/googletest/src/gtest-all.cc) - configure_file(googletest.cmake - ${CMAKE_CURRENT_LIST_DIR}/external/googletest/CMakeLists.txt COPYONLY) - execute_process(COMMAND ${CMAKE_COMMAND} . - RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/external/googletest ) - if(result) - message(FATAL_ERROR "CMake step for googletest failed: ${result}") - endif() - execute_process(COMMAND ${CMAKE_COMMAND} --build . - RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/external/googletest ) - if(result) - message(FATAL_ERROR "Build step for googletest failed: ${result}") - endif() -endif() - -if(ANDROID) - # Build an Android application. - - # Source files used for the Android build. - set(FIREBASE_APP_FRAMEWORK_ANDROID_SRCS - src/android/android_app_framework.cc - ) - - # Source files used for the Android build. - set(FIREBASE_TEST_FRAMEWORK_ANDROID_SRCS - src/android/android_firebase_test_framework.cc - ) - - # Build native_app_glue as a static lib - add_library(native_app_glue STATIC - ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c) - - # Export ANativeActivity_onCreate(), - # Refer to: https://github.com/android-ndk/ndk/issues/381. - set(CMAKE_SHARED_LINKER_FLAGS - "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate") - - add_library(gtest STATIC - ${GOOGLETEST_ROOT}/src/googletest/src/gtest-all.cc) - target_include_directories(gtest - PRIVATE ${GOOGLETEST_ROOT}/src/googletest - PUBLIC ${GOOGLETEST_ROOT}/src/googletest/include) - add_library(gmock STATIC - ${GOOGLETEST_ROOT}/src/googlemock/src/gmock-all.cc) - target_include_directories(gmock - PRIVATE ${GOOGLETEST_ROOT}/src/googletest - PRIVATE ${GOOGLETEST_ROOT}/src/googlemock - PUBLIC ${GOOGLETEST_ROOT}/src/googletest/include - PUBLIC ${GOOGLETEST_ROOT}/src/googlemock/include) - - # Define the target as a shared library, as that is what gradle expects. - set(integration_test_target_name "android_integration_test_main") - add_library(${integration_test_target_name} SHARED - ${FIREBASE_APP_FRAMEWORK_SRCS} - ${FIREBASE_APP_FRAMEWORK_ANDROID_SRCS} - ${FIREBASE_INTEGRATION_TEST_SRCS} - ${FIREBASE_TEST_FRAMEWORK_SRCS} - ${FIREBASE_TEST_FRAMEWORK_ANDROID_SRCS} - ) - - target_include_directories(${integration_test_target_name} PRIVATE - ${ANDROID_NDK}/sources/android/native_app_glue) - - set(ADDITIONAL_LIBS log android atomic native_app_glue) -else() - # Build a desktop application. - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) - - # Prevent overriding the parent project's compiler/linker - # settings on Windows - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - - # Add googletest directly to our build. This defines - # the gtest and gtest_main targets. - add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/external/googletest/src - ${CMAKE_CURRENT_LIST_DIR}/external/googletest/build - EXCLUDE_FROM_ALL) - - # The gtest/gtest_main targets carry header search path - # dependencies automatically when using CMake 2.8.11 or - # later. Otherwise we have to add them here ourselves. - if (CMAKE_VERSION VERSION_LESS 2.8.11) - include_directories("${gtest_SOURCE_DIR}/include") - include_directories("${gmock_SOURCE_DIR}/include") - endif() - - # Windows runtime mode, either MD or MT depending on whether you are using - # /MD or /MT. For more information see: - # https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx - set(MSVC_RUNTIME_MODE MD) - - # Platform abstraction layer for the desktop integration test. - set(FIREBASE_APP_FRAMEWORK_DESKTOP_SRCS - src/desktop/desktop_app_framework.cc - src/desktop/desktop_firebase_test_framework.cc - ) - - set(integration_test_target_name "integration_test") - add_executable(${integration_test_target_name} - ${FIREBASE_APP_FRAMEWORK_SRCS} - ${FIREBASE_APP_FRAMEWORK_DESKTOP_SRCS} - ${FIREBASE_TEST_FRAMEWORK_SRCS} - ${FIREBASE_INTEGRATION_TEST_SRCS} - ) - - if(APPLE) - set(ADDITIONAL_LIBS - gssapi_krb5 - pthread - "-framework CoreFoundation" - "-framework Foundation" - "-framework GSS" - "-framework Security" - ) - elseif(MSVC) - set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32) - else() - set(ADDITIONAL_LIBS pthread) - endif() - - # If a config file is present, copy it into the binary location so that it's - # possible to create the default Firebase app. - set(FOUND_JSON_FILE FALSE) - foreach(config "google-services-desktop.json" "google-services.json") - if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/${config}") - add_custom_command( - TARGET ${integration_test_target_name} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy - "${CMAKE_CURRENT_LIST_DIR}/${config}" $) - set(FOUND_JSON_FILE TRUE) - break() - endif() - endforeach() - if(NOT FOUND_JSON_FILE) - message(WARNING "Failed to find either google-services-desktop.json or google-services.json. See the readme.md for more information.") - endif() -endif() - -# Add the Firebase libraries to the target using the function from the SDK. -add_subdirectory(${FIREBASE_CPP_SDK_DIR} bin/ EXCLUDE_FROM_ALL) -# Note that firebase_app needs to be last in the list. -set(firebase_libs firebase_dynamic_links firebase_app) -set(gtest_libs gtest gmock) -target_link_libraries(${integration_test_target_name} ${firebase_libs} - ${gtest_libs} ${ADDITIONAL_LIBS}) diff --git a/dynamic_links/integration_test/Images.xcassets/AppIcon.appiconset/Contents.json b/dynamic_links/integration_test/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d8db8d65fd..0000000000 --- a/dynamic_links/integration_test/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "83.5x83.5", - "scale" : "2x" - }, - { - "idiom" : "ios-marketing", - "size" : "1024x1024", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/dynamic_links/integration_test/Images.xcassets/LaunchImage.launchimage/Contents.json b/dynamic_links/integration_test/Images.xcassets/LaunchImage.launchimage/Contents.json deleted file mode 100644 index 6f870a4629..0000000000 --- a/dynamic_links/integration_test/Images.xcassets/LaunchImage.launchimage/Contents.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "images" : [ - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "iphone", - "subtype" : "retina4", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/dynamic_links/integration_test/Info.plist b/dynamic_links/integration_test/Info.plist deleted file mode 100644 index 7b0cefa0bc..0000000000 --- a/dynamic_links/integration_test/Info.plist +++ /dev/null @@ -1,56 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleURLSchemes - - $(PRODUCT_BUNDLE_IDENTIFIER) - - CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLName - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleURLSchemes - - $(PRODUCT_BUNDLE_IDENTIFIER) - - - - CFBundleTypeRole - Editor - CFBundleURLName - google - CFBundleURLSchemes - - REPLACE_WITH_REVERSED_CLIENT_ID - firebase-game-loop - - - - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - NSContactsUsageDescription - Invite others to use the app. - - diff --git a/dynamic_links/integration_test/LaunchScreen.storyboard b/dynamic_links/integration_test/LaunchScreen.storyboard deleted file mode 100644 index 673e0f7e68..0000000000 --- a/dynamic_links/integration_test/LaunchScreen.storyboard +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/dynamic_links/integration_test/LibraryManifest.xml b/dynamic_links/integration_test/LibraryManifest.xml deleted file mode 100644 index 3cd768235d..0000000000 --- a/dynamic_links/integration_test/LibraryManifest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - diff --git a/dynamic_links/integration_test/Podfile b/dynamic_links/integration_test/Podfile deleted file mode 100644 index d6a404cee9..0000000000 --- a/dynamic_links/integration_test/Podfile +++ /dev/null @@ -1,16 +0,0 @@ -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '13.0' -# Firebase Dynamic Links test application. -use_frameworks! :linkage => :static - -target 'integration_test' do - platform :ios, '13.0' - pod 'Firebase/DynamicLinks', '11.14.0' -end - -post_install do |installer| - # If this is running from inside the SDK directory, run the setup script. - system("if [[ -r ../../setup_integration_tests.py ]]; then python3 ../../setup_integration_tests.py .; fi") - system("python3 ./download_googletest.py") -end - diff --git a/dynamic_links/integration_test/build.gradle b/dynamic_links/integration_test/build.gradle deleted file mode 100644 index 65c65fc06b..0000000000 --- a/dynamic_links/integration_test/build.gradle +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2020 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. - -// Top-level build file where you can add configuration options common to all sub-projects/modules. -buildscript { - repositories { - mavenLocal() - maven { url 'https://maven.google.com' } - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - // r8 on this version of the Android tools has a bug, - // so specify a different version to use. - classpath 'com.android.tools:r8:8.3.37' - classpath 'com.google.gms:google-services:4.4.1' - } -} - -allprojects { - repositories { - mavenLocal() - maven { url 'https://maven.google.com' } - mavenCentral() - } -} - -apply plugin: 'com.android.application' - -android { - compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 - } - compileSdkVersion 34 - ndkPath System.getenv('ANDROID_NDK_HOME') - buildToolsVersion '32.0.0' - - sourceSets { - main { - jniLibs.srcDirs = ['libs'] - manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = ['src/android/java'] - res.srcDirs = ['res'] - } - } - - defaultConfig { - applicationId 'com.google.android.dynamiclinks.testapp' - minSdkVersion 23 - targetSdkVersion 34 - versionCode 1 - versionName '1.0' - externalNativeBuild.cmake { - arguments "-DFIREBASE_CPP_SDK_DIR=$gradle.firebase_cpp_sdk_dir" - } - } - externalNativeBuild.cmake { - path 'CMakeLists.txt' - } - buildTypes { - release { - minifyEnabled true - proguardFile getDefaultProguardFile('proguard-android.txt') - proguardFile file('proguard.pro') - } - } -} - -apply from: "$gradle.firebase_cpp_sdk_dir/Android/firebase_dependencies.gradle" -firebaseCpp.dependencies { - dynamicLinks -} - -apply plugin: 'com.google.gms.google-services' - -task copyIntegrationTestFiles(type:Exec) { - // If this is running form inside the SDK directory, run the setup script. - if (project.file('../../setup_integration_tests.py').exists()) { - commandLine 'python3', '../../setup_integration_tests.py', project.projectDir.toString() - } - else { - commandLine 'echo', '' - } -} - -build.dependsOn(copyIntegrationTestFiles) - -project.afterEvaluate { - project.tasks.withType(com.android.build.gradle.internal.tasks.CheckAarMetadataTask) { - enabled = false - } -} diff --git a/dynamic_links/integration_test/googletest.cmake b/dynamic_links/integration_test/googletest.cmake deleted file mode 100644 index 2261a3a7f6..0000000000 --- a/dynamic_links/integration_test/googletest.cmake +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2020 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. - -# Download GoogleTest from GitHub as an external project. -# Pin to 1.11.0 because we touch internal GoogleTest structures that could change in the future. - -# This CMake file is taken from: -# https://github.com/google/googletest/blob/master/googletest/README.md#incorporating-into-an-existing-cmake-project - -cmake_minimum_required(VERSION 2.8.2) - -project(googletest-download NONE) - -include(ExternalProject) -ExternalProject_Add(googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG "release-1.11.0" - SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/src" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/build" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" -) diff --git a/dynamic_links/integration_test/gradle.properties b/dynamic_links/integration_test/gradle.properties deleted file mode 100644 index ac891ac594..0000000000 --- a/dynamic_links/integration_test/gradle.properties +++ /dev/null @@ -1,2 +0,0 @@ -android.useAndroidX = true -org.gradle.jvmargs=-Xmx2560m diff --git a/dynamic_links/integration_test/gradle/wrapper/gradle-wrapper.jar b/dynamic_links/integration_test/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 8c0fb64a86..0000000000 Binary files a/dynamic_links/integration_test/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/dynamic_links/integration_test/gradle/wrapper/gradle-wrapper.properties b/dynamic_links/integration_test/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 2eb04a3b17..0000000000 --- a/dynamic_links/integration_test/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Mon Nov 27 14:03:45 PST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https://services.gradle.org/distributions/gradle-7.5.1-all.zip diff --git a/dynamic_links/integration_test/gradlew b/dynamic_links/integration_test/gradlew deleted file mode 100755 index 7b9f9e2991..0000000000 --- a/dynamic_links/integration_test/gradlew +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright 2020 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. - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/dynamic_links/integration_test/gradlew.bat b/dynamic_links/integration_test/gradlew.bat deleted file mode 100644 index 4ba75ee288..0000000000 --- a/dynamic_links/integration_test/gradlew.bat +++ /dev/null @@ -1,104 +0,0 @@ -@rem Copyright 2020 Google LLC -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem http://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/dynamic_links/integration_test/integration_test.entitlements b/dynamic_links/integration_test/integration_test.entitlements deleted file mode 100644 index f8adad53ee..0000000000 --- a/dynamic_links/integration_test/integration_test.entitlements +++ /dev/null @@ -1,12 +0,0 @@ - - - - - application-identifier - $(AppIdentifierPrefix)$(CFBundleIdentifier) - com.apple.developer.associated-domains - - applinks:REPLACE_WITH_YOUR_URI_PREFIX - - - diff --git a/dynamic_links/integration_test/integration_test.xcodeproj/project.pbxproj b/dynamic_links/integration_test/integration_test.xcodeproj/project.pbxproj deleted file mode 100644 index 76cdf2d9af..0000000000 --- a/dynamic_links/integration_test/integration_test.xcodeproj/project.pbxproj +++ /dev/null @@ -1,377 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 520BC0391C869159008CFBC3 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 520BC0381C869159008CFBC3 /* GoogleService-Info.plist */; }; - 529226D61C85F68000C89379 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529226D51C85F68000C89379 /* Foundation.framework */; }; - 529226D81C85F68000C89379 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529226D71C85F68000C89379 /* CoreGraphics.framework */; }; - 529226DA1C85F68000C89379 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529226D91C85F68000C89379 /* UIKit.framework */; }; - D603B7262819C8CA008A979F /* empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = D603B7252819C8CA008A979F /* empty.swift */; }; - D61C5F8E22BABA9C00A79141 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D61C5F8C22BABA9B00A79141 /* Images.xcassets */; }; - D61C5F9622BABAD200A79141 /* integration_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D61C5F9222BABAD100A79141 /* integration_test.cc */; }; - D62CCBC022F367140099BE9F /* gmock-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = D62CCBBF22F367140099BE9F /* gmock-all.cc */; }; - D66B16871CE46E8900E5638A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D66B16861CE46E8900E5638A /* LaunchScreen.storyboard */; }; - D67D355822BABD2200292C1D /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = D67D355622BABD2100292C1D /* gtest-all.cc */; }; - D6C179E922CB322900C2651A /* ios_app_framework.mm in Sources */ = {isa = PBXBuildFile; fileRef = D6C179E722CB322900C2651A /* ios_app_framework.mm */; }; - D6C179EA22CB322900C2651A /* ios_firebase_test_framework.mm in Sources */ = {isa = PBXBuildFile; fileRef = D6C179E822CB322900C2651A /* ios_firebase_test_framework.mm */; }; - D6C179EE22CB323300C2651A /* firebase_test_framework.cc in Sources */ = {isa = PBXBuildFile; fileRef = D6C179EC22CB323300C2651A /* firebase_test_framework.cc */; }; - D6C179F022CB32A000C2651A /* app_framework.cc in Sources */ = {isa = PBXBuildFile; fileRef = D6C179EF22CB32A000C2651A /* app_framework.cc */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 520BC0381C869159008CFBC3 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; - 529226D21C85F68000C89379 /* integration_test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = integration_test.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 529226D51C85F68000C89379 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 529226D71C85F68000C89379 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - 529226D91C85F68000C89379 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - 529226EE1C85F68000C89379 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; - D603B7252819C8CA008A979F /* empty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = empty.swift; path = src/empty.swift; sourceTree = ""; }; - D61C5F8C22BABA9B00A79141 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - D61C5F8D22BABA9C00A79141 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - D61C5F9222BABAD100A79141 /* integration_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = integration_test.cc; path = src/integration_test.cc; sourceTree = ""; }; - D62CCBBF22F367140099BE9F /* gmock-all.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gmock-all.cc"; path = "external/googletest/src/googlemock/src/gmock-all.cc"; sourceTree = ""; }; - D62CCBC122F367320099BE9F /* gmock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gmock.h; path = external/googletest/src/googlemock/include/gmock/gmock.h; sourceTree = ""; }; - D66B16861CE46E8900E5638A /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; - D67D355622BABD2100292C1D /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gtest-all.cc"; path = "external/googletest/src/googletest/src/gtest-all.cc"; sourceTree = ""; }; - D67D355722BABD2100292C1D /* gtest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gtest.h; path = external/googletest/src/googletest/include/gtest/gtest.h; sourceTree = ""; }; - D6C179E722CB322900C2651A /* ios_app_framework.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ios_app_framework.mm; path = src/ios/ios_app_framework.mm; sourceTree = ""; }; - D6C179E822CB322900C2651A /* ios_firebase_test_framework.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ios_firebase_test_framework.mm; path = src/ios/ios_firebase_test_framework.mm; sourceTree = ""; }; - D6C179EB22CB323300C2651A /* firebase_test_framework.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = firebase_test_framework.h; path = src/firebase_test_framework.h; sourceTree = ""; }; - D6C179EC22CB323300C2651A /* firebase_test_framework.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = firebase_test_framework.cc; path = src/firebase_test_framework.cc; sourceTree = ""; }; - D6C179ED22CB323300C2651A /* app_framework.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = app_framework.h; path = src/app_framework.h; sourceTree = ""; }; - D6C179EF22CB32A000C2651A /* app_framework.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = app_framework.cc; path = src/app_framework.cc; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 529226CF1C85F68000C89379 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 529226D81C85F68000C89379 /* CoreGraphics.framework in Frameworks */, - 529226DA1C85F68000C89379 /* UIKit.framework in Frameworks */, - 529226D61C85F68000C89379 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 529226C91C85F68000C89379 = { - isa = PBXGroup; - children = ( - D61C5F8C22BABA9B00A79141 /* Images.xcassets */, - D61C5F8D22BABA9C00A79141 /* Info.plist */, - D66B16861CE46E8900E5638A /* LaunchScreen.storyboard */, - 520BC0381C869159008CFBC3 /* GoogleService-Info.plist */, - 5292271D1C85FB5500C89379 /* src */, - 529226D41C85F68000C89379 /* Frameworks */, - 529226D31C85F68000C89379 /* Products */, - ); - sourceTree = ""; - }; - 529226D31C85F68000C89379 /* Products */ = { - isa = PBXGroup; - children = ( - 529226D21C85F68000C89379 /* integration_test.app */, - ); - name = Products; - sourceTree = ""; - }; - 529226D41C85F68000C89379 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 529226D51C85F68000C89379 /* Foundation.framework */, - 529226D71C85F68000C89379 /* CoreGraphics.framework */, - 529226D91C85F68000C89379 /* UIKit.framework */, - 529226EE1C85F68000C89379 /* XCTest.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 5292271D1C85FB5500C89379 /* src */ = { - isa = PBXGroup; - children = ( - D603B7252819C8CA008A979F /* empty.swift */, - D62CCBC122F367320099BE9F /* gmock.h */, - D62CCBBF22F367140099BE9F /* gmock-all.cc */, - D67D355622BABD2100292C1D /* gtest-all.cc */, - D67D355722BABD2100292C1D /* gtest.h */, - D6C179EF22CB32A000C2651A /* app_framework.cc */, - D6C179ED22CB323300C2651A /* app_framework.h */, - D6C179EC22CB323300C2651A /* firebase_test_framework.cc */, - D6C179EB22CB323300C2651A /* firebase_test_framework.h */, - D61C5F9222BABAD100A79141 /* integration_test.cc */, - 5292271E1C85FB5B00C89379 /* ios */, - ); - name = src; - sourceTree = ""; - }; - 5292271E1C85FB5B00C89379 /* ios */ = { - isa = PBXGroup; - children = ( - D6C179E722CB322900C2651A /* ios_app_framework.mm */, - D6C179E822CB322900C2651A /* ios_firebase_test_framework.mm */, - ); - name = ios; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 529226D11C85F68000C89379 /* integration_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 529226F91C85F68000C89379 /* Build configuration list for PBXNativeTarget "integration_test" */; - buildPhases = ( - 529226CE1C85F68000C89379 /* Sources */, - 529226CF1C85F68000C89379 /* Frameworks */, - 529226D01C85F68000C89379 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = integration_test; - productName = testapp; - productReference = 529226D21C85F68000C89379 /* integration_test.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 529226CA1C85F68000C89379 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0640; - ORGANIZATIONNAME = Google; - TargetAttributes = { - 529226D11C85F68000C89379 = { - CreatedOnToolsVersion = 6.4; - DevelopmentTeam = EQHXZ8M8AV; - LastSwiftMigration = 1320; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 529226CD1C85F68000C89379 /* Build configuration list for PBXProject "integration_test" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - English, - en, - ); - mainGroup = 529226C91C85F68000C89379; - productRefGroup = 529226D31C85F68000C89379 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 529226D11C85F68000C89379 /* integration_test */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 529226D01C85F68000C89379 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D61C5F8E22BABA9C00A79141 /* Images.xcassets in Resources */, - D66B16871CE46E8900E5638A /* LaunchScreen.storyboard in Resources */, - 520BC0391C869159008CFBC3 /* GoogleService-Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 529226CE1C85F68000C89379 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D67D355822BABD2200292C1D /* gtest-all.cc in Sources */, - D62CCBC022F367140099BE9F /* gmock-all.cc in Sources */, - D6C179EA22CB322900C2651A /* ios_firebase_test_framework.mm in Sources */, - D61C5F9622BABAD200A79141 /* integration_test.cc in Sources */, - D6C179E922CB322900C2651A /* ios_app_framework.mm in Sources */, - D603B7262819C8CA008A979F /* empty.swift in Sources */, - D6C179F022CB32A000C2651A /* app_framework.cc in Sources */, - D6C179EE22CB323300C2651A /* firebase_test_framework.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 529226F71C85F68000C89379 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 529226F81C85F68000C89379 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 529226FA1C85F68000C89379 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)", - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "\"$(SRCROOT)/src\"", - "\"$(SRCROOT)/external/googletest/src/googletest/include\"", - "\"$(SRCROOT)/external/googletest/src/googlemock/include\"", - "\"$(SRCROOT)/external/googletest/src/googletest\"", - "\"$(SRCROOT)/external/googletest/src/googlemock\"", - ); - INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.3; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - 529226FB1C85F68000C89379 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)", - ); - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "\"$(SRCROOT)/src\"", - "\"$(SRCROOT)/external/googletest/src/googletest/include\"", - "\"$(SRCROOT)/external/googletest/src/googlemock/include\"", - "\"$(SRCROOT)/external/googletest/src/googletest\"", - "\"$(SRCROOT)/external/googletest/src/googlemock\"", - ); - INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.3; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 529226CD1C85F68000C89379 /* Build configuration list for PBXProject "integration_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 529226F71C85F68000C89379 /* Debug */, - 529226F81C85F68000C89379 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 529226F91C85F68000C89379 /* Build configuration list for PBXNativeTarget "integration_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 529226FA1C85F68000C89379 /* Debug */, - 529226FB1C85F68000C89379 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 529226CA1C85F68000C89379 /* Project object */; -} diff --git a/dynamic_links/integration_test/proguard.pro b/dynamic_links/integration_test/proguard.pro deleted file mode 100644 index 2d04b8a9a5..0000000000 --- a/dynamic_links/integration_test/proguard.pro +++ /dev/null @@ -1,2 +0,0 @@ --ignorewarnings --keep,includedescriptorclasses public class com.google.firebase.example.LoggingUtils { * ; } diff --git a/dynamic_links/integration_test/res/layout/main.xml b/dynamic_links/integration_test/res/layout/main.xml deleted file mode 100644 index cbe90c3ebe..0000000000 --- a/dynamic_links/integration_test/res/layout/main.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - diff --git a/dynamic_links/integration_test/res/values/strings.xml b/dynamic_links/integration_test/res/values/strings.xml deleted file mode 100644 index 0c05e26ec7..0000000000 --- a/dynamic_links/integration_test/res/values/strings.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Firebase Dynamic Links Integration Test - diff --git a/dynamic_links/integration_test/settings.gradle b/dynamic_links/integration_test/settings.gradle deleted file mode 100644 index 8b600af5be..0000000000 --- a/dynamic_links/integration_test/settings.gradle +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2018 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. - -def firebase_cpp_sdk_dir = System.getProperty('firebase_cpp_sdk.dir') -if (firebase_cpp_sdk_dir == null || firebase_cpp_sdk_dir.isEmpty()) { - firebase_cpp_sdk_dir = System.getenv('FIREBASE_CPP_SDK_DIR') - if (firebase_cpp_sdk_dir == null || firebase_cpp_sdk_dir.isEmpty()) { - if ((file('../../cpp_sdk_version.json')).exists()) { - firebase_cpp_sdk_dir = file('../..').absolutePath - } - else if ((file('firebase_cpp_sdk')).exists()) { - firebase_cpp_sdk_dir = 'firebase_cpp_sdk' - } else { - throw new StopActionException( - 'firebase_cpp_sdk.dir property or the FIREBASE_CPP_SDK_DIR ' + - 'environment variable must be set to reference the Firebase C++ ' + - 'SDK install directory. This is used to configure static library ' + - 'and C/C++ include paths for the SDK.') - } - } -} -if (!(new File(firebase_cpp_sdk_dir)).exists()) { - throw new StopActionException( - sprintf('Firebase C++ SDK directory %s does not exist', - firebase_cpp_sdk_dir)) -} -gradle.ext.firebase_cpp_sdk_dir = "$firebase_cpp_sdk_dir" -includeBuild("$firebase_cpp_sdk_dir") { - name = "firebase_cpp_sdk" -} diff --git a/dynamic_links/integration_test/src/integration_test.cc b/dynamic_links/integration_test/src/integration_test.cc deleted file mode 100644 index df73206cb3..0000000000 --- a/dynamic_links/integration_test/src/integration_test.cc +++ /dev/null @@ -1,711 +0,0 @@ -// Copyright 2019 Google Inc. All rights reserved. -// -// 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 - -#include -#include -#include -#include -#include - -#include "app_framework.h" // NOLINT -#include "firebase/app.h" -#include "firebase/dynamic_links.h" -#include "firebase/dynamic_links/components.h" -#include "firebase/internal/platform.h" -#include "firebase/log.h" -#include "firebase/util.h" -#include "firebase_test_framework.h" // NOLINT - -// The TO_STRING macro is useful for command line defined strings as the quotes -// get stripped. -#define TO_STRING_EXPAND(X) #X -#define TO_STRING(X) TO_STRING_EXPAND(X) - -// Path to the Firebase config file to load. -#ifdef FIREBASE_CONFIG -#define FIREBASE_CONFIG_STRING TO_STRING(FIREBASE_CONFIG) -#else -#define FIREBASE_CONFIG_STRING "" -#endif // FIREBASE_CONFIG - -namespace firebase_testapp_automated { - -using app_framework::LogDebug; -using app_framework::LogInfo; - -using app_framework::ProcessEvents; -using firebase_test_framework::FirebaseTest; - -// Bundle IDs needed for opening Dynamic Links. -static const char kIOSBundleID[] = - "com.google.FirebaseCppDynamicLinksTestApp.dev"; -static const char kAndroidBundleID[] = - "com.google.android.dynamiclinks.testapp"; -static const char kIOSAppStoreID[] = "2233445566"; // Placeholder ID. - -static const char kDomainUriPrefixInvalidError[] = - "kDomainUriPrefix is not valid, link shortening will fail.\n" - "To resolve this:\n" - "* Goto the Firebase console https://firebase.google.com/console/\n" - "* Click on the Dynamic Links tab\n" - "* Copy the URI prefix e.g https://a12cd.app.goo.gl or " - " https://your-project.page.link\n" - "* Replace the value of kDomainUriPrefix with the copied URI prefix.\n"; - -// IMPORTANT: You need to set this to a valid URI prefix from the Firebase -// console (see kDomainUriPrefixInvalidError for the details). -static const char* kDomainUriPrefix = "https://REPLACE_WITH_YOUR_URI_PREFIX"; - -#define TARGET_URL_PREFIX "https://mysite.example.com" - -// When one of the tests tries to open a URL, it suppresses the other tests -// that are attempting to do the same, since only one URL can be opened at a -// time. It does so by setting the "current test" flag to its own test name. -static const char kCurrentTestKey[] = "openurl_current_test"; - -class TestListener; - -class FirebaseDynamicLinksTest : public FirebaseTest { - public: - static void SetUpTestSuite(); - static void TearDownTestSuite(); - - protected: - // Try to claim the "current test" flag, returning true if successful and - // false if not. Because tests run in sequence, this does not actually - // require any mutexes. This returns true if it was already claimed by this - // test, or if no test was claiming it before (in which case, now this test - // is). - bool ClaimCurrentTest(const char* test_name); - // Release the "current test" flag, allowing the next test to run. - void ReleaseCurrentTest(); - - static firebase::App* shared_app_; - static TestListener* shared_listener_; - static bool is_desktop_stub_; - // A list of persistent keys we've saved on the device, to be erased on - // shutdown after all tests are finished. - static std::vector cleanup_persistent_keys_; -}; - -firebase::App* FirebaseDynamicLinksTest::shared_app_ = nullptr; -TestListener* FirebaseDynamicLinksTest::shared_listener_ = nullptr; -bool FirebaseDynamicLinksTest::is_desktop_stub_ = false; -// NOLINTNEXTLINE -std::vector FirebaseDynamicLinksTest::cleanup_persistent_keys_; - -// Handles a received dynamic link. -class TestListener : public firebase::dynamic_links::Listener { - public: - TestListener() : received_link_(false) {} - void OnDynamicLinkReceived( - const firebase::dynamic_links::DynamicLink* dynamic_link) override { - LogInfo("Received dynamic link: %s", dynamic_link->url.c_str()); - link_ = *dynamic_link; - received_link_ = true; - } - - bool WaitForDynamicLink(firebase::dynamic_links::DynamicLink* link_output) { - const int kWaitSeconds = 10; - for (int i = 0; i < kWaitSeconds; i++) { - ProcessEvents(1000); - if (received_link_) { - *link_output = link_; - return true; - } - } - return false; - } - bool received_link_; - firebase::dynamic_links::DynamicLink link_; -}; - -void FirebaseDynamicLinksTest::SetUpTestSuite() { - FindFirebaseConfig(FIREBASE_CONFIG_STRING); - - firebase::SetLogLevel(firebase::kLogLevelDebug); - LogDebug("Initialize Firebase App."); - -#if defined(__ANDROID__) - shared_app_ = ::firebase::App::Create(app_framework::GetJniEnv(), - app_framework::GetActivity()); -#else - shared_app_ = ::firebase::App::Create(); -#endif // defined(__ANDROID__) - - LogDebug("Initializing Firebase Dynamic Links."); - - shared_listener_ = new TestListener(); - - ::firebase::ModuleInitializer initializer; - initializer.Initialize( - shared_app_, shared_listener_, - [](::firebase::App* app, void* listener_void) { - LogDebug("Try to initialize Firebase Dynamic Links"); - firebase::InitResult result; - result = firebase::dynamic_links::Initialize( - *app, reinterpret_cast( - listener_void)); - return result; - }); - - FirebaseTest::WaitForCompletion(initializer.InitializeLastResult(), - "Initialize"); - - ASSERT_EQ(initializer.InitializeLastResult().error(), 0) - << initializer.InitializeLastResult().error_message(); - - is_desktop_stub_ = false; -#if !defined(__ANDROID__) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) - is_desktop_stub_ = true; -#endif // !defined(__ANDROID__) && !(defined(TARGET_OS_IPHONE) && - // TARGET_OS_IPHONE) - - LogDebug("Successfully initialized Firebase Dynamic Links."); -} - -void FirebaseDynamicLinksTest::TearDownTestSuite() { - // On teardown, delete all the persistent keys we should clean up, as long as - // there is no longer a current test running. - std::string value; - if (GetPersistentString(kCurrentTestKey, &value) && !value.empty()) { - // Don't clean up the persistent keys yet, not until all the tests are done. - return; - } - LogDebug("Tests finished, cleaning up all persistent keys."); - for (int i = 0; i < cleanup_persistent_keys_.size(); ++i) { - SetPersistentString(cleanup_persistent_keys_[i].c_str(), nullptr); - } - cleanup_persistent_keys_.clear(); - - LogDebug("Shutdown Firebase Dynamic Links."); - firebase::dynamic_links::Terminate(); - - delete shared_listener_; - shared_listener_ = nullptr; - - LogDebug("Shutdown Firebase App."); - delete shared_app_; - shared_app_ = nullptr; - - ProcessEvents(100); -} - -// Test cases below. - -TEST_F(FirebaseDynamicLinksTest, TestInitializeAndTerminate) { - // Already tested via SetUp() and TearDown(). -} - -TEST_F(FirebaseDynamicLinksTest, CheckForDomainUriPrefix) { - ASSERT_EQ(strstr(kDomainUriPrefix, "REPLACE_WITH"), nullptr) - << kDomainUriPrefixInvalidError; -} - -TEST_F(FirebaseDynamicLinksTest, TestCreateLongLink) { - firebase::dynamic_links::GoogleAnalyticsParameters analytics_parameters; - analytics_parameters.source = "mysource"; - analytics_parameters.medium = "mymedium"; - analytics_parameters.campaign = "mycampaign"; - analytics_parameters.term = "myterm"; - analytics_parameters.content = "mycontent"; - - firebase::dynamic_links::IOSParameters ios_parameters("com.myapp.bundleid"); - ios_parameters.fallback_url = TARGET_URL_PREFIX "/fallback"; - ios_parameters.custom_scheme = "mycustomscheme"; - ios_parameters.minimum_version = "1.2.3"; - ios_parameters.ipad_bundle_id = "com.myapp.bundleid.ipad"; - ios_parameters.ipad_fallback_url = TARGET_URL_PREFIX "/fallbackipad"; - - firebase::dynamic_links::ITunesConnectAnalyticsParameters - app_store_parameters; - app_store_parameters.affiliate_token = "abcdefg"; - app_store_parameters.campaign_token = "hijklmno"; - app_store_parameters.provider_token = "pq-rstuv"; - - firebase::dynamic_links::AndroidParameters android_parameters( - "com.myapp.packageid"); - android_parameters.fallback_url = TARGET_URL_PREFIX "/fallback"; - android_parameters.minimum_version = 12; - - firebase::dynamic_links::SocialMetaTagParameters social_parameters; - social_parameters.title = "My App!"; - social_parameters.description = "My app is awesome!"; - social_parameters.image_url = TARGET_URL_PREFIX "/someimage.jpg"; - - firebase::dynamic_links::DynamicLinkComponents components( - "https://google.com/abc", kDomainUriPrefix); - components.google_analytics_parameters = &analytics_parameters; - components.ios_parameters = &ios_parameters; - components.itunes_connect_analytics_parameters = &app_store_parameters; - components.android_parameters = &android_parameters; - components.social_meta_tag_parameters = &social_parameters; - - firebase::dynamic_links::GeneratedDynamicLink generated_link = - firebase::dynamic_links::GetLongLink(components); - - if (is_desktop_stub_) { - // On desktop, it's enough that we just don't crash. - SUCCEED(); - return; - } - - EXPECT_TRUE(generated_link.error.empty()); - EXPECT_NE(generated_link.url, ""); - EXPECT_EQ(generated_link.url.find(kDomainUriPrefix), 0) - << "Dynamic Link URL (" << generated_link.url - << ") does not begin with Domain URI Prefix (" << kDomainUriPrefix << ")"; - if (!generated_link.warnings.empty()) { - LogDebug("GetLongLink warnings:"); - for (auto it = generated_link.warnings.begin(); - it != generated_link.warnings.end(); ++it) { - LogDebug(" %s", it->c_str()); - } - } -} - -TEST_F(FirebaseDynamicLinksTest, TestGetShortLinkFromComponents) { - firebase::dynamic_links::GoogleAnalyticsParameters analytics_parameters; - analytics_parameters.source = "mysource"; - analytics_parameters.medium = "mymedium"; - analytics_parameters.campaign = "mycampaign"; - analytics_parameters.term = "myterm"; - analytics_parameters.content = "mycontent"; - - firebase::dynamic_links::IOSParameters ios_parameters("com.myapp.bundleid"); - ios_parameters.fallback_url = TARGET_URL_PREFIX "/fallback"; - ios_parameters.custom_scheme = "mycustomscheme"; - ios_parameters.minimum_version = "1.2.3"; - ios_parameters.ipad_bundle_id = "com.myapp.bundleid.ipad"; - ios_parameters.ipad_fallback_url = TARGET_URL_PREFIX "/fallbackipad"; - - firebase::dynamic_links::ITunesConnectAnalyticsParameters - app_store_parameters; - app_store_parameters.affiliate_token = "abcdefg"; - app_store_parameters.campaign_token = "hijklmno"; - app_store_parameters.provider_token = "pq-rstuv"; - - firebase::dynamic_links::AndroidParameters android_parameters( - "com.myapp.packageid"); - android_parameters.fallback_url = TARGET_URL_PREFIX "/fallback"; - android_parameters.minimum_version = 12; - - firebase::dynamic_links::SocialMetaTagParameters social_parameters; - social_parameters.title = "My App!"; - social_parameters.description = "My app is awesome!"; - social_parameters.image_url = TARGET_URL_PREFIX "/someimage.jpg"; - - firebase::dynamic_links::DynamicLinkComponents components( - "https://google.com/def", kDomainUriPrefix); - components.google_analytics_parameters = &analytics_parameters; - components.ios_parameters = &ios_parameters; - components.itunes_connect_analytics_parameters = &app_store_parameters; - components.android_parameters = &android_parameters; - components.social_meta_tag_parameters = &social_parameters; - - firebase::Future future; - - FLAKY_TEST_SECTION_BEGIN(); // Occasionally there can be a connection error. - future = firebase::dynamic_links::GetShortLink(components); - WaitForCompletion(future, "GetShortLinkFromComponents"); - FLAKY_TEST_SECTION_END(); - - if (is_desktop_stub_) { - // On desktop, it's enough that we just don't crash. - SUCCEED(); - return; - } - - const firebase::dynamic_links::GeneratedDynamicLink& generated_link = - *future.result(); - - EXPECT_TRUE(generated_link.error.empty()); - EXPECT_NE(generated_link.url, ""); - EXPECT_EQ(generated_link.url.find(kDomainUriPrefix), 0) - << "Dynamic Link URL (" << generated_link.url - << ") does not begin with Domain URI Prefix (" << kDomainUriPrefix << ")"; - if (!generated_link.warnings.empty()) { - LogDebug("GetShortLinkFromComponents warnings:"); - for (auto it = generated_link.warnings.begin(); - it != generated_link.warnings.end(); ++it) { - LogDebug(" %s", it->c_str()); - } - } -} - -TEST_F(FirebaseDynamicLinksTest, TestGetShortLinkFromLongLink) { - firebase::dynamic_links::GoogleAnalyticsParameters analytics_parameters; - analytics_parameters.source = "mysource"; - analytics_parameters.medium = "mymedium"; - analytics_parameters.campaign = "mycampaign"; - analytics_parameters.term = "myterm"; - analytics_parameters.content = "mycontent"; - - firebase::dynamic_links::IOSParameters ios_parameters("com.myapp.bundleid"); - ios_parameters.fallback_url = TARGET_URL_PREFIX "/fallback"; - ios_parameters.custom_scheme = "mycustomscheme"; - ios_parameters.minimum_version = "1.2.3"; - ios_parameters.ipad_bundle_id = "com.myapp.bundleid.ipad"; - ios_parameters.ipad_fallback_url = TARGET_URL_PREFIX "/fallbackipad"; - - firebase::dynamic_links::ITunesConnectAnalyticsParameters - app_store_parameters; - app_store_parameters.affiliate_token = "abcdefg"; - app_store_parameters.campaign_token = "hijklmno"; - app_store_parameters.provider_token = "pq-rstuv"; - - firebase::dynamic_links::AndroidParameters android_parameters( - "com.myapp.packageid"); - android_parameters.fallback_url = TARGET_URL_PREFIX "/fallback"; - android_parameters.minimum_version = 12; - - firebase::dynamic_links::SocialMetaTagParameters social_parameters; - social_parameters.title = "My App!"; - social_parameters.description = "My app is awesome!"; - social_parameters.image_url = TARGET_URL_PREFIX "/someimage.jpg"; - - firebase::dynamic_links::DynamicLinkComponents components( - "https://google.com/ghi", kDomainUriPrefix); - components.google_analytics_parameters = &analytics_parameters; - components.ios_parameters = &ios_parameters; - components.itunes_connect_analytics_parameters = &app_store_parameters; - components.android_parameters = &android_parameters; - components.social_meta_tag_parameters = &social_parameters; - - firebase::dynamic_links::GeneratedDynamicLink long_link = - firebase::dynamic_links::GetLongLink(components); - - if (is_desktop_stub_) { - // On desktop, it's enough that we just don't crash. - SUCCEED(); - return; - } - - EXPECT_NE(long_link.url, ""); - - firebase::dynamic_links::DynamicLinkOptions options; - options.path_length = firebase::dynamic_links::kPathLengthShort; - firebase::Future future; - - FLAKY_TEST_SECTION_BEGIN(); // Occasional connection errors. - future = - firebase::dynamic_links::GetShortLink(long_link.url.c_str(), options); - WaitForCompletion(future, "GetShortLinkFromLongLink"); - FLAKY_TEST_SECTION_END(); - - const firebase::dynamic_links::GeneratedDynamicLink& generated_link = - *future.result(); - - EXPECT_TRUE(generated_link.error.empty()); - EXPECT_NE(generated_link.url, ""); - EXPECT_EQ(generated_link.url.find(kDomainUriPrefix), 0) - << "Dynamic Link URL (" << generated_link.url - << ") does not begin with Domain URI Prefix (" << kDomainUriPrefix << ")"; - if (!generated_link.warnings.empty()) { - LogDebug("GetShortLinkFromLongLink warnings:"); - for (auto it = generated_link.warnings.begin(); - it != generated_link.warnings.end(); ++it) { - LogDebug(" %s", it->c_str()); - } - } -} - -bool FirebaseDynamicLinksTest::ClaimCurrentTest(const char* test_name) { - // Tests using OpenUrlInBrowser must be run one at a time per run of the app. - // The workflow for these tests is: - // - // Run #1: Test A opens its link in browser, tests B & C do nothing. - // Run #2: Test A verifies that its link loaded, test B opens its link in - // browser, test C does nothing. - // Run #3: Test A remembers whether its link had loaded, test B verifies that - // its link loaded, test C opens its link in browser. - // Run #4: Tests A & B remember whether their links had loaded, test C - // verifies that its link loaded. - // - // This is accomplished by setting the value of kCurrentTestKey, which tells - // us which of the tests is currently doing its thing. Each test can also set - // a state variable saying whether they are opening the link in browser (the - // starting state), verifying that the link opened, or previously opened (or - // failed to open) the link. Tests that previously failed to open the link - // will continue to register a FAIL until all the tests are finished. - std::string value; - if (!GetPersistentString(kCurrentTestKey, &value) || value == test_name) { - // If not already set to it, take ownership of the current test. - if (value != test_name) { - SetPersistentString(kCurrentTestKey, test_name); - } - return true; - } - return false; -} - -void FirebaseDynamicLinksTest::ReleaseCurrentTest() { - SetPersistentString(kCurrentTestKey, nullptr); -} - -static firebase::dynamic_links::DynamicLinkComponents GenerateComponentsForTest( - const char* url) { - static firebase::dynamic_links::AndroidParameters android_parameters( - kAndroidBundleID); - static firebase::dynamic_links::IOSParameters ios_parameters(kIOSBundleID); - ios_parameters.app_store_id = kIOSAppStoreID; - static firebase::dynamic_links::SocialMetaTagParameters social_parameters; - static firebase::dynamic_links::ITunesConnectAnalyticsParameters - app_store_parameters; - static firebase::dynamic_links::GoogleAnalyticsParameters - analytics_parameters; - firebase::dynamic_links::DynamicLinkComponents components(url, - kDomainUriPrefix); - components.google_analytics_parameters = &analytics_parameters; - components.ios_parameters = &ios_parameters; - components.itunes_connect_analytics_parameters = &app_store_parameters; - components.android_parameters = &android_parameters; - components.social_meta_tag_parameters = &social_parameters; - return components; -} -static const char kStateSentLink[] = "sentLink"; -static const char kStateReceivedLink[] = "receivedLink"; -static const char kStateReceivedLinkFail[] = "receivedLinkFail"; - -TEST_F(FirebaseDynamicLinksTest, TestOpeningLongLinkInRunningApp) { - // On iOS, the dynamic link landing page requires a click. - // On Android, the first time a dynamic link is clicked on the device, Google - // Play services shows a TOS popup. Either way, this test requires user - // interaction. -#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || defined(__ANDROID__) - TEST_REQUIRES_USER_INTERACTION; -#endif // (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || - // defined(__ANDROID__) - - // This test uses a persistent key to keep track of how it's running. - const char kUrlToOpen[] = "https://google.com/test_opening_long_link"; - std::string persistent_key_str = test_info_->name(); - const char* persistent_key = persistent_key_str.c_str(); - - bool owns_current_test = ClaimCurrentTest(persistent_key); - - cleanup_persistent_keys_.push_back(persistent_key); - std::string value; - if (owns_current_test && !GetPersistentString(persistent_key, &value)) { - // The first time, create a dynamic link and open it in the browser. - LogDebug("First run, creating and opening long dynamic link..."); - - firebase::dynamic_links::DynamicLinkComponents components = - GenerateComponentsForTest(kUrlToOpen); - firebase::dynamic_links::GeneratedDynamicLink link = - firebase::dynamic_links::GetLongLink(components); - - if (is_desktop_stub_) { - // On desktop, it's enough that we just don't crash. - LogDebug("Succeeded as stub."); - SUCCEED(); - return; - } - EXPECT_TRUE(link.error.empty()); - SetPersistentString(persistent_key, kStateSentLink); - // This will trigger the test to start over. - OpenUrlInBrowser(link.url.c_str()); - exit(0); // Kill the app after opening the URL so it can be restarted - // properly. - } else if (owns_current_test && GetPersistentString(persistent_key, &value) && - value == kStateSentLink) { - // The second time, check that we received the dynamic link. - LogDebug("Second run, checking for dynamic link..."); - firebase::dynamic_links::DynamicLink got_link; - EXPECT_TRUE(shared_listener_->WaitForDynamicLink(&got_link)); - EXPECT_EQ(got_link.url, kUrlToOpen); - if (got_link.url == kUrlToOpen) { - SetPersistentString(persistent_key, kStateReceivedLink); - } else { - SetPersistentString(persistent_key, kStateReceivedLinkFail); - } - ReleaseCurrentTest(); - } else if (GetPersistentString(persistent_key, &value) && - value == kStateReceivedLink) { - // Already verified the link was correct. - LogDebug("Previously verified that dynamic link was received."); - SUCCEED(); - } else if (GetPersistentString(persistent_key, &value) && - value == kStateReceivedLinkFail) { - // Already verified the link failed. - FAIL() << "Previous attempt to get link failed."; - } else { - LogDebug("Skipping this test because another test has taken ownership."); - SUCCEED(); - } -} - -TEST_F(FirebaseDynamicLinksTest, TestOpeningShortLinkFromLongLinkInRunningApp) { - // On iOS, the dynamic link landing page requires a click. - // On Android, the first time a dynamic link is clicked on the device, Google - // Play services shows a TOS popup. Either way, this test requires user - // interaction. -#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || defined(__ANDROID__) - TEST_REQUIRES_USER_INTERACTION; -#endif // (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || - // defined(__ANDROID__) - - // This test uses a persistent key to keep track of how it's running. - const char kUrlToOpen[] = - "https://google.com/test_opening_short_link_from_long_link"; - std::string persistent_key_str = test_info_->name(); - const char* persistent_key = persistent_key_str.c_str(); - - bool owns_current_test = ClaimCurrentTest(persistent_key); - - cleanup_persistent_keys_.push_back(persistent_key); - std::string value; - if (owns_current_test && !GetPersistentString(persistent_key, &value)) { - // The first time, create a dynamic link and open it in the browser. - LogDebug( - "First run, creating and opening short dynamic link from long link..."); - firebase::dynamic_links::DynamicLinkComponents components = - GenerateComponentsForTest(kUrlToOpen); - firebase::dynamic_links::GeneratedDynamicLink long_link = - firebase::dynamic_links::GetLongLink(components); - // Shorten link. - firebase::dynamic_links::DynamicLinkOptions options; - options.path_length = firebase::dynamic_links::kPathLengthShort; - firebase::Future future; - - FLAKY_TEST_SECTION_BEGIN(); // Occasional connection errors. - future = - firebase::dynamic_links::GetShortLink(long_link.url.c_str(), options); - WaitForCompletion(future, "GetShortLinkFromLongLink"); - FLAKY_TEST_SECTION_END(); - - if (is_desktop_stub_) { - // On desktop, it's enough that we just don't crash. - LogDebug("Succeeded as stub."); - SUCCEED(); - return; - } - const firebase::dynamic_links::GeneratedDynamicLink& link = - *future.result(); - - EXPECT_TRUE(link.error.empty()); - SetPersistentString(persistent_key, kStateSentLink); - // This will trigger the test to start over. - OpenUrlInBrowser(link.url.c_str()); - exit(0); // Kill the app after opening the URL so it can be restarted - // properly; - } else if (owns_current_test && GetPersistentString(persistent_key, &value) && - value == kStateSentLink) { - // The second time, check that we received the dynamic link. - LogDebug("Second run, checking for dynamic link..."); - firebase::dynamic_links::DynamicLink got_link; - EXPECT_TRUE(shared_listener_->WaitForDynamicLink(&got_link)); - EXPECT_EQ(got_link.url, kUrlToOpen); - if (got_link.url == kUrlToOpen) { - SetPersistentString(persistent_key, kStateReceivedLink); - } else { - SetPersistentString(persistent_key, kStateReceivedLinkFail); - } - ReleaseCurrentTest(); - } else if (GetPersistentString(persistent_key, &value) && - value == kStateReceivedLink) { - // Already verified the link was correct. - LogDebug("Previously verified that dynamic link was received."); - SUCCEED(); - } else if (GetPersistentString(persistent_key, &value) && - value == kStateReceivedLinkFail) { - // Already verified the link failed. - FAIL() << "Previous attempt to get link failed."; - } else { - LogDebug("Skipping this test because another test has taken ownership."); - SUCCEED(); - } -} - -TEST_F(FirebaseDynamicLinksTest, - TestOpeningShortLinkFromComponentsInRunningApp) { - // On iOS, the dynamic link landing page requires a click. - // On Android, the first time a dynamic link is clicked on the device, Google - // Play services shows a TOS popup. Either way, this test requires user - // interaction. -#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || defined(__ANDROID__) - TEST_REQUIRES_USER_INTERACTION; -#endif // (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || - // defined(__ANDROID__) - - // This test uses a persistent key to keep track of how it's running. - const char kUrlToOpen[] = - "https://google.com/test_opening_short_link_from_components"; - std::string persistent_key_str = test_info_->name(); - const char* persistent_key = persistent_key_str.c_str(); - - bool owns_current_test = ClaimCurrentTest(persistent_key); - - cleanup_persistent_keys_.push_back(persistent_key); - std::string value; - if (owns_current_test && !GetPersistentString(persistent_key, &value)) { - // The first time, create a dynamic link and open it in the browser. - LogDebug( - "First run, creating and opening short dynamic link from " - "components..."); - firebase::dynamic_links::DynamicLinkComponents components = - GenerateComponentsForTest(kUrlToOpen); - - firebase::Future future; - FLAKY_TEST_SECTION_BEGIN(); // Occasional connection errors. - future = firebase::dynamic_links::GetShortLink(components); - WaitForCompletion(future, "GetShortLinkFromLongLink"); - FLAKY_TEST_SECTION_END(); // Occasional connection errors. - - if (is_desktop_stub_) { - // On desktop, it's enough that we just don't crash. - LogDebug("Succeeded as stub."); - SUCCEED(); - return; - } - - const firebase::dynamic_links::GeneratedDynamicLink& link = - *future.result(); - - EXPECT_TRUE(link.error.empty()); - SetPersistentString(persistent_key, kStateSentLink); - // This will trigger the test to start over. - OpenUrlInBrowser(link.url.c_str()); - exit(0); // Kill the app after opening the URL so it can be restarted - // properly. - } else if (owns_current_test && GetPersistentString(persistent_key, &value) && - value == kStateSentLink) { - // The second time, check that we received the dynamic link. - LogDebug("Second run, checking for dynamic link..."); - firebase::dynamic_links::DynamicLink got_link; - EXPECT_TRUE(shared_listener_->WaitForDynamicLink(&got_link)); - EXPECT_EQ(got_link.url, kUrlToOpen); - if (got_link.url == kUrlToOpen) { - SetPersistentString(persistent_key, kStateReceivedLink); - } else { - SetPersistentString(persistent_key, kStateReceivedLinkFail); - } - ReleaseCurrentTest(); - } else if (GetPersistentString(persistent_key, &value) && - value == kStateReceivedLink) { - // Already verified the link was correct. - LogDebug("Previously verified that dynamic link was received."); - SUCCEED(); - } else if (GetPersistentString(persistent_key, &value) && - value == kStateReceivedLinkFail) { - // Already verified the link failed. - FAIL() << "Previous attempt to get link failed."; - } else { - LogDebug("Skipping this test because another test has taken ownership."); - SUCCEED(); - } -} -} // namespace firebase_testapp_automated diff --git a/dynamic_links/samples/src/doc_samples.cc b/dynamic_links/samples/src/doc_samples.cc deleted file mode 100644 index 89312b55ca..0000000000 --- a/dynamic_links/samples/src/doc_samples.cc +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2017 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. - -// WARNING: Code from this file is included verbatim in the Auth C++ -// documentation. Only change existing code if it is safe to release -// to the public. Otherwise, a tech writer may make an unrelated -// modification, regenerate the docs, and unwittingly release an -// unannounced modification to the public. - -// [START dynamic_link_includes] -#include "firebase/app.h" -#include "firebase/dynamic_links.h" - -// Needed for creating links only. -#include "firebase/dynamic_links/components.h" -// [END dynamic_link_includes] - -#if defined(__ANDROID__) -JNIEnv* my_jni_env = nullptr; -jobject my_activity = nullptr; -#endif // defined(__ANDROID__) - -void CreateLinks() { - { - // [START dlink_create_longlink_minimal] - firebase::dynamic_links::IOSParameters ios_parameters("com.example.ios"); - - firebase::dynamic_links::AndroidParameters android_parameters( - "com.example.android.package_name"); - - firebase::dynamic_links::DynamicLinkComponents components( - "https://www.example.com/", "example.page.link"); - components.android_parameters = &android_parameters; - components.ios_parameters = &ios_parameters; - - firebase::dynamic_links::GeneratedDynamicLink long_link = - firebase::dynamic_links::GetLongLink(components); - // [END dlink_create_longlink_minimal] - - // [START dlink_create_shortlink_minimal] - firebase::dynamic_links::DynamicLinkOptions short_link_options; - short_link_options.path_length = firebase::dynamic_links::kPathLengthShort; - - firebase::Future result = - firebase::dynamic_links::GetShortLink(components, short_link_options); - // [END dlink_create_shortlink_minimal] - - // [START poll_dlink_future] - if (result.status() == firebase::kFutureStatusComplete) { - if (result.error() == firebase::dynamic_links::kErrorCodeSuccess) { - firebase::dynamic_links::GeneratedDynamicLink link = *result.result(); - printf("Create short link succeeded: %s\n", link.url.c_str()); - } else { - printf("Created short link failed with error '%s'\n", - result.error_message()); - } - } - // [END poll_dlink_future] - } -} - -// [START dlink_listener] -class Listener : public firebase::dynamic_links::Listener { - public: - // Called on the client when a dynamic link arrives. - void OnDynamicLinkReceived( - const firebase::dynamic_links::DynamicLink* dynamic_link) override { - printf("Received link: %s", dynamic_link->url.c_str()); - } -}; -// [END dlink_listener] diff --git a/dynamic_links/src/common.cc b/dynamic_links/src/common.cc deleted file mode 100644 index 0031246b29..0000000000 --- a/dynamic_links/src/common.cc +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2017 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 "dynamic_links/src/common.h" - -#include - -#include "app/src/cleanup_notifier.h" -#include "app/src/invites/cached_receiver.h" -#include "app/src/invites/invites_receiver_internal.h" -#include "app/src/util.h" -#include "dynamic_links/src/include/firebase/dynamic_links.h" - -// Register the module initializer. -FIREBASE_APP_REGISTER_CALLBACKS( - dynamic_links, - { - if (app == ::firebase::App::GetInstance()) { - return firebase::dynamic_links::Initialize(*app, nullptr); - } - return kInitResultSuccess; - }, - { - if (app == ::firebase::App::GetInstance()) { - firebase::dynamic_links::Terminate(); - } - }, - false); - -namespace firebase { -namespace dynamic_links { - -namespace internal { -const char kDynamicLinksModuleName[] = "dynamic_links"; -} // namespace internal - -// Notifies a listener of a cached invite. -class CachedListenerNotifier : public invites::internal::ReceiverInterface { - public: - CachedListenerNotifier() : listener_(nullptr) {} - virtual ~CachedListenerNotifier() { SetListener(nullptr); } - - // Set the listener which should be notified of any cached or receiver - // links. - Listener* SetListener(Listener* listener) { - MutexLock lock(lock_); - Listener* previous_listener = listener_; - listener_ = listener; - receiver_.SetReceiver(listener ? this : nullptr); - return previous_listener; - } - - private: - // Callback called when an invite is received. If an error occurred, - // result_code should be non-zero. Otherwise, either invitation_id should be - // set, or deep_link_url should be set, or both. - void ReceivedInviteCallback( - const std::string& invitation_id, const std::string& deep_link_url, - invites::internal::InternalLinkMatchStrength match_strength, - int result_code, const std::string& error_message) override { - MutexLock lock(lock_); - if (listener_) { - if (!deep_link_url.empty()) { - DynamicLink link; - link.url = deep_link_url; - link.match_strength = static_cast(match_strength); - listener_->OnDynamicLinkReceived(&link); - } - } else { - receiver_.ReceivedInviteCallback(invitation_id, deep_link_url, - match_strength, result_code, - error_message); - } - } - - private: - // Protects access to members of this class. - Mutex lock_; - // End user's listener which is notified of invites. - Listener* listener_; - // Caches received links. - invites::internal::CachedReceiver receiver_; -}; - -static invites::internal::InvitesReceiverInternal* g_receiver = nullptr; -static CachedListenerNotifier* g_cached_receiver = nullptr; - -FutureData* FutureData::s_future_data_ = nullptr; - -// Create FutureData singleton. -FutureData* FutureData::Create() { - s_future_data_ = new FutureData(); - return s_future_data_; -} - -// Destroy the FutureData singleton. -void FutureData::Destroy() { - delete s_future_data_; - s_future_data_ = nullptr; -} - -// Get the Future data singleton. -FutureData* FutureData::Get() { return s_future_data_; } - -bool CreateReceiver(const App& app) { - assert(!g_cached_receiver && !g_receiver); - g_cached_receiver = new CachedListenerNotifier(); - g_receiver = invites::internal::InvitesReceiverInternal::CreateInstance( - app, g_cached_receiver); - if (!g_receiver) { - delete g_cached_receiver; - g_cached_receiver = nullptr; - return false; - } - if (!AppCallback::GetEnabledByName(internal::kDynamicLinksModuleName)) { - CleanupNotifier* cleanup_notifier = - CleanupNotifier::FindByOwner(const_cast(g_receiver->app())); - assert(cleanup_notifier); - cleanup_notifier->RegisterObject( - const_cast(internal::kDynamicLinksModuleName), [](void*) { - LogError( - "dynamic_links::Terminate() should be called before the " - "default app is destroyed."); - if (g_receiver) firebase::dynamic_links::Terminate(); - }); - } - return true; -} - -void DestroyReceiver() { - assert(g_cached_receiver && g_receiver); - if (!AppCallback::GetEnabledByName(internal::kDynamicLinksModuleName)) { - CleanupNotifier* cleanup_notifier = - CleanupNotifier::FindByOwner(const_cast(g_receiver->app())); - assert(cleanup_notifier); - cleanup_notifier->UnregisterObject( - const_cast(internal::kDynamicLinksModuleName)); - } - SetListener(nullptr); - invites::internal::InvitesReceiverInternal::DestroyInstance( - g_receiver, g_cached_receiver); - g_receiver = nullptr; - delete g_cached_receiver; - g_cached_receiver = nullptr; -} - -Listener* SetListener(Listener* listener) { - if (g_cached_receiver == nullptr) return nullptr; - - if (listener) { - Fetch(); - } - - return g_cached_receiver->SetListener(listener); -} - -void Fetch() { - if (g_receiver) g_receiver->Fetch(); -} - -} // namespace dynamic_links -} // namespace firebase diff --git a/dynamic_links/src/common.h b/dynamic_links/src/common.h deleted file mode 100644 index 290f4497d3..0000000000 --- a/dynamic_links/src/common.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2017 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. - -#ifndef FIREBASE_DYNAMIC_LINKS_SRC_COMMON_H_ -#define FIREBASE_DYNAMIC_LINKS_SRC_COMMON_H_ - -#include "app/src/include/firebase/app.h" -#include "app/src/reference_counted_future_impl.h" -#include "dynamic_links/src/include/firebase/dynamic_links.h" - -namespace firebase { -namespace dynamic_links { - -enum DynamicLinksFn { kDynamicLinksFnGetShortLink, kDynamicLinksFnCount }; - -// Data structure which holds the Future API implementation with the -// future required by this API. -class FutureData { - public: - FutureData() : api_(kDynamicLinksFnCount) {} - ~FutureData() {} - - ReferenceCountedFutureImpl* api() { return &api_; } - - // Create the FutureData singleton. - static FutureData* Create(); - // Destroy the FutureData singleton. - static void Destroy(); - // Get the FutureData singleton. - static FutureData* Get(); - - private: - ReferenceCountedFutureImpl api_; - - static FutureData* s_future_data_; -}; - -// Create the dynamic links receiver. -bool CreateReceiver(const App& app); -// Destroy the dynamic links receiver. -void DestroyReceiver(); - -} // namespace dynamic_links -} // namespace firebase - -#endif // FIREBASE_DYNAMIC_LINKS_SRC_COMMON_H_ diff --git a/dynamic_links/src/dynamic_links_android.cc b/dynamic_links/src/dynamic_links_android.cc deleted file mode 100644 index a0a8fb328d..0000000000 --- a/dynamic_links/src/dynamic_links_android.cc +++ /dev/null @@ -1,1019 +0,0 @@ -// Copyright 2017 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 -#include - -#include "app/src/assert.h" -#include "app/src/include/firebase/app.h" -#include "app/src/include/firebase/internal/common.h" -#include "app/src/include/firebase/version.h" -#include "app/src/reference_counted_future_impl.h" -#include "app/src/util.h" -#include "app/src/util_android.h" -#include "dynamic_links/src/common.h" -#include "dynamic_links/src/include/firebase/dynamic_links.h" -#include "dynamic_links/src/include/firebase/dynamic_links/components.h" - -namespace firebase { -namespace dynamic_links { - -DEFINE_FIREBASE_VERSION_STRING(FirebaseDynamicLinks); - -// Methods of the FirebaseDynamicLinks class. -// clang-format off -#define DYNAMIC_LINKS_METHODS(X) \ - X(GetInstance, "getInstance", \ - "()Lcom/google/firebase/dynamiclinks/FirebaseDynamicLinks;", \ - util::kMethodTypeStatic), \ - X(GetDynamicLinkFromIntent, "getDynamicLink", \ - "(Landroid/content/Intent;)Lcom/google/android/gms/tasks/Task;"), \ - X(GetDynamicLinkFromUri, "getDynamicLink", \ - "(Landroid/net/Uri;)Lcom/google/android/gms/tasks/Task;"), \ - X(CreateDynamicLink, "createDynamicLink", \ - "()Lcom/google/firebase/dynamiclinks/DynamicLink$Builder;") -// clang-format on - -METHOD_LOOKUP_DECLARATION(dynamic_links, DYNAMIC_LINKS_METHODS) -METHOD_LOOKUP_DEFINITION( - dynamic_links, - PROGUARD_KEEP_CLASS "com/google/firebase/dynamiclinks/FirebaseDynamicLinks", - DYNAMIC_LINKS_METHODS) - -// Methods of the DynamicLink class. -// clang-format off -#define DLINK_METHODS(X) \ - X(GetUri, "getUri", "()Landroid/net/Uri;") -// clang-format on - -METHOD_LOOKUP_DECLARATION(dlink, DLINK_METHODS) -METHOD_LOOKUP_DEFINITION(dlink, - PROGUARD_KEEP_CLASS - "com/google/firebase/dynamiclinks/DynamicLink", - DLINK_METHODS) - -// Methods of the DynamicLink.Builder class. -// clang-format off -#define DLINK_BUILDER_METHODS(X) \ - X(SetLongLink, "setLongLink", \ - "(Landroid/net/Uri;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$Builder;"), \ - X(SetLink, "setLink", \ - "(Landroid/net/Uri;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$Builder;"), \ - X(SetDomainUriPrefix, "setDomainUriPrefix", \ - "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$Builder;"), \ - X(SetAndroidParameters, "setAndroidParameters", \ - "(Lcom/google/firebase/dynamiclinks/DynamicLink$AndroidParameters;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$Builder;"), \ - X(SetIosParameters, "setIosParameters", \ - "(Lcom/google/firebase/dynamiclinks/DynamicLink$IosParameters;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$Builder;"), \ - X(SetGoogleAnalyticsParameters, "setGoogleAnalyticsParameters", \ - "(Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "GoogleAnalyticsParameters;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$Builder;"), \ - X(SetItunesConnectAnalyticsParameters, \ - "setItunesConnectAnalyticsParameters", \ - "(Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "ItunesConnectAnalyticsParameters;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$Builder;"), \ - X(SetSocialMetaTagParameters, "setSocialMetaTagParameters", \ - "(Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "SocialMetaTagParameters;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$Builder;"), \ - X(BuildDynamicLink, "buildDynamicLink", \ - "()Lcom/google/firebase/dynamiclinks/DynamicLink;"), \ - X(BuildShortDynamicLink, "buildShortDynamicLink", \ - "()Lcom/google/android/gms/tasks/Task;"), \ - X(BuildShortDynamicLinkWithOption, "buildShortDynamicLink", \ - "(I)Lcom/google/android/gms/tasks/Task;") -// clang-format on - -METHOD_LOOKUP_DECLARATION(dlink_builder, DLINK_BUILDER_METHODS) -METHOD_LOOKUP_DEFINITION(dlink_builder, - PROGUARD_KEEP_CLASS - "com/google/firebase/dynamiclinks/DynamicLink$Builder", - DLINK_BUILDER_METHODS) - -// Methods of the DynamicLink.AndroidParameters.Builder class. -// clang-format off -#define DLINK_ANDROID_PARAMS_BUILDER_METHODS(X) \ - X(Constructor, "", "()V"), \ - X(ConstructorFromPackageName, "", "(Ljava/lang/String;)V"), \ - X(SetFallbackUrl, "setFallbackUrl", \ - "(Landroid/net/Uri;)Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "AndroidParameters$Builder;"), \ - X(SetMinimumVersion, "setMinimumVersion", \ - "(I)Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "AndroidParameters$Builder;"), \ - X(Build, "build", "()Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "AndroidParameters;") -// clang-format on - -METHOD_LOOKUP_DECLARATION(dlink_android_params_builder, - DLINK_ANDROID_PARAMS_BUILDER_METHODS) -METHOD_LOOKUP_DEFINITION( - dlink_android_params_builder, - PROGUARD_KEEP_CLASS - "com/google/firebase/dynamiclinks/DynamicLink$AndroidParameters$Builder", - DLINK_ANDROID_PARAMS_BUILDER_METHODS) - -// Methods of the DynamicLink.GoogleAnalyticsParameters.Builder class. -// clang-format off -#define DLINK_GOOGLE_ANALYTICS_PARAMATERS_BUILDER_METHODS(X) \ - X(Constructor, "", "()V"), \ - X(SetSource, "setSource", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "GoogleAnalyticsParameters$Builder;"), \ - X(SetMedium, "setMedium", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "GoogleAnalyticsParameters$Builder;"), \ - X(SetCampaign, "setCampaign", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "GoogleAnalyticsParameters$Builder;"), \ - X(SetTerm, "setTerm", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "GoogleAnalyticsParameters$Builder;"), \ - X(SetContent, "setContent", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "GoogleAnalyticsParameters$Builder;"), \ - X(Build, "build", "()Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "GoogleAnalyticsParameters;") -// clang-format on - -METHOD_LOOKUP_DECLARATION(dlink_google_analytics_params_builder, - DLINK_GOOGLE_ANALYTICS_PARAMATERS_BUILDER_METHODS) -METHOD_LOOKUP_DEFINITION(dlink_google_analytics_params_builder, - PROGUARD_KEEP_CLASS - "com/google/firebase/dynamiclinks/DynamicLink$" - "GoogleAnalyticsParameters$Builder", - DLINK_GOOGLE_ANALYTICS_PARAMATERS_BUILDER_METHODS) - -// Methods of the DynamicLink.IosParameters.Builder class. -// clang-format off -#define DLINK_IOS_PARAMETERS_BUILDER_METHODS(X) \ - X(Constructor, "", "(Ljava/lang/String;)V"), \ - X(SetFallbackUrl, "setFallbackUrl", "(Landroid/net/Uri;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$IosParameters$Builder;"), \ - X(SetCustomScheme, "setCustomScheme", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$IosParameters$Builder;"), \ - X(SetIpadFallbackUrl, "setIpadFallbackUrl", "(Landroid/net/Uri;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$IosParameters$Builder;"), \ - X(SetIpadBundleId, "setIpadBundleId", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$IosParameters$Builder;"), \ - X(SetAppStoreId, "setAppStoreId", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$IosParameters$Builder;"), \ - X(SetMinimumVersion, "setMinimumVersion", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$IosParameters$Builder;"), \ - X(Build, "build", \ - "()Lcom/google/firebase/dynamiclinks/DynamicLink$IosParameters;") -// clang-format on - -METHOD_LOOKUP_DECLARATION(dlink_ios_params_builder, - DLINK_IOS_PARAMETERS_BUILDER_METHODS) -METHOD_LOOKUP_DEFINITION( - dlink_ios_params_builder, - PROGUARD_KEEP_CLASS - "com/google/firebase/dynamiclinks/DynamicLink$IosParameters$Builder", - DLINK_IOS_PARAMETERS_BUILDER_METHODS) - -// Methods of the DynamicLink.ItunesConnectAnalyticsParameters.Builder class. -// clang-format off -#define DLINK_ITUNES_CONNECT_PARAMETERS_BUILDER_METHODS(X) \ - X(Constructor, "", "()V"), \ - X(SetProviderToken, "setProviderToken", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "ItunesConnectAnalyticsParameters$Builder;"), \ - X(SetAffiliateToken, "setAffiliateToken", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "ItunesConnectAnalyticsParameters$Builder;"), \ - X(SetCampaignToken, "setCampaignToken", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "ItunesConnectAnalyticsParameters$Builder;"), \ - X(Build, "build", "()Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "ItunesConnectAnalyticsParameters;") -// clang-format on - -METHOD_LOOKUP_DECLARATION(dlink_itunes_params_builder, - DLINK_ITUNES_CONNECT_PARAMETERS_BUILDER_METHODS) -METHOD_LOOKUP_DEFINITION(dlink_itunes_params_builder, - PROGUARD_KEEP_CLASS - "com/google/firebase/dynamiclinks/DynamicLink$" - "ItunesConnectAnalyticsParameters$Builder", - DLINK_ITUNES_CONNECT_PARAMETERS_BUILDER_METHODS) - -// Methods of the DynamicLink.SocialMetaTagParameters.Builder class. -// clang-format off -#define DLINK_SOCIAL_META_TAG_PARAMETERS_BUILDER_METHODS(X) \ - X(Constructor, "", "()V"), \ - X(SetTitle, "setTitle", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "SocialMetaTagParameters$Builder;"), \ - X(SetDescription, "setDescription", "(Ljava/lang/String;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "SocialMetaTagParameters$Builder;"), \ - X(SetImageUrl, "setImageUrl", "(Landroid/net/Uri;)" \ - "Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "SocialMetaTagParameters$Builder;"), \ - X(Build, "build", "()Lcom/google/firebase/dynamiclinks/DynamicLink$" \ - "SocialMetaTagParameters;") -// clang-format on - -METHOD_LOOKUP_DECLARATION(dlink_social_meta_params_builder, - DLINK_SOCIAL_META_TAG_PARAMETERS_BUILDER_METHODS) -METHOD_LOOKUP_DEFINITION(dlink_social_meta_params_builder, - PROGUARD_KEEP_CLASS - "com/google/firebase/dynamiclinks/DynamicLink$" - "SocialMetaTagParameters$Builder", - DLINK_SOCIAL_META_TAG_PARAMETERS_BUILDER_METHODS) - -// Methods of the PendingDynamicLinkData class. -// clang-format off -#define PENDING_DYNAMIC_LINK_DATA_METHODS(X) \ - X(GetLink, "getLink", "()Landroid/net/Uri;"), \ - X(GetMinimumAppVersion, "getMinimumAppVersion", "()I"), \ - X(GetClickTimestamp, "getClickTimestamp", "()J"), \ - X(GetUpdateAppIntent, "getUpdateAppIntent", \ - "(Landroid/content/Context;)Landroid/content/Intent;") -// clang-format on - -METHOD_LOOKUP_DECLARATION(pending_dynamic_link_data, - PENDING_DYNAMIC_LINK_DATA_METHODS) -METHOD_LOOKUP_DEFINITION( - pending_dynamic_link_data, - PROGUARD_KEEP_CLASS - "com/google/firebase/dynamiclinks/PendingDynamicLinkData", - PENDING_DYNAMIC_LINK_DATA_METHODS) - -// Methods of the ShortDynamicLink interface. -// clang-format off -#define SHORT_DYNAMIC_LINK_METHODS(X) \ - X(GetShortLink, "getShortLink", "()Landroid/net/Uri;"), \ - X(GetPreviewLink, "getPreviewLink", "()Landroid/net/Uri;"), \ - X(GetWarnings, "getWarnings", "()Ljava/util/List;") -// clang-format on - -METHOD_LOOKUP_DECLARATION(short_dynamic_link, SHORT_DYNAMIC_LINK_METHODS) -METHOD_LOOKUP_DEFINITION(short_dynamic_link, - PROGUARD_KEEP_CLASS - "com/google/firebase/dynamiclinks/ShortDynamicLink", - SHORT_DYNAMIC_LINK_METHODS) - -// Methods of the ShortDynamicLinkWarning interface. -// clang-format off -#define SHORT_DYNAMIC_LINK_WARNING_METHODS(X) \ - X(GetCode, "getCode", "()Ljava/lang/String;"), \ - X(GetMessage, "getMessage", "()Ljava/lang/String;") -// clang-format on - -METHOD_LOOKUP_DECLARATION(short_dynamic_link_warning, - SHORT_DYNAMIC_LINK_WARNING_METHODS) -METHOD_LOOKUP_DEFINITION( - short_dynamic_link_warning, - PROGUARD_KEEP_CLASS - "com/google/firebase/dynamiclinks/ShortDynamicLink$Warning", - SHORT_DYNAMIC_LINK_WARNING_METHODS) - -// Fields of the ShortDynamicLink$Suffix interface. -// clang-format off -#define SHORT_DYNAMIC_LINK_SUFFIX_FIELDS(X) \ - X(Unguessable, "UNGUESSABLE", "I", util::kFieldTypeStatic), \ - X(Short, "SHORT", "I", util::kFieldTypeStatic) -// clang-format on - -METHOD_LOOKUP_DECLARATION(short_dynamic_link_suffix, METHOD_LOOKUP_NONE, - SHORT_DYNAMIC_LINK_SUFFIX_FIELDS) -METHOD_LOOKUP_DEFINITION( - short_dynamic_link_suffix, - PROGUARD_KEEP_CLASS - "com/google/firebase/dynamiclinks/ShortDynamicLink$Suffix", - METHOD_LOOKUP_NONE, SHORT_DYNAMIC_LINK_SUFFIX_FIELDS) - -// Map c++ PathLength constants to java path length constants. -static struct { - PathLength path_length_code; - short_dynamic_link_suffix::Field java_path_length_field; - jint value; -} g_path_length_codes[] = { - {kPathLengthShort, short_dynamic_link_suffix::kShort}, - {kPathLengthUnguessable, short_dynamic_link_suffix::kUnguessable}, -}; - -// Global reference to the Android FirebaseDynamicLinks class instance. -// This is initialized in dynamic_links::Initialize() and never released -// during the lifetime of the application. -static jobject g_dynamic_links_class_instance = nullptr; - -// Used to retrieve the JNI environment in order to call methods on the -// Android Analytics class. -static const ::firebase::App* g_app = nullptr; - -static const char* kApiIdentifier = "Dynamic Links"; - -static void ReleaseClasses(JNIEnv* env) { - dynamic_links::ReleaseClass(env); - dlink::ReleaseClass(env); - dlink_builder::ReleaseClass(env); - dlink_android_params_builder::ReleaseClass(env); - dlink_google_analytics_params_builder::ReleaseClass(env); - dlink_ios_params_builder::ReleaseClass(env); - dlink_itunes_params_builder::ReleaseClass(env); - dlink_social_meta_params_builder::ReleaseClass(env); - pending_dynamic_link_data::ReleaseClass(env); - short_dynamic_link::ReleaseClass(env); - short_dynamic_link_warning::ReleaseClass(env); - short_dynamic_link_suffix::ReleaseClass(env); -} - -InitResult Initialize(const App& app, Listener* listener) { - if (g_app) { - LogWarning("%s API already initialized", kApiIdentifier); - return kInitResultSuccess; - } - FIREBASE_UTIL_RETURN_FAILURE_IF_GOOGLE_PLAY_UNAVAILABLE(app); - - LogDebug("%s API Initializing", kApiIdentifier); - assert(!g_dynamic_links_class_instance); - - if (!CreateReceiver(app)) { - return kInitResultFailedMissingDependency; - } - - JNIEnv* env = app.GetJNIEnv(); - jobject activity = app.activity(); - - // Cache method pointers. - if (!(dynamic_links::CacheMethodIds(env, activity) && - dlink::CacheMethodIds(env, activity) && - dlink_builder::CacheMethodIds(env, activity) && - dlink_android_params_builder::CacheMethodIds(env, activity) && - dlink_google_analytics_params_builder::CacheMethodIds(env, activity) && - dlink_ios_params_builder::CacheMethodIds(env, activity) && - dlink_itunes_params_builder::CacheMethodIds(env, activity) && - dlink_social_meta_params_builder::CacheMethodIds(env, activity) && - pending_dynamic_link_data::CacheMethodIds(env, activity) && - short_dynamic_link::CacheMethodIds(env, activity) && - short_dynamic_link_warning::CacheMethodIds(env, activity) && - short_dynamic_link_suffix::CacheFieldIds(env, activity))) { - ReleaseClasses(env); - DestroyReceiver(); - return kInitResultFailedMissingDependency; - } - - g_app = &app; - - // Create the dynamic links class. - jclass dynamic_links_class = dynamic_links::GetClass(); - jobject dynamic_links_instance_local = env->CallStaticObjectMethod( - dynamic_links_class, - dynamic_links::GetMethodId(dynamic_links::kGetInstance)); - assert(dynamic_links_instance_local); - g_dynamic_links_class_instance = - env->NewGlobalRef(dynamic_links_instance_local); - env->DeleteLocalRef(dynamic_links_instance_local); - - // Cache PathLength codes - { - int i; - for (i = 0; i < FIREBASE_ARRAYSIZE(g_path_length_codes); ++i) { - g_path_length_codes[i].value = env->GetStaticIntField( - short_dynamic_link_suffix::GetClass(), - short_dynamic_link_suffix::GetFieldId( - g_path_length_codes[i].java_path_length_field)); - } - // The map from FieldLengths to suffix field IDs doesn't match the number of - // fields defined on the Suffix interface. - assert(i == short_dynamic_link_suffix::kFieldCount); - } - - FutureData::Create(); - SetListener(listener); - - LogInfo("%s API Initialized", kApiIdentifier); - return kInitResultSuccess; -} - -namespace internal { - -bool IsInitialized() { return g_app != nullptr; } - -} // namespace internal - -void Terminate() { - if (!g_app) { - LogWarning("%s already shut down", kApiIdentifier); - return; - } - DestroyReceiver(); - JNIEnv* env = g_app->GetJNIEnv(); - g_app = nullptr; - env->DeleteGlobalRef(g_dynamic_links_class_instance); - g_dynamic_links_class_instance = nullptr; - util::CancelCallbacks(env, kApiIdentifier); - - FutureData::Destroy(); - ReleaseClasses(env); -} - -// Creates a Uri from the string passed in and sets it on the builder using -// the builder_set_method_id. -// Deletes and clears the reference to the builder passed in. -// Returns the new builder which can be used for additional calls. -static jobject SetBuilderUri(JNIEnv* jni_env, jobject builder, - const char* value, - jmethodID builder_set_method_id) { - // The builder is null. Did you forget to take the builder result of a - // previous set call? - assert(builder); - // If there's no value to set, we can just return the original builder. - if (!value) return builder; - jobject uri_local = util::ParseUriString(jni_env, value); - jobject builder_morphed = - jni_env->CallObjectMethod(builder, builder_set_method_id, uri_local); - jni_env->DeleteLocalRef(uri_local); - jni_env->DeleteLocalRef(builder); - return builder_morphed; -} - -// Creates a jstring from the string passed in and sets it on the builder using -// the builder_set_method_id. -// Deletes and clears the reference to the builder passed in. -// Returns the new builder which can be used for additional calls. -static jobject SetBuilderString(JNIEnv* jni_env, jobject builder, - const char* value, - jmethodID builder_set_method_id) { - // The builder is null. Did you forget to take the builder result of a - // previous set call? - assert(builder); - if (!value) return builder; - jstring string_value = jni_env->NewStringUTF(value); - jobject builder_morphed = - jni_env->CallObjectMethod(builder, builder_set_method_id, string_value); - jni_env->DeleteLocalRef(string_value); - jni_env->DeleteLocalRef(builder); - return builder_morphed; -} - -// Sets an object reference on a builder -static jobject SetBuilderObject(JNIEnv* jni_env, jobject builder, jobject obj, - jmethodID builder_set_method_id) { - // The builder is null. Did you forget to take the builder result of a - // previous set call? - assert(builder); - jobject builder_morphed = - jni_env->CallObjectMethod(builder, builder_set_method_id, obj); - jni_env->DeleteLocalRef(builder); - return builder_morphed; -} - -// Sets a native type on the builder using the builder_set_method_id. -// T should be cast to the appropriate base java type: -// jboolean, jbyte, jchar, jshort, jint, jlong, jfloat, jdouble -// This is mainly to help all the builder calls be consistent. -// Deletes and clears the reference to the builder passed in. -// Returns the new builder which can be used for additional calls. -template -static jobject SetBuilderBaseType(JNIEnv* jni_env, jobject builder, T arg, - jmethodID builder_set_method_id) { - // The builder is null. Did you forget to take the builder result of a - // previous set call? - assert(builder); - jobject builder_morphed = - jni_env->CallObjectMethod(builder, builder_set_method_id, arg); - jni_env->DeleteLocalRef(builder); - return builder_morphed; -} - -// Calls the builder.Build function (method_id passed in). -// This also deletes the local ref to the builder. -// Returns a local ref to the constructed object. (You must call DeleteLocalRef -// on the returned object.) -static jobject BuildBuilder(JNIEnv* jni_env, jobject builder, - jmethodID builder_build_method_id) { - // The builder is null. Did you forget to take the builder result of a - // previous set call? - assert(builder); - jobject built_obj = - jni_env->CallObjectMethod(builder, builder_build_method_id); - jni_env->DeleteLocalRef(builder); - return built_obj; -} - -// You must call DeleteLocalRef on the returned object. -static jobject CreateAndroidParameters(JNIEnv* jni_env, - const AndroidParameters& params, - std::string* error_out) { - if (!params.package_name || !*params.package_name) { - *error_out = "Android Package Name is missing."; - return nullptr; - } - - jstring package_name_local = jni_env->NewStringUTF(params.package_name); - jobject builder = jni_env->NewObject( - dlink_android_params_builder::GetClass(), - dlink_android_params_builder::GetMethodId( - dlink_android_params_builder::kConstructorFromPackageName), - package_name_local); - jni_env->DeleteLocalRef(package_name_local); - - if (params.fallback_url) { - builder = SetBuilderUri(jni_env, builder, params.fallback_url, - dlink_android_params_builder::GetMethodId( - dlink_android_params_builder::kSetFallbackUrl)); - } - builder = - SetBuilderBaseType(jni_env, builder, (jint)params.minimum_version, - dlink_android_params_builder::GetMethodId( - dlink_android_params_builder::kSetMinimumVersion)); - return BuildBuilder(jni_env, builder, - dlink_android_params_builder::GetMethodId( - dlink_android_params_builder::kBuild)); -} - -// You must call DeleteLocalRef on the returned object. -static jobject CreateGoogleAnalyticsParameters( - JNIEnv* jni_env, const GoogleAnalyticsParameters& params) { - jobject builder = jni_env->NewObject( - dlink_google_analytics_params_builder::GetClass(), - dlink_google_analytics_params_builder::GetMethodId( - dlink_google_analytics_params_builder::kConstructor)); - - builder = - SetBuilderString(jni_env, builder, params.source, - dlink_google_analytics_params_builder::GetMethodId( - dlink_google_analytics_params_builder::kSetSource)); - builder = - SetBuilderString(jni_env, builder, params.medium, - dlink_google_analytics_params_builder::GetMethodId( - dlink_google_analytics_params_builder::kSetMedium)); - builder = SetBuilderString( - jni_env, builder, params.campaign, - dlink_google_analytics_params_builder::GetMethodId( - dlink_google_analytics_params_builder::kSetCampaign)); - builder = - SetBuilderString(jni_env, builder, params.term, - dlink_google_analytics_params_builder::GetMethodId( - dlink_google_analytics_params_builder::kSetTerm)); - builder = - SetBuilderString(jni_env, builder, params.content, - dlink_google_analytics_params_builder::GetMethodId( - dlink_google_analytics_params_builder::kSetContent)); - - return BuildBuilder(jni_env, builder, - dlink_google_analytics_params_builder::GetMethodId( - dlink_google_analytics_params_builder::kBuild)); -} - -// You must call DeleteLocalRef on the returned object. -static jobject CreateIOSParameters(JNIEnv* jni_env, const IOSParameters& params, - std::string* error_out) { - if (!params.bundle_id || !*params.bundle_id) { - *error_out = "IOS Bundle ID is missing."; - return nullptr; - } - - jstring bundle_id_local = jni_env->NewStringUTF(params.bundle_id); - jobject builder = - jni_env->NewObject(dlink_ios_params_builder::GetClass(), - dlink_ios_params_builder::GetMethodId( - dlink_ios_params_builder::kConstructor), - bundle_id_local); - jni_env->DeleteLocalRef(bundle_id_local); - - builder = SetBuilderUri(jni_env, builder, params.fallback_url, - dlink_ios_params_builder::GetMethodId( - dlink_ios_params_builder::kSetFallbackUrl)); - builder = SetBuilderString(jni_env, builder, params.custom_scheme, - dlink_ios_params_builder::GetMethodId( - dlink_ios_params_builder::kSetCustomScheme)); - builder = SetBuilderUri(jni_env, builder, params.ipad_fallback_url, - dlink_ios_params_builder::GetMethodId( - dlink_ios_params_builder::kSetIpadFallbackUrl)); - builder = SetBuilderString(jni_env, builder, params.ipad_bundle_id, - dlink_ios_params_builder::GetMethodId( - dlink_ios_params_builder::kSetIpadBundleId)); - builder = SetBuilderString(jni_env, builder, params.app_store_id, - dlink_ios_params_builder::GetMethodId( - dlink_ios_params_builder::kSetAppStoreId)); - builder = SetBuilderString(jni_env, builder, params.minimum_version, - dlink_ios_params_builder::GetMethodId( - dlink_ios_params_builder::kSetMinimumVersion)); - - return BuildBuilder( - jni_env, builder, - dlink_ios_params_builder::GetMethodId(dlink_ios_params_builder::kBuild)); -} - -// You must call DeleteLocalRef on the returned object. -static jobject CreateItunesAnalyticsParameters( - JNIEnv* jni_env, const ITunesConnectAnalyticsParameters& params) { - jobject builder = - jni_env->NewObject(dlink_itunes_params_builder::GetClass(), - dlink_itunes_params_builder::GetMethodId( - dlink_itunes_params_builder::kConstructor)); - - builder = - SetBuilderString(jni_env, builder, params.provider_token, - dlink_itunes_params_builder::GetMethodId( - dlink_itunes_params_builder::kSetProviderToken)); - builder = - SetBuilderString(jni_env, builder, params.affiliate_token, - dlink_itunes_params_builder::GetMethodId( - dlink_itunes_params_builder::kSetAffiliateToken)); - builder = - SetBuilderString(jni_env, builder, params.campaign_token, - dlink_itunes_params_builder::GetMethodId( - dlink_itunes_params_builder::kSetCampaignToken)); - - return BuildBuilder(jni_env, builder, - dlink_itunes_params_builder::GetMethodId( - dlink_itunes_params_builder::kBuild)); -} - -// You must call DeleteLocalRef on the returned object. -static jobject CreateSocalMetaParameters( - JNIEnv* jni_env, const SocialMetaTagParameters& params) { - jobject builder = - jni_env->NewObject(dlink_social_meta_params_builder::GetClass(), - dlink_social_meta_params_builder::GetMethodId( - dlink_social_meta_params_builder::kConstructor)); - - builder = SetBuilderString(jni_env, builder, params.title, - dlink_social_meta_params_builder::GetMethodId( - dlink_social_meta_params_builder::kSetTitle)); - builder = - SetBuilderString(jni_env, builder, params.description, - dlink_social_meta_params_builder::GetMethodId( - dlink_social_meta_params_builder::kSetDescription)); - builder = SetBuilderUri(jni_env, builder, params.image_url, - dlink_social_meta_params_builder::GetMethodId( - dlink_social_meta_params_builder::kSetImageUrl)); - - return BuildBuilder(jni_env, builder, - dlink_social_meta_params_builder::GetMethodId( - dlink_social_meta_params_builder::kBuild)); -} - -// You must call DeleteLocalRef on the returned object. -// if there is an error, error_out will be written and jobject will be nullptr. -static jobject PopulateLinkBuilder(JNIEnv* jni_env, - const DynamicLinkComponents& components, - std::string* error_out) { - assert(error_out != nullptr); - if (!components.link || !*components.link) { - *error_out = "Link is missing."; - return nullptr; - } - if (!components.domain_uri_prefix || !*components.domain_uri_prefix) { - *error_out = - "DynamicLinkComponents.domain_uri_prefix is required and cannot be " - "empty."; - return nullptr; - } - - jobject link_builder = jni_env->CallObjectMethod( - g_dynamic_links_class_instance, - dynamic_links::GetMethodId(dynamic_links::kCreateDynamicLink)); - - link_builder = - SetBuilderUri(jni_env, link_builder, components.link, - dlink_builder::GetMethodId(dlink_builder::kSetLink)); - *error_out = util::GetAndClearExceptionMessage(jni_env); - if (error_out->size()) { - // setLink() threw an exception. - jni_env->DeleteLocalRef(link_builder); - return nullptr; - } - - link_builder = SetBuilderString( - jni_env, link_builder, components.domain_uri_prefix, - dlink_builder::GetMethodId(dlink_builder::kSetDomainUriPrefix)); - *error_out = util::GetAndClearExceptionMessage(jni_env); - if (error_out->size()) { - // setDomainUriPrefix() threw an exception. - jni_env->DeleteLocalRef(link_builder); - return nullptr; - } - - if (components.android_parameters) { - jobject android_parameters_local = CreateAndroidParameters( - jni_env, *components.android_parameters, error_out); - if (!android_parameters_local) { - // some required inputs were missing. - jni_env->DeleteLocalRef(link_builder); - return nullptr; - } - - link_builder = SetBuilderObject( - jni_env, link_builder, android_parameters_local, - dlink_builder::GetMethodId(dlink_builder::kSetAndroidParameters)); - jni_env->DeleteLocalRef(android_parameters_local); - } - - // GoogleAnalyticsParameters - if (components.google_analytics_parameters) { - jobject google_analytics_parameters_local = CreateGoogleAnalyticsParameters( - jni_env, *components.google_analytics_parameters); - // There no required parameters, so no exceptions or errors to find here. - link_builder = SetBuilderObject( - jni_env, link_builder, google_analytics_parameters_local, - dlink_builder::GetMethodId( - dlink_builder::kSetGoogleAnalyticsParameters)); - jni_env->DeleteLocalRef(google_analytics_parameters_local); - } - - // IOSParameters - if (components.ios_parameters) { - jobject ios_parameters_local = - CreateIOSParameters(jni_env, *components.ios_parameters, error_out); - if (!ios_parameters_local) { - // some required inputs were missing. - jni_env->DeleteLocalRef(link_builder); - return nullptr; - } - link_builder = SetBuilderObject( - jni_env, link_builder, ios_parameters_local, - dlink_builder::GetMethodId(dlink_builder::kSetIosParameters)); - jni_env->DeleteLocalRef(ios_parameters_local); - } - - // ITunesConnectAnalyticsParameters - if (components.itunes_connect_analytics_parameters) { - jobject itunes_analytics_parameters_local = CreateItunesAnalyticsParameters( - jni_env, *components.itunes_connect_analytics_parameters); - // There no required parameters, so no exceptions or errors to find here. - link_builder = SetBuilderObject( - jni_env, link_builder, itunes_analytics_parameters_local, - dlink_builder::GetMethodId( - dlink_builder::kSetItunesConnectAnalyticsParameters)); - jni_env->DeleteLocalRef(itunes_analytics_parameters_local); - } - - // SocialMetaTagParameters - if (components.social_meta_tag_parameters) { - jobject social_meta_parameters_local = CreateSocalMetaParameters( - jni_env, *components.social_meta_tag_parameters); - // There no required parameters, so no exceptions or errors to find here. - link_builder = SetBuilderObject( - jni_env, link_builder, social_meta_parameters_local, - dlink_builder::GetMethodId(dlink_builder::kSetSocialMetaTagParameters)); - jni_env->DeleteLocalRef(social_meta_parameters_local); - } - - return link_builder; -} - -static jobject PopulateLinkBuilder(JNIEnv* jni_env, const char* long_link, - std::string* error_out) { - jobject link_builder = jni_env->CallObjectMethod( - g_dynamic_links_class_instance, - dynamic_links::GetMethodId(dynamic_links::kCreateDynamicLink)); - *error_out = util::GetAndClearExceptionMessage(jni_env); - if (error_out->size()) { - jni_env->DeleteLocalRef(link_builder); - return nullptr; - } - - link_builder = - SetBuilderUri(jni_env, link_builder, long_link, - dlink_builder::GetMethodId(dlink_builder::kSetLongLink)); - - return link_builder; -} - -// Converts a `java.util.List` to a `std::vector`, where -// Warning contains 2 strings, one for the warning code and one for the message. -// These are concatenated together in the form ": ". -void JavaWarningListToStdStringVector(JNIEnv* env, - std::vector* vector, - jobject java_list_obj) { - int size = env->CallIntMethod(java_list_obj, - util::list::GetMethodId(util::list::kSize)); - vector->clear(); - vector->reserve(size); - for (int i = 0; i < size; i++) { - jobject warning_element = env->CallObjectMethod( - java_list_obj, util::list::GetMethodId(util::list::kGet), i); - - jobject code_string_local = env->CallObjectMethod( - warning_element, short_dynamic_link_warning::GetMethodId( - short_dynamic_link_warning::kGetCode)); - jobject message_string_local = env->CallObjectMethod( - warning_element, short_dynamic_link_warning::GetMethodId( - short_dynamic_link_warning::kGetMessage)); - - env->DeleteLocalRef(warning_element); - - // these consume the local ref. - std::string code = util::JniStringToString(env, code_string_local); - std::string msg = util::JniStringToString(env, message_string_local); - - vector->push_back(code + ": " + msg); - } -} - -GeneratedDynamicLink GetLongLink(const DynamicLinkComponents& components) { - GeneratedDynamicLink gen_link; - FIREBASE_ASSERT_RETURN(gen_link, internal::IsInitialized()); - - JNIEnv* jni_env = g_app->GetJNIEnv(); - jobject link_builder = - PopulateLinkBuilder(jni_env, components, &gen_link.error); - if (!link_builder) { - return gen_link; - } - - jobject dlink_local = jni_env->CallObjectMethod( - link_builder, - dlink_builder::GetMethodId(dlink_builder::kBuildDynamicLink)); - gen_link.error = util::GetAndClearExceptionMessage(jni_env); - if (gen_link.error.size()) { - jni_env->DeleteLocalRef(dlink_local); - jni_env->DeleteLocalRef(link_builder); - return gen_link; - } - - jobject uri_local = jni_env->CallObjectMethod( - dlink_local, dlink::GetMethodId(dlink::kGetUri)); - gen_link.error = util::GetAndClearExceptionMessage(jni_env); - if (gen_link.error.size()) { - jni_env->DeleteLocalRef(uri_local); - jni_env->DeleteLocalRef(dlink_local); - jni_env->DeleteLocalRef(link_builder); - return gen_link; - } - - gen_link.url = util::JniUriToString(jni_env, uri_local); - - jni_env->DeleteLocalRef(dlink_local); - jni_env->DeleteLocalRef(link_builder); - return gen_link; -} - -static void FutureShortLinkCallback(JNIEnv* jni_env, jobject result, - util::FutureResult result_code, - const char* status_message, - void* callback_data) { - if (result_code == util::kFutureResultSuccess) { - // There should only one type that this callback currently handles on - // success. - assert(jni_env->IsInstanceOf(result, short_dynamic_link::GetClass())); - - GeneratedDynamicLink result_link; - - jobject uri_local = jni_env->CallObjectMethod( - result, - short_dynamic_link::GetMethodId(short_dynamic_link::kGetShortLink)); - result_link.url = util::JniUriToString(jni_env, uri_local); - - jobject warnings_list_local = jni_env->CallObjectMethod( - result, - short_dynamic_link::GetMethodId(short_dynamic_link::kGetWarnings)); - if (warnings_list_local != nullptr) { - // TODO(butterfield): NOTE: Currently the Java code does not return any - // warnings, so this code is untested! - JavaWarningListToStdStringVector(jni_env, &result_link.warnings, - warnings_list_local); - jni_env->DeleteLocalRef(warnings_list_local); - } - - FutureData* future_data = FutureData::Get(); - if (future_data) { - future_data->api()->CompleteWithResult( - FutureHandle(reinterpret_cast(callback_data)), - kErrorCodeSuccess, result_link); - } - } else { // result_code != Success - GeneratedDynamicLink result_link; - FutureData* future_data = FutureData::Get(); - if (future_data) { - result_link.error = status_message; - future_data->api()->CompleteWithResult( - FutureHandle(reinterpret_cast(callback_data)), - kErrorCodeFailed, status_message, result_link); - } - } -} - -static jint GetSuffixOption(const PathLength& path_length) { - for (int i = 0; i < FIREBASE_ARRAYSIZE(g_path_length_codes); ++i) { - if (g_path_length_codes[i].path_length_code == path_length) - return g_path_length_codes[i].value; - } - // Couldn't find the value in the map, must be default. - return kPathLengthDefault; -} - -// Common code for short links to set up the callback to handle the result. -static Future HandleShortLinkTask( - JNIEnv* jni_env, jobject link_builder, - const DynamicLinkOptions& dynamic_link_options, const std::string& error) { - ReferenceCountedFutureImpl* api = FutureData::Get()->api(); - const SafeFutureHandle handle = - api->SafeAlloc(kDynamicLinksFnGetShortLink); - - if (!link_builder) { - GeneratedDynamicLink gen_link; - gen_link.error = error; - api->CompleteWithResult(handle, kErrorCodeFailed, error.c_str(), gen_link); - return MakeFuture(api, handle); - } - jobject task; - if (dynamic_link_options.path_length != kPathLengthDefault) { - task = jni_env->CallObjectMethod( - link_builder, - dlink_builder::GetMethodId( - dlink_builder::kBuildShortDynamicLinkWithOption), - GetSuffixOption(dynamic_link_options.path_length)); - } else { - task = jni_env->CallObjectMethod( - link_builder, - dlink_builder::GetMethodId(dlink_builder::kBuildShortDynamicLink)); - } - - std::string exception_message = util::GetAndClearExceptionMessage(jni_env); - if (exception_message.size()) { - GeneratedDynamicLink gen_link; - gen_link.error = exception_message; - LogError("Couldn't build short link: %s", exception_message.c_str()); - api->CompleteWithResult(handle, kErrorCodeFailed, exception_message.c_str(), - gen_link); - } else { - util::RegisterCallbackOnTask(jni_env, task, FutureShortLinkCallback, - reinterpret_cast(handle.get().id()), - kApiIdentifier); - } - - jni_env->DeleteLocalRef(link_builder); - jni_env->DeleteLocalRef(task); - return MakeFuture(api, handle); -} - -Future GetShortLink( - const DynamicLinkComponents& components, - const DynamicLinkOptions& options) { - FIREBASE_ASSERT_RETURN(Future(), - internal::IsInitialized()); - JNIEnv* jni_env = g_app->GetJNIEnv(); - - // Temporary workaround: Get short link from long link rather than from - // components. TODO(b/113628371): remove this when the "Error 8" bug is fixed. - // - // First, get the long link. If that returns an error, pass that error and - // a null link builder to HandleShortLinkTask(), which will return a Future - // that propagates the error to the caller. - // - // If there was no error getting the long link, PopulateLinkBuilder handles - // getting the short link the same way that GetShortLink(long_link) does. - GeneratedDynamicLink long_link = GetLongLink(components); - std::string error = long_link.error; - jobject link_builder = nullptr; - if (error.empty()) { - link_builder = PopulateLinkBuilder(jni_env, long_link.url.c_str(), &error); - } - return HandleShortLinkTask(jni_env, link_builder, options, error); -} - -Future GetShortLink( - const DynamicLinkComponents& components) { - return GetShortLink(components, DynamicLinkOptions()); -} - -Future GetShortLink(const char* long_dynamic_link, - const DynamicLinkOptions& options) { - FIREBASE_ASSERT_RETURN(Future(), - internal::IsInitialized()); - JNIEnv* jni_env = g_app->GetJNIEnv(); - std::string error; - jobject link_builder = - PopulateLinkBuilder(jni_env, long_dynamic_link, &error); - return HandleShortLinkTask(jni_env, link_builder, options, error); -} - -Future GetShortLink(const char* long_dynamic_link) { - return GetShortLink(long_dynamic_link, DynamicLinkOptions()); -} - -Future GetShortLinkLastResult() { - FIREBASE_ASSERT_RETURN(Future(), - internal::IsInitialized()); - ReferenceCountedFutureImpl* api = FutureData::Get()->api(); - return static_cast&>( - api->LastResult(kDynamicLinksFnGetShortLink)); -} - -} // namespace dynamic_links -} // namespace firebase diff --git a/dynamic_links/src/dynamic_links_ios.mm b/dynamic_links/src/dynamic_links_ios.mm deleted file mode 100644 index 5e707fcfa7..0000000000 --- a/dynamic_links/src/dynamic_links_ios.mm +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright 2017 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 - -#include "dynamic_links/src/include/firebase/dynamic_links.h" -#include "dynamic_links/src/include/firebase/dynamic_links/components.h" - -#include "FDLURLComponents.h" - -#include "app/src/assert.h" -#include "app/src/include/firebase/variant.h" -#include "app/src/include/firebase/version.h" -#include "app/src/invites/ios/invites_receiver_internal_ios.h" -#include "app/src/reference_counted_future_impl.h" -#include "app/src/util_ios.h" -#include "dynamic_links/src/common.h" - -namespace firebase { -namespace dynamic_links { - -DEFINE_FIREBASE_VERSION_STRING(FirebaseDynamicLinks); - -static invites::internal::InvitesReceiverInternalIos::StartupRegistration - g_invites_startup_registration("ddl"); -static bool g_initialized = false; -static const char* kUrlEncodingError = "Specified link could not be encoded as a URL."; - -InitResult Initialize(const App& app, Listener* listener) { - if (!g_initialized) { - invites::internal::InvitesReceiverInternalIos::RegisterStartup(&g_invites_startup_registration); - g_initialized = CreateReceiver(app); - assert(g_initialized); - FutureData::Create(); - SetListener(listener); - } - return kInitResultSuccess; -} - -namespace internal { - -bool IsInitialized() { return g_initialized; } - -} // namespace internal - -void Terminate() { - if (!g_initialized) return; - DestroyReceiver(); - FutureData::Destroy(); - g_initialized = false; -} - -// Encode a URL from a C string. If this fails, nil is returned. -static NSURL* EncodeUrlFromString(const char* url_string) { - // Try encoding without escaping as the URL may already be escaped correctly. - NSURL* url = [NSURL URLWithString:@(url_string)]; - if (url) return url; - // If encoding without escaping fails, try again with percent encoding. - return [NSURL - URLWithString:[@(url_string) stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; -} - -// Add a warning to the list of warnings regarding failure to encode the specified -// URL. -static void AddUrlEncodingWarning(std::vector* warnings, const char* url, - const char* field_description) { - warnings->push_back(std::string("Failed to encode URL for ") + std::string(field_description) + - ", URL: " + url); -} - -// Set a URL field of an iOS dynamic link components object from a C++ structure string field. -#define FIR_DYNAMIC_LINK_PARAMS_SET_URL(fir_params_object, field, cpp_params_object, cpp_field, \ - field_description, generated_link_warnings) \ - { \ - if ((cpp_params_object)->cpp_field) { \ - NSURL* ns_url = EncodeUrlFromString((cpp_params_object)->cpp_field); \ - if (ns_url) { \ - (fir_params_object).field = ns_url; \ - } else { \ - AddUrlEncodingWarning(generated_link_warnings, (cpp_params_object)->cpp_field, \ - field_description); \ - } \ - } \ - } - -// Set a string field of an iOS dynamic link components object from a C++ structure string field. -#define FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params_object, field, cpp_params_object, cpp_field) \ - { \ - if ((cpp_params_object)->cpp_field) { \ - (fir_params_object).field = @((cpp_params_object)->cpp_field); \ - } \ - } - -// Construct FIRDynamicLinkComponents and populate GeneratedDynamicLink from DynamicLinkComponents. -static FIRDynamicLinkComponents* GetFIRComponentsAndGeneratedLink( - const DynamicLinkComponents& components, GeneratedDynamicLink* generated_link) { - static const char* kMissingFieldPostfix = "must be specified"; - if (!components.link) { - generated_link->error = std::string("Link ") + kMissingFieldPostfix; - return nil; - } - if (!components.domain_uri_prefix || !*components.domain_uri_prefix) { - generated_link->error = std::string("Domain URI Prefix ") + kMissingFieldPostfix; - return nil; - } - NSURL* link_url = EncodeUrlFromString(components.link); - if (!link_url) { - generated_link->error = kUrlEncodingError; - return nil; - } - FIRDynamicLinkComponents* fir_components = - [FIRDynamicLinkComponents componentsWithLink:link_url - domainURIPrefix:@(components.domain_uri_prefix)]; - { - auto* cpp_params = components.google_analytics_parameters; - if (cpp_params) { - FIRDynamicLinkGoogleAnalyticsParameters* fir_params = - [[FIRDynamicLinkGoogleAnalyticsParameters alloc] init]; - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, source, cpp_params, source); - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, medium, cpp_params, medium); - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, campaign, cpp_params, campaign); - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, term, cpp_params, term); - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, content, cpp_params, content); - fir_components.analyticsParameters = fir_params; - } - } - { - auto* cpp_params = components.ios_parameters; - if (cpp_params) { - if (!cpp_params->bundle_id) { - generated_link->error = std::string("iOS parameters bundle ID ") + kMissingFieldPostfix; - return nil; - } - FIRDynamicLinkIOSParameters* fir_params = - [FIRDynamicLinkIOSParameters parametersWithBundleID:@(cpp_params->bundle_id)]; - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, appStoreID, cpp_params, app_store_id); - FIR_DYNAMIC_LINK_PARAMS_SET_URL(fir_params, fallbackURL, cpp_params, fallback_url, - "iOS fallback URL", &generated_link->warnings); - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, customScheme, cpp_params, custom_scheme); - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, iPadBundleID, cpp_params, ipad_bundle_id); - FIR_DYNAMIC_LINK_PARAMS_SET_URL(fir_params, iPadFallbackURL, cpp_params, ipad_fallback_url, - "iOS iPad fallback URL", &generated_link->warnings); - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, minimumAppVersion, cpp_params, - minimum_version); - fir_components.iOSParameters = fir_params; - } - } - { - auto* cpp_params = components.itunes_connect_analytics_parameters; - if (cpp_params) { - FIRDynamicLinkItunesConnectAnalyticsParameters* fir_params = - [[FIRDynamicLinkItunesConnectAnalyticsParameters alloc] init]; - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, affiliateToken, cpp_params, affiliate_token); - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, campaignToken, cpp_params, campaign_token); - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, providerToken, cpp_params, provider_token); - fir_components.iTunesConnectParameters = fir_params; - } - } - { - auto* cpp_params = components.android_parameters; - if (cpp_params) { - if (!cpp_params->package_name) { - generated_link->error = - std::string("Android parameters package name ") + kMissingFieldPostfix; - return nil; - } - FIRDynamicLinkAndroidParameters* fir_params = - [FIRDynamicLinkAndroidParameters parametersWithPackageName:@(cpp_params->package_name)]; - FIR_DYNAMIC_LINK_PARAMS_SET_URL(fir_params, fallbackURL, cpp_params, fallback_url, - "Android fallback URL", &generated_link->warnings); - fir_params.minimumVersion = cpp_params->minimum_version; - fir_components.androidParameters = fir_params; - } - } - { - auto* cpp_params = components.social_meta_tag_parameters; - if (cpp_params) { - FIRDynamicLinkSocialMetaTagParameters* fir_params = - [[FIRDynamicLinkSocialMetaTagParameters alloc] init]; - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, title, cpp_params, title); - FIR_DYNAMIC_LINK_PARAMS_SET_STRING(fir_params, descriptionText, cpp_params, description); - FIR_DYNAMIC_LINK_PARAMS_SET_URL(fir_params, imageURL, cpp_params, image_url, - "Social Image URL", &generated_link->warnings); - fir_components.socialMetaTagParameters = fir_params; - } - } - if (fir_components.url) { - generated_link->url = util::NSStringToString(fir_components.url.absoluteString); - } else { - generated_link->error = "Failed to generated long link."; - } - return fir_components; -} - -GeneratedDynamicLink GetLongLink(const DynamicLinkComponents& components) { - FIREBASE_ASSERT_RETURN(GeneratedDynamicLink(), internal::IsInitialized()); - GeneratedDynamicLink generated_link; - GetFIRComponentsAndGeneratedLink(components, &generated_link); - return generated_link; -} - -// Convert DynamicLinkOptions to FIRDynamicLinkComponentsOptions. -static FIRDynamicLinkComponentsOptions* ToFIRDynamicLinkComponentsOptions( - const DynamicLinkOptions& dynamic_link_options) { - FIRDynamicLinkComponentsOptions* fir_options = [[FIRDynamicLinkComponentsOptions alloc] init]; - switch (dynamic_link_options.path_length) { - case kPathLengthShort: - fir_options.pathLength = FIRShortDynamicLinkPathLengthShort; - break; - case kPathLengthUnguessable: - fir_options.pathLength = FIRShortDynamicLinkPathLengthUnguessable; - break; - case kPathLengthDefault: - // Drop through. - default: - fir_options.pathLength = FIRShortDynamicLinkPathLengthDefault; - break; - } - return fir_options; -} - -// Generate a short link from a long dynamic link. -static Future GetShortLink(NSURL* long_link_url, - const GeneratedDynamicLink& generated_link, - const DynamicLinkOptions& dynamic_link_options) { - FIREBASE_ASSERT_RETURN(Future(), internal::IsInitialized()); - ReferenceCountedFutureImpl* api = FutureData::Get()->api(); - const SafeFutureHandle handle = - api->SafeAlloc(kDynamicLinksFnGetShortLink); - if (long_link_url) { - GeneratedDynamicLink* output_generated_link = new GeneratedDynamicLink(); - *output_generated_link = generated_link; - [FIRDynamicLinkComponents - shortenURL:long_link_url - options:ToFIRDynamicLinkComponentsOptions(dynamic_link_options) - completion:^(NSURL* _Nullable shortURL, NSArray* _Nullable warnings, - NSError* _Nullable error) { - int error_code = kErrorCodeSuccess; - if (error) { - error_code = error.code ? static_cast(error.code) : kErrorCodeFailed; - output_generated_link->error = util::NSStringToString(error.localizedDescription); - } else { - if (warnings) { - for (NSString* warning in warnings) { - output_generated_link->warnings.push_back(warning.UTF8String); - } - } - if (shortURL) { - output_generated_link->url = util::NSStringToString(shortURL.absoluteString); - } else { - error_code = kErrorCodeFailed; - output_generated_link->error = - std::string("Failed to shorten link ") + output_generated_link->url; - } - } - FutureData::Get()->api()->CompleteWithResult( - handle, error_code, output_generated_link->error.c_str(), *output_generated_link); - delete output_generated_link; - }]; - } else { - api->CompleteWithResult(handle, kErrorCodeFailed, generated_link.error.c_str(), generated_link); - } - return MakeFuture(api, handle); -} - -Future GetShortLink(const DynamicLinkComponents& components, - const DynamicLinkOptions& dynamic_link_options) { - FIREBASE_ASSERT_RETURN(Future(), internal::IsInitialized()); - GeneratedDynamicLink generated_link; - FIRDynamicLinkComponents* fir_components = - GetFIRComponentsAndGeneratedLink(components, &generated_link); - return GetShortLink(fir_components ? fir_components.url : nil, generated_link, - dynamic_link_options); -} - -Future GetShortLink(const DynamicLinkComponents& components) { - return GetShortLink(components, DynamicLinkOptions()); -} - -Future GetShortLink(const char* long_dynamic_link, - const DynamicLinkOptions& dynamic_link_options) { - FIREBASE_ASSERT_RETURN(Future(), internal::IsInitialized()); - GeneratedDynamicLink generated_link; - NSURL* link_url = EncodeUrlFromString(long_dynamic_link); - if (!link_url) generated_link.error = kUrlEncodingError; - return GetShortLink(link_url, generated_link, dynamic_link_options); -} - -Future GetShortLink(const char* long_dynamic_link) { - return GetShortLink(long_dynamic_link, DynamicLinkOptions()); -} - -Future GetShortLinkLastResult() { - FIREBASE_ASSERT_RETURN(Future(), internal::IsInitialized()); - ReferenceCountedFutureImpl* api = FutureData::Get()->api(); - return static_cast&>( - api->LastResult(kDynamicLinksFnGetShortLink)); -} - -} // namespace dynamic_links -} // namespace firebase diff --git a/dynamic_links/src/dynamic_links_stub.cc b/dynamic_links/src/dynamic_links_stub.cc deleted file mode 100644 index a4c79333bb..0000000000 --- a/dynamic_links/src/dynamic_links_stub.cc +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright 2017 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 - -#include -#include -#include - -#include "app/src/assert.h" -#include "app/src/include/firebase/variant.h" -#include "app/src/include/firebase/version.h" -#include "app/src/reference_counted_future_impl.h" -#include "dynamic_links/src/common.h" -#include "dynamic_links/src/include/firebase/dynamic_links.h" -#include "dynamic_links/src/include/firebase/dynamic_links/components.h" - -namespace firebase { -namespace dynamic_links { - -DEFINE_FIREBASE_VERSION_STRING(FirebaseDynamicLinks); - -static const char* kLinkShorteningNotSupported = - "Link shortening is not supported on desktop."; - -bool g_initialized = false; - -InitResult Initialize(const App& app, Listener* listener) { - if (!g_initialized) { - g_initialized = CreateReceiver(app); - assert(g_initialized); - FutureData::Create(); - SetListener(listener); - } - return kInitResultSuccess; -} - -namespace internal { - -bool IsInitialized() { return g_initialized; } - -} // namespace internal - -void Terminate() { - if (!g_initialized) return; - DestroyReceiver(); - FutureData::Destroy(); - g_initialized = false; -} - -// Store a value (as a string) associated with the string key in the specified -// output_map. -template -void StoreKeyValuePairAsStringInMap( - std::map* output_map, const char* key, - const T value) { - (*output_map)[key] = Variant(value).AsString().mutable_string(); -} - -// Specialization of StoreKeyValuePairAsStringInMap() that ignores null strings. -template <> -void StoreKeyValuePairAsStringInMap( - std::map* output_map, const char* key, - const char* value) { - if (value) (*output_map)[key] = value; -} - -// Generate a query string from map of strings. -std::string QueryStringFromMap( - const std::map& parameters) { - std::string query_string; - int index = 0; - for (auto it = parameters.begin(); it != parameters.end(); ++it, ++index) { - const char* prefix = index == 0 ? "?" : "&"; - // TODO(smiles): URLs really need to be percent encoded. - query_string += prefix; - query_string += it->first; - query_string += "="; - query_string += it->second; - } - return query_string; -} - -// Generate a long link from dynamic links components. -static GeneratedDynamicLink LongLinkFromComponents( - const DynamicLinkComponents& components) { - GeneratedDynamicLink generated_link; - if (components.link == nullptr || strlen(components.link) == 0) { - generated_link.error = "No target link specified."; - return generated_link; - } - if (components.domain_uri_prefix == nullptr || - strlen(components.domain_uri_prefix) == 0) { - generated_link.error = "No domain specified."; - return generated_link; - } - std::map query_parameters; - StoreKeyValuePairAsStringInMap(&query_parameters, "link", components.link); - { - const auto* params = components.google_analytics_parameters; - if (params) { - StoreKeyValuePairAsStringInMap(&query_parameters, "utm_source", - params->source); - StoreKeyValuePairAsStringInMap(&query_parameters, "utm_medium", - params->medium); - StoreKeyValuePairAsStringInMap(&query_parameters, "utm_campaign", - params->campaign); - StoreKeyValuePairAsStringInMap(&query_parameters, "utm_term", - params->term); - StoreKeyValuePairAsStringInMap(&query_parameters, "utm_content", - params->content); - } - } - { - const auto* params = components.ios_parameters; - if (params) { - StoreKeyValuePairAsStringInMap(&query_parameters, "ibi", - params->bundle_id); - StoreKeyValuePairAsStringInMap(&query_parameters, "isi", - params->app_store_id); - StoreKeyValuePairAsStringInMap(&query_parameters, "ifl", - params->fallback_url); - StoreKeyValuePairAsStringInMap(&query_parameters, "ius", - params->custom_scheme); - StoreKeyValuePairAsStringInMap(&query_parameters, "imv", - params->minimum_version); - StoreKeyValuePairAsStringInMap(&query_parameters, "ipbi", - params->ipad_bundle_id); - StoreKeyValuePairAsStringInMap(&query_parameters, "ipfl", - params->ipad_fallback_url); - } - } - { - const auto* params = components.itunes_connect_analytics_parameters; - if (params) { - StoreKeyValuePairAsStringInMap(&query_parameters, "pt", - params->provider_token); - StoreKeyValuePairAsStringInMap(&query_parameters, "ct", - params->campaign_token); - StoreKeyValuePairAsStringInMap(&query_parameters, "at", - params->affiliate_token); - } - } - { - const auto* params = components.android_parameters; - if (params) { - StoreKeyValuePairAsStringInMap(&query_parameters, "apn", - params->package_name); - StoreKeyValuePairAsStringInMap(&query_parameters, "afl", - params->fallback_url); - StoreKeyValuePairAsStringInMap(&query_parameters, "amv", - params->minimum_version); - } - } - { - const auto* params = components.social_meta_tag_parameters; - if (params) { - StoreKeyValuePairAsStringInMap(&query_parameters, "st", params->title); - StoreKeyValuePairAsStringInMap(&query_parameters, "sd", - params->description); - StoreKeyValuePairAsStringInMap(&query_parameters, "si", - params->image_url); - } - } - generated_link.url = std::string(components.domain_uri_prefix) + "/" + - QueryStringFromMap(query_parameters); - return generated_link; -} - -GeneratedDynamicLink GetLongLink(const DynamicLinkComponents& components) { - FIREBASE_ASSERT_RETURN(GeneratedDynamicLink(), internal::IsInitialized()); - return LongLinkFromComponents(components); -} - -Future GetShortLink( - const DynamicLinkComponents& components, - const DynamicLinkOptions& /*dynamic_link_options*/) { - FIREBASE_ASSERT_RETURN(Future(), - internal::IsInitialized()); - auto long_link = GetLongLink(components); - long_link.warnings.push_back(kLinkShorteningNotSupported); - ReferenceCountedFutureImpl* api = FutureData::Get()->api(); - const auto handle = - api->SafeAlloc(kDynamicLinksFnGetShortLink); - api->CompleteWithResult(handle, 0, "", long_link); - return GetShortLinkLastResult(); -} - -Future GetShortLink( - const DynamicLinkComponents& components) { - return GetShortLink(components, DynamicLinkOptions()); -} - -Future GetShortLink( - const char* long_dynamic_link, - const DynamicLinkOptions& /*dynamic_link_options*/) { - FIREBASE_ASSERT_RETURN(Future(), - internal::IsInitialized()); - GeneratedDynamicLink long_link; - long_link.url = long_dynamic_link; - long_link.warnings.push_back(kLinkShorteningNotSupported); - ReferenceCountedFutureImpl* api = FutureData::Get()->api(); - const auto handle = - api->SafeAlloc(kDynamicLinksFnGetShortLink); - api->CompleteWithResult(handle, 0, "", long_link); - return GetShortLinkLastResult(); -} - -Future GetShortLink(const char* long_dynamic_link) { - return GetShortLink(long_dynamic_link, DynamicLinkOptions()); -} - -Future GetShortLinkLastResult() { - FIREBASE_ASSERT_RETURN(Future(), - internal::IsInitialized()); - ReferenceCountedFutureImpl* api = FutureData::Get()->api(); - return static_cast&>( - api->LastResult(kDynamicLinksFnGetShortLink)); -} - -} // namespace dynamic_links -} // namespace firebase diff --git a/dynamic_links/src/include/firebase/dynamic_links.h b/dynamic_links/src/include/firebase/dynamic_links.h deleted file mode 100644 index eb1bf6e47d..0000000000 --- a/dynamic_links/src/include/firebase/dynamic_links.h +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2017 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. - -#ifndef FIREBASE_DYNAMIC_LINKS_SRC_INCLUDE_FIREBASE_DYNAMIC_LINKS_H_ -#define FIREBASE_DYNAMIC_LINKS_SRC_INCLUDE_FIREBASE_DYNAMIC_LINKS_H_ - -#include - -#include "firebase/app.h" -#include "firebase/internal/common.h" - -#if !defined(DOXYGEN) && !defined(SWIG) -FIREBASE_APP_REGISTER_CALLBACKS_REFERENCE(dynamic_links) -#endif // !defined(DOXYGEN) && !defined(SWIG) - -namespace firebase { - -/// @brief Firebase Dynamic Links API. -/// -/// Firebase Dynamic Links is a cross-platform solution for generating and -/// receiving links, whether or not the app is already installed. -/// -/// @deprecated Dynamic Links is now deprecated. Please see the support -/// documentation at https://firebase.google.com/support/dynamic-links-faq -/// for more information. -namespace dynamic_links { - -#ifndef SWIG -/// @brief Error code used by Futures returned by this API. -enum ErrorCode { - kErrorCodeSuccess = 0, - kErrorCodeFailed, -}; -#endif // SWIG - -/// @brief Enum describing the strength of a dynamic links match. -/// -/// This version is local to dynamic links; there is a similar enum in invites -/// and another internal version in app. -enum LinkMatchStrength { - /// No match has been achieved - kLinkMatchStrengthNoMatch = 0, - - /// The match between the Dynamic Link and device is not perfect. You should - /// not reveal any personal information related to the Dynamic Link. - kLinkMatchStrengthWeakMatch, - - /// The match between the Dynamic Link and this device has a high confidence, - /// but there is a small possibility of error. - kLinkMatchStrengthStrongMatch, - - /// The match between the Dynamic Link and the device is exact. You may - /// safely reveal any personal information related to this Dynamic Link. - kLinkMatchStrengthPerfectMatch -}; - -/// @brief The received Dynamic Link. -struct DynamicLink { - /// The URL that was passed to the app. - std::string url; - /// The match strength of the dynamic link. - LinkMatchStrength match_strength; -}; - -/// @brief Base class used to receive Dynamic Links. -class Listener { - public: - virtual ~Listener(); - - /// Called on the client when a dynamic link arrives. - /// - /// @param[in] dynamic_link The data describing the Dynamic Link. - virtual void OnDynamicLinkReceived(const DynamicLink* dynamic_link) = 0; -}; - -/// @brief Initialize Firebase Dynamic Links. -/// -/// After Initialize is called, the implementation may call functions on the -/// Listener provided at any time. -/// -/// @param[in] app The Firebase App object for this application. -/// @param[in] listener A Listener object that receives Dynamic Links. -/// -/// @return kInitResultSuccess if initialization succeeded, or -/// kInitResultFailedMissingDependency on Android if Google Play services is -/// not available on the current device. -/// -/// @deprecated Dynamic Links is now deprecated. Please see the support -/// documentation at https://firebase.google.com/support/dynamic-links-faq -/// for more information. -FIREBASE_DEPRECATED InitResult Initialize(const App& app, Listener* listener); - -/// @brief Terminate Firebase Dynamic Links. -/// -/// @deprecated Dynamic Links is now deprecated. Please see the support -/// documentation at https://firebase.google.com/support/dynamic-links-faq -/// for more information. -FIREBASE_DEPRECATED void Terminate(); - -/// @brief Set the listener for receiving Dynamic Links. -/// -/// @param[in] listener A Listener object that receives Dynamic Links. -/// -/// @return Pointer to the previously set listener. -/// -/// @deprecated Dynamic Links is now deprecated. Please see the support -/// documentation at https://firebase.google.com/support/dynamic-links-faq -/// for more information. -FIREBASE_DEPRECATED Listener* SetListener(Listener* listener); - -/// Fetch any pending dynamic links. Each pending link will trigger a call to -/// the registered Listener class. -/// -/// This function is implicitly called on initialization. On iOS this is called -/// automatically when the app gains focus, but on Android this needs to be -/// called manually. -/// -/// @deprecated Dynamic Links is now deprecated. Please see the support -/// documentation at https://firebase.google.com/support/dynamic-links-faq -/// for more information. -FIREBASE_DEPRECATED void Fetch(); - -} // namespace dynamic_links -} // namespace firebase - -#endif // FIREBASE_DYNAMIC_LINKS_SRC_INCLUDE_FIREBASE_DYNAMIC_LINKS_H_ diff --git a/dynamic_links/src/include/firebase/dynamic_links/components.h b/dynamic_links/src/include/firebase/dynamic_links/components.h deleted file mode 100644 index 7a8e8fa1a4..0000000000 --- a/dynamic_links/src/include/firebase/dynamic_links/components.h +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright 2017 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. - -#ifndef FIREBASE_DYNAMIC_LINKS_SRC_INCLUDE_FIREBASE_DYNAMIC_LINKS_COMPONENTS_H_ -#define FIREBASE_DYNAMIC_LINKS_SRC_INCLUDE_FIREBASE_DYNAMIC_LINKS_COMPONENTS_H_ - -#include -#include -#include - -#include "firebase/future.h" - -namespace firebase { - -namespace dynamic_links { - -/// @brief Google Analytics Parameters. -/// -/// Note that the strings used by the struct are not copied, as so must -/// either be statically allocated, or must persist in memory until the -/// DynamicLinkComponents that uses them goes out of scope. -struct GoogleAnalyticsParameters { - /// Constructs an empty set of Google Analytics parameters. - GoogleAnalyticsParameters() - : source(nullptr), - medium(nullptr), - campaign(nullptr), - term(nullptr), - content(nullptr) {} - - /// The campaign source; used to identify a search engine, newsletter, - /// or other source. - const char* source; - /// The campaign medium; used to identify a medium such as email or - /// cost-per-click (cpc). - const char* medium; - /// The campaign name; The individual campaign name, slogan, promo code, etc. - /// for a product. - const char* campaign; - /// The campaign term; used with paid search to supply the keywords for ads. - const char* term; - /// The campaign content; used for A/B testing and content-targeted ads to - /// differentiate ads or links that point to the same URL. - const char* content; -}; - -/// @brief iOS Parameters. -/// -/// Note that the strings used by the struct are not copied, as so must -/// either be statically allocated, or must persist in memory until the -/// DynamicLinkComponents that uses them goes out of scope. -struct IOSParameters { - /// Constructs a set of IOS parameters with the given bundle id. - /// - /// @param bundle_id_ The parameters ID of the iOS app to use to open the - /// link. - IOSParameters(const char* bundle_id_) - : bundle_id(bundle_id_), - fallback_url(nullptr), - custom_scheme(nullptr), - ipad_fallback_url(nullptr), - ipad_bundle_id(nullptr), - app_store_id(nullptr), - minimum_version(nullptr) {} - - /// Constructs an empty set of IOS parameters. - IOSParameters() - : bundle_id(nullptr), - fallback_url(nullptr), - custom_scheme(nullptr), - ipad_fallback_url(nullptr), - ipad_bundle_id(nullptr), - app_store_id(nullptr), - minimum_version(nullptr) {} - - /// The parameters ID of the iOS app to use to open the link. The app must be - /// connected to your project from the Overview page of the Firebase console. - /// Note this field is required. - const char* bundle_id; - /// The link to open on iOS if the app is not installed. - /// - /// Specify this to do something other than install your app from the - /// App Store when the app isn't installed, such as open the mobile - /// web version of the content, or display a promotional page for your app. - const char* fallback_url; - /// The app's custom URL scheme, if defined to be something other than your - /// app's parameters ID. - const char* custom_scheme; - /// The link to open on iPad if the app is not installed. - /// - /// Overrides fallback_url when on iPad. - const char* ipad_fallback_url; - /// The iPad parameters ID of the app. - const char* ipad_bundle_id; - /// The App Store ID, used to send users to the App Store when the app isn't - /// installed. - const char* app_store_id; - /// The minimum version of your app that can open the link. - const char* minimum_version; -}; - -/// @brief iTunes Connect App Analytics Parameters. -/// -/// Note that the strings used by the struct are not copied, as so must -/// either be statically allocated, or must persist in memory until the -/// DynamicLinkComponents that uses them goes out of scope. -struct ITunesConnectAnalyticsParameters { - /// Constructs an empty set of ITunes Connect Analytics parameters. - ITunesConnectAnalyticsParameters() - : provider_token(nullptr), - affiliate_token(nullptr), - campaign_token(nullptr) {} - - /// The provider token that enables analytics for Dynamic Links from - /// within iTunes Connect. - const char* provider_token; - /// The affiliate token used to create affiliate-coded links. - const char* affiliate_token; - /// The campaign token that developers can add to any link in order to - /// track sales from a specific marketing campaign. - const char* campaign_token; -}; - -/// @brief Android Parameters. -/// -/// Note that the strings used by the struct are not copied, as so must -/// either be statically allocated, or must persist in memory until the -/// DynamicLinkComponents that uses them goes out of scope. -struct AndroidParameters { - /// Constructs a set of Android parameters with the given package name. - /// - /// The package name of the Android app to use to open the link. - AndroidParameters(const char* package_name_) - : package_name(package_name_), - fallback_url(nullptr), - minimum_version(0) {} - - /// Constructs an empty set of Android parameters. - AndroidParameters() - : package_name(nullptr), fallback_url(nullptr), minimum_version(0) {} - - /// The package name of the Android app to use to open the link. The app - /// must be connected to your project from the Overview page of the Firebase - /// console. - /// Note this field is required. - const char* package_name; - /// The link to open when the app isn't installed. - /// - /// Specify this to do something other than install your app from the - /// Play Store when the app isn't installed, such as open the mobile web - /// version of the content, or display a promotional page for your app. - const char* fallback_url; - /// The versionCode of the minimum version of your app that can open the link. - int minimum_version; -}; - -/// @brief Social meta-tag Parameters. -/// -/// Note that the strings used by the struct are not copied, as so must -/// either be statically allocated, or must persist in memory until the -/// DynamicLinkComponents that uses them goes out of scope. -struct SocialMetaTagParameters { - /// Constructs an empty set of Social meta-tag parameters. - SocialMetaTagParameters() - : title(nullptr), description(nullptr), image_url(nullptr) {} - - /// The title to use when the Dynamic Link is shared in a social post. - const char* title; - /// The description to use when the Dynamic Link is shared in a social post. - const char* description; - /// The URL to an image related to this link. - const char* image_url; -}; - -/// @brief The desired path length for shortened Dynamic Link URLs. -enum PathLength { - /// Uses the server-default for the path length. - /// See https://goo.gl/8yDAqC for more information. - kPathLengthDefault = 0, - /// Typical short link for non-sensitive links. - kPathLengthShort, - /// Short link that uses a very long path to make it more difficult to - /// guess. Useful for sensitive links. - kPathLengthUnguessable, -}; - -/// @brief Additional options for Dynamic Link creation. -struct DynamicLinkOptions { - /// Constructs an empty set of Dynamic Link options. - DynamicLinkOptions() : path_length(kPathLengthDefault) {} - - /// The desired path length for shortened Dynamic Link URLs. - PathLength path_length; -}; - -/// @brief The returned value from creating a Dynamic Link. -struct GeneratedDynamicLink { - /// The Dynamic Link value. - std::string url; - /// Information about potential warnings on link creation. - /// - /// Usually presence of warnings means parameter format errors, parameter - /// value errors, or missing parameters. - std::vector warnings; - /// If non-empty, the cause of the Dynamic Link generation failure. - std::string error; -}; - -/// @brief The information needed to generate a Dynamic Link. -/// -/// Note that the strings used by the struct are not copied, as so must -/// either be statically allocated, or must persist in memory until this -/// struct goes out of scope. -struct DynamicLinkComponents { - /// The link your app will open. - /// You can specify any URL your app can handle, such as a link to your - /// app's content, or a URL that initiates some - /// app-specific logic such as crediting the user with a coupon, or - /// displaying a specific welcome screen. This link must be a well-formatted - /// URL, be properly URL-encoded, and use the HTTP or HTTPS scheme. - /// Note, this field is required. - const char* link; - /// The domain (of the form "https://xyz.app.goo.gl") to use for this Dynamic - /// Link. You can find this value in the Dynamic Links section of the Firebase - /// console. - /// - /// If you have set up custom domains on your project, set this to your - /// project's custom domain as listed in the Firebase console. - /// - /// Only https:// links are supported. - /// - /// Note, this field is required. - const char* domain_uri_prefix; - /// The Google Analytics parameters. - GoogleAnalyticsParameters* google_analytics_parameters; - /// The iOS parameters. - IOSParameters* ios_parameters; - /// The iTunes Connect App Analytics parameters. - ITunesConnectAnalyticsParameters* itunes_connect_analytics_parameters; - /// The Android parameters. - AndroidParameters* android_parameters; - /// The social meta-tag parameters. - SocialMetaTagParameters* social_meta_tag_parameters; - - /// Default constructor, initializes all fields to null. - DynamicLinkComponents() - : link(nullptr), - domain_uri_prefix(nullptr), - google_analytics_parameters(nullptr), - ios_parameters(nullptr), - itunes_connect_analytics_parameters(nullptr), - android_parameters(nullptr), - social_meta_tag_parameters(nullptr) {} - - /// Constructor that initializes with the given link and domain. - /// - /// @param link_ The link your app will open. - /// @param domain_uri_prefix_ The domain (of the form - /// "https://xyz.app.goo.gl") to use for this Dynamic Link. You can find this - /// value in the Dynamic Links section of the Firebase console. If you have - /// set up custom domains on your project, set this to your project's custom - /// domain as listed in the Firebase console. Note: If you do not specify - /// "https://" as the URI scheme, it will be added. - DynamicLinkComponents(const char* link_, const char* domain_uri_prefix_) - : link(link_), - domain_uri_prefix(domain_uri_prefix_), - google_analytics_parameters(nullptr), - ios_parameters(nullptr), - itunes_connect_analytics_parameters(nullptr), - android_parameters(nullptr), - social_meta_tag_parameters(nullptr) { - // For backwards compatibility with dynamic_link_domain, if - // domain_uri_prefix doesn't start with "https://", add it. - static const char kHttpsPrefix[] = "https://"; - static const size_t kHttpsPrefixLength = sizeof(kHttpsPrefix) - 1; - if (strncmp(domain_uri_prefix, kHttpsPrefix, kHttpsPrefixLength) != 0) { - domain_uri_prefix_with_scheme = - std::string(kHttpsPrefix) + domain_uri_prefix; - domain_uri_prefix = domain_uri_prefix_with_scheme.c_str(); - } - } - -#ifndef INTERNAL_EXPERIMENTAL - - private: -#endif // INTERNAL_EXPERIMENTAL - std::string domain_uri_prefix_with_scheme; -}; - -/// Creates a long Dynamic Link from the given parameters. -GeneratedDynamicLink GetLongLink(const DynamicLinkComponents& components); - -/// Creates a shortened Dynamic Link from the given parameters. -/// @param components: Settings used to configure the behavior for the link. -Future GetShortLink( - const DynamicLinkComponents& components); - -/// Creates a shortened Dynamic Link from the given parameters. -/// @param components: Settings used to configure the behavior for the link. -/// @param options: Additional options for Dynamic Link shortening, indicating -/// whether or not to produce an unguessable or shortest possible link. -/// No references to the options object will be retained after the call. -Future GetShortLink( - const DynamicLinkComponents& components, const DynamicLinkOptions& options); - -/// Creates a shortened Dynamic Link from a given long Dynamic Link. -/// @param long_dynamic_link A link previously generated from GetLongLink. -Future GetShortLink(const char* long_dynamic_link); - -/// Creates a shortened Dynamic Link from a given long Dynamic Link. -/// @param long_dynamic_link: A link previously generated from GetLongLink. -/// @param options: Additional options for Dynamic Link shortening, indicating -/// whether or not to produce an unguessable or shortest possible link. -/// No references to the options object will be retained after the call. -Future GetShortLink(const char* long_dynamic_link, - const DynamicLinkOptions& options); - -/// Get the (possibly still pending) results of the most recent GetShortUrl -/// call. -Future GetShortLinkLastResult(); - -} // namespace dynamic_links -} // namespace firebase - -#endif // FIREBASE_DYNAMIC_LINKS_SRC_INCLUDE_FIREBASE_DYNAMIC_LINKS_COMPONENTS_H_ diff --git a/dynamic_links/src/listener.cc b/dynamic_links/src/listener.cc deleted file mode 100644 index d342673dd9..0000000000 --- a/dynamic_links/src/listener.cc +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017 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 "dynamic_links/src/include/firebase/dynamic_links.h" - -namespace firebase { -namespace dynamic_links { - -// Non-inline implementation of Listener's virtual destructor -// to prevent its vtable being emitted in each translation unit. -Listener::~Listener() {} - -} // namespace dynamic_links -} // namespace firebase diff --git a/release_build_files/Android/firebase_dependencies.gradle b/release_build_files/Android/firebase_dependencies.gradle index 142de79cc7..efcc1983b6 100644 --- a/release_build_files/Android/firebase_dependencies.gradle +++ b/release_build_files/Android/firebase_dependencies.gradle @@ -24,7 +24,6 @@ def firebaseDependenciesMap = [ 'analytics' : ['com.google.firebase:firebase-analytics'], 'auth' : ['com.google.firebase:firebase-auth'], 'database' : ['com.google.firebase:firebase-database'], - 'dynamic_links' : ['com.google.firebase:firebase-dynamic-links'], 'firestore' : ['com.google.firebase:firebase-firestore'], 'functions' : ['com.google.firebase:firebase-functions'], 'gma' : ['com.google.android.gms:play-services-ads:23.0.0', @@ -66,9 +65,6 @@ class Dependencies { def getDatabase() { libSet.add('database') } - def getDynamicLinks() { - libSet.add('dynamic_links') - } def getFirestore() { libSet.add('firestore') } @@ -81,9 +77,6 @@ class Dependencies { def getInstallations() { libSet.add('installations') } - def getInvites() { - libSet.add('invites') - } def getMessaging() { libSet.add('messaging') } diff --git a/release_build_files/CMakeLists.txt b/release_build_files/CMakeLists.txt index 594440937d..f25a66bcad 100644 --- a/release_build_files/CMakeLists.txt +++ b/release_build_files/CMakeLists.txt @@ -93,7 +93,6 @@ add_firebase_target(firebase_analytics) add_firebase_target(firebase_app_check) add_firebase_target(firebase_auth) add_firebase_target(firebase_database) -add_firebase_target(firebase_dynamic_links) add_firebase_target(firebase_firestore) add_firebase_target(firebase_functions) add_firebase_target(firebase_gma) diff --git a/settings.gradle b/settings.gradle index ad2d909d3d..2877286a44 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,7 +2,6 @@ rootProject.name = 'firebase_cpp_sdk' include ':app', ':app:app_resources', ':app:google_api_resources', - ':app:invites_resources', ':app_check', ":app_check:app_check_resources", ':analytics', @@ -10,7 +9,6 @@ include ':app', ':auth:auth_resources', ':database', ':database:database_resources', - ':dynamic_links', ':firestore', ':firestore:firestore_resources', ':functions',