Merge "Define all the entry-level display info in Entry."
This commit is contained in:
@@ -30,12 +30,39 @@ import com.android.internal.util.AnnotationValidations;
|
||||
* @hide
|
||||
*/
|
||||
public class Entry implements Parcelable {
|
||||
// TODO: move to jetpack.
|
||||
// TODO: these constants should go to jetpack.
|
||||
public static final String VERSION = "v1";
|
||||
public static final Uri CREDENTIAL_MANAGER_ENTRY_URI = Uri.parse("credentialmanager.slice");
|
||||
public static final String HINT_TITLE = "hint_title";
|
||||
public static final String HINT_SUBTITLE = "hint_subtitle";
|
||||
public static final String HINT_ICON = "hint_icon";
|
||||
// TODO: remove these hint constants and use the credential entry & action ones defined below.
|
||||
public static final String HINT_TITLE = "HINT_TITLE";
|
||||
public static final String HINT_SUBTITLE = "HINT_SUBTITLE";
|
||||
public static final String HINT_ICON = "HINT_ICON";
|
||||
/**
|
||||
* 1. CREDENTIAL ENTRY CONSTANTS
|
||||
*/
|
||||
// User profile picture associated with this credential entry.
|
||||
public static final String HINT_PROFILE_ICON = "HINT_PROFILE_ICON";
|
||||
public static final String HINT_CREDENTIAL_TYPE_ICON = "HINT_CREDENTIAL_TYPE_ICON";
|
||||
// The user account name of this provider app associated with this entry.
|
||||
// Note: this is independent from the request app.
|
||||
public static final String HINT_USER_PROVIDER_ACCOUNT_NAME = "HINT_USER_PROVIDER_ACCOUNT_NAME";
|
||||
public static final String HINT_PASSWORD_COUNT = "HINT_PASSWORD_COUNT";
|
||||
public static final String HINT_PASSKEY_COUNT = "HINT_PASSKEY_COUNT";
|
||||
public static final String HINT_TOTAL_CREDENTIAL_COUNT = "HINT_TOTAL_CREDENTIAL_COUNT";
|
||||
public static final String HINT_LAST_USED_TIME_MILLIS = "HINT_LAST_USED_TIME_MILLIS";
|
||||
/** Below are only available for get flows. */
|
||||
public static final String HINT_NOTE = "HINT_NOTE";
|
||||
public static final String HINT_USER_NAME = "HINT_USER_NAME";
|
||||
public static final String HINT_CREDENTIAL_TYPE = "HINT_CREDENTIAL_TYPE";
|
||||
public static final String HINT_PASSKEY_USER_DISPLAY_NAME = "HINT_PASSKEY_USER_DISPLAY_NAME";
|
||||
public static final String HINT_PASSWORD_VALUE = "HINT_PASSWORD_VALUE";
|
||||
|
||||
/**
|
||||
* 2. ACTION CONSTANTS
|
||||
*/
|
||||
public static final String HINT_ACTION_TITLE = "HINT_ACTION_TITLE";
|
||||
public static final String HINT_ACTION_SUBTEXT = "HINT_ACTION_SUBTEXT";
|
||||
public static final String HINT_ACTION_ICON = "HINT_ACTION_ICON";
|
||||
|
||||
/**
|
||||
* The intent extra key for the action chip {@code Entry} list when launching the UX activities.
|
||||
@@ -55,7 +82,7 @@ public class Entry implements Parcelable {
|
||||
public static final String EXTRA_ENTRY_AUTHENTICATION_ACTION =
|
||||
"android.credentials.ui.extra.ENTRY_AUTHENTICATION_ACTION";
|
||||
|
||||
// TODO: may be changed to other type depending on the service implementation.
|
||||
// TODO: change to string key + string subkey.
|
||||
private final int mId;
|
||||
|
||||
@NonNull
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack
|
||||
|
||||
import android.app.slice.Slice
|
||||
import android.graphics.drawable.Icon
|
||||
|
||||
/**
|
||||
* UI representation for a credential entry used during the get credential flow.
|
||||
*
|
||||
* TODO: move to jetpack.
|
||||
*/
|
||||
abstract class CredentialEntryUi(
|
||||
val credentialTypeIcon: Icon,
|
||||
val profileIcon: Icon?,
|
||||
val lastUsedTimeMillis: Long?,
|
||||
val note: CharSequence?,
|
||||
) {
|
||||
companion object {
|
||||
fun fromSlice(slice: Slice): CredentialEntryUi {
|
||||
return when (slice.spec?.type) {
|
||||
TYPE_PUBLIC_KEY_CREDENTIAL -> PasskeyCredentialEntryUi.fromSlice(slice)
|
||||
TYPE_PASSWORD_CREDENTIAL -> PasswordCredentialEntryUi.fromSlice(slice)
|
||||
else -> throw IllegalArgumentException("Unexpected type: ${slice.spec?.type}")
|
||||
}
|
||||
}
|
||||
|
||||
const val TYPE_PUBLIC_KEY_CREDENTIAL: String =
|
||||
"androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"
|
||||
const val TYPE_PASSWORD_CREDENTIAL: String = "androidx.credentials.TYPE_PASSWORD"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack
|
||||
|
||||
import android.app.slice.Slice
|
||||
import android.credentials.ui.Entry
|
||||
import android.graphics.drawable.Icon
|
||||
|
||||
class PasskeyCredentialEntryUi(
|
||||
val userName: CharSequence,
|
||||
val userDisplayName: CharSequence?,
|
||||
credentialTypeIcon: Icon,
|
||||
profileIcon: Icon?,
|
||||
lastUsedTimeMillis: Long?,
|
||||
note: CharSequence?,
|
||||
) : CredentialEntryUi(credentialTypeIcon, profileIcon, lastUsedTimeMillis, note) {
|
||||
companion object {
|
||||
fun fromSlice(slice: Slice): CredentialEntryUi {
|
||||
var userName: CharSequence? = null
|
||||
var userDisplayName: CharSequence? = null
|
||||
var credentialTypeIcon: Icon? = null
|
||||
var profileIcon: Icon? = null
|
||||
var lastUsedTimeMillis: Long? = null
|
||||
var note: CharSequence? = null
|
||||
|
||||
val items = slice.items
|
||||
items.forEach {
|
||||
if (it.hasHint(Entry.HINT_USER_NAME)) {
|
||||
userName = it.text
|
||||
} else if (it.hasHint(Entry.HINT_PASSKEY_USER_DISPLAY_NAME)) {
|
||||
userDisplayName = it.text
|
||||
} else if (it.hasHint(Entry.HINT_CREDENTIAL_TYPE_ICON)) {
|
||||
credentialTypeIcon = it.icon
|
||||
} else if (it.hasHint(Entry.HINT_PROFILE_ICON)) {
|
||||
profileIcon = it.icon
|
||||
} else if (it.hasHint(Entry.HINT_LAST_USED_TIME_MILLIS)) {
|
||||
lastUsedTimeMillis = it.long
|
||||
} else if (it.hasHint(Entry.HINT_NOTE)) {
|
||||
note = it.text
|
||||
}
|
||||
}
|
||||
// TODO: fail NPE more elegantly.
|
||||
return PasskeyCredentialEntryUi(
|
||||
userName!!, userDisplayName, credentialTypeIcon!!,
|
||||
profileIcon, lastUsedTimeMillis, note,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack
|
||||
|
||||
import android.app.slice.Slice
|
||||
import android.credentials.ui.Entry
|
||||
import android.graphics.drawable.Icon
|
||||
|
||||
/**
|
||||
* UI representation for a password credential entry used during the get credential flow.
|
||||
*
|
||||
* TODO: move to jetpack.
|
||||
*/
|
||||
class PasswordCredentialEntryUi(
|
||||
val userName: CharSequence,
|
||||
val password: CharSequence,
|
||||
credentialTypeIcon: Icon,
|
||||
profileIcon: Icon?,
|
||||
lastUsedTimeMillis: Long?,
|
||||
note: CharSequence?,
|
||||
) : CredentialEntryUi(credentialTypeIcon, profileIcon, lastUsedTimeMillis, note) {
|
||||
companion object {
|
||||
fun fromSlice(slice: Slice): CredentialEntryUi {
|
||||
var userName: CharSequence? = null
|
||||
var password: CharSequence? = null
|
||||
var credentialTypeIcon: Icon? = null
|
||||
var profileIcon: Icon? = null
|
||||
var lastUsedTimeMillis: Long? = null
|
||||
var note: CharSequence? = null
|
||||
|
||||
val items = slice.items
|
||||
items.forEach {
|
||||
if (it.hasHint(Entry.HINT_USER_NAME)) {
|
||||
userName = it.text
|
||||
} else if (it.hasHint(Entry.HINT_PASSWORD_VALUE)) {
|
||||
password = it.text
|
||||
} else if (it.hasHint(Entry.HINT_CREDENTIAL_TYPE_ICON)) {
|
||||
credentialTypeIcon = it.icon
|
||||
} else if (it.hasHint(Entry.HINT_PROFILE_ICON)) {
|
||||
profileIcon = it.icon
|
||||
} else if (it.hasHint(Entry.HINT_LAST_USED_TIME_MILLIS)) {
|
||||
lastUsedTimeMillis = it.long
|
||||
} else if (it.hasHint(Entry.HINT_NOTE)) {
|
||||
note = it.text
|
||||
}
|
||||
}
|
||||
// TODO: fail NPE more elegantly.
|
||||
return PasswordCredentialEntryUi(
|
||||
userName!!, password!!, credentialTypeIcon!!,
|
||||
profileIcon, lastUsedTimeMillis, note,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
package com.android.credentialmanager.jetpack
|
||||
|
||||
import android.app.slice.Slice
|
||||
import android.credentials.ui.Entry
|
||||
import android.graphics.drawable.Icon
|
||||
|
||||
/**
|
||||
* UI representation for a save entry used during the create credential flow.
|
||||
*
|
||||
* TODO: move to jetpack.
|
||||
*/
|
||||
class SaveEntryUi(
|
||||
val userProviderAccountName: CharSequence,
|
||||
val credentialTypeIcon: Icon?,
|
||||
val profileIcon: Icon?,
|
||||
val passwordCount: Int?,
|
||||
val passkeyCount: Int?,
|
||||
val totalCredentialCount: Int?,
|
||||
val lastUsedTimeMillis: Long?,
|
||||
) {
|
||||
companion object {
|
||||
fun fromSlice(slice: Slice): SaveEntryUi {
|
||||
var userProviderAccountName: CharSequence? = null
|
||||
var credentialTypeIcon: Icon? = null
|
||||
var profileIcon: Icon? = null
|
||||
var passwordCount: Int? = null
|
||||
var passkeyCount: Int? = null
|
||||
var totalCredentialCount: Int? = null
|
||||
var lastUsedTimeMillis: Long? = null
|
||||
|
||||
|
||||
val items = slice.items
|
||||
items.forEach {
|
||||
if (it.hasHint(Entry.HINT_USER_PROVIDER_ACCOUNT_NAME)) {
|
||||
userProviderAccountName = it.text
|
||||
} else if (it.hasHint(Entry.HINT_CREDENTIAL_TYPE_ICON)) {
|
||||
credentialTypeIcon = it.icon
|
||||
} else if (it.hasHint(Entry.HINT_PROFILE_ICON)) {
|
||||
profileIcon = it.icon
|
||||
} else if (it.hasHint(Entry.HINT_PASSWORD_COUNT)) {
|
||||
passwordCount = it.int
|
||||
} else if (it.hasHint(Entry.HINT_PASSKEY_COUNT)) {
|
||||
passkeyCount = it.int
|
||||
} else if (it.hasHint(Entry.HINT_TOTAL_CREDENTIAL_COUNT)) {
|
||||
totalCredentialCount = it.int
|
||||
} else if (it.hasHint(Entry.HINT_LAST_USED_TIME_MILLIS)) {
|
||||
lastUsedTimeMillis = it.long
|
||||
}
|
||||
}
|
||||
// TODO: fail NPE more elegantly.
|
||||
return SaveEntryUi(
|
||||
userProviderAccountName!!, credentialTypeIcon, profileIcon,
|
||||
passwordCount, passkeyCount, totalCredentialCount, lastUsedTimeMillis,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user