Skip to content

Commit 39b1b9e

Browse files
authored
Android AppCheck providers implementation (#1194)
* rough draft debug provider * Initial implementation of debug provider * cleaning up code and formatting * only exclude unsupported tests on android as desktop should now support more methods * Add safety net and play integrity providers following same pattern as debug * autoformat * resolving lint warnings and cleaning up todos * Remove SafetyNet provider. this is deprecated by android SDK * format * additional lint warnings resolved * also exclude safetynet in the release gradle file * review feedback * fix a couple comments
1 parent 179939a commit 39b1b9e

16 files changed

+581
-153
lines changed

Android/firebase_dependencies.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ import org.gradle.util.ConfigureUtil;
1717
// A map of library to the dependencies that need to be added for it.
1818
def firebaseDependenciesMap = [
1919
'app' : ['com.google.firebase:firebase-analytics'],
20+
'app_check' : ['com.google.firebase:firebase-appcheck',
21+
'com.google.firebase:firebase-appcheck-debug',
22+
'com.google.firebase:firebase-appcheck-playintegrity'],
2023
'play_services' : ['com.google.android.gms:play-services-base:18.1.0'],
2124
'admob' : ['com.google.firebase:firebase-ads:19.8.0',
2225
'com.google.firebase:firebase-analytics'],

app/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -500,8 +500,7 @@ if (IOS)
500500
${FIREBASE_SOURCE_DIR}/app_check/src/include/firebase/app_check/app_attest_provider.h
501501
${FIREBASE_SOURCE_DIR}/app_check/src/include/firebase/app_check/debug_provider.h
502502
${FIREBASE_SOURCE_DIR}/app_check/src/include/firebase/app_check/device_check_provider.h
503-
${FIREBASE_SOURCE_DIR}/app_check/src/include/firebase/app_check/play_integrity_provider.h
504-
${FIREBASE_SOURCE_DIR}/app_check/src/include/firebase/app_check/safety_net_provider.h)
503+
${FIREBASE_SOURCE_DIR}/app_check/src/include/firebase/app_check/play_integrity_provider.h)
505504
set(auth_HDRS
506505
${FIREBASE_SOURCE_DIR}/auth/src/include/firebase/auth.h
507506
${FIREBASE_SOURCE_DIR}/auth/src/include/firebase/auth/credential.h

app_check/CMakeLists.txt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ set(common_SRCS
2222
src/include/firebase/app_check.h
2323
src/include/firebase/app_check/debug_provider.h
2424
src/include/firebase/app_check/play_integrity_provider.h
25-
src/include/firebase/app_check/safety_net_provider.h
2625
src/include/firebase/app_check/device_check_provider.h
2726
src/include/firebase/app_check/app_attest_provider.h
2827
)
@@ -31,11 +30,13 @@ set(common_SRCS
3130
set(android_SRCS
3231
src/android/app_check_android.cc
3332
src/android/app_check_android.h
33+
src/android/common_android.cc
34+
src/android/common_android.h
3435
# Supported providers
3536
src/android/debug_provider_android.cc
3637
src/android/debug_provider_android.h
3738
src/android/play_integrity_provider_android.cc
38-
src/android/safety_net_provider_android.cc
39+
src/android/play_integrity_provider_android.h
3940
# Unsupported providers
4041
src/stub/app_attest_provider_stub.cc
4142
src/stub/device_check_provider_stub.cc
@@ -54,7 +55,6 @@ set(ios_SRCS
5455
src/ios/device_check_provider_ios.mm
5556
# Unsupported providers
5657
src/stub/play_integrity_provider_stub.cc
57-
src/stub/safety_net_provider_stub.cc
5858
)
5959

6060
# Flatbuffer resource files used by desktop
@@ -105,7 +105,6 @@ set(desktop_SRCS
105105
src/stub/app_attest_provider_stub.cc
106106
src/stub/device_check_provider_stub.cc
107107
src/stub/play_integrity_provider_stub.cc
108-
src/stub/safety_net_provider_stub.cc
109108
)
110109

111110
if(ANDROID)

app_check/integration_test/src/integration_test.cc

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include "firebase/app_check/debug_provider.h"
3434
#include "firebase/app_check/device_check_provider.h"
3535
#include "firebase/app_check/play_integrity_provider.h"
36-
#include "firebase/app_check/safety_net_provider.h"
3736
#include "firebase/auth.h"
3837
#include "firebase/database.h"
3938
#include "firebase/internal/platform.h"
@@ -150,11 +149,13 @@ void FirebaseAppCheckTest::InitializeAppCheckWithDebug() {
150149
}
151150

152151
void FirebaseAppCheckTest::TerminateAppCheck() {
153-
::firebase::app_check::AppCheck* app_check =
154-
::firebase::app_check::AppCheck::GetInstance(app_);
155-
if (app_check) {
156-
LogDebug("Shutdown App Check.");
157-
delete app_check;
152+
if (app_) {
153+
::firebase::app_check::AppCheck* app_check =
154+
::firebase::app_check::AppCheck::GetInstance(app_);
155+
if (app_check) {
156+
LogDebug("Shutdown App Check.");
157+
delete app_check;
158+
}
158159
}
159160
}
160161

@@ -357,6 +358,8 @@ TEST_F(FirebaseAppCheckTest, TestInitializeAndTerminate) {
357358
InitializeApp();
358359
}
359360

361+
// Android does not yet implement the main app check methods
362+
#if !FIREBASE_PLATFORM_ANDROID
360363
TEST_F(FirebaseAppCheckTest, TestGetTokenForcingRefresh) {
361364
InitializeAppCheckWithDebug();
362365
InitializeApp();
@@ -389,7 +392,10 @@ TEST_F(FirebaseAppCheckTest, TestGetTokenForcingRefresh) {
389392
EXPECT_NE(future.result()->expire_time_millis,
390393
future3.result()->expire_time_millis);
391394
}
395+
#endif // !FIREBASE_PLATFORM_ANDROID
392396

397+
// Android does not yet implement the main app check methods
398+
#if !FIREBASE_PLATFORM_ANDROID
393399
TEST_F(FirebaseAppCheckTest, TestGetTokenLastResult) {
394400
InitializeAppCheckWithDebug();
395401
InitializeApp();
@@ -407,7 +413,10 @@ TEST_F(FirebaseAppCheckTest, TestGetTokenLastResult) {
407413
EXPECT_EQ(future.result()->expire_time_millis,
408414
future2.result()->expire_time_millis);
409415
}
416+
#endif // !FIREBASE_PLATFORM_ANDROID
410417

418+
// Android does not yet implement the main app check methods
419+
#if !FIREBASE_PLATFORM_ANDROID
411420
TEST_F(FirebaseAppCheckTest, TestAddTokenChangedListener) {
412421
InitializeAppCheckWithDebug();
413422
InitializeApp();
@@ -427,7 +436,10 @@ TEST_F(FirebaseAppCheckTest, TestAddTokenChangedListener) {
427436
ASSERT_EQ(token_changed_listener.num_token_changes_, 1);
428437
EXPECT_EQ(token_changed_listener.last_token_.token, token.token);
429438
}
439+
#endif // !FIREBASE_PLATFORM_ANDROID
430440

441+
// Android does not yet implement the main app check methods
442+
#if !FIREBASE_PLATFORM_ANDROID
431443
TEST_F(FirebaseAppCheckTest, TestRemoveTokenChangedListener) {
432444
InitializeAppCheckWithDebug();
433445
InitializeApp();
@@ -446,6 +458,7 @@ TEST_F(FirebaseAppCheckTest, TestRemoveTokenChangedListener) {
446458

447459
ASSERT_EQ(token_changed_listener.num_token_changes_, 0);
448460
}
461+
#endif // !FIREBASE_PLATFORM_ANDROID
449462

450463
TEST_F(FirebaseAppCheckTest, TestSignIn) {
451464
InitializeAppCheckWithDebug();
@@ -457,9 +470,16 @@ TEST_F(FirebaseAppCheckTest, TestSignIn) {
457470
TEST_F(FirebaseAppCheckTest, TestDebugProviderValidToken) {
458471
firebase::app_check::DebugAppCheckProviderFactory* factory =
459472
firebase::app_check::DebugAppCheckProviderFactory::GetInstance();
460-
#if FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_DESKTOP
461473
ASSERT_NE(factory, nullptr);
474+
InitializeAppCheckWithDebug();
462475
InitializeApp();
476+
// TODO(almostmatt): Once app initialization automatically initializes
477+
// AppCheck, this test will no longer need to explicitly get an instance of
478+
// AppCheck.
479+
::firebase::app_check::AppCheck* app_check =
480+
::firebase::app_check::AppCheck::GetInstance(app_);
481+
ASSERT_NE(app_check, nullptr);
482+
463483
firebase::app_check::AppCheckProvider* provider =
464484
factory->CreateProvider(app_);
465485
ASSERT_NE(provider, nullptr);
@@ -477,9 +497,6 @@ TEST_F(FirebaseAppCheckTest, TestDebugProviderValidToken) {
477497
auto got_token_future = got_token_promise->get_future();
478498
ASSERT_EQ(std::future_status::ready,
479499
got_token_future.wait_for(kGetTokenTimeout));
480-
#else
481-
EXPECT_EQ(factory, nullptr);
482-
#endif
483500
}
484501

485502
TEST_F(FirebaseAppCheckTest, TestAppAttestProvider) {
@@ -551,20 +568,6 @@ TEST_F(FirebaseAppCheckTest, TestPlayIntegrityProvider) {
551568
#endif
552569
}
553570

554-
TEST_F(FirebaseAppCheckTest, TestSafetyNetProvider) {
555-
firebase::app_check::SafetyNetProviderFactory* factory =
556-
firebase::app_check::SafetyNetProviderFactory::GetInstance();
557-
#if FIREBASE_PLATFORM_ANDROID
558-
ASSERT_NE(factory, nullptr);
559-
InitializeApp();
560-
firebase::app_check::AppCheckProvider* provider =
561-
factory->CreateProvider(app_);
562-
EXPECT_NE(provider, nullptr);
563-
#else
564-
EXPECT_EQ(factory, nullptr);
565-
#endif
566-
}
567-
568571
// Disabling the database tests for now, since they are crashing or hanging.
569572
TEST_F(FirebaseAppCheckTest, DISABLED_TestDatabaseFailure) {
570573
// Don't initialize App Check this time. Database should fail.

app_check/src/android/app_check_android.cc

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,60 @@
1414

1515
#include "app_check/src/android/app_check_android.h"
1616

17+
#include "app/src/util_android.h"
18+
#include "app_check/src/android/common_android.h"
19+
#include "app_check/src/android/debug_provider_android.h"
20+
#include "app_check/src/android/play_integrity_provider_android.h"
1721
#include "app_check/src/common/common.h"
1822

1923
namespace firebase {
2024
namespace app_check {
2125
namespace internal {
2226

2327
static AppCheckProviderFactory* g_provider_factory = nullptr;
28+
static int g_initialized_count = 0;
29+
30+
// Release cached Java classes.
31+
static void ReleaseClasses(JNIEnv* env) {
32+
ReleaseCommonAndroidClasses(env);
33+
ReleaseDebugProviderClasses(env);
34+
ReleasePlayIntegrityProviderClasses(env);
35+
}
2436

2537
AppCheckInternal::AppCheckInternal(App* app) : app_(app) {
2638
future_manager().AllocFutureApi(this, kAppCheckFnCount);
39+
40+
// Cache the JNI method ids so we only have to look them up by name once.
41+
if (!g_initialized_count) {
42+
JNIEnv* env = app->GetJNIEnv();
43+
jobject activity = app->activity();
44+
if (util::Initialize(env, activity)) {
45+
if (!(CacheCommonAndroidMethodIds(env, activity))) {
46+
ReleaseClasses(env);
47+
util::Terminate(env);
48+
} else {
49+
// Each provider is optional as a user may or may not use it.
50+
CacheDebugProviderMethodIds(env, activity);
51+
CachePlayIntegrityProviderMethodIds(env, activity);
52+
g_initialized_count++;
53+
}
54+
}
55+
} else {
56+
g_initialized_count++;
57+
}
2758
}
2859

2960
AppCheckInternal::~AppCheckInternal() {
3061
future_manager().ReleaseFutureApi(this);
62+
JNIEnv* env = app_->GetJNIEnv();
3163
app_ = nullptr;
64+
65+
FIREBASE_ASSERT(g_initialized_count);
66+
g_initialized_count--;
67+
if (g_initialized_count == 0) {
68+
ReleaseClasses(env);
69+
util::Terminate(env);
70+
}
3271
}
3372

3473
::firebase::App* AppCheckInternal::app() const { return app_; }

0 commit comments

Comments
 (0)