diff --git a/BlockStore/app/build.gradle b/BlockStore/app/build.gradle index c7fb65be..3d0acdda 100644 --- a/BlockStore/app/build.gradle +++ b/BlockStore/app/build.gradle @@ -14,23 +14,21 @@ * limitations under the License. */ plugins { - id 'com.android.application' - id 'kotlin-android' - id 'dagger.hilt.android.plugin' - id 'kotlin-kapt' + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.hilt.android) + alias(libs.plugins.kotlin.kapt) } android { - compileSdkVersion 31 - buildToolsVersion "30.0.3" - + compileSdk 35 + namespace "com.google.android.gms.identity.sample.blockstore" defaultConfig { applicationId "com.google.android.gms.identity.sample.blockstore" - minSdkVersion 21 - targetSdkVersion 31 + minSdk 21 + targetSdk 35 versionCode 1 versionName "1.0" - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -44,42 +42,44 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } + kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '17' } } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.google.android.material:material:1.4.0' - implementation 'com.google.android.gms:play-services-auth-blockstore:16.0.2' - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.6.0' - implementation 'androidx.appcompat:appcompat:1.3.1' - implementation 'androidx.constraintlayout:constraintlayout:2.1.0' - implementation 'androidx.test.espresso:espresso-idling-resource:3.4.0' - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' - androidTestImplementation 'androidx.test.ext:junit:1.1.3' + implementation libs.kotlin.stdlib + implementation libs.play.services.auth.blockstore + implementation libs.material.design + implementation libs.androidx.core.ktx + implementation libs.androidx.appcompat + implementation libs.androidx.constraintlayout + implementation libs.androidx.work.runtime // Hilt - implementation 'com.google.dagger:hilt-android:2.37' - kapt 'com.google.dagger:hilt-android-compiler:2.37' - implementation 'androidx.hilt:hilt-work:1.0.0' - kapt 'androidx.hilt:hilt-compiler:1.0.0' + implementation libs.hilt.android + kapt libs.hilt.android.compiler + implementation libs.hilt.work + kapt libs.hilt.compiler // Lifecycle - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0-alpha03" - implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1" - implementation "androidx.lifecycle:lifecycle-common-java8:2.3.1" + implementation libs.bundles.androidx.lifecycle // Activity - implementation "androidx.activity:activity-ktx:1.3.1" + implementation libs.androidx.activity.ktx // Coroutines - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.4.3" + implementation libs.kotlinx.coroutines.play.services + + // jUnit + testImplementation libs.junit + debugImplementation libs.androidx.test.monitor + androidTestImplementation libs.bundles.androidx.test + implementation libs.androidx.test.espresso.idling.resource } \ No newline at end of file diff --git a/BlockStore/app/src/main/AndroidManifest.xml b/BlockStore/app/src/main/AndroidManifest.xml index 92948fc1..8027840f 100644 --- a/BlockStore/app/src/main/AndroidManifest.xml +++ b/BlockStore/app/src/main/AndroidManifest.xml @@ -11,8 +11,8 @@ See the License for the specific language governing permissions and limitations under the License. --> - + - diff --git a/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/AppModule.kt b/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/AppModule.kt index a2a5a3a7..f7cf3225 100644 --- a/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/AppModule.kt +++ b/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/AppModule.kt @@ -35,4 +35,4 @@ class AppModule { @Provides fun provideBlockStoreClient(@ApplicationContext context: Context): BlockstoreClient = Blockstore.getClient(context) -} \ No newline at end of file +} diff --git a/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/BlockStoreRepository.kt b/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/BlockStoreRepository.kt index 1eb4d0db..525640a4 100644 --- a/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/BlockStoreRepository.kt +++ b/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/BlockStoreRepository.kt @@ -1,7 +1,10 @@ package com.google.android.gms.identity.sample.blockstore import com.google.android.gms.auth.blockstore.BlockstoreClient +import com.google.android.gms.auth.blockstore.RetrieveBytesRequest +import com.google.android.gms.auth.blockstore.RetrieveBytesResponse import com.google.android.gms.auth.blockstore.StoreBytesData +import com.google.android.gms.tasks.Task import kotlinx.coroutines.tasks.await import javax.inject.Inject @@ -13,20 +16,29 @@ class BlockStoreRepository @Inject constructor( private val blockStoreClient: BlockstoreClient ) { - // This function saves the authentication token to Block Store. + /** This function saves the authentication token to Block Store. */ suspend fun storeBytes(inputString: String) { val data: StoreBytesData = StoreBytesData.Builder().setBytes(inputString.toByteArray()).build() blockStoreClient.storeBytes(data).await() } - // This function retrieves your Block Store data. + /** This function retrieves your Block Store data. */ + @Deprecated(message = "retrieveBytes() now requires argument RetrieveBytesRequest") suspend fun retrieveBytes(): String { return String(blockStoreClient.retrieveBytes().await()) } - // This function clears your Block Store data. + /** This function retrieves your Block Store data with RetrieveBytesRequest. */ + suspend fun retrieveBytes(bytesRequest: RetrieveBytesRequest) { + val response: Task = blockStoreClient + .retrieveBytes(bytesRequest) + .addOnSuccessListener {} + .addOnFailureListener {} + } + + /** This function clears your Block Store data. */ suspend fun clearBytes() { storeBytes("") } -} \ No newline at end of file +} diff --git a/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/MainActivity.kt b/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/MainActivity.kt index 7882c6fb..6201615f 100644 --- a/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/MainActivity.kt +++ b/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/MainActivity.kt @@ -55,5 +55,4 @@ class MainActivity : AppCompatActivity() { viewModel.clearBytes() } } - -} \ No newline at end of file +} diff --git a/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/MainApplication.kt b/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/MainApplication.kt index aa5b40dc..83e00faa 100644 --- a/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/MainApplication.kt +++ b/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/MainApplication.kt @@ -23,4 +23,4 @@ import dagger.hilt.android.HiltAndroidApp * Application class, needed to enable dependency injection with Hilt. */ @HiltAndroidApp -class MainApplication : Application() \ No newline at end of file +class MainApplication : Application() diff --git a/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/MainViewModel.kt b/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/MainViewModel.kt index e68eb9ea..6e9e01f5 100644 --- a/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/MainViewModel.kt +++ b/BlockStore/app/src/main/java/com/google/android/gms/identity/sample/blockstore/MainViewModel.kt @@ -45,4 +45,4 @@ class MainViewModel @Inject constructor( _state.value = State(bytes = null) } } -} \ No newline at end of file +} diff --git a/BlockStore/build.gradle b/BlockStore/build.gradle index f5fca2ef..a5ff8633 100644 --- a/BlockStore/build.gradle +++ b/BlockStore/build.gradle @@ -14,30 +14,13 @@ * limitations under the License. */ // Top-level build file where you can add configuration options common to all sub-projects/modules. -buildscript { - ext.kotlin_version = "1.5.21" - repositories { - google() - mavenCentral() - } - dependencies { - classpath "com.android.tools.build:gradle:4.2.2" - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38.1' - - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } +plugins { + alias(libs.plugins.android.application) apply false + alias(libs.plugins.android.library) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.hilt.android) apply false } -allprojects { - repositories { - google() - mavenCentral() - } +tasks.register('clean', Delete) { + delete rootProject.fileTree("build") } - -task clean(type: Delete) { - delete rootProject.buildDir -} \ No newline at end of file diff --git a/BlockStore/gradle.properties b/BlockStore/gradle.properties index 25217527..547bf822 100644 --- a/BlockStore/gradle.properties +++ b/BlockStore/gradle.properties @@ -16,4 +16,6 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true # Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official \ No newline at end of file +kotlin.code.style=official + +kapt.use.k2=true \ No newline at end of file diff --git a/BlockStore/gradle/libs.versions.toml b/BlockStore/gradle/libs.versions.toml new file mode 100644 index 00000000..2cd47b9b --- /dev/null +++ b/BlockStore/gradle/libs.versions.toml @@ -0,0 +1,53 @@ +[versions] +android_gradle_plugin = '8.6.0' +hilt_android = '2.52' +hilt = '1.2.0' +kotlin = '2.0.20' +kotlinx_coroutines = '1.7.3' +junit = '4.13.2' +material_design = '1.12.0' +androidx_core = '1.13.1' +androidx_activity = '1.9.2' +androidx_appcompat = '1.7.0' +androidx_constraintlayout = '2.1.4' +androidx_lifecycle = '2.8.5' +androidx_work = '2.9.1' +androidx_test_ext_junit = '1.2.1' +androidx_test_monitor = '1.7.2' +androidx_test_espresso = '3.6.1' +play_services_auth_blockstore = '16.4.0' + +[plugins] +android_application = { id = "com.android.application", version.ref = "android_gradle_plugin" } +android_library = { id = "com.android.library", version.ref = "android_gradle_plugin" } +kotlin_android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin_kapt = { id = "org.jetbrains.kotlin.kapt" } +hilt_android = { id = "com.google.dagger.hilt.android", version.ref = "hilt_android" } + +[libraries] +hilt_compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "hilt" } +hilt_work = { module = "androidx.hilt:hilt-work", version.ref = "hilt" } +hilt_android = { module = "com.google.dagger:hilt-android", version.ref = "hilt_android" } +hilt_android_compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt_android" } +junit = { module = "junit:junit", version.ref = "junit" } +kotlin_stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } +kotlinx_coroutines_play_services = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-play-services", version.ref = "kotlinx_coroutines" } +material_design = { module = "com.google.android.material:material", version.ref = "material_design" } +androidx_core_ktx = { module = "androidx.core:core-ktx", version.ref = "androidx_core" } +androidx_activity_ktx = { module = "androidx.activity:activity-ktx", version.ref = "androidx_activity" } +androidx_appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx_appcompat" } +androidx_constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidx_constraintlayout" } +play_services_auth_blockstore = { module = "com.google.android.gms:play-services-auth-blockstore", version.ref = "play_services_auth_blockstore" } +androidx_lifecycle_common_java8 = { module = "androidx.lifecycle:lifecycle-common-java8", version.ref = "androidx_lifecycle" } +androidx_lifecycle_livedata_ktx = { module = "androidx.lifecycle:lifecycle-livedata-ktx", version.ref = "androidx_lifecycle" } +androidx_lifecycle_viewmodel_ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx_lifecycle" } +androidx_work_runtime = { module = "androidx.work:work-runtime", version.ref = "androidx_work" } +androidx_work_runtime_ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "androidx_work" } +androidx_test_monitor = { module = "androidx.test:monitor", version.ref = "androidx_test_monitor" } +androidx_test_ext_junit = { module = "androidx.test.ext:junit", version.ref = "androidx_test_ext_junit" } +androidx_test_espresso_core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx_test_espresso" } +androidx_test_espresso_idling_resource = { module = "androidx.test.espresso:espresso-idling-resource", version.ref = "androidx_test_espresso" } + +[bundles] +androidx_lifecycle = ["androidx_lifecycle_common_java8", "androidx_lifecycle_livedata_ktx", "androidx_lifecycle_viewmodel_ktx"] +androidx_test = ["androidx_test_ext_junit", "androidx_test_espresso_core"] diff --git a/BlockStore/gradle/wrapper/gradle-wrapper.properties b/BlockStore/gradle/wrapper/gradle-wrapper.properties index f7564048..8fcac46f 100644 --- a/BlockStore/gradle/wrapper/gradle-wrapper.properties +++ b/BlockStore/gradle/wrapper/gradle-wrapper.properties @@ -14,7 +14,7 @@ # #Thu Aug 19 16:25:07 EDT 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/BlockStore/settings.gradle b/BlockStore/settings.gradle index e2161442..fc8797d2 100644 --- a/BlockStore/settings.gradle +++ b/BlockStore/settings.gradle @@ -13,5 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +pluginManagement { + repositories { + gradlePluginPortal() + google() + mavenCentral() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + mavenCentral() + } +} rootProject.name = "BlockStore" include ':app' diff --git a/CredentialManager/app/build.gradle b/CredentialManager/app/build.gradle index bb498a4c..e4d875e1 100644 --- a/CredentialManager/app/build.gradle +++ b/CredentialManager/app/build.gradle @@ -15,12 +15,11 @@ */ plugins { - id 'com.android.application' - id 'org.jetbrains.kotlin.android' -} -repositories { - google() - mavenCentral() + alias(libs.plugins.android.application) + alias(libs.plugins.google.services) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.hilt.android) + alias(libs.plugins.kotlin.kapt) } // Load keystore properties for our signing key @@ -31,15 +30,13 @@ keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) android { namespace 'com.google.credentialmanager.sample' - compileSdk 34 - compileSdkPreview "VanillaIceCream" + compileSdk 35 defaultConfig { applicationId "com.google.credentialmanager.sample" minSdk 21 - targetSdkPreview "VanillaIceCream" + targetSdk 35 versionCode 1 - versionName "1.0" - + versionName "1.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary true @@ -55,7 +52,6 @@ android { } } - buildTypes { release { applicationIdSuffix ".release" @@ -67,19 +63,17 @@ android { debug { signingConfig signingConfigs.config } - } + compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } + kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '17' } - composeOptions { - kotlinCompilerExtensionVersion = "1.4.2" - } packagingOptions { resources { excludes += '/META-INF/{AL2.0,LGPL2.1}' @@ -89,27 +83,29 @@ android { buildFeatures { viewBinding true } + + hilt { + enableAggregatingTask = true + } } dependencies { - - implementation 'androidx.core:core-ktx:1.12.0' - implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'com.google.android.material:material:1.11.0' - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.5' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - - implementation 'androidx.credentials:credentials-play-services-auth:1.5.0-alpha02' - implementation 'androidx.credentials:credentials:1.5.0-alpha02' - - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3" - - implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3" - implementation "androidx.lifecycle:lifecycle-runtime-compose:2.6.2" - + implementation libs.material.design + implementation libs.androidx.core.ktx + implementation libs.androidx.appcompat + implementation libs.androidx.constraintlayout + + implementation libs.bundles.androidx.credentials + implementation libs.bundles.kotlin.coroutines + implementation libs.bundles.androidx.lifecycle + + // Hilt + implementation libs.hilt.android + kapt libs.hilt.android.compiler + implementation libs.hilt.work + kapt libs.hilt.compiler + + testImplementation libs.junit + debugImplementation libs.androidx.test.monitor + androidTestImplementation libs.bundles.androidx.test } diff --git a/CredentialManager/app/src/main/AndroidManifest.xml b/CredentialManager/app/src/main/AndroidManifest.xml index 6b9638aa..579cfd1e 100644 --- a/CredentialManager/app/src/main/AndroidManifest.xml +++ b/CredentialManager/app/src/main/AndroidManifest.xml @@ -29,7 +29,8 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.CredentialManagerSample" - tools:targetApi="31"> + android:enableOnBackInvokedCallback="true" + tools:targetApi="tiramisu"> 0) { + supportFragmentManager.popBackStack() + } else if (supportFragmentManager.backStackEntryCount == 0) { + finish() + } + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) + onBackPressedDispatcher + .addCallback(this@MainActivity, this.navigateOnBackPressed) + DataProvider.initSharedPref(applicationContext) if (DataProvider.isSignedIn()) { @@ -75,12 +93,4 @@ class MainActivity : AppCompatActivity(), MainFragmentCallback, HomeFragmentCall supportFragmentManager.beginTransaction().replace(id.fragment_container, fragment) .addToBackStack(backstackString).commit() } - - override fun onBackPressed() { - if (DataProvider.isSignedIn() || supportFragmentManager.backStackEntryCount == 1) { - finish() - } else { - super.onBackPressed() - } - } } diff --git a/CredentialManager/app/src/main/java/com/google/credentialmanager/sample/SignInFragment.kt b/CredentialManager/app/src/main/java/com/google/credentialmanager/sample/SignInFragment.kt index 09277b0b..e9c9e667 100644 --- a/CredentialManager/app/src/main/java/com/google/credentialmanager/sample/SignInFragment.kt +++ b/CredentialManager/app/src/main/java/com/google/credentialmanager/sample/SignInFragment.kt @@ -172,8 +172,8 @@ class SignInFragment : Fragment() { return "Got Password - User:${cred.id} Password: ${cred.password}" } if (result.credential is CustomCredential) { - //If you are also using any external sign-in libraries, parse them here with the - // utility functions provided. + // If you are also using any external sign-in libraries, + // parse them here with the utility functions provided. } return null } diff --git a/CredentialManager/build.gradle b/CredentialManager/build.gradle index bfe8fae9..b1eb8cc1 100644 --- a/CredentialManager/build.gradle +++ b/CredentialManager/build.gradle @@ -14,37 +14,16 @@ * limitations under the License. */ -buildscript { - repositories { - // Make sure that you have the following two repositories - google() // Google's Maven repository - mavenCentral() // Maven Central repository - - } - dependencies { - // Add the dependency for the Google services Gradle plugin - classpath 'com.google.gms:google-services:4.3.15' - classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38.1' - //classpath for kotlin may introduce different version jars - - } -} - // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id 'com.android.application' version '8.1.0' apply false - id 'com.android.library' version '8.1.0' apply false - id 'org.jetbrains.kotlin.android' version '1.8.10' apply false -} - -task clean(type: Delete) { - delete rootProject.buildDir + alias(libs.plugins.android.application) apply false + alias(libs.plugins.android.library) apply false + alias(libs.plugins.google.services) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.kapt) apply false + alias(libs.plugins.hilt.android) apply false } -allprojects { - repositories { - // Make sure that you have the following two repositories - google() // Google's Maven repository - mavenCentral() // Maven Central repository - } +tasks.register('clean', Delete) { + delete rootProject.fileTree("build") } diff --git a/CredentialManager/gradle/libs.versions.toml b/CredentialManager/gradle/libs.versions.toml new file mode 100644 index 00000000..9bcf7a03 --- /dev/null +++ b/CredentialManager/gradle/libs.versions.toml @@ -0,0 +1,52 @@ +[versions] +android_gradle_plugin = '8.6.0' +google_services_plugin = '4.4.2' +hilt_android = "2.52" +hilt = "1.2.0" +kotlin = '2.0.20' +kotlin_coroutines = '1.7.3' +junit = '4.13.2' +material_design = '1.12.0' +androidx_core = '1.13.1' +androidx_appcompat = '1.7.0' +androidx_constraintlayout = '2.1.4' +androidx_credentials = '1.5.0-alpha05' +androidx_lifecycle = '2.8.5' +androidx_test_ext_junit = '1.2.1' +androidx_test_monitor = '1.7.2' +androidx_test_espresso = '3.6.1' + +[plugins] +android_application = { id = "com.android.application", version.ref = "android_gradle_plugin" } +android_library = { id = "com.android.library", version.ref = "android_gradle_plugin" } +google_services = { id = "com.google.gms.google-services", version.ref = "google_services_plugin" } +kotlin_android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin_kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } +hilt_android = { id = "com.google.dagger.hilt.android", version.ref = "hilt_android" } + +[libraries] +hilt_compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "hilt" } +hilt_work = { module = "androidx.hilt:hilt-work", version.ref = "hilt" } +hilt_android = { module = "com.google.dagger:hilt-android", version.ref = "hilt_android" } +hilt_android_compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt_android" } +junit = { module = "junit:junit", version.ref = "junit" } +kotlin_coroutines_core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin_coroutines" } +kotlin_coroutines_android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlin_coroutines" } +material_design = { module = "com.google.android.material:material", version.ref = "material_design" } +androidx_core_ktx = { module = "androidx.core:core-ktx", version.ref = "androidx_core" } +androidx_appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx_appcompat" } +androidx_constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidx_constraintlayout" } +androidx_credentials = { module = "androidx.credentials:credentials", version.ref = "androidx_credentials" } +androidx_credentials_play_auth = { module = "androidx.credentials:credentials-play-services-auth", version.ref = "androidx_credentials" } +androidx_lifecycle_runtime_ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidx_lifecycle" } +androidx_lifecycle_runtime_compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx_lifecycle" } +androidx_lifecycle_viewmodel_ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx_lifecycle" } +androidx_test_monitor = { module = "androidx.test:monitor", version.ref = "androidx_test_monitor" } +androidx_test_ext_junit = { module = "androidx.test.ext:junit", version.ref = "androidx_test_ext_junit" } +androidx_test_espresso_core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx_test_espresso" } + +[bundles] +kotlin_coroutines = ["kotlin_coroutines_core", "kotlin_coroutines_android"] +androidx_lifecycle = ["androidx_lifecycle_runtime_ktx", "androidx_lifecycle_runtime_compose", "androidx_lifecycle_viewmodel_ktx"] +androidx_credentials = ["androidx_credentials", "androidx_credentials_play_auth"] +androidx_test = ["androidx_test_ext_junit", "androidx_test_espresso_core"] diff --git a/CredentialManager/gradle/wrapper/gradle-wrapper.properties b/CredentialManager/gradle/wrapper/gradle-wrapper.properties index b20ba551..b1246838 100644 --- a/CredentialManager/gradle/wrapper/gradle-wrapper.properties +++ b/CredentialManager/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Dec 28 18:22:13 IST 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/CredentialManager/settings.gradle b/CredentialManager/settings.gradle index 939e7f44..aebd7d64 100644 --- a/CredentialManager/settings.gradle +++ b/CredentialManager/settings.gradle @@ -1,3 +1,5 @@ +import org.gradle.api.initialization.resolve.RepositoriesMode + /* * Copyright 2023 Google LLC * @@ -21,5 +23,20 @@ pluginManagement { mavenCentral() } } + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + mavenCentral() + } +} + rootProject.name = "CredentialManagerSample" include ':app' diff --git a/CredentialProvider/MyVault/app/build.gradle.kts b/CredentialProvider/MyVault/app/build.gradle.kts index 14e1c51f..c5e367af 100644 --- a/CredentialProvider/MyVault/app/build.gradle.kts +++ b/CredentialProvider/MyVault/app/build.gradle.kts @@ -15,27 +15,26 @@ */ plugins { alias(libs.plugins.android.application) - alias(libs.plugins.jetbrains.kotlin.android) + alias(libs.plugins.kotlin.compose.compiler) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.androidx.navigation.safeargs) + alias(libs.plugins.androidx.room) alias(libs.plugins.devtools.ksp) } android { namespace = "com.example.android.authentication.myvault" - - compileSdkPreview = "VanillaIceCream" - + compileSdk = 35 defaultConfig { applicationId = "com.example.android.authentication.myvault" minSdk = 34 - targetSdkPreview = "VanillaIceCream" + targetSdk = 35 versionCode = 1 versionName = "1.0" - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true } - } buildTypes { @@ -48,36 +47,35 @@ android { } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = "17" } buildFeatures { compose = true } - composeOptions { - kotlinCompilerExtensionVersion = "1.5.10" - } packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } + room { + schemaDirectory("${rootDir}/schema") + } } dependencies { - implementation(libs.androidx.core.ktx) implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.activity.compose) implementation(platform(libs.androidx.compose.bom)) - implementation(libs.androidx.ui) - implementation(libs.androidx.ui.graphics) - implementation(libs.androidx.ui.tooling.preview) - implementation(libs.androidx.material3) - implementation(libs.androidx.credential.manager) + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.ui.graphics) + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.compose.material3) + implementation(libs.androidx.credentials) implementation(libs.androidx.room.ktx) implementation(libs.androidx.room.runtime) ksp(libs.androidx.room.compiler) @@ -85,12 +83,12 @@ dependencies { implementation(libs.androidx.biometrics) implementation(libs.androidx.navigation) implementation(libs.google.accompanist) - implementation(libs.androidx.lifecyle.runtime.compose) + implementation(libs.androidx.lifecycle.runtime.compose) testImplementation(libs.junit) - androidTestImplementation(libs.androidx.junit) - androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(libs.androidx.test.ext.junit) + androidTestImplementation(libs.androidx.test.espresso.core) androidTestImplementation(platform(libs.androidx.compose.bom)) - androidTestImplementation(libs.androidx.ui.test.junit4) - debugImplementation(libs.androidx.ui.tooling) - debugImplementation(libs.androidx.ui.test.manifest) + androidTestImplementation(libs.androidx.compose.ui.test.junit4) + debugImplementation(libs.androidx.compose.ui.tooling) + debugImplementation(libs.androidx.compose.ui.test.manifest) } diff --git a/CredentialProvider/MyVault/app/src/main/AndroidManifest.xml b/CredentialProvider/MyVault/app/src/main/AndroidManifest.xml index 907bc0f4..a08d09c2 100644 --- a/CredentialProvider/MyVault/app/src/main/AndroidManifest.xml +++ b/CredentialProvider/MyVault/app/src/main/AndroidManifest.xml @@ -14,22 +14,23 @@ * limitations under the License. --> - + + + android:name="com.example.android.authentication.myvault.MyVaultApplication" + android:icon="@drawable/android_secure" + android:label="@string/app_name" + android:roundIcon="@drawable/android_secure" + android:supportsRtl="true" + tools:ignore="LockedOrientationActivity" + android:theme="@style/Theme.MyVault"> + android:name="com.example.android.authentication.myvault.ui.MainActivity" + android:exported="true"> @@ -40,20 +41,17 @@ + android:name="com.example.android.authentication.myvault.ui.CreatePasswordActivity" + android:exported="true"> + android:name="com.example.android.authentication.myvault.ui.CreatePasskeyActivity" + android:enabled="true" + android:exported="true"> @@ -61,30 +59,27 @@ + android:name=".ui.UnlockActivity" + android:enabled="true" + android:exported="true"> + android:name=".ui.GetPasskeyActivity" + android:enabled="true" + android:exported="true"> + android:name="com.example.android.authentication.myvault.ui.GetPasswordActivity" + android:enabled="true" + android:exported="true"> @@ -92,18 +87,18 @@ + android:name="com.example.android.authentication.myvault.data.MyVaultService" + android:enabled="true" + android:exported="true" + android:icon="@drawable/android_secure" + android:label="@string/service_name" + android:permission="android.permission.BIND_CREDENTIAL_PROVIDER_SERVICE"> + android:name="android.credentials.provider" + android:resource="@xml/provider" /> diff --git a/CredentialProvider/MyVault/app/src/main/java/com/example/android/authentication/myvault/ui/GetPasskeyActivity.kt b/CredentialProvider/MyVault/app/src/main/java/com/example/android/authentication/myvault/ui/GetPasskeyActivity.kt index aec0e5ec..67a2f90f 100644 --- a/CredentialProvider/MyVault/app/src/main/java/com/example/android/authentication/myvault/ui/GetPasskeyActivity.kt +++ b/CredentialProvider/MyVault/app/src/main/java/com/example/android/authentication/myvault/ui/GetPasskeyActivity.kt @@ -78,8 +78,8 @@ class GetPasskeyActivity : FragmentActivity() { intent.getBooleanExtra(getString(R.string.is_auto_selected), false) /* - * retrieveProviderGetCredentialRequest extracts the [ProviderGetCredentialRequest] from the provider's - * [PendingIntent] invoked by the Android system, when the user selects a + * retrieveProviderGetCredentialRequest extracts the [ProviderGetCredentialRequest] from + * the provider's [PendingIntent] invoked by the Android system, when the user selects a * [CredentialEntry]. */ val request = PendingIntentHandler.retrieveProviderGetCredentialRequest(intent) @@ -112,8 +112,11 @@ class GetPasskeyActivity : FragmentActivity() { // Extract the requestJson and clientDataHash from this option. var clientDataHash: ByteArray? = null - if (request.callingAppInfo.origin != null) { - clientDataHash = publicKeyRequest.clientDataHash + val privilegedAllowlist: String? = getGPMPrivilegedAppAllowlist() + if (privilegedAllowlist != null) { + if (request.callingAppInfo.getOrigin(privilegedAllowlist) != null) { + clientDataHash = publicKeyRequest.clientDataHash + } } if (callingAppOriginInfo != null) { @@ -130,7 +133,7 @@ class GetPasskeyActivity : FragmentActivity() { } /** - * This method helps check the asset linking to verify client app idenity + * This method helps check the asset linking to verify client app identity * @param rpId : Relying party identifier * @param callingAppInfo : Information pertaining to the calling application. */ diff --git a/CredentialProvider/MyVault/build.gradle.kts b/CredentialProvider/MyVault/build.gradle.kts index 0646386f..08a55112 100644 --- a/CredentialProvider/MyVault/build.gradle.kts +++ b/CredentialProvider/MyVault/build.gradle.kts @@ -1,6 +1,10 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { alias(libs.plugins.android.application) apply false - alias(libs.plugins.jetbrains.kotlin.android) apply false + alias(libs.plugins.kotlin.compose.compiler) apply false + alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.devtools.ksp) apply false + alias(libs.plugins.diffplug.spotless) apply false + alias(libs.plugins.androidx.navigation.safeargs) apply false + alias(libs.plugins.androidx.room) apply false } diff --git a/CredentialProvider/MyVault/gradle/libs.versions.toml b/CredentialProvider/MyVault/gradle/libs.versions.toml index a3b9e2e4..8623f3cd 100644 --- a/CredentialProvider/MyVault/gradle/libs.versions.toml +++ b/CredentialProvider/MyVault/gradle/libs.versions.toml @@ -1,51 +1,53 @@ [versions] -agp = "8.4.0" -ksp = "1.9.22-1.0.17" -kotlin = "1.9.22" -coreKtx = "1.12.0" -junit = "4.13.2" -junitVersion = "1.1.5" -espressoCore = "3.5.1" -lifecycleRuntime = "2.8.2" -activityCompose = "1.9.0" -composeBom = "2024.06.00" -credentials = "1.5.0-alpha02" -room = "2.6.1" -biometrics = "1.2.0-alpha05" -accompanist = "0.28.0" -navigation = "2.7.7" - -[libraries] -androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } -junit = { group = "junit", name = "junit", version.ref = "junit" } -androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } -androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } -androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntime" } -androidx-lifecyle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycleRuntime" } -androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } -androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } -androidx-ui = { group = "androidx.compose.ui", name = "ui" } -androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } -androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } -androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } -androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } -androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } -androidx-material3 = { group = "androidx.compose.material3", name = "material3" } -androidx-credential-manager = { group = "androidx.credentials", name = "credentials", version.ref = "credentials" } -androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" } -androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" } -androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" } -androidx-biometrics = { group = "androidx.biometric", name = "biometric", version.ref = "biometrics" } -androidx-navigation = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation" } -google-accompanist = { group = "com.google.accompanist", name = "accompanist-systemuicontroller", version.ref = "accompanist" } - +android_gradle_plugin = '8.6.0' +devtools_ksp = '2.0.20-1.0.25' +google_accompanist = '0.28.0' +kotlin = '2.0.20' +ktlint = '1.0.1' +junit = '4.13.2' +diffplug_spotless = '6.25.0' +androidx_core_ktx = '1.13.1' +androidx_test_ext_junit = '1.2.1' +androidx_test_espresso = '3.6.1' +androidx_lifecycle = '2.8.5' +androidx_activity_compose = '1.9.2' +androidx_compose_bom = '2024.09.00' +androidx_credentials = '1.5.0-alpha05' +androidx_biometrics = '1.2.0-alpha05' +androidx_navigation = '2.8.0' +androidx_room = '2.6.1' [plugins] -android-application = { id = "com.android.application", version.ref = "agp" } -jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } -devtools-ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } - - +android_application = { id = "com.android.application", version.ref = "android_gradle_plugin" } +kotlin_compose_compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +kotlin_android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +diffplug_spotless = { id = "com.diffplug.spotless", version.ref = "diffplug_spotless" } +devtools_ksp = { id = "com.google.devtools.ksp", version.ref = "devtools_ksp" } +androidx_room = { id = "androidx.room", version.ref = "androidx_room" } +androidx_navigation_safeargs = { id = "androidx.navigation.safeargs", version.ref = "androidx_navigation" } +[libraries] +androidx_core_ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidx_core_ktx" } +androidx_lifecycle_runtime_ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "androidx_lifecycle" } +androidx_lifecycle_runtime_compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidx_lifecycle" } +androidx_activity_compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidx_activity_compose" } +androidx_compose_bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidx_compose_bom" } +androidx_compose_ui = { group = "androidx.compose.ui", name = "ui" } +androidx_compose_ui_graphics = { group = "androidx.compose.ui", name = "ui-graphics" } +androidx_compose_ui_tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx_compose_ui_tooling_preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx_compose_ui_test_manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } +androidx_compose_ui_test_junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } +androidx_compose_material3 = { group = "androidx.compose.material3", name = "material3" } +androidx_credentials = { group = "androidx.credentials", name = "credentials", version.ref = "androidx_credentials" } +androidx_room_runtime = { group = "androidx.room", name = "room-runtime", version.ref = "androidx_room" } +androidx_room_ktx = { group = "androidx.room", name = "room-ktx", version.ref = "androidx_room" } +androidx_room_compiler = { group = "androidx.room", name = "room-compiler", version.ref = "androidx_room" } +androidx_biometrics = { group = "androidx.biometric", name = "biometric", version.ref = "androidx_biometrics" } +androidx_navigation = { group = "androidx.navigation", name = "navigation-compose", version.ref = "androidx_navigation" } +google_accompanist = { group = "com.google.accompanist", name = "accompanist-systemuicontroller", version.ref = "google_accompanist" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +androidx_test_ext_junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx_test_ext_junit" } +androidx_test_espresso_core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "androidx_test_espresso" } diff --git a/CredentialProvider/MyVault/gradle/wrapper/gradle-wrapper.properties b/CredentialProvider/MyVault/gradle/wrapper/gradle-wrapper.properties index 55da2ea3..f532d297 100644 --- a/CredentialProvider/MyVault/gradle/wrapper/gradle-wrapper.properties +++ b/CredentialProvider/MyVault/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Mar 27 12:33:40 IST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/CredentialProvider/MyVault/init.gradle.kts b/CredentialProvider/MyVault/init.gradle.kts index 34c7d35b..0bb5bc7e 100644 --- a/CredentialProvider/MyVault/init.gradle.kts +++ b/CredentialProvider/MyVault/init.gradle.kts @@ -14,20 +14,6 @@ * limitations under the License. */ -val ktlintVersion = "1.0.1" - -initscript { - val spotlessVersion = "6.23.3" - - repositories { - mavenCentral() - } - - dependencies { - classpath("com.diffplug.spotless:spotless-plugin-gradle:$spotlessVersion") - } -} - rootProject { subprojects { apply() @@ -35,10 +21,8 @@ rootProject { kotlin { target("**/*.kt") targetExclude("**/build/**/*.kt") - ktlint(ktlintVersion).editorConfigOverride( - mapOf( - "android" to "true", - ), + ktlint(libs.versions.ktlint.get()).editorConfigOverride( + mapOf("android" to "true") ) licenseHeaderFile(rootProject.file("spotless/copyright.kt")) } diff --git a/CredentialProvider/MyVault/settings.gradle.kts b/CredentialProvider/MyVault/settings.gradle.kts index 2db4150d..12199dc6 100644 --- a/CredentialProvider/MyVault/settings.gradle.kts +++ b/CredentialProvider/MyVault/settings.gradle.kts @@ -1,3 +1,19 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + pluginManagement { repositories { google { @@ -12,7 +28,7 @@ pluginManagement { } } dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) repositories { google() mavenCentral() @@ -21,4 +37,3 @@ dependencyResolutionManagement { rootProject.name = "MyVault" include(":app") - \ No newline at end of file diff --git a/Fido2/app/build.gradle b/Fido2/app/build.gradle index 75fd03fd..bdb8cbf7 100644 --- a/Fido2/app/build.gradle +++ b/Fido2/app/build.gradle @@ -20,11 +20,12 @@ apply plugin: 'kotlin-kapt' apply plugin: 'dagger.hilt.android.plugin' android { - compileSdkVersion 31 + namespace 'com.google.android.gms.identity.sample.fido2' + compileSdk 35 defaultConfig { applicationId 'com.google.android.gms.identity.sample.fido2' - minSdkVersion 21 - targetSdkVersion 31 + minSdk 21 + targetSdk 35 versionCode 1 versionName '1.0' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' @@ -46,13 +47,14 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '17' } buildFeatures { + buildConfig true dataBinding true } buildTypes { @@ -68,48 +70,27 @@ android { } dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation libs.kotlin.stdlib + implementation libs.material.design + implementation libs.play.services.fido - implementation 'com.google.android.gms:play-services-fido:19.0.0-beta' + implementation libs.androidx.appcompat + implementation libs.androidx.fragment.ktx + implementation libs.androidx.core.ktx + implementation libs.androidx.constraintlayout + implementation libs.androidx.datastore.preferences - implementation 'androidx.appcompat:appcompat:1.3.1' - implementation 'androidx.fragment:fragment-ktx:1.3.6' + implementation libs.bundles.androidx.lifecycle + implementation libs.bundles.kotlin.coroutines + implementation libs.bundles.okhttp - implementation 'androidx.core:core-ktx:1.6.0' - implementation 'androidx.constraintlayout:constraintlayout:2.1.0' + // Hilt + implementation libs.dagger.hilt.android + kapt libs.androidx.hilt.compiler + kapt libs.dagger.hilt.compiler - implementation "androidx.datastore:datastore-preferences:1.0.0" - - def coroutine_version = '1.5.0' - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutine_version" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutine_version" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutine_version" - - def hilt_version = '2.38.1' - implementation "com.google.dagger:hilt-android:$hilt_version" - kapt "com.google.dagger:hilt-compiler:$hilt_version" - kapt "androidx.hilt:hilt-compiler:1.0.0" - - def lifecycle_version = '2.4.0-alpha03' - implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" - implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" - testImplementation 'androidx.arch.core:core-testing:2.1.0' - - implementation 'com.google.android.material:material:1.4.0' - - def okhttp_version = '4.9.0' - implementation "com.squareup.okhttp3:okhttp:$okhttp_version" - implementation "com.squareup.okhttp3:logging-interceptor:$okhttp_version" - implementation "ru.gildor.coroutines:kotlin-coroutines-okhttp:1.0" - - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test:runner:1.4.0' - androidTestImplementation 'androidx.test:rules:1.4.0' - - androidTestImplementation 'androidx.test.ext:junit:1.1.3' - androidTestImplementation 'androidx.test.ext:truth:1.4.0' - androidTestImplementation 'com.google.truth:truth:1.1.2' - - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + testImplementation libs.junit + testImplementation libs.androidx.core.testing + debugImplementation libs.androidx.test.monitor + androidTestImplementation libs.bundles.androidx.test } diff --git a/Fido2/app/src/main/AndroidManifest.xml b/Fido2/app/src/main/AndroidManifest.xml index ca81adc5..83472b6f 100644 --- a/Fido2/app/src/main/AndroidManifest.xml +++ b/Fido2/app/src/main/AndroidManifest.xml @@ -16,8 +16,7 @@ --> + xmlns:tools="http://schemas.android.com/tools"> diff --git a/Fido2/app/src/main/java/com/google/android/gms/identity/sample/fido2/api/AuthApi.kt b/Fido2/app/src/main/java/com/google/android/gms/identity/sample/fido2/api/AuthApi.kt index 94588cc5..3e58f2d4 100644 --- a/Fido2/app/src/main/java/com/google/android/gms/identity/sample/fido2/api/AuthApi.kt +++ b/Fido2/app/src/main/java/com/google/android/gms/identity/sample/fido2/api/AuthApi.kt @@ -153,7 +153,7 @@ class AuthApi @Inject constructor( sessionId: String, credential: PublicKeyCredential ): ApiResult> { - val rawId = credential.rawId.toBase64() + val rawId = credential.rawId!!.toBase64() val response = credential.response as AuthenticatorAttestationResponse val call = client.newCall( @@ -242,7 +242,7 @@ class AuthApi @Inject constructor( sessionId: String, credential: PublicKeyCredential ): ApiResult> { - val rawId = credential.rawId.toBase64() + val rawId = credential.rawId!!.toBase64() val response = credential.response as AuthenticatorAssertionResponse val call = client.newCall( @@ -304,6 +304,7 @@ class AuthApi @Inject constructor( JsonReader(body.byteStream().bufferedReader()).use { reader -> reader.beginObject() while (reader.hasNext()) { + // TODO: unhandled IllegalStateException: Expected a name but was BEGIN_OBJECT. when (reader.nextName()) { "user" -> builder.setUser(parseUser(reader)) "challenge" -> builder.setChallenge(reader.nextString().decodeBase64()) diff --git a/Fido2/app/src/main/java/com/google/android/gms/identity/sample/fido2/repository/AuthRepository.kt b/Fido2/app/src/main/java/com/google/android/gms/identity/sample/fido2/repository/AuthRepository.kt index 39053cbd..36853e45 100644 --- a/Fido2/app/src/main/java/com/google/android/gms/identity/sample/fido2/repository/AuthRepository.kt +++ b/Fido2/app/src/main/java/com/google/android/gms/identity/sample/fido2/repository/AuthRepository.kt @@ -249,7 +249,7 @@ class AuthRepository @Inject constructor( suspend fun registerResponse(credential: PublicKeyCredential) { try { val sessionId = dataStore.read(SESSION_ID)!! - val credentialId = credential.rawId.toBase64() + val credentialId = credential.rawId!!.toBase64() when (val result = api.registerResponse(sessionId, credential)) { ApiResult.SignedOutFromServer -> forceSignOut() is ApiResult.Success -> { @@ -309,7 +309,7 @@ class AuthRepository @Inject constructor( try { val username = dataStore.read(USERNAME)!! val sessionId = dataStore.read(SESSION_ID)!! - val credentialId = credential.rawId.toBase64() + val credentialId = credential.rawId!!.toBase64() when (val result = api.signinResponse(sessionId, credential)) { ApiResult.SignedOutFromServer -> forceSignOut() is ApiResult.Success -> { diff --git a/Fido2/build.gradle b/Fido2/build.gradle index 909ecfcc..5d877708 100644 --- a/Fido2/build.gradle +++ b/Fido2/build.gradle @@ -13,27 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -buildscript { - ext.kotlin_version = '1.5.21' - repositories { - google() - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:7.0.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38.1' - } -} - -allprojects { - repositories { - google() - mavenCentral() - } +plugins { + alias(libs.plugins.android.application) apply false + alias(libs.plugins.android.library) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.hilt.android) apply false } -task clean(type: Delete) { - delete rootProject.buildDir +tasks.register('clean', Delete) { + delete rootProject.fileTree("build") } diff --git a/Fido2/gradle.properties b/Fido2/gradle.properties index d79feb72..efb4bd36 100644 --- a/Fido2/gradle.properties +++ b/Fido2/gradle.properties @@ -32,7 +32,7 @@ org.gradle.jvmargs=-Xmx1536m # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX -android.enableJetifier=true +android.enableJetifier=false # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official diff --git a/Fido2/gradle/libs.versions.toml b/Fido2/gradle/libs.versions.toml new file mode 100644 index 00000000..59cea083 --- /dev/null +++ b/Fido2/gradle/libs.versions.toml @@ -0,0 +1,70 @@ +[versions] +android_gradle_plugin = '8.6.0' +hilt_android = '2.52' +androidx_hilt = '1.2.0' +kotlin = '2.0.20' +kotlin_coroutines_okhttp = '1.0' +kotlinx_coroutines = '1.7.3' +junit = '4.13.2' +google_truth = '1.4.0' +material_design = '1.12.0' +okhttp = '4.12.0' +play_services_fido = '21.1.0' +androidx_core = '1.13.1' +androidx_core_testing = '2.2.0' +androidx_appcompat = '1.7.0' +androidx_constraintlayout = '2.1.4' +androidx_datastore_preferences = '1.1.1' +androidx_fragment_ktx = '1.8.3' +androidx_lifecycle = '2.8.5' +androidx_test_ext_junit = '1.2.1' +androidx_test_ext_truth = '1.6.0' +androidx_test_rules = '1.6.1' +androidx_test_runner = '1.6.2' +androidx_test_monitor = '1.7.2' +androidx_test_espresso = '3.6.1' + + +[plugins] +android_application = { id = "com.android.application", version.ref = "android_gradle_plugin" } +android_library = { id = "com.android.library", version.ref = "android_gradle_plugin" } +kotlin_android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +hilt_android = { id = "com.google.dagger.hilt.android", version.ref = "hilt_android" } + + +[libraries] +androidx_hilt_compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "androidx_hilt" } +dagger_hilt_android = { module = "com.google.dagger:hilt-android", version.ref = "hilt_android" } +dagger_hilt_compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt_android" } +androidx_datastore_preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "androidx_datastore_preferences" } +androidx_fragment_ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "androidx_fragment_ktx" } +junit = { module = "junit:junit", version.ref = "junit" } +kotlin_stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } +kotlin_coroutines_okhttp = { module = "ru.gildor.coroutines:kotlin-coroutines-okhttp", version.ref = "kotlin_coroutines_okhttp" } +kotlinx_coroutines_core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx_coroutines" } +kotlinx_coroutines_android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx_coroutines" } +kotlinx_coroutines_play_services = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-play-services", version.ref = "kotlinx_coroutines" } +material_design = { module = "com.google.android.material:material", version.ref = "material_design" } +androidx_core_ktx = { module = "androidx.core:core-ktx", version.ref = "androidx_core" } +androidx_core_testing = { module = "androidx.arch.core:core-testing", version.ref = "androidx_core_testing" } +androidx_appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx_appcompat" } +androidx_constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidx_constraintlayout" } +okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } +okhttp_logging_interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" } +play_services_fido = { module = "com.google.android.gms:play-services-fido", version.ref = "play_services_fido" } +androidx_lifecycle_runtime_ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidx_lifecycle" } +androidx_lifecycle_livedata_ktx = { module = "androidx.lifecycle:lifecycle-livedata-ktx", version.ref = "androidx_lifecycle" } +androidx_lifecycle_viewmodel_ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx_lifecycle" } +androidx_test_monitor = { module = "androidx.test:monitor", version.ref = "androidx_test_monitor" } +androidx_test_ext_junit = { module = "androidx.test.ext:junit", version.ref = "androidx_test_ext_junit" } +androidx_test_ext_truth = { module = "androidx.test.ext:truth", version.ref = "androidx_test_ext_truth" } +androidx_test_rules = { module = "androidx.test:rules", version.ref = "androidx_test_rules" } +androidx_test_runner = { module = "androidx.test:runner", version.ref = "androidx_test_runner" } +androidx_test_espresso_core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx_test_espresso" } +google_truth = { module = "com.google.truth:truth", version.ref = "google_truth" } + +[bundles] +kotlin_coroutines = ["kotlin_coroutines_okhttp", "kotlinx_coroutines_core", "kotlinx_coroutines_android", "kotlinx_coroutines_play_services"] +androidx_lifecycle = ["androidx_lifecycle_runtime_ktx", "androidx_lifecycle_livedata_ktx", "androidx_lifecycle_viewmodel_ktx"] +androidx_test = ["androidx_test_ext_junit", "androidx_test_ext_truth", "google_truth", "androidx_test_rules", "androidx_test_runner", "androidx_test_espresso_core"] +okhttp = ["okhttp", "okhttp_logging_interceptor"] diff --git a/Fido2/gradle/wrapper/gradle-wrapper.properties b/Fido2/gradle/wrapper/gradle-wrapper.properties index 88441a21..9ca29711 100644 --- a/Fido2/gradle/wrapper/gradle-wrapper.properties +++ b/Fido2/gradle/wrapper/gradle-wrapper.properties @@ -19,4 +19,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip diff --git a/Fido2/settings.gradle b/Fido2/settings.gradle index 33e604ea..30285a78 100644 --- a/Fido2/settings.gradle +++ b/Fido2/settings.gradle @@ -13,5 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +pluginManagement { + repositories { + gradlePluginPortal() + google() + mavenCentral() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + mavenCentral() + } +} +rootProject.name = "Fido2" include ':app' diff --git a/IdentityCredential/app/.gitignore b/IdentityCredential/app/.gitignore new file mode 100644 index 00000000..d12fa1a5 --- /dev/null +++ b/IdentityCredential/app/.gitignore @@ -0,0 +1 @@ +/google-services.json diff --git a/SmsVerification/app/build.gradle b/SmsVerification/app/build.gradle index 08e77bcc..bec32480 100644 --- a/SmsVerification/app/build.gradle +++ b/SmsVerification/app/build.gradle @@ -1,23 +1,15 @@ -apply plugin: 'com.android.application' +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.google.services) +} android { - compileSdkVersion 30 - buildToolsVersion '30.0.3' - - signingConfigs { - debug { - // Note: mutual dependency between this file, and SMS generated by - // server. (See README.md.) - if (new File('../debug.keystore').exists()) { - storeFile file('../debug.keystore') - } - } - } - + namespace "com.google.samples.smartlock.sms_verify" + compileSdk 35 defaultConfig { applicationId "com.google.samples.smartlock.sms_verify" - minSdkVersion 23 - targetSdkVersion 30 + minSdk 23 + targetSdk 35 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -28,28 +20,34 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } -} - -repositories { - flatDir { - dirs 'libs' + signingConfigs { + debug { + // Note: mutual dependency between this file, and SMS generated by server. + // See README.md. + if (new File('../debug.keystore').exists()) { + storeFile file('../debug.keystore') + } + } } } dependencies { - androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { - exclude group: 'com.android.support', module: 'support-annotations' - }) + constraints { + //noinspection ForeignDelegate + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") { + because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib") + } + //noinspection ForeignDelegate + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") { + because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib") + } + } - implementation 'androidx.appcompat:appcompat:1.3.0' - implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0' - implementation 'com.android.volley:volley:1.2.0' - implementation 'com.google.android.gms:play-services-base:17.6.0' - implementation 'com.google.android.gms:play-services-identity:17.0.0' - implementation 'com.google.android.gms:play-services-auth:19.0.0' - implementation 'com.google.android.gms:play-services-auth-api-phone:17.5.1' - testImplementation 'junit:junit:4.13.2' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' -} + implementation libs.bundles.androidx + implementation libs.bundles.google.play.services + implementation libs.volley -apply plugin: 'com.google.gms.google-services' + testImplementation libs.junit + debugImplementation libs.androidx.test.monitor + androidTestImplementation libs.bundles.androidx.test +} diff --git a/SmsVerification/app/src/androidTest/java/com/google/samples/smartlock/sms_verify/ExampleInstrumentedTest.java b/SmsVerification/app/src/androidTest/java/com/google/samples/smartlock/sms_verify/ExampleInstrumentedTest.java index 5bd25e38..99ee9dcc 100644 --- a/SmsVerification/app/src/androidTest/java/com/google/samples/smartlock/sms_verify/ExampleInstrumentedTest.java +++ b/SmsVerification/app/src/androidTest/java/com/google/samples/smartlock/sms_verify/ExampleInstrumentedTest.java @@ -1,14 +1,15 @@ package com.google.samples.smartlock.sms_verify; import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.*; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + /** * Instrumentation test, which will execute on an Android device. * @@ -19,7 +20,7 @@ public class ExampleInstrumentedTest { @Test public void useAppContext() throws Exception { // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); assertEquals("com.google.samples.smartlock.sms_verify", appContext.getPackageName()); } diff --git a/SmsVerification/app/src/main/AndroidManifest.xml b/SmsVerification/app/src/main/AndroidManifest.xml index fda43d32..08b45461 100644 --- a/SmsVerification/app/src/main/AndroidManifest.xml +++ b/SmsVerification/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ - + @@ -10,28 +10,33 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> - + - - + + - + + - - + android:parentActivityName=".ui.MainActivity" + android:exported="false"/> + \ No newline at end of file diff --git a/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/ApiHelper.java b/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/ApiHelper.java index 1688bbdb..c8e403b8 100644 --- a/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/ApiHelper.java +++ b/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/ApiHelper.java @@ -6,6 +6,8 @@ import android.text.TextUtils; import android.util.Log; +import androidx.annotation.NonNull; + import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; @@ -39,13 +41,13 @@ public ApiHelper(Context base) { } public void request(String phoneNo, final RequestResponse successReceiver, - final ApiError failureReceiver) { + @NonNull final ApiError failureReceiver) { HashMap params = new HashMap<>(); params.put("phone", phoneNo); sendRequest(R.string.url_request, params, new Response.Listener() { @Override public void onResponse(JSONObject response) { - Boolean success = false; + boolean success = false; try { success = response.getBoolean(RESPONSE_SUCCESS); } catch (JSONException e) { @@ -53,12 +55,7 @@ public void onResponse(JSONObject response) { } successReceiver.onResponse(success); } - }, new Response.ErrorListener() { - @Override - public void onErrorResponse(VolleyError error) { - failureReceiver.onError(error); - } - }); + }, failureReceiver::onError); } public void verify(String phoneNo, String smsMessage, final VerifyResponse successReceiver, @@ -70,7 +67,7 @@ public void verify(String phoneNo, String smsMessage, final VerifyResponse succe sendRequest(R.string.url_verify, params, new Response.Listener() { @Override public void onResponse(JSONObject response) { - Boolean success = false; + boolean success = false; String phoneNo = null; try { success = response.getBoolean(RESPONSE_SUCCESS); @@ -95,7 +92,7 @@ public void reset(String phoneNo, final ResetResponse successReceiver, sendRequest(R.string.url_reset, params, new Response.Listener() { @Override public void onResponse(JSONObject response) { - Boolean success = false; + boolean success = false; try { success = response.getBoolean(RESPONSE_SUCCESS); } catch (JSONException e) { @@ -111,12 +108,12 @@ public void onErrorResponse(VolleyError error) { }); } - protected void sendRequest(int urlId, HashMap params, Response.Listener success, + protected void sendRequest(int urlId, HashMap params, Response.Listener success, Response.ErrorListener failure) { sendRequest(getString(urlId), params, success, failure); } - protected void sendRequest(String url, HashMap params, Response.Listener success, + protected void sendRequest(String url, HashMap params, Response.Listener success, Response.ErrorListener failure) { String secret = prefsHelper.getSecretOverride(null); if (TextUtils.isEmpty(secret)) { @@ -141,7 +138,7 @@ protected void sendRequest(String url, HashMap params, Response. } } - private static int getGmsVersion(Context context) { + private static int getGmsVersion(@NonNull Context context) { try { return context.getPackageManager() .getPackageInfo("com.google.android.gms", 0 ).versionCode; diff --git a/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/PhoneNumberVerifier.java b/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/PhoneNumberVerifier.java index 7e5b0c3f..8b4b11a4 100644 --- a/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/PhoneNumberVerifier.java +++ b/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/PhoneNumberVerifier.java @@ -1,12 +1,16 @@ package com.google.samples.smartlock.sms_verify; +import android.annotation.SuppressLint; import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -14,6 +18,8 @@ import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; import androidx.localbroadcastmanager.content.LocalBroadcastManager; + +import android.os.Looper; import android.util.Log; import android.widget.Toast; @@ -86,6 +92,7 @@ public static void stopActionVerify(Context context) { } @Override + @SuppressLint("UnspecifiedRegisterReceiverFlag") public void onCreate() { super.onCreate(); if (smsReceiver == null) { @@ -97,7 +104,11 @@ public void onCreate() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(SmsRetriever.SMS_RETRIEVED_ACTION); - getApplicationContext().registerReceiver(smsReceiver, intentFilter); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + getApplicationContext().registerReceiver(smsReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED); + } else { + getApplicationContext().registerReceiver(smsReceiver, intentFilter); + } api = new ApiHelper(this); } @@ -143,6 +154,7 @@ public IBinder onBind(Intent intent) { } public void notifyStatus(int status, @Nullable String phoneNo) { + if (status < STATUS_STARTED || status >= STATUS_RESPONSE_VERIFIED) { isVerifying = false; } else { @@ -264,6 +276,8 @@ public static boolean isVerifying() { return isVerifying; } + @NonNull + @SuppressWarnings("deprecation") private Notification getNotification(Context context, int status, @Nullable String phoneNo) { if (phoneNo != null) { Intent cancelI = new Intent(this, PhoneNumberVerifier.class); @@ -276,7 +290,18 @@ private Notification getNotification(Context context, int status, @Nullable Stri getString(R.string.cancel_verification), cancelPI ).build(); - notification = new NotificationCompat.Builder(context) + NotificationCompat.Builder builder = null; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + NotificationChannel notificationChannel = new NotificationChannel("SmsVerification", "SmsVerification", NotificationManager.IMPORTANCE_DEFAULT); + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.createNotificationChannel(notificationChannel); + builder = new NotificationCompat.Builder(getApplicationContext(), notificationChannel.getId()); + } else { + //noinspection deprecation + builder = new NotificationCompat.Builder(getApplicationContext()); + } + + notification = builder .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(context.getString(R.string.phone_verify_notify_title)) .setContentText(context.getString(R.string.phone_verify_notify_message, phoneNo)) @@ -290,13 +315,8 @@ private Notification getNotification(Context context, int status, @Nullable Stri } class SmsBrReceiver extends BroadcastReceiver { - Handler h = new Handler(); - Runnable r = new Runnable() { - @Override - public void run() { - doTimeout(); - } - }; + Handler h = new Handler(Looper.getMainLooper()); + Runnable r = this::doTimeout; public void setTimeout() { h.postDelayed(r, MAX_TIMEOUT); @@ -307,6 +327,7 @@ public void cancelTimeout() { } @Override + @SuppressWarnings({"deprecation", "RedundantSuppression"}) public void onReceive(Context context, Intent intent) { if (intent == null) { return; @@ -317,20 +338,29 @@ public void onReceive(Context context, Intent intent) { cancelTimeout(); notifyStatus(STATUS_RESPONSE_RECEIVED, null); Bundle extras = intent.getExtras(); - Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS); - switch(status.getStatusCode()) { - case CommonStatusCodes.SUCCESS: - String smsMessage = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE); - Log.d(TAG, "Retrieved sms code: " + smsMessage); - if (smsMessage != null) { - verifyMessage(smsMessage); + if (extras != null) { + Status status; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) { + status = extras.getParcelable(SmsRetriever.EXTRA_STATUS, Status.class); + } else { + status = (Status) extras.get(SmsRetriever.EXTRA_STATUS); + } + if (status != null) { + switch (status.getStatusCode()) { + case CommonStatusCodes.SUCCESS: + String smsMessage = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE); + Log.d(TAG, "Retrieved sms code: " + smsMessage); + if (smsMessage != null) { + verifyMessage(smsMessage); + } + break; + case CommonStatusCodes.TIMEOUT: + doTimeout(); + break; + default: + break; } - break; - case CommonStatusCodes.TIMEOUT: - doTimeout(); - break; - default: - break; + } } } } diff --git a/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/PrefsHelper.java b/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/PrefsHelper.java index 3cdfadb8..d1df13a9 100644 --- a/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/PrefsHelper.java +++ b/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/PrefsHelper.java @@ -2,8 +2,9 @@ import android.content.Context; import android.content.SharedPreferences; -import android.preference.PreferenceManager; + import androidx.annotation.Nullable; +import androidx.preference.PreferenceManager; /** * Created by pmatthews on 9/14/16. diff --git a/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/ui/MainActivity.java b/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/ui/MainActivity.java index b3f73a9a..f0e8cf0e 100644 --- a/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/ui/MainActivity.java +++ b/SmsVerification/app/src/main/java/com/google/samples/smartlock/sms_verify/ui/MainActivity.java @@ -5,6 +5,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; + +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; @@ -73,17 +75,14 @@ public boolean onCreateOptionsMenu(Menu menu) { } @Override - public boolean onOptionsItemSelected(MenuItem item) { - Intent i; - switch (item.getItemId()) { - case R.id.menu_settings: - i = new Intent(this, SettingsActivity.class); - startActivity(i); - break; - case R.id.menu_reset_verification: - i = new Intent(this, ResetActivity.class); - startActivity(i); - break; + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + Intent intent; + if (item.getItemId() == R.id.menu_settings) { + intent = new Intent(this, SettingsActivity.class); + startActivity(intent); + } else if (item.getItemId() == R.id.menu_reset_verification){ + intent = new Intent(this, ResetActivity.class); + startActivity(intent); } return super.onOptionsItemSelected(item); } diff --git a/SmsVerification/build.gradle b/SmsVerification/build.gradle index 649e1fbe..92a292b7 100644 --- a/SmsVerification/build.gradle +++ b/SmsVerification/build.gradle @@ -1,26 +1,20 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - google() - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:4.2.1' - classpath 'com.google.gms:google-services:4.3.8' // provides com.google.gms.google-services plugin - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } +plugins { + alias(libs.plugins.android.application) apply false + alias(libs.plugins.android.library) apply false + alias(libs.plugins.google.services) apply false } allprojects { - repositories { - google() - mavenCentral() + gradle.projectsEvaluated { + tasks.withType(JavaCompile).tap { + configureEach { + options.compilerArgs << "-Xlint:deprecation" + } + } } } -task clean(type: Delete) { - delete rootProject.buildDir +tasks.register('clean', Delete) { + delete rootProject.fileTree("build") } diff --git a/SmsVerification/gradle.properties b/SmsVerification/gradle.properties index ca84fc49..e4cf3331 100644 --- a/SmsVerification/gradle.properties +++ b/SmsVerification/gradle.properties @@ -17,5 +17,4 @@ org.gradle.jvmargs=-Xmx1536m # org.gradle.parallel=true android.useAndroidX=true -android.enableJetifier=true - +android.enableJetifier=false diff --git a/SmsVerification/gradle/libs.versions.toml b/SmsVerification/gradle/libs.versions.toml new file mode 100644 index 00000000..37b3ccf9 --- /dev/null +++ b/SmsVerification/gradle/libs.versions.toml @@ -0,0 +1,44 @@ +[versions] +android_gradle_plugin = '8.6.0' +google_services_plugin = '4.4.2' +junit = '4.13.2' +volley = '1.2.1' +androidx_appcompat = '1.7.0' +androidx_constraint_layout = '2.1.4' +androidx_localbroadcast_manager = '1.1.0' +androidx_preference = '1.2.1' +androidx_test_ext_junit = '1.2.1' +androidx_test_monitor = '1.7.2' +androidx_test_core = '1.6.1' +androidx_test_espresso = '3.6.1' +google_play_services_base = '18.5.0' +google_play_services_identity = '18.1.0' +# provides com.google.android.gms.auth.api.credentials +google_play_services_auth = '20.5.0' +google_play_services_auth_api_phone = '18.1.0' + +[plugins] +android_application = { id = "com.android.application", version.ref = "android_gradle_plugin" } +android_library = { id = "com.android.library", version.ref = "android_gradle_plugin" } +google_services = { id = "com.google.gms.google-services", version.ref = "google_services_plugin" } + +[libraries] +junit = { module = "junit:junit", version.ref = "junit" } +volley = { module = "com.android.volley:volley", version.ref = "volley" } +androidx_appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx_appcompat" } +androidx_constraint_layout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidx_constraint_layout" } +androidx_localbroadcast_manager = { module = "androidx.localbroadcastmanager:localbroadcastmanager", version.ref = "androidx_localbroadcast_manager" } +androidx_preference = { module = "androidx.preference:preference", version.ref = "androidx_preference" } +androidx_test_monitor = { module = "androidx.test:monitor", version.ref = "androidx_test_monitor" } +androidx_test_core = { module = "androidx.test:core", version.ref = "androidx_test_core" } +androidx_test_ext_junit = { module = "androidx.test.ext:junit", version.ref = "androidx_test_ext_junit" } +androidx_test_espresso_core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx_test_espresso" } +google_play_services_base = { module = "com.google.android.gms:play-services-base", version.ref = "google_play_services_base" } +google_play_services_identity = { module = "com.google.android.gms:play-services-identity", version.ref = "google_play_services_identity" } +google_play_services_auth = { module = "com.google.android.gms:play-services-auth", version.ref = "google_play_services_auth" } +google_play_services_auth_api_phone = { module = "com.google.android.gms:play-services-auth-api-phone", version.ref = "google_play_services_auth_api_phone" } + +[bundles] +androidx = ["androidx_appcompat", "androidx_constraint_layout", "androidx_localbroadcast_manager", "androidx_preference"] +androidx_test = ["androidx_test_core", "androidx_test_ext_junit", "androidx_test_espresso_core"] +google_play_services = ["google_play_services_base", "google_play_services_identity", "google_play_services_auth", "google_play_services_auth_api_phone"] diff --git a/SmsVerification/gradle/wrapper/gradle-wrapper.properties b/SmsVerification/gradle/wrapper/gradle-wrapper.properties index 61738398..4d6b48fd 100644 --- a/SmsVerification/gradle/wrapper/gradle-wrapper.properties +++ b/SmsVerification/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip diff --git a/SmsVerification/settings.gradle b/SmsVerification/settings.gradle index e7b4def4..ab91d2d4 100644 --- a/SmsVerification/settings.gradle +++ b/SmsVerification/settings.gradle @@ -1 +1,37 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +pluginManagement { + repositories { + gradlePluginPortal() + google() + mavenCentral() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + mavenCentral() + } +} +rootProject.name = "SmsVerification" include ':app'