summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/CredentialManager/res/values/strings.xml4
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt4
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt22
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt59
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt9
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt9
6 files changed, 97 insertions, 10 deletions
diff --git a/packages/CredentialManager/res/values/strings.xml b/packages/CredentialManager/res/values/strings.xml
index 2f6d1b4bea02..114de89ce82a 100644
--- a/packages/CredentialManager/res/values/strings.xml
+++ b/packages/CredentialManager/res/values/strings.xml
@@ -62,4 +62,8 @@
<string name="locked_credential_entry_label_subtext">Tap to unlock</string>
<!-- Column heading for displaying action chips for managing sign-ins from each credential provider. [CHAR LIMIT=80] -->
<string name="get_dialog_heading_manage_sign_ins">Manage sign-ins</string>
+ <!-- Column heading for displaying option to use sign-ins saved on a different device. [CHAR LIMIT=80] -->
+ <string name="get_dialog_heading_from_another_device">From another device</string>
+ <!-- Headline text for an option to use sign-ins saved on a different device. [CHAR LIMIT=120] -->
+ <string name="get_dialog_option_headline_use_a_different_device">Use a different device</string>
</resources> \ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index b848a47f37de..7e69987f1bf8 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -194,7 +194,7 @@ class CredentialManagerRepo(
)
)
.setRemoteEntry(
- newRemoteEntry("key1", "subkey-1")
+ newRemoteEntry("key2", "subkey-1")
)
.setIsDefaultProvider(true)
.build(),
@@ -252,6 +252,8 @@ class CredentialManagerRepo(
"Open Google Password Manager", "beckett-family@gmail.com"
),
)
+ ).setRemoteEntry(
+ newRemoteEntry("key4", "subkey-1")
).build(),
GetCredentialProviderData.Builder("com.dashlane")
.setCredentialEntries(
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
index df797436baf6..fad9364e3c23 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
@@ -30,6 +30,7 @@ import com.android.credentialmanager.getflow.ActionEntryInfo
import com.android.credentialmanager.getflow.AuthenticationEntryInfo
import com.android.credentialmanager.getflow.CredentialEntryInfo
import com.android.credentialmanager.getflow.ProviderInfo
+import com.android.credentialmanager.getflow.RemoteEntryInfo
import com.android.credentialmanager.jetpack.provider.ActionUi
import com.android.credentialmanager.jetpack.provider.CredentialEntryUi
import com.android.credentialmanager.jetpack.provider.SaveEntryUi
@@ -59,10 +60,11 @@ class GetFlowUtils {
credentialEntryList = getCredentialOptionInfoList(
it.providerFlattenedComponentName, it.credentialEntries, context),
authenticationEntry = getAuthenticationEntry(
- it.providerFlattenedComponentName,
- providerDisplayName,
- providerIcon,
- it.authenticationEntry),
+ it.providerFlattenedComponentName,
+ providerDisplayName,
+ providerIcon,
+ it.authenticationEntry),
+ remoteEntry = getRemoteEntry(it.providerFlattenedComponentName, it.remoteEntry),
actionEntryList = getActionEntryList(
it.providerFlattenedComponentName, it.actionChips, context),
)
@@ -116,6 +118,18 @@ class GetFlowUtils {
)
}
+ private fun getRemoteEntry(providerId: String, remoteEntry: Entry?): RemoteEntryInfo? {
+ // TODO: should also call fromSlice after getting the official jetpack code.
+ if (remoteEntry == null) {
+ return null
+ }
+ return RemoteEntryInfo(
+ providerId = providerId,
+ entryKey = remoteEntry.key,
+ entrySubkey = remoteEntry.subkey,
+ )
+ }
+
private fun getActionEntryList(
providerId: String,
actionEntries: List<Entry>,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index 6fd51dd3b69a..19a032fcf4b8 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -45,6 +45,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@@ -220,16 +221,25 @@ fun AllSignInOptionCard(
)
}
// Locked password manager
- item {
- if (!authenticationEntryList.isEmpty()) {
+ if (!authenticationEntryList.isEmpty()) {
+ item {
LockedCredentials(
authenticationEntryList = authenticationEntryList,
onEntrySelected = onEntrySelected,
)
}
}
- // TODO: Remote action
- // Manage sign-ins
+ // From another device
+ val remoteEntry = providerDisplayInfo.remoteEntry
+ if (remoteEntry != null) {
+ item {
+ RemoteEntryCard(
+ remoteEntry = remoteEntry,
+ onEntrySelected = onEntrySelected,
+ )
+ }
+ }
+ // Manage sign-ins (action chips)
item {
ActionChips(providerInfoList = providerInfoList, onEntrySelected = onEntrySelected)
}
@@ -271,6 +281,47 @@ fun ActionChips(
}
@Composable
+fun RemoteEntryCard(
+ remoteEntry: RemoteEntryInfo,
+ onEntrySelected: (EntryInfo) -> Unit,
+) {
+ Text(
+ text = stringResource(R.string.get_dialog_heading_from_another_device),
+ style = MaterialTheme.typography.labelLarge,
+ modifier = Modifier.padding(vertical = 8.dp)
+ )
+ Card(
+ modifier = Modifier.fillMaxWidth().wrapContentHeight(),
+ shape = MaterialTheme.shapes.medium,
+ ) {
+ Column(
+ modifier = Modifier.fillMaxWidth().wrapContentHeight(),
+ verticalArrangement = Arrangement.spacedBy(2.dp),
+ ) {
+ Entry(
+ onClick = {onEntrySelected(remoteEntry)},
+ icon = {
+ Icon(
+ painter = painterResource(R.drawable.ic_other_devices),
+ contentDescription = null,
+ tint = Color.Unspecified,
+ modifier = Modifier.padding(start = 18.dp)
+ )
+ },
+ label = {
+ Text(
+ text = stringResource(R.string.get_dialog_option_headline_use_a_different_device),
+ style = MaterialTheme.typography.titleLarge,
+ modifier = Modifier.padding(start = 16.dp, top = 18.dp, bottom = 18.dp)
+ .align(alignment = Alignment.CenterHorizontally)
+ )
+ }
+ )
+ }
+ }
+}
+
+@Composable
fun LockedCredentials(
authenticationEntryList: List<AuthenticationEntryInfo>,
onEntrySelected: (EntryInfo) -> Unit,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
index f78456aab332..22370a91cde4 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
@@ -27,6 +27,7 @@ import com.android.credentialmanager.CredentialManagerRepo
import com.android.credentialmanager.common.DialogResult
import com.android.credentialmanager.common.ResultState
import com.android.credentialmanager.jetpack.developer.PublicKeyCredential
+import com.android.internal.util.Preconditions
data class GetCredentialUiState(
val providerInfoList: List<ProviderInfo>,
@@ -86,10 +87,14 @@ private fun toProviderDisplayInfo(
val userNameToCredentialEntryMap = mutableMapOf<String, MutableList<CredentialEntryInfo>>()
val authenticationEntryList = mutableListOf<AuthenticationEntryInfo>()
+ val remoteEntryList = mutableListOf<RemoteEntryInfo>()
providerInfoList.forEach { providerInfo ->
if (providerInfo.authenticationEntry != null) {
authenticationEntryList.add(providerInfo.authenticationEntry)
}
+ if (providerInfo.remoteEntry != null) {
+ remoteEntryList.add(providerInfo.remoteEntry)
+ }
providerInfo.credentialEntryList.forEach {
userNameToCredentialEntryMap.compute(
@@ -105,6 +110,9 @@ private fun toProviderDisplayInfo(
}
}
}
+ // There can only be at most one remote entry
+ // TODO: fail elegantly
+ Preconditions.checkState(remoteEntryList.size <= 1)
// Compose sortedUserNameToCredentialEntryList
val comparator = CredentialEntryInfoComparator()
@@ -122,6 +130,7 @@ private fun toProviderDisplayInfo(
return ProviderDisplayInfo(
sortedUserNameToCredentialEntryList = sortedUserNameToCredentialEntryList,
authenticationEntryList = authenticationEntryList,
+ remoteEntry = remoteEntryList.getOrNull(0),
)
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
index c541e08ffbb4..76d9847f5356 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
@@ -28,8 +28,8 @@ data class ProviderInfo(
val displayName: String,
val credentialEntryList: List<CredentialEntryInfo>,
val authenticationEntry: AuthenticationEntryInfo?,
+ val remoteEntry: RemoteEntryInfo?,
val actionEntryList: List<ActionEntryInfo>,
- // TODO: add remote entry
)
/** Display-centric data structure derived from the [ProviderInfo]. This abstraction is not grouping
@@ -41,6 +41,7 @@ data class ProviderDisplayInfo(
*/
val sortedUserNameToCredentialEntryList: List<PerUserNameCredentialEntryList>,
val authenticationEntryList: List<AuthenticationEntryInfo>,
+ val remoteEntry: RemoteEntryInfo?
)
abstract class EntryInfo (
@@ -72,6 +73,12 @@ class AuthenticationEntryInfo(
val icon: Drawable,
) : EntryInfo(providerId, entryKey, entrySubkey)
+class RemoteEntryInfo(
+ providerId: String,
+ entryKey: String,
+ entrySubkey: String,
+) : EntryInfo(providerId, entryKey, entrySubkey)
+
class ActionEntryInfo(
providerId: String,
entryKey: String,