Skip to content
Snippets Groups Projects
Commit e7073a64 authored by Shuang Hao's avatar Shuang Hao Committed by Android (Google) Code Review
Browse files

Merge "Introduce Hilt to replace manual dependency injection." into main

parents 092aeff1 50fdb1a0
No related branches found
No related tags found
No related merge requests found
Showing
with 47 additions and 88 deletions
......@@ -16,5 +16,6 @@ android_library {
"androidx.core_core-ktx",
"androidx.credentials_credentials",
"guava",
"hilt_android",
],
}
......@@ -25,8 +25,11 @@ import android.util.Log
import com.android.credentialmanager.TAG
import com.android.credentialmanager.model.Password
import com.android.credentialmanager.model.Request
import javax.inject.Inject
import javax.inject.Singleton
class PasswordRepository {
@Singleton
class PasswordRepository @Inject constructor() {
suspend fun selectPassword(
password: Password,
......
......@@ -16,17 +16,20 @@
package com.android.credentialmanager.repository
import android.app.Application
import android.content.Intent
import android.content.pm.PackageManager
import android.util.Log
import com.android.credentialmanager.TAG
import com.android.credentialmanager.model.Request
import com.android.credentialmanager.parse
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject
import javax.inject.Singleton
class RequestRepository(
private val application: Application,
@Singleton
class RequestRepository @Inject constructor(
private val packageManager: PackageManager,
) {
private val _requests = MutableStateFlow<Request?>(null)
......@@ -34,7 +37,7 @@ class RequestRepository(
suspend fun processRequest(intent: Intent, previousIntent: Intent? = null) {
val request = intent.parse(
packageManager = application.packageManager,
packageManager = packageManager,
previousIntent = previousIntent
)
......
......@@ -22,6 +22,7 @@ android_app {
static_libs: [
"CredentialManagerShared",
"hilt_android",
"Horologist",
"PlatformComposeCore",
"androidx.activity_activity-compose",
......
......@@ -29,13 +29,13 @@ import com.android.credentialmanager.ui.WearApp
import com.android.credentialmanager.ui.screens.single.password.SinglePasswordScreen
import com.google.android.horologist.annotations.ExperimentalHorologistApi
import com.google.android.horologist.compose.layout.belowTimeTextPreview
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
class CredentialSelectorActivity : ComponentActivity() {
@AndroidEntryPoint(ComponentActivity::class)
class CredentialSelectorActivity : Hilt_CredentialSelectorActivity() {
private val viewModel: CredentialSelectorViewModel by viewModels {
CredentialSelectorViewModel.Factory
}
private val viewModel: CredentialSelectorViewModel by viewModels()
@OptIn(ExperimentalHorologistApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
......
......@@ -17,18 +17,7 @@
package com.android.credentialmanager
import android.app.Application
import com.android.credentialmanager.di.inject
import com.android.credentialmanager.repository.PasswordRepository
import com.android.credentialmanager.repository.RequestRepository
import dagger.hilt.android.HiltAndroidApp
class CredentialSelectorApp : Application() {
lateinit var requestRepository: RequestRepository
lateinit var passwordRepository: PasswordRepository
override fun onCreate() {
super.onCreate()
inject()
}
}
\ No newline at end of file
@HiltAndroidApp(Application::class)
class CredentialSelectorApp : Hilt_CredentialSelectorApp()
\ No newline at end of file
......@@ -18,20 +18,20 @@ package com.android.credentialmanager
import android.content.Intent
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import com.android.credentialmanager.model.Request
import com.android.credentialmanager.repository.RequestRepository
import com.android.credentialmanager.ui.mappers.toGet
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import javax.inject.Inject
class CredentialSelectorViewModel(
@HiltViewModel
class CredentialSelectorViewModel @Inject constructor(
private val requestRepository: RequestRepository,
) : ViewModel() {
......@@ -56,22 +56,6 @@ class CredentialSelectorViewModel(
requestRepository.processRequest(intent = intent, previousIntent = previousIntent)
}
}
companion object {
val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras
): T {
val application = checkNotNull(extras[APPLICATION_KEY])
return CredentialSelectorViewModel(
requestRepository = (application as CredentialSelectorApp).requestRepository,
) as T
}
}
}
}
sealed class CredentialSelectorUiState {
......
package com.android.credentialmanager.di
import android.content.Context
import android.content.pm.PackageManager
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
@Module
@InstallIn(SingletonComponent::class)
internal object AppModule {
@Provides
@JvmStatic
fun providePackageManager(@ApplicationContext context: Context): PackageManager =
context.packageManager
}
package com.android.credentialmanager.di
import android.app.Application
import com.android.credentialmanager.CredentialSelectorApp
import com.android.credentialmanager.repository.PasswordRepository
import com.android.credentialmanager.repository.RequestRepository
// TODO b/301601582 add Hilt for dependency injection
fun CredentialSelectorApp.inject() {
requestRepository = requestRepository(application = this)
passwordRepository = passwordRepository()
}
private fun requestRepository(
application: Application,
): RequestRepository = RequestRepository(
application = application,
)
private fun passwordRepository(): PasswordRepository = PasswordRepository()
......@@ -47,8 +47,7 @@ fun SinglePasswordScreen(
columnState: ScalingLazyColumnState,
onCloseApp: () -> Unit,
modifier: Modifier = Modifier,
viewModel: SinglePasswordScreenViewModel =
viewModel(factory = SinglePasswordScreenViewModel.Factory),
viewModel: SinglePasswordScreenViewModel = viewModel(),
) {
viewModel.initialize()
......
......@@ -21,11 +21,7 @@ import android.util.Log
import androidx.activity.result.IntentSenderRequest
import androidx.annotation.MainThread
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import com.android.credentialmanager.CredentialSelectorApp
import com.android.credentialmanager.TAG
import com.android.credentialmanager.ktx.getIntentSenderRequest
import com.android.credentialmanager.model.Password
......@@ -33,12 +29,15 @@ import com.android.credentialmanager.model.Request
import com.android.credentialmanager.repository.PasswordRepository
import com.android.credentialmanager.repository.RequestRepository
import com.android.credentialmanager.ui.model.PasswordUiModel
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import javax.inject.Inject
class SinglePasswordScreenViewModel(
@HiltViewModel
class SinglePasswordScreenViewModel @Inject constructor(
private val requestRepository: RequestRepository,
private val passwordRepository: PasswordRepository,
) : ViewModel() {
......@@ -105,23 +104,6 @@ class SinglePasswordScreenViewModel(
_uiState.value = SinglePasswordScreenUiState.Completed
}
}
companion object {
val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras
): T {
val application = checkNotNull(extras[APPLICATION_KEY])
return SinglePasswordScreenViewModel(
requestRepository = (application as CredentialSelectorApp).requestRepository,
passwordRepository = application.passwordRepository,
) as T
}
}
}
}
sealed class SinglePasswordScreenUiState {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment