Revision control
Copy as Markdown
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
*/
package mozilla.lockbox.autofill
import android.os.Build
import android.os.Parcel
import android.os.ParcelFormatException
import android.os.Parcelable
import android.service.autofill.SaveInfo
import android.view.autofill.AutofillId
import androidx.annotation.RequiresApi
open class ParsedStructureData<Id>(
val usernameId: Id? = null,
val passwordId: Id? = null,
val webDomain: String? = null,
val packageName: String
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is ParsedStructureData<*>) return false
if (usernameId != other.usernameId) return false
if (passwordId != other.passwordId) return false
if (webDomain != other.webDomain) return false
if (packageName != other.packageName) return false
return true
}
override fun hashCode(): Int {
var result = usernameId?.hashCode() ?: 0
result = 31 * result + (passwordId?.hashCode() ?: 0)
result = 31 * result + (webDomain?.hashCode() ?: 0)
result = 31 * result + packageName.hashCode()
return result
}
}
// This should be kept in the same order as `allPossibleIds` below.
@RequiresApi(Build.VERSION_CODES.O)
val saveDataTypeMasks = arrayOf(
SaveInfo.SAVE_DATA_TYPE_USERNAME,
SaveInfo.SAVE_DATA_TYPE_PASSWORD
)
@RequiresApi(Build.VERSION_CODES.O)
class ParsedStructure(
usernameId: AutofillId? = null,
passwordId: AutofillId? = null,
webDomain: String? = null,
packageName: String
) : ParsedStructureData<AutofillId>(usernameId, passwordId, webDomain, packageName), Parcelable {
// This is a paired array with `saveDataTypeMasks` above.
// We'll use this to calculate both the available autofillIds and the saveInfo mask.
private val allPossibleIds = arrayOf(usernameId, passwordId)
val autofillIds: Array<AutofillId> by lazy {
allPossibleIds.filterNotNull()
.toTypedArray()
}
// Construct the saveInfo mask based upon the autofillIds that are available.
// This relies on the paired arrays of `saveDataTypeMasks` and the null padded `allPossibleIds`.
val saveInfoMask: Int by lazy {
allPossibleIds.mapIndexed { index, autofillId ->
autofillId?.let { saveDataTypeMasks[index] } ?: 0
}
.reduce { totalMask, saveDataTypeMask ->
totalMask or saveDataTypeMask
}
}
constructor(parcel: Parcel) : this(
parcel.readParcelable(AutofillId::class.java.classLoader),
parcel.readParcelable(AutofillId::class.java.classLoader),
parcel.readString(),
parcel.readString() ?: throw ParcelFormatException("packageName")
)
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeParcelable(this.usernameId, flags)
parcel.writeParcelable(this.passwordId, flags)
parcel.writeString(this.webDomain)
parcel.writeString(this.packageName)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<ParsedStructure> {
override fun createFromParcel(parcel: Parcel): ParsedStructure {
return ParsedStructure(parcel)
}
override fun newArray(size: Int): Array<ParsedStructure?> {
return arrayOfNulls(size)
}
}
}