@@ -47,6 +47,7 @@ static const ::firebase::App* g_app = nullptr;
4747// clang-format off
4848#define ANALYTICS_METHODS (X ) \
4949 X (SetEnabled, " setAnalyticsCollectionEnabled" , " (Z)V" ), \
50+ X (SetConsent, " setConsent" , " (Ljava/util/Map;)V" ), \
5051 X (LogEvent, " logEvent" , " (Ljava/lang/String;Landroid/os/Bundle;)V" ), \
5152 X (SetUserProperty, " setUserProperty" , \
5253 " (Ljava/lang/String;Ljava/lang/String;)V" ), \
@@ -60,12 +61,46 @@ static const ::firebase::App* g_app = nullptr;
6061 firebase::util::kMethodTypeStatic )
6162// clang-format on
6263
64+ // clang-format off
65+ #define ANALYTICS_CONSENT_TYPE_FIELDS (X ) \
66+ X (AnalyticsStorage, " ANALYTICS_STORAGE" , \
67+ " Lcom/google/firebase/analytics/FirebaseAnalytics$ConsentType;" , \
68+ util::kFieldTypeStatic ), \
69+ X (AdStorage, " AD_STORAGE" , \
70+ " Lcom/google/firebase/analytics/FirebaseAnalytics$ConsentType;" , \
71+ util::kFieldTypeStatic )
72+
73+ #define ANALYTICS_CONSENT_STATUS_FIELDS (X ) \
74+ X (Granted, " GRANTED" , \
75+ " Lcom/google/firebase/analytics/FirebaseAnalytics$ConsentStatus;" , \
76+ util::kFieldTypeStatic ), \
77+ X (Denied, " DENIED" , \
78+ " Lcom/google/firebase/analytics/FirebaseAnalytics$ConsentStatus;" , \
79+ util::kFieldTypeStatic )
80+ // clang-format on
81+
6382METHOD_LOOKUP_DECLARATION (analytics, ANALYTICS_METHODS)
6483METHOD_LOOKUP_DEFINITION (analytics,
6584 PROGUARD_KEEP_CLASS
6685 " com/google/firebase/analytics/FirebaseAnalytics" ,
6786 ANALYTICS_METHODS)
6887
88+ METHOD_LOOKUP_DECLARATION (analytics_consent_type, METHOD_LOOKUP_NONE,
89+ ANALYTICS_CONSENT_TYPE_FIELDS)
90+ METHOD_LOOKUP_DEFINITION (
91+ analytics_consent_type,
92+ PROGUARD_KEEP_CLASS
93+ " com/google/firebase/analytics/FirebaseAnalytics$ConsentType" ,
94+ METHOD_LOOKUP_NONE, ANALYTICS_CONSENT_TYPE_FIELDS)
95+
96+ METHOD_LOOKUP_DECLARATION (analytics_consent_status, METHOD_LOOKUP_NONE,
97+ ANALYTICS_CONSENT_STATUS_FIELDS)
98+ METHOD_LOOKUP_DEFINITION (
99+ analytics_consent_status,
100+ PROGUARD_KEEP_CLASS
101+ " com/google/firebase/analytics/FirebaseAnalytics$ConsentStatus" ,
102+ METHOD_LOOKUP_NONE, ANALYTICS_CONSENT_STATUS_FIELDS)
103+
69104// Initialize the Analytics API.
70105void Initialize (const ::firebase::App& app) {
71106 if (g_app) {
@@ -85,6 +120,17 @@ void Initialize(const ::firebase::App& app) {
85120 util::Terminate (env);
86121 return ;
87122 }
123+ if (!analytics_consent_type::CacheFieldIds (env, app.activity ())) {
124+ analytics::ReleaseClass (env);
125+ util::Terminate (env);
126+ return ;
127+ }
128+ if (!analytics_consent_status::CacheFieldIds (env, app.activity ())) {
129+ analytics_consent_type::ReleaseClass (env);
130+ analytics::ReleaseClass (env);
131+ util::Terminate (env);
132+ return ;
133+ }
88134
89135 internal::FutureData::Create ();
90136 g_app = &app;
@@ -123,6 +169,8 @@ void Terminate() {
123169 g_app = nullptr ;
124170 env->DeleteGlobalRef (g_analytics_class_instance);
125171 g_analytics_class_instance = nullptr ;
172+ analytics_consent_status::ReleaseClass (env);
173+ analytics_consent_type::ReleaseClass (env);
126174 analytics::ReleaseClass (env);
127175 util::Terminate (env);
128176}
@@ -138,6 +186,74 @@ void SetAnalyticsCollectionEnabled(bool enabled) {
138186 util::CheckAndClearJniExceptions (env);
139187}
140188
189+ void SetConsent (const std::map<ConsentType, ConsentStatus>& consent_settings) {
190+ FIREBASE_ASSERT_RETURN_VOID (internal::IsInitialized ());
191+ JNIEnv* env = g_app->GetJNIEnv ();
192+
193+ jobject consent_map =
194+ env->NewObject (util::hash_map::GetClass (),
195+ util::hash_map::GetMethodId (util::hash_map::kConstructor ));
196+ util::CheckAndClearJniExceptions (env);
197+ jmethodID put_method = util::map::GetMethodId (util::map::kPut );
198+ for (auto it = consent_settings.begin (); it != consent_settings.end (); ++it) {
199+ jobject consent_type;
200+ switch (it->first ) {
201+ case kConsentTypeAdStorage :
202+ consent_type =
203+ env->GetStaticObjectField (analytics_consent_type::GetClass (),
204+ analytics_consent_type::GetFieldId (
205+ analytics_consent_type::kAdStorage ));
206+ util::CheckAndClearJniExceptions (env);
207+ break ;
208+ case kConsentTypeAnalyticsStorage :
209+ consent_type = env->GetStaticObjectField (
210+ analytics_consent_type::GetClass (),
211+ analytics_consent_type::GetFieldId (
212+ analytics_consent_type::kAnalyticsStorage ));
213+
214+ util::CheckAndClearJniExceptions (env);
215+ break ;
216+ default :
217+ LogError (" Unknown ConsentType value: %d" , it->first );
218+ env->DeleteLocalRef (consent_map);
219+ return ;
220+ }
221+ jobject consent_status;
222+ switch (it->second ) {
223+ case kConsentStatusGranted :
224+ consent_status =
225+ env->GetStaticObjectField (analytics_consent_status::GetClass (),
226+ analytics_consent_status::GetFieldId (
227+ analytics_consent_status::kGranted ));
228+ util::CheckAndClearJniExceptions (env);
229+ break ;
230+ case kConsentStatusDenied :
231+ consent_status =
232+ env->GetStaticObjectField (analytics_consent_status::GetClass (),
233+ analytics_consent_status::GetFieldId (
234+ analytics_consent_status::kDenied ));
235+ util::CheckAndClearJniExceptions (env);
236+ break ;
237+ default :
238+ LogError (" Unknown ConsentStatus value: %d" , it->second );
239+ env->DeleteLocalRef (consent_map);
240+ env->DeleteLocalRef (consent_type);
241+ return ;
242+ }
243+ jobject previous = env->CallObjectMethod (consent_map, put_method,
244+ consent_type, consent_status);
245+ util::CheckAndClearJniExceptions (env);
246+ if (previous) env->DeleteLocalRef (previous);
247+ env->DeleteLocalRef (consent_type);
248+ env->DeleteLocalRef (consent_status);
249+ }
250+ env->CallVoidMethod (g_analytics_class_instance,
251+ analytics::GetMethodId (analytics::kSetConsent ),
252+ consent_map);
253+ util::CheckAndClearJniExceptions (env);
254+ env->DeleteLocalRef (consent_map);
255+ }
256+
141257// Build an event bundle using build_bundle and log it.
142258template <typename BuildBundleFunction>
143259void LogEvent (JNIEnv* env, const char * name, BuildBundleFunction build_bundle) {
0 commit comments