Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7cdfc29
Update to use the latest analytics dll and source headers to account …
john-mikhail Sep 25, 2025
a8422d8
Update analytics.h
john-mikhail Sep 25, 2025
22387e3
Added integration tests
john-mikhail Sep 30, 2025
1f824c0
Update analytics/src/include/firebase/analytics.h
john-mikhail Sep 30, 2025
1e8d3be
Fix formatting
john-mikhail Sep 30, 2025
ef94be8
Fix formatting
john-mikhail Sep 30, 2025
525d2d2
Format fixes
john-mikhail Sep 30, 2025
737f99d
Merge branch 'analytics-windows-dll-update' of https://github.com/fir…
john-mikhail Sep 30, 2025
a3f362a
Update mobile dependencies - Fri Oct 10 2025 (#1794)
firebase-workflow-trigger[bot] Oct 13, 2025
97f3e35
Update the python version used by GHA runners (#1797)
a-maurice Oct 22, 2025
5166e78
Feat: add UseEmulator to storage api (#1795)
AustinBenoit Oct 28, 2025
9f384cf
Feat: add in no ops for NotifyApplifecyclechange
AustinBenoit Nov 17, 2025
787a529
Merge branch 'main' into analytics-windows-dll-update
AustinBenoit Nov 17, 2025
3282116
fix formatting
AustinBenoit Nov 17, 2025
02e164f
fix the wrong param type
AustinBenoit Nov 17, 2025
4263601
fixup the wording for NotifyApplifecyclechange to be windows only
AustinBenoit Nov 17, 2025
a16308d
feat: add in the Setlogcallback function for desktop analytics
AustinBenoit Nov 18, 2025
fd814e9
Remove double implementation of the loglevel
AustinBenoit Nov 19, 2025
ecd7e83
Merge branch 'main' into analytics-windows-dll-update
AustinBenoit Nov 19, 2025
64384db
Fix up the formatting and the enum in tc
AustinBenoit Nov 20, 2025
e28d475
format fix up and make test win only
AustinBenoit Nov 20, 2025
408c55c
Add in threading considerations for the callback test
AustinBenoit Nov 21, 2025
065c47b
Add in future header to the integration tests
AustinBenoit Nov 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ __pycache__/

### IDE generated files
.vscode/
**/.vs/

# Unencrypted secret files
google-services.json
Expand Down
2 changes: 1 addition & 1 deletion analytics/generate_windows_stubs.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def generate_function_pointers(dll_file_path, header_file_path, output_h_path, o
)
parser.add_argument(
"--windows_dll",
default = os.path.join(os.path.dirname(sys.argv[0]), "windows/analytics_win.dll"),
default = os.path.join(os.path.dirname(sys.argv[0]), "windows/google_analytics.dll"),
help="Path to the DLL file to calculate a hash."
)
parser.add_argument(
Expand Down
2 changes: 1 addition & 1 deletion analytics/integration_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ else()
)
elseif(MSVC)
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32)
set(ANALYTICS_WINDOWS_DLL "${FIREBASE_CPP_SDK_DIR}/analytics/windows/analytics_win.dll")
set(ANALYTICS_WINDOWS_DLL "${FIREBASE_CPP_SDK_DIR}/analytics/windows/google_analytics.dll")

# For Windows, check if the Analytics DLL exists, and copy it in if so.
if (EXISTS "${ANALYTICS_WINDOWS_DLL}")
Expand Down
31 changes: 31 additions & 0 deletions analytics/integration_test/src/integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,29 @@ TEST_F(FirebaseAnalyticsTest, TestSetProperties) {
InitiateOnDeviceConversionMeasurementWithHashedPhoneNumber(hashed_phone);
}

#if defined(_WIN32)
TEST_F(FirebaseAnalyticsTest, TestSetLogCallback) {
std::promise<void> finishedPromise;
std::future<void> finished Future = readyPromise.get_future();
bool log_callback_called = false;
firebase::analytics::SetLogCallback(
[&](firebase::LogLevel log_level, const char* message) {
log_callback_called = true;
finishedPromise.set_value();
});
// Log an event with an invalid parameter to trigger a log message.
const firebase::analytics::Parameter kInvalidParameters[] = {
firebase::analytics::Parameter("invalid_character_!", 5),
};
firebase::analytics::LogEvent(
"invalid_event", kInvalidParameters,
sizeof(kInvalidParameters) / sizeof(kInvalidParameters[0]));
readyPromise.set_value();
EXPECT_TRUE(log_callback_called);
firebase::analytics::SetLogCallback(nullptr);
}
#endif // defined(_WIN32)

TEST_F(FirebaseAnalyticsTest, TestLogEvents) {
// Log an event with no parameters.
firebase::analytics::LogEvent(firebase::analytics::kEventLogin);
Expand All @@ -259,6 +282,14 @@ TEST_F(FirebaseAnalyticsTest, TestLogEvents) {
"spoon_welders");
}

TEST_F(FirebaseAnalyticsTest, TestNotifyAppLifecycleChange) {
// Can't confirm that these do anything but just run them all to ensure the
// app doesn't crash.
firebase::analytics::NotifyAppLifecycleChange(firebase::analytics::kUnknown);
firebase::analytics::NotifyAppLifecycleChange(
firebase::analytics::kTermination);
}

TEST_F(FirebaseAnalyticsTest, TestLogEventWithMultipleParameters) {
const firebase::analytics::Parameter kLevelUpParameters[] = {
firebase::analytics::Parameter(firebase::analytics::kParameterLevel, 5),
Expand Down
6 changes: 6 additions & 0 deletions analytics/src/analytics_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,12 @@ void ResetAnalyticsData() {
util::CheckAndClearJniExceptions(env);
}

// NO-OP in Android and iOS. Only used in Windows.
void SetLogCallback(const LogCallback&) {}

// NO-OP in Android and iOS. Only used in Windows.
void NotifyAppLifecycleChange(AppLifecycleState) {}

Future<std::string> GetAnalyticsInstanceId() {
FIREBASE_ASSERT_RETURN(GetAnalyticsInstanceIdLastResult(),
internal::IsInitialized());
Expand Down
54 changes: 53 additions & 1 deletion analytics/src/analytics_desktop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <future>
#include <map>
#include <mutex>
#include <sstream>
#include <string>
#include <vector>
Expand All @@ -25,6 +27,7 @@
#include "app/src/include/firebase/future.h"
#include "app/src/include/firebase/variant.h"
#include "app/src/log.h"
#include "firebase/log.h"

#if defined(_WIN32)
#include <windows.h>
Expand All @@ -36,14 +39,16 @@ namespace firebase {
namespace analytics {

#if defined(_WIN32)
#define ANALYTICS_DLL_FILENAME L"analytics_win.dll"
#define ANALYTICS_DLL_FILENAME L"google_analytics.dll"

static HMODULE g_analytics_module = 0;
#endif // defined(_WIN32)

// Future data for analytics.
// This is initialized in `Initialize()` and cleaned up in `Terminate()`.
static bool g_initialized = false;
static LogCallback g_log_callback;
static std::mutex g_log_callback_mutex;
static int g_fake_instance_id = 0;
static bool g_analytics_collection_enabled = true;
static std::string g_app_id;
Expand Down Expand Up @@ -134,6 +139,10 @@ bool IsInitialized() { return g_initialized; }
void Terminate() {
#if defined(_WIN32)
if (g_analytics_module) {
// Make sure to notify the SDK that the analytics is being terminated to
// upload any pending data.
NotifyAppLifecycleChange(AppLifecycleState::kTermination);

FirebaseAnalytics_UnloadDynamicFunctions();
FreeLibrary(g_analytics_module);
g_analytics_module = 0;
Expand Down Expand Up @@ -386,6 +395,49 @@ void ResetAnalyticsData() {
g_fake_instance_id++;
}

LogLevel ConvertAnalyticsLogLevelToFirebaseLogLevel(
GoogleAnalytics_LogLevel log_level) {
switch (log_level) {
case kDebug:
return kLogLevelDebug;
case kInfo:
return kLogLevelInfo;
case kWarning:
return kLogLevelWarning;
case kError:
return kLogLevelError;
default:
return kLogLevelInfo;
}
}

// C-style callback that will be passed to the Google Analytics C API.
static void GoogleAnalyticsWraperLogCallback(GoogleAnalytics_LogLevel log_level,
const char* message) {
if (g_log_callback) {
LogLevel firebase_log_level =
ConvertAnalyticsLogLevelToFirebaseLogLevel(log_level);
g_log_callback(firebase_log_level, message);
}
}

// Allows the passing of a callback to be used when the SDK logs any
// messages regarding its behavior. The callback must be thread-safe.
void SetLogCallback(const LogCallback& callback) {
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
// The C API does not support user data, so we must use a global variable.
std::lock_guard<std::mutex> lock(g_log_callback_mutex);
g_log_callback = callback;
GoogleAnalytics_SetLogCallback(GoogleAnalyticsWraperLogCallback);
}

// Notify the Analytics SDK about the current state of the app's lifecycle.
void NotifyAppLifecycleChange(AppLifecycleState state) {
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
GoogleAnalytics_NotifyAppLifecycleChange(
static_cast<GoogleAnalytics_AppLifecycleState>(state));
}

// Overloaded versions of LogEvent for convenience.

void LogEvent(const char* name) {
Expand Down
Loading
Loading