Skip to content

Commit

Permalink
Merge remote branch 'origin/master' into GitHub
Browse files Browse the repository at this point in the history
  • Loading branch information
a-maurice committed Nov 16, 2019
2 parents e8aeb12 + 0841a2d commit b85a33f
Show file tree
Hide file tree
Showing 104 changed files with 2,203 additions and 597 deletions.
10 changes: 5 additions & 5 deletions Android/firebase_dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ def firebaseDependenciesMap = [
'admob' : ['com.google.firebase:firebase-ads:18.2.0',
'com.google.android.gms:play-services-measurement-sdk-api:17.2.0'],
'analytics' : ['com.google.firebase:firebase-analytics:17.2.0'],
'auth' : ['com.google.firebase:firebase-auth:19.0.0'],
'database' : ['com.google.firebase:firebase-database:19.1.0'],
'auth' : ['com.google.firebase:firebase-auth:19.1.0'],
'database' : ['com.google.firebase:firebase-database:19.2.0'],
'dynamic_links' : ['com.google.firebase:firebase-dynamic-links:19.0.0'],
'functions' : ['com.google.firebase:firebase-functions:19.0.1'],
'instance_id' : ['com.google.firebase:firebase-iid:20.0.0'],
'invites' : ['com.google.firebase:firebase-invites:17.0.0'],
// Messaging has an additional local dependency to include.
'messaging' : ['com.google.firebase:firebase-messaging:20.0.0',
'firebase_cpp_sdk.messaging:messaging_java'],
'performance' : ['com.google.firebase:firebase-perf:19.0.0'],
'remote_config' : ['com.google.firebase:firebase-config:19.0.1'],
'storage' : ['com.google.firebase:firebase-storage:19.0.1']
'performance' : ['com.google.firebase:firebase-perf:19.0.1'],
'remote_config' : ['com.google.firebase:firebase-config:19.0.3'],
'storage' : ['com.google.firebase:firebase-storage:19.1.0']
]

// A map of library to the gradle resources that they depend upon.
Expand Down
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ option(FIREBASE_CPP_BUILD_TESTS
option(FIREBASE_FORCE_FAKE_SECURE_STORAGE
"Disable use of platform secret store and use fake impl." OFF)

if(WIN32)
# Turn on the use of the __cplusplus compiler define that is used to detect if
# move operators are supported
add_definitions("/Zc:__cplusplus")
endif()

list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_LIST_DIR}/cmake)
include(external_rules)

Expand Down
43 changes: 42 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,61 @@ git clone https://github.com/firebase/firebase-cpp-sdk.git
## Prerequisites
The following prerequisites are required for all platforms. Be sure to add any
directories to your PATH as needed.

- [CMake](https://cmake.org/), version 3.1, or newer
- [Python](https://www.python.com/), the latest version of 2.7, or newer
- [Python2](https://www.python.com/), version of 2.7, or newer
- [Abseil-py](https://github.com/abseil/abseil-py)

Note: Once python is installed you can use the following commands to install
required packages:

* python -m ensurepip --default-pip
* python -m pip install --user absl-py
* python -m pip install --user protobuf

### Prerequisites for Desktop
The following prerequisites are required when building the libraries for
desktop platforms.

- [OpenSSL](https://www.openssl.org/), needed for Realtime Database
- [Protobuf](https://github.com/protocolbuffers/protobuf/blob/master/src/README.md),
needed for Remote Config

### Prerequisites for Windows
Prebuilt packages for openssl can be found using google and if CMake fails to
find the install path use the command line option
**-DOPENSSL_ROOT_DIR=[Open SSL Dir]**.

Since there are no prebuilt packages for protobuf, getting it working on Windows
is a little tricky. The following steps can be used as a guide:

* Download source [zip from github](https://github.com/protocolbuffers/protobuf/releases/download/v3.9.2/protobuf-all-3.9.2.zip).
* Extract source and open command prompt to root folder
* Make new folder **vsprojects**
* CD to **vsprojects**
* run cmake: **cmake ..\cmake -Dprotobuf_BUILD_TESTS=OFF -A Win32**
* Build solution
* Add command line define to firebase cmake command (see below)
**-DPROTOBUF_SRC_ROOT_FOLDER=[Source Root Folder]**

Note: For x64 builds folder needs to be **vsprojects\x64** and change **Win32**
in cmake command to **x64**

### Prerequisites for Mac
Home brew can be used to install required dependencies:

```bash
# https://github.com/protocolbuffers/protobuf/blob/master/kokoro/macos/prepare_build_macos_rc#L20
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
source $HOME/.rvm/scripts/rvm
brew install cmake protobuf python2
sudo chown -R $(whoami) /usr/local
```

### Prerequisites for Android
The following prerequisites are required when building the libraries for
Android.

- Android SDK, Android NDK, and CMake for Android (version 3.10.2 recommended)
- Download sdkmanager (either independently, or as a part of Android Studio)
[here](https://developer.android.com/studio/#downloads)
Expand Down
18 changes: 16 additions & 2 deletions admob/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
cmake_minimum_required (VERSION 3.1)
set (CMAKE_CXX_STANDARD 11)

include(binary_to_array)
include(download_pod_headers)
include(firebase_cpp_gradle)

project(firebase_admob NONE)
enable_language(C)
Expand All @@ -36,6 +38,8 @@ set(common_SRCS
src/common/rewarded_video_internal.cc)

# Define the resource build needed for Android
firebase_cpp_gradle(":admob:admob_resources:generateDexJarRelease"
"${CMAKE_CURRENT_LIST_DIR}/admob_resources/build/dexed.jar")
binary_to_array("admob_resources"
"${CMAKE_CURRENT_LIST_DIR}/admob_resources/build/dexed.jar"
"firebase_admob"
Expand Down Expand Up @@ -107,7 +111,9 @@ else()
add_definitions(-include assert.h -include string.h)
endif()

if(IOS)
if(ANDROID)
firebase_cpp_proguard_file(admob)
elseif(IOS)
# AdMob for iOS uses weak references, which requires enabling Automatic
# Reference Counting (ARC).
set_property(
Expand All @@ -119,7 +125,7 @@ if(IOS)
set(pod_target_name "download_admob_pod_headers")
set(pods_dir "${PROJECT_BINARY_DIR}/Pods")
set(pod_list "")
list(APPEND pod_list "'Firebase/AdMob', '6.9.0'")
list(APPEND pod_list "'Firebase/AdMob', '6.10.0'")

setup_pod_headers_target("${pod_target_name}" "${pods_dir}" "${pod_list}")

Expand All @@ -129,6 +135,14 @@ if(IOS)
PRIVATE
${base_header_dir}/Google-Mobile-Ads-SDK
)
string(CONCAT google_mobile_ads_framework_path
"${pods_dir}/Pods/Google-Mobile-Ads-SDK/"
"Frameworks/GoogleMobileAdsFramework-Current/GoogleMobileAds.framework")
# AdMob expects the header files to be in a subfolder, so set up a symlink to
# accomplish that.
symlink_framework_headers(firebase_admob ${pod_target_name}
${google_mobile_ads_framework_path} GoogleMobileAds
)

# Add a dependency to downloading the headers onto admob.
add_dependencies(firebase_admob ${pod_target_name})
Expand Down
6 changes: 6 additions & 0 deletions admob/admob_resources/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.FirebaseCppSdkBuild">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-sdk android:minSdkVersion="3"/>
</manifest>
2 changes: 1 addition & 1 deletion admob/admob_resources/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ android {

sourceSets {
main {
manifest.srcFile '../../android_build_files/AndroidManifest.xml'
manifest.srcFile 'AndroidManifest.xml'
java {
srcDirs = ['../src_java/com/google/firebase/admob/internal/cpp']
}
Expand Down
13 changes: 9 additions & 4 deletions analytics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ cmake_minimum_required (VERSION 3.1)
set (CMAKE_CXX_STANDARD 11)

include(download_pod_headers)
include(firebase_cpp_gradle)

project(firebase_analytics NONE)
enable_language(C)
Expand Down Expand Up @@ -121,7 +122,9 @@ else()
add_definitions(-include assert.h -include string.h)
endif()

if(IOS)
if(ANDROID)
firebase_cpp_proguard_file(analytics)
elseif(IOS)
# Enable Automatic Reference Counting (ARC).
set_property(
TARGET firebase_analytics
Expand All @@ -132,17 +135,19 @@ if(IOS)
set(pod_target_name "download_analytics_pod_headers")
set(pods_dir "${PROJECT_BINARY_DIR}/Pods")
set(pod_list "")
list(APPEND pod_list "'Firebase/Core', '6.9.0'")
list(APPEND pod_list "'Firebase/Analytics', '6.9.0'")
list(APPEND pod_list "'Firebase/Core', '6.10.0'")
list(APPEND pod_list "'Firebase/Analytics', '6.10.0'")

setup_pod_headers_target("${pod_target_name}" "${pods_dir}" "${pod_list}")

# Add the Cocoapod headers to the include directories
set(base_header_dir "${pods_dir}/Pods/Headers/Public")
set(analytics_framework_path
"${pods_dir}/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework")
target_include_directories(firebase_analytics
PRIVATE
${base_header_dir}/FirebaseCore
${base_header_dir}/FirebaseAnalytics/FirebaseAnalytics
${analytics_framework_path}/Headers
)

# Add a dependency to downloading the headers onto analytics.
Expand Down
2 changes: 1 addition & 1 deletion analytics/src/analytics_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ Future<std::string> GetAnalyticsInstanceId() {
util::RegisterCallbackOnTask(
env, task,
[](JNIEnv* env, jobject result, util::FutureResult result_code,
int status, const char* status_message, void* callback_data) {
const char* status_message, void* callback_data) {
auto* future_data = internal::FutureData::Get();
if (future_data) {
bool success =
Expand Down
113 changes: 109 additions & 4 deletions analytics/src/analytics_ios.mm
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,103 @@
#include "app/src/include/firebase/version.h"
#include "app/src/assert.h"
#include "app/src/log.h"
#include "app/src/mutex.h"
#include "app/src/time.h"
#include "app/src/thread.h"
#include "app/src/util.h"
#include "app/src/util_ios.h"

namespace firebase {
namespace analytics {

// Used to workaround b/143656277 and b/110166640
class AnalyticsDataResetter {
private:
enum ResetState {
kResetStateNone = 0,
kResetStateRequested,
kResetStateRetry,
};
public:
// Initialize the class.
AnalyticsDataResetter() : reset_state_(kResetStateNone), reset_timestamp_(0) {}

// Reset analytics data.
void Reset() {
MutexLock lock(mutex_);
reset_timestamp_ = firebase::internal::GetTimestampEpoch();
reset_state_ = kResetStateRequested;
instance_id_ = util::StringFromNSString([FIRAnalytics appInstanceID]);
[FIRAnalytics resetAnalyticsData];
}

// Get the instance ID, returning a non-empty string if it's valid or an empty string if it's
// still being reset.
std::string GetInstanceId() {
MutexLock lock(mutex_);
std::string current_instance_id = util::StringFromNSString([FIRAnalytics appInstanceID]);
uint64_t reset_time_elapsed_milliseconds = GetResetTimeElapsedMilliseconds();
switch (reset_state_) {
case kResetStateNone:
break;
case kResetStateRequested:
if (reset_time_elapsed_milliseconds >= kResetRetryIntervalMilliseconds) {
// Firebase Analytics on iOS can take a while to initialize, in this case we try to reset
// again if the instance ID hasn't changed for a while.
reset_state_ = kResetStateRetry;
reset_timestamp_ = firebase::internal::GetTimestampEpoch();
[FIRAnalytics resetAnalyticsData];
return std::string();
}
FIREBASE_CASE_FALLTHROUGH;

case kResetStateRetry:
if ((current_instance_id.empty() || current_instance_id == instance_id_) &&
reset_time_elapsed_milliseconds < kResetTimeoutMilliseconds) {
return std::string();
}
break;
}
instance_id_ = current_instance_id;
return current_instance_id;
}

private:
// Get the time elapsed in milliseconds since reset was requested.
uint64_t GetResetTimeElapsedMilliseconds() const {
return firebase::internal::GetTimestampEpoch() - reset_timestamp_;
}

private:
Mutex mutex_;
// Reset attempt.
ResetState reset_state_;
// When a reset was last requested.
uint64_t reset_timestamp_;
// Instance ID before it was reset.
std::string instance_id_;

// Time to wait before trying to reset again.
static const uint64_t kResetRetryIntervalMilliseconds;
// Time to wait before giving up on resetting the ID.
static const uint64_t kResetTimeoutMilliseconds;
};

DEFINE_FIREBASE_VERSION_STRING(FirebaseAnalytics);

const uint64_t AnalyticsDataResetter::kResetRetryIntervalMilliseconds = 1000;
const uint64_t AnalyticsDataResetter::kResetTimeoutMilliseconds = 5000;

static const double kMillisecondsPerSecond = 1000.0;
static Mutex g_mutex; // NOLINT
static bool g_initialized = false;
static AnalyticsDataResetter *g_resetter = nullptr;

// Initialize the API.
void Initialize(const ::firebase::App& app) {
MutexLock lock(g_mutex);
g_initialized = true;
g_resetter = new AnalyticsDataResetter();
internal::RegisterTerminateOnDefaultAppDestroy();
internal::FutureData::Create();
}
Expand All @@ -50,8 +134,11 @@ void Initialize(const ::firebase::App& app) {

// Terminate the API.
void Terminate() {
MutexLock lock(g_mutex);
internal::FutureData::Destroy();
internal::UnregisterTerminateOnDefaultAppDestroy();
delete g_resetter;
g_resetter = nullptr;
g_initialized = false;
}

Expand Down Expand Up @@ -169,22 +256,40 @@ void SetCurrentScreen(const char* screen_name, const char* screen_class) {
}

void ResetAnalyticsData() {
MutexLock lock(g_mutex);
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
[FIRAnalytics resetAnalyticsData];
g_resetter->Reset();
}

Future<std::string> GetAnalyticsInstanceId() {
MutexLock lock(g_mutex);
FIREBASE_ASSERT_RETURN(Future<std::string>(), internal::IsInitialized());
auto* api = internal::FutureData::Get()->api();
const auto future_handle = api->SafeAlloc<std::string>(
internal::kAnalyticsFnGetAnalyticsInstanceId);
api->CompleteWithResult(
future_handle, 0, "",
util::StringFromNSString([FIRAnalytics appInstanceID]));
static int kPollTimeMs = 100;
Thread get_id_thread([](SafeFutureHandle<std::string>* handle) {
for ( ; ; ) {
{
MutexLock lock(g_mutex);
if (!internal::IsInitialized()) break;
std::string instance_id = g_resetter->GetInstanceId();
if (!instance_id.empty()) {
internal::FutureData::Get()->api()->CompleteWithResult(
*handle, 0, "", instance_id);
break;
}
}
firebase::internal::Sleep(kPollTimeMs);
}
delete handle;
}, new SafeFutureHandle<std::string>(future_handle));
get_id_thread.Detach();
return Future<std::string>(api, future_handle.get());
}

Future<std::string> GetAnalyticsInstanceIdLastResult() {
MutexLock lock(g_mutex);
FIREBASE_ASSERT_RETURN(Future<std::string>(), internal::IsInitialized());
return static_cast<const Future<std::string>&>(
internal::FutureData::Get()->api()->LastResult(
Expand Down
Loading

0 comments on commit b85a33f

Please sign in to comment.