Skip to content

Commit

Permalink
Merge pull request #106 from fingerprintjs/fix/platform-interaction-s…
Browse files Browse the repository at this point in the history
…tability-improvements

Fix/platform interaction stability improvements
  • Loading branch information
Sergey-Makarov authored Oct 2, 2023
2 parents 367472e + 6c2e32d commit 3285701
Show file tree
Hide file tree
Showing 38 changed files with 948 additions and 460 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/blank.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ jobs:
steps:
- uses: actions/checkout@v2

- name: Set up Java env
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'

- name: Make gradlew executable
run: chmod +x ./gradlew

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/instumented_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ jobs:
- name: Set up Java env
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '11'
distribution: 'temurin'
java-version: '17'

- name: Instrumented tests
id: instrumented_tests
Expand Down
20 changes: 15 additions & 5 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
}

android {
compileSdk = 33
compileSdk = 34

defaultConfig {
applicationId = "com.fingerprintjs.android.playground"
Expand Down Expand Up @@ -47,7 +47,7 @@ android {
isMinifyEnabled = true
proguardFiles (getDefaultProguardFile ("proguard-android-optimize.txt"), "proguard-rules.pro")
signingConfig = signingConfigs.getByName("releaseDummySign")
setMatchingFallbacks("release")
matchingFallbacks += listOf("release")
}
// same as previous, but also profileable
// when changing the name of the following build type, don't forget to update src/{this_build_type} dir
Expand All @@ -65,12 +65,21 @@ android {
}
}

compileOptions {
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}

buildFeatures {
compose = true
buildConfig = true
}

composeOptions {
kotlinCompilerExtensionVersion = "1.4.7"
kotlinCompilerExtensionVersion = "1.5.3"
}
}

Expand All @@ -95,8 +104,9 @@ dependencies {

implementation("com.google.accompanist:accompanist-pager:0.27.0")

implementation("com.google.dagger:dagger:2.44")
kapt("com.google.dagger:dagger-compiler:2.44")
val daggerVersion = "2.48"
implementation("com.google.dagger:dagger:$daggerVersion")
kapt("com.google.dagger:dagger-compiler:$daggerVersion")

implementation("com.google.code.gson:gson:2.10")
}
3 changes: 1 addition & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ buildscript {
gradlePluginPortal()
}
dependencies {
classpath("com.android.tools.build:gradle:7.4.2")
classpath("com.android.tools.build:gradle:8.1.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Constants.kotlinVersion}")
classpath("com.github.dcendents:android-maven-gradle-plugin:2.1")
}
}

Expand Down
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/Constants.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
object Constants {
const val kotlinVersion = "1.8.21"
const val kotlinVersion = "1.9.10"
}
26 changes: 23 additions & 3 deletions fingerprint/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,23 @@ publishing {
}

android {
compileSdk = 33
publishing {
singleVariant("release") {
withSourcesJar()
}
}

compileSdk = 34

defaultConfig {
minSdk = 21
// This property does not affect the library itself, but affects test apk and lint.
// As for now, I don't see any non-deprecated ways of accomplishing this task.
// Discussions:
// https://stackoverflow.com/questions/76084080/apply-targetsdk-in-android-instrumentation-test
// https://issuetracker.google.com/issues/230625468 (looks like lint.targetSdk and testOptions.targetSdk will become available soon)
targetSdk = 33

minSdk = 21
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}
Expand Down Expand Up @@ -62,6 +74,14 @@ android {
}
}
}

compileOptions {
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java) {
Expand All @@ -74,7 +94,7 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:${Constants.kotlinVersion}")
implementation("androidx.appcompat:appcompat:1.6.1")
testImplementation("junit:junit:4.13.2")
testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
testImplementation("io.mockk:mockk:1.12.7")
androidTestImplementation("androidx.test.ext:junit-ktx:1.1.5")
androidTestImplementation("androidx.test:runner:1.5.2")
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,25 @@ import com.fingerprintjs.android.fingerprint.signal_providers.hardware.HardwareS
import com.fingerprintjs.android.fingerprint.signal_providers.installed_apps.InstalledAppsSignalGroupProvider
import com.fingerprintjs.android.fingerprint.signal_providers.os_build.OsBuildSignalGroupProvider
import com.fingerprintjs.android.fingerprint.tools.DeprecationMessages
import com.fingerprintjs.android.fingerprint.tools.DummyResults
import com.fingerprintjs.android.fingerprint.tools.FingerprintingLegacySchemeSupportExtensions
import com.fingerprintjs.android.fingerprint.tools.hashers.Hasher
import com.fingerprintjs.android.fingerprint.tools.hashers.MurMur3x64x128Hasher
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import com.fingerprintjs.android.fingerprint.tools.logs.Logger
import com.fingerprintjs.android.fingerprint.tools.logs.ePleaseReport
import com.fingerprintjs.android.fingerprint.tools.safe.Safe
import com.fingerprintjs.android.fingerprint.tools.safe.safe
import com.fingerprintjs.android.fingerprint.tools.safe.safeAsync


public class Fingerprinter internal constructor(
private val legacyArgs: LegacyArgs?,
private val fpSignalsProvider: FingerprintingSignalsProvider,
private val deviceIdSignalsProvider: DeviceIdSignalsProvider,
) {

private val executor: ExecutorService = Executors.newSingleThreadExecutor()

@Volatile
private var deviceIdResult: DeviceIdResult? = null
@Volatile
private var fingerprintResult: FingerprintResult? = null

/**
Expand Down Expand Up @@ -59,7 +62,12 @@ public class Fingerprinter internal constructor(
return
}

executor.execute {
safeAsync(
onError = {
listener.invoke(DummyResults.deviceIdResult)
Logger.ePleaseReport(it)
}
) {
val deviceIdResult = DeviceIdResult(
legacyArgs.deviceIdProvider.fingerprint(),
legacyArgs.deviceIdProvider.rawData().gsfId().value,
Expand All @@ -82,7 +90,12 @@ public class Fingerprinter internal constructor(
* @param listener device ID listener.
*/
public fun getDeviceId(version: Version, listener: (DeviceIdResult) -> Unit) {
executor.execute {
safeAsync(
onError = {
listener.invoke(DummyResults.deviceIdResult)
Logger.ePleaseReport(it)
}
) {
listener.invoke(
DeviceIdResult(
deviceId = deviceIdSignalsProvider.getSignalMatching(version).getIdString(),
Expand Down Expand Up @@ -128,7 +141,12 @@ public class Fingerprinter internal constructor(
listener.invoke(it)
return
}
executor.execute {
safeAsync(
onError = {
listener.invoke(DummyResults.fingerprintResult)
Logger.ePleaseReport(it)
}
) {
val fingerprintSb = StringBuilder()

fingerprintSb.apply {
Expand Down Expand Up @@ -178,8 +196,12 @@ public class Fingerprinter internal constructor(
hasher: Hasher = MurMur3x64x128Hasher(),
listener: (String) -> (Unit),
) {
executor.execute {

safeAsync(
onError = {
listener.invoke(DummyResults.fingerprint)
Logger.ePleaseReport(it)
}
) {
val result = if (version < Version.fingerprintingFlattenedSignalsFirstVersion) {
val joinedHashes = with(FingerprintingLegacySchemeSupportExtensions) {
listOf(
Expand Down Expand Up @@ -221,7 +243,9 @@ public class Fingerprinter internal constructor(
fingerprintingSignals: List<FingerprintingSignal<*>>,
hasher: Hasher = MurMur3x64x128Hasher(),
): String {
return hasher.hash(fingerprintingSignals)
return safe(timeoutMs = Safe.timeoutLong) { hasher.hash(fingerprintingSignals) }
.onFailure { Logger.ePleaseReport(it) }
.getOrDefault(DummyResults.fingerprint)
}

private fun Hasher.hash(fingerprintingSignals: List<FingerprintingSignal<*>>): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ import com.fingerprintjs.android.fingerprint.signal_providers.installed_apps.Ins
import com.fingerprintjs.android.fingerprint.signal_providers.os_build.OsBuildSignalGroupProvider
import com.fingerprintjs.android.fingerprint.tools.hashers.Hasher
import com.fingerprintjs.android.fingerprint.tools.hashers.MurMur3x64x128Hasher
import com.fingerprintjs.android.fingerprint.tools.safe.safeLazy
import com.fingerprintjs.android.fingerprint.tools.safe.safe


/**
* A factory for [Fingerprinter] class.
*/
public object FingerprinterFactory {

private var configuration: Configuration = Configuration(version = Fingerprinter.Version.fingerprintingGroupedSignalsLastVersion.intValue)
private var configuration = Configuration(version = Fingerprinter.Version.fingerprintingGroupedSignalsLastVersion.intValue)
private var instance: Fingerprinter? = null
private var hasher: Hasher = MurMur3x64x128Hasher()

Expand Down Expand Up @@ -179,83 +181,73 @@ public object FingerprinterFactory {
private fun createCpuInfoProvider() = CpuInfoProviderImpl()

private fun createMemoryInfoProvider(context: Context): MemInfoProvider {
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val internalStorageDir = Environment.getRootDirectory().absolutePath
val internalStorageStatFs = StatFs(internalStorageDir)

val externalStorageDir = context.getExternalFilesDir(null)
val externalStorageDirPath = externalStorageDir?.absolutePath
val externalStorageStatFs =
if (externalStorageDirPath != null && externalStorageDir.canRead()) {
StatFs(externalStorageDirPath)
} else {
null
}

return MemInfoProviderImpl(
activityManager,
internalStorageStatFs,
externalStorageStatFs
activityManager = safeLazy { context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager },
internalStorageStats = safeLazy { StatFs(Environment.getRootDirectory()!!.absolutePath!!) },
externalStorageStats = safeLazy {
context.getExternalFilesDir(null)
?.takeIf { it.canRead() }
?.let { StatFs(it.absolutePath!!) }!!
},
)
}

private fun createOsBuildInfoProvider() = OsBuildInfoProviderImpl()

private fun createGsfIdProvider(context: Context) = GsfIdProvider(context.contentResolver!!)
private fun createGsfIdProvider(context: Context) = GsfIdProvider(
safe { context.contentResolver!! }.getOrDefault(null)
)

private fun createMediaDrmProvider() = MediaDrmIdProvider()

private fun createAndroidIdProvider(context: Context) =
AndroidIdProvider(context.contentResolver!!)
private fun createAndroidIdProvider(context: Context) = AndroidIdProvider(
safe { context.contentResolver!! }.getOrDefault(null)
)

private fun createSensorDataSource(context: Context) = SensorDataSourceImpl(
context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
safeLazy { context.getSystemService(Context.SENSOR_SERVICE) as SensorManager }
)

private fun createInputDevicesDataSource(context: Context) = InputDevicesDataSourceImpl(
context.getSystemService(Context.INPUT_SERVICE) as InputManager
safeLazy { context.getSystemService(Context.INPUT_SERVICE) as InputManager }
)

private fun createPackageManagerDataSource(context: Context) = PackageManagerDataSourceImpl(
context.packageManager
safeLazy { context.packageManager!! }
)

private fun createSettingsDataSource(context: Context) = SettingsDataSourceImpl(
context.contentResolver
safeLazy { context.contentResolver!! }
)


private fun createDevicePersonalizationDataSource(context: Context) =
DevicePersonalizationInfoProviderImpl(
RingtoneManager(context),
context.assets,
context.resources.configuration
ringtoneManager = safeLazy { RingtoneManager(context) },
assetManager = safeLazy { context.assets!! },
configuration = safeLazy { context.resources!!.configuration!! },
)

private fun createFingerprintSensorStatusProvider(context: Context) =
FingerprintSensorInfoProviderImpl(
FingerprintManagerCompat.from(context)
safeLazy { FingerprintManagerCompat.from(context)!! }
)

private fun createDeviceSecurityProvider(context: Context) = DeviceSecurityInfoProviderImpl(
context.getSystemService(Context.DEVICE_POLICY_SERVICE) as? DevicePolicyManager,
context.getSystemService(Context.KEYGUARD_SERVICE) as? KeyguardManager
safeLazy { context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager },
safeLazy { context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager },
)

private fun createCodecInfoProvider() = CodecInfoProviderImpl(
MediaCodecList(MediaCodecList.ALL_CODECS)
safeLazy { MediaCodecList(MediaCodecList.ALL_CODECS) }
)

private fun createBatteryInfoDataSource(context: Context) = BatteryInfoProviderImpl(
context
)
private fun createBatteryInfoDataSource(context: Context) = BatteryInfoProviderImpl(context)

private fun createCameraInfoProvider(): CameraInfoProvider {
return CameraInfoProviderImpl()
}
private fun createCameraInfoProvider(): CameraInfoProvider = CameraInfoProviderImpl()

private fun createGpuInfoProvider(context: Context) =
GpuInfoProviderImpl(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager)
GpuInfoProviderImpl(safeLazy { context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager } )

//endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import android.annotation.SuppressLint
import android.content.ContentResolver
import android.provider.Settings
import com.fingerprintjs.android.fingerprint.tools.DeprecationMessages
import com.fingerprintjs.android.fingerprint.tools.executeSafe
import com.fingerprintjs.android.fingerprint.tools.safe.safe


@Deprecated(message = DeprecationMessages.UNREACHABLE_SYMBOL_UNINTENDED_PUBLIC_API)
public class AndroidIdProvider(
private val contentResolver: ContentResolver
private val contentResolver: ContentResolver?
) {
@SuppressLint("HardwareIds")
public fun getAndroidId(): String {
return executeSafe({
return safe {
Settings.Secure.getString(
contentResolver,
contentResolver!!,
Settings.Secure.ANDROID_ID
)
}, "")
)!!
}.getOrDefault("")
}
}
Loading

0 comments on commit 3285701

Please sign in to comment.