Skip to content

Analytics multihash 2 #1743

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions analytics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ set_property(TARGET firebase_analytics PROPERTY FOLDER "Firebase Cpp")
# Set up the dependency on Firebase App.
target_link_libraries(firebase_analytics
PUBLIC firebase_app)
if(WIN32)
target_link_libraries(firebase_analytics PUBLIC Crypt32.lib)
endif()
# 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_analytics
Expand Down
40 changes: 38 additions & 2 deletions analytics/src/analytics_desktop_dynamic.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,29 @@ static void* g_stub_memory = NULL;
// clang-format off

// Number of Google Analytics functions expected to be loaded from the DLL.
const int FirebaseAnalytics_DynamicFunctionCount = 19;
const int FirebaseAnalytics_DynamicFunctionCount = 22;

#if defined(_WIN32)
// Array of known Google Analytics Windows DLL SHA256 hashes (hex strings).
const char* FirebaseAnalytics_KnownWindowsDllHashes[] = {
"c1b9ff6e9119c30bbeb7472326dcde418f45682e6b822e25eed922fe6e3cc698"
"13ae5f9349b24186f1f3667b52832076e8d14ad9656c3546b1b7fca79ac8144b"
};

// Count of known Google Analytics Windows DLL SHA256 hashes.
const int FirebaseAnalytics_KnownWindowsDllHashCount = 1;
#endif // defined(_WIN32)

// --- Stub Function Definitions ---
// Stub for GoogleAnalytics_Options_Create
static GoogleAnalytics_Options* Stub_GoogleAnalytics_Options_Create() {
return (GoogleAnalytics_Options*)(&g_stub_memory);
}

// Stub for GoogleAnalytics_Options_Destroy
static void Stub_GoogleAnalytics_Options_Destroy(GoogleAnalytics_Options* options) {
// No return value.
}

// Stub for GoogleAnalytics_Item_Create
static GoogleAnalytics_Item* Stub_GoogleAnalytics_Item_Create() {
return (GoogleAnalytics_Item*)(&g_stub_memory);
Expand Down Expand Up @@ -116,6 +126,11 @@ static void Stub_GoogleAnalytics_EventParameters_Destroy(GoogleAnalytics_EventPa
// No return value.
}

// Stub for GoogleAnalytics_Initialize
static bool Stub_GoogleAnalytics_Initialize(const GoogleAnalytics_Options* options) {
return 1;
}

// Stub for GoogleAnalytics_LogEvent
static void Stub_GoogleAnalytics_LogEvent(const char* name, GoogleAnalytics_EventParameters* parameters) {
// No return value.
Expand Down Expand Up @@ -144,6 +159,8 @@ static void Stub_GoogleAnalytics_SetAnalyticsCollectionEnabled(bool enabled) {


// --- Function Pointer Initializations ---
GoogleAnalytics_Options* (*ptr_GoogleAnalytics_Options_Create)() = &Stub_GoogleAnalytics_Options_Create;
void (*ptr_GoogleAnalytics_Options_Destroy)(GoogleAnalytics_Options* options) = &Stub_GoogleAnalytics_Options_Destroy;
GoogleAnalytics_Item* (*ptr_GoogleAnalytics_Item_Create)() = &Stub_GoogleAnalytics_Item_Create;
void (*ptr_GoogleAnalytics_Item_InsertInt)(GoogleAnalytics_Item* item, const char* key, int64_t value) = &Stub_GoogleAnalytics_Item_InsertInt;
void (*ptr_GoogleAnalytics_Item_InsertDouble)(GoogleAnalytics_Item* item, const char* key, double value) = &Stub_GoogleAnalytics_Item_InsertDouble;
Expand All @@ -158,6 +175,7 @@ void (*ptr_GoogleAnalytics_EventParameters_InsertDouble)(GoogleAnalytics_EventPa
void (*ptr_GoogleAnalytics_EventParameters_InsertString)(GoogleAnalytics_EventParameters* event_parameter_map, const char* key, const char* value) = &Stub_GoogleAnalytics_EventParameters_InsertString;
void (*ptr_GoogleAnalytics_EventParameters_InsertItemVector)(GoogleAnalytics_EventParameters* event_parameter_map, const char* key, GoogleAnalytics_ItemVector* value) = &Stub_GoogleAnalytics_EventParameters_InsertItemVector;
void (*ptr_GoogleAnalytics_EventParameters_Destroy)(GoogleAnalytics_EventParameters* event_parameter_map) = &Stub_GoogleAnalytics_EventParameters_Destroy;
bool (*ptr_GoogleAnalytics_Initialize)(const GoogleAnalytics_Options* options) = &Stub_GoogleAnalytics_Initialize;
void (*ptr_GoogleAnalytics_LogEvent)(const char* name, GoogleAnalytics_EventParameters* parameters) = &Stub_GoogleAnalytics_LogEvent;
void (*ptr_GoogleAnalytics_SetUserProperty)(const char* name, const char* value) = &Stub_GoogleAnalytics_SetUserProperty;
void (*ptr_GoogleAnalytics_SetUserId)(const char* user_id) = &Stub_GoogleAnalytics_SetUserId;
Expand All @@ -173,6 +191,16 @@ int FirebaseAnalytics_LoadDynamicFunctions(HMODULE dll_handle) {
return count;
}

FARPROC proc_GoogleAnalytics_Options_Create = GetProcAddress(dll_handle, "GoogleAnalytics_Options_Create");
if (proc_GoogleAnalytics_Options_Create) {
ptr_GoogleAnalytics_Options_Create = (GoogleAnalytics_Options* (*)())proc_GoogleAnalytics_Options_Create;
count++;
}
FARPROC proc_GoogleAnalytics_Options_Destroy = GetProcAddress(dll_handle, "GoogleAnalytics_Options_Destroy");
if (proc_GoogleAnalytics_Options_Destroy) {
ptr_GoogleAnalytics_Options_Destroy = (void (*)(GoogleAnalytics_Options* options))proc_GoogleAnalytics_Options_Destroy;
count++;
}
FARPROC proc_GoogleAnalytics_Item_Create = GetProcAddress(dll_handle, "GoogleAnalytics_Item_Create");
if (proc_GoogleAnalytics_Item_Create) {
ptr_GoogleAnalytics_Item_Create = (GoogleAnalytics_Item* (*)())proc_GoogleAnalytics_Item_Create;
Expand Down Expand Up @@ -243,6 +271,11 @@ int FirebaseAnalytics_LoadDynamicFunctions(HMODULE dll_handle) {
ptr_GoogleAnalytics_EventParameters_Destroy = (void (*)(GoogleAnalytics_EventParameters* event_parameter_map))proc_GoogleAnalytics_EventParameters_Destroy;
count++;
}
FARPROC proc_GoogleAnalytics_Initialize = GetProcAddress(dll_handle, "GoogleAnalytics_Initialize");
if (proc_GoogleAnalytics_Initialize) {
ptr_GoogleAnalytics_Initialize = (bool (*)(const GoogleAnalytics_Options* options))proc_GoogleAnalytics_Initialize;
count++;
}
FARPROC proc_GoogleAnalytics_LogEvent = GetProcAddress(dll_handle, "GoogleAnalytics_LogEvent");
if (proc_GoogleAnalytics_LogEvent) {
ptr_GoogleAnalytics_LogEvent = (void (*)(const char* name, GoogleAnalytics_EventParameters* parameters))proc_GoogleAnalytics_LogEvent;
Expand Down Expand Up @@ -273,6 +306,8 @@ int FirebaseAnalytics_LoadDynamicFunctions(HMODULE dll_handle) {
}

void FirebaseAnalytics_UnloadDynamicFunctions(void) {
ptr_GoogleAnalytics_Options_Create = &Stub_GoogleAnalytics_Options_Create;
ptr_GoogleAnalytics_Options_Destroy = &Stub_GoogleAnalytics_Options_Destroy;
ptr_GoogleAnalytics_Item_Create = &Stub_GoogleAnalytics_Item_Create;
ptr_GoogleAnalytics_Item_InsertInt = &Stub_GoogleAnalytics_Item_InsertInt;
ptr_GoogleAnalytics_Item_InsertDouble = &Stub_GoogleAnalytics_Item_InsertDouble;
Expand All @@ -287,6 +322,7 @@ void FirebaseAnalytics_UnloadDynamicFunctions(void) {
ptr_GoogleAnalytics_EventParameters_InsertString = &Stub_GoogleAnalytics_EventParameters_InsertString;
ptr_GoogleAnalytics_EventParameters_InsertItemVector = &Stub_GoogleAnalytics_EventParameters_InsertItemVector;
ptr_GoogleAnalytics_EventParameters_Destroy = &Stub_GoogleAnalytics_EventParameters_Destroy;
ptr_GoogleAnalytics_Initialize = &Stub_GoogleAnalytics_Initialize;
ptr_GoogleAnalytics_LogEvent = &Stub_GoogleAnalytics_LogEvent;
ptr_GoogleAnalytics_SetUserProperty = &Stub_GoogleAnalytics_SetUserProperty;
ptr_GoogleAnalytics_SetUserId = &Stub_GoogleAnalytics_SetUserId;
Expand Down
77 changes: 77 additions & 0 deletions analytics/src/analytics_desktop_dynamic.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,79 @@
#include <stdbool.h> // needed for bool type in pure C

// --- Copied from original header ---
#include <stdbool.h>
#include <stdint.h>

/**
* @brief GoogleAnalytics_Options for initializing the Analytics SDK.
* GoogleAnalytics_Options_Create() must be used to create an instance of this
* struct with default values. If these options are created manually instead of
* using GoogleAnalytics_Options_Create(), initialization will fail, and the
* caller will be responsible for destroying the options.
*/
ANALYTICS_API typedef struct {
/**
* @brief The unique identifier for the Firebase app across all of Firebase
* with a platform-specific format. This is a required field, can not be null
* or empty, and must be UTF-8 encoded.
*
* The caller is responsible for allocating this memory, and deallocating it
* once the options instance has been destroyed.
*
* Example: 1:1234567890:android:321abc456def7890
*/
const char* app_id;

/**
* @brief Unique identifier for the application implementing the SDK. The
* format typically follows a reversed domain name convention. This is a
* required field, can not be null or empty, and must be UTF-8 encoded.
*
* The caller is responsible for allocating this memory, and deallocating it
* once the options instance has been destroyed.
*
* Example: com.google.analytics.AnalyticsApp
*/
const char* package_name;

/**
* @brief Whether Analytics is enabled at the very first launch.
* This value is then persisted across app sessions, and from then on, takes
* precedence over the value of this field.
* GoogleAnalytics_SetAnalyticsCollectionEnabled() can be used to
* enable/disable after that point.
*/
bool analytics_collection_enabled_at_first_launch;

/**
* @brief Reserved for internal use by the SDK.
*/
GoogleAnalytics_Reserved* reserved;
} GoogleAnalytics_Options;

/**
* @brief Creates an instance of GoogleAnalytics_Options with default values.
*
* The caller is responsible for destroying the options using the
* GoogleAnalytics_Options_Destroy() function, unless it has been passed to the
* GoogleAnalytics_Initialize() function, in which case it will be destroyed
* automatically.
*
* @return A pointer to a newly allocated GoogleAnalytics_Options instance.
*/
ANALYTICS_API GoogleAnalytics_Options* GoogleAnalytics_Options_Create();

/**
* @brief Destroys the GoogleAnalytics_Options instance. Must not be called if
* the options were created with GoogleAnalytics_Options_Create() and passed to
* the GoogleAnalytics_Initialize() function, which would destroy them
* automatically.
*
* @param[in] options The GoogleAnalytics_Options instance to destroy.
*/
ANALYTICS_API void GoogleAnalytics_Options_Destroy(
GoogleAnalytics_Options* options);

/**
* @brief Opaque type for an item.
*
Expand Down Expand Up @@ -71,6 +142,8 @@ extern "C" {

// --- Function Pointer Declarations ---
// clang-format off
extern GoogleAnalytics_Options* (*ptr_GoogleAnalytics_Options_Create)();
extern void (*ptr_GoogleAnalytics_Options_Destroy)(GoogleAnalytics_Options* options);
extern GoogleAnalytics_Item* (*ptr_GoogleAnalytics_Item_Create)();
extern void (*ptr_GoogleAnalytics_Item_InsertInt)(GoogleAnalytics_Item* item, const char* key, int64_t value);
extern void (*ptr_GoogleAnalytics_Item_InsertDouble)(GoogleAnalytics_Item* item, const char* key, double value);
Expand All @@ -85,12 +158,15 @@ extern void (*ptr_GoogleAnalytics_EventParameters_InsertDouble)(GoogleAnalytics_
extern void (*ptr_GoogleAnalytics_EventParameters_InsertString)(GoogleAnalytics_EventParameters* event_parameter_map, const char* key, const char* value);
extern void (*ptr_GoogleAnalytics_EventParameters_InsertItemVector)(GoogleAnalytics_EventParameters* event_parameter_map, const char* key, GoogleAnalytics_ItemVector* value);
extern void (*ptr_GoogleAnalytics_EventParameters_Destroy)(GoogleAnalytics_EventParameters* event_parameter_map);
extern bool (*ptr_GoogleAnalytics_Initialize)(const GoogleAnalytics_Options* options);
extern void (*ptr_GoogleAnalytics_LogEvent)(const char* name, GoogleAnalytics_EventParameters* parameters);
extern void (*ptr_GoogleAnalytics_SetUserProperty)(const char* name, const char* value);
extern void (*ptr_GoogleAnalytics_SetUserId)(const char* user_id);
extern void (*ptr_GoogleAnalytics_ResetAnalyticsData)();
extern void (*ptr_GoogleAnalytics_SetAnalyticsCollectionEnabled)(bool enabled);

#define GoogleAnalytics_Options_Create ptr_GoogleAnalytics_Options_Create
#define GoogleAnalytics_Options_Destroy ptr_GoogleAnalytics_Options_Destroy
#define GoogleAnalytics_Item_Create ptr_GoogleAnalytics_Item_Create
#define GoogleAnalytics_Item_InsertInt ptr_GoogleAnalytics_Item_InsertInt
#define GoogleAnalytics_Item_InsertDouble ptr_GoogleAnalytics_Item_InsertDouble
Expand All @@ -105,6 +181,7 @@ extern void (*ptr_GoogleAnalytics_SetAnalyticsCollectionEnabled)(bool enabled);
#define GoogleAnalytics_EventParameters_InsertString ptr_GoogleAnalytics_EventParameters_InsertString
#define GoogleAnalytics_EventParameters_InsertItemVector ptr_GoogleAnalytics_EventParameters_InsertItemVector
#define GoogleAnalytics_EventParameters_Destroy ptr_GoogleAnalytics_EventParameters_Destroy
#define GoogleAnalytics_Initialize ptr_GoogleAnalytics_Initialize
#define GoogleAnalytics_LogEvent ptr_GoogleAnalytics_LogEvent
#define GoogleAnalytics_SetUserProperty ptr_GoogleAnalytics_SetUserProperty
#define GoogleAnalytics_SetUserId ptr_GoogleAnalytics_SetUserId
Expand Down
7 changes: 6 additions & 1 deletion analytics/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
# limitations under the License.



if(WIN32)
set(ANALYTICS_TEST_PLATFORM_DEPS Crypt32.lib)
else()
set(ANALYTICS_TEST_PLATFORM_DEPS "")
endif()

firebase_cpp_cc_test(
firebase_analytics_test
Expand All @@ -23,6 +27,7 @@ firebase_cpp_cc_test(
firebase_app_for_testing
firebase_analytics
firebase_testing
${ANALYTICS_TEST_PLATFORM_DEPS}
)

firebase_cpp_cc_test_on_ios(
Expand Down
Binary file modified analytics/windows/analytics_win.dll
Binary file not shown.
53 changes: 52 additions & 1 deletion analytics/windows/include/public/analytics.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Copyright 2025 Google LLC
#ifndef ANALYTICS_MOBILE_CONSOLE_MEASUREMENT_PUBLIC_ANALYTICS_H_
#define ANALYTICS_MOBILE_CONSOLE_MEASUREMENT_PUBLIC_ANALYTICS_H_

Expand Down Expand Up @@ -32,6 +31,38 @@ class Analytics {
std::variant<int64_t, double, std::string, ItemVector>;
using EventParameters = std::unordered_map<std::string, EventParameterValue>;

/**
* @brief Options for initializing the Analytics SDK.
*/
struct Options {
/**
* @brief The unique identifier for the Firebase app across all of Firebase
* with a platform-specific format. This is a required field, can not be
* empty, and must be UTF-8 encoded.
*
* Example: 1:1234567890:android:321abc456def7890
*/
std::string app_id;

/**
* @brief Unique identifier for the application implementing the SDK. The
* format typically follows a reversed domain name convention. This is a
* required field, can not be empty, and must be UTF-8 encoded.
*
* Example: com.google.analytics.AnalyticsApp
*/
std::string package_name;

/**
* @brief Whether Analytics is enabled at the very first launch.
* This value is then persisted across app sessions, and from then on, takes
* precedence over the value of this field.
* SetAnalyticsCollectionEnabled() can be used to enable/disable after that
* point.
*/
bool analytics_collection_enabled_at_first_launch = true;
};

/**
* @brief Returns the singleton instance of the Analytics class.
*/
Expand All @@ -46,6 +77,26 @@ class Analytics {
Analytics(Analytics&&) = delete;
Analytics& operator=(Analytics&&) = delete;

/**
* @brief Initializes the Analytics SDK with the given options. Until this is
* called, all analytics methods below will be no-ops.
*
* @param[in] options The options to initialize the Analytics SDK with.
*
* @return true if the Analytics SDK was successfully initialized, false
* otherwise. Also returns false if the Analytics SDK has already been
* initialized.
*/
bool Initialize(const Options& options) {
GoogleAnalytics_Options* google_analytics_options =
GoogleAnalytics_Options_Create();
google_analytics_options->app_id = options.app_id.c_str();
google_analytics_options->package_name = options.package_name.c_str();
google_analytics_options->analytics_collection_enabled_at_first_launch =
options.analytics_collection_enabled_at_first_launch;
return GoogleAnalytics_Initialize(google_analytics_options);
}

/**
* @brief Logs an app event.
*
Expand Down
Loading
Loading