Home | History | Annotate | Download | only in model
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.example.android.autofillframework.multidatasetservice.model
     17 
     18 import android.service.autofill.Dataset
     19 import android.util.Log
     20 import android.view.View
     21 import android.view.autofill.AutofillId
     22 import android.view.autofill.AutofillValue
     23 import com.example.android.autofillframework.CommonUtil.TAG
     24 import com.example.android.autofillframework.multidatasetservice.AutofillFieldMetadataCollection
     25 import com.google.gson.annotations.Expose
     26 import java.util.HashMap
     27 
     28 
     29 /**
     30  * FilledAutofillFieldCollection is the model that represents all of the form data on a client app's page, plus the
     31  * dataset name associated with it.
     32  */
     33 class FilledAutofillFieldCollection @JvmOverloads constructor(
     34         @Expose var datasetName: String? = null,
     35         @Expose private val hintMap: HashMap<String, FilledAutofillField> = HashMap<String,
     36                 FilledAutofillField>()
     37 ) {
     38 
     39     /**
     40      * Sets values for a list of autofillHints.
     41      */
     42     fun add(autofillField: FilledAutofillField) {
     43         autofillField.autofillHints.forEach { autofillHint ->
     44             hintMap[autofillHint] = autofillField
     45         }
     46     }
     47 
     48     /**
     49      * Populates a [Dataset.Builder] with appropriate values for each [AutofillId]
     50      * in a `AutofillFieldMetadataCollection`. In other words, it builds an Autofill dataset
     51      * by applying saved values (from this `FilledAutofillFieldCollection`) to Views specified
     52      * in a `AutofillFieldMetadataCollection`, which represents the current page the user is
     53      * on.
     54      */
     55     fun applyToFields(autofillFieldMetadataCollection: AutofillFieldMetadataCollection,
     56             datasetBuilder: Dataset.Builder): Boolean {
     57         var setValueAtLeastOnce = false
     58         for (hint in autofillFieldMetadataCollection.allAutofillHints) {
     59             val autofillFields = autofillFieldMetadataCollection.getFieldsForHint(hint) ?: continue
     60             for (autofillField in autofillFields) {
     61                 val autofillId = autofillField.autofillId
     62                 val autofillType = autofillField.autofillType
     63                 val savedAutofillValue = hintMap[hint]
     64                 when (autofillType) {
     65                     View.AUTOFILL_TYPE_LIST -> {
     66                         savedAutofillValue?.textValue?.let {
     67                             val index = autofillField.getAutofillOptionIndex(it)
     68                             if (index != -1) {
     69                                 datasetBuilder.setValue(autofillId, AutofillValue.forList(index))
     70                                 setValueAtLeastOnce = true
     71                             }
     72                         }
     73                     }
     74                     View.AUTOFILL_TYPE_DATE -> {
     75                         savedAutofillValue?.dateValue?.let { date ->
     76                             datasetBuilder.setValue(autofillId, AutofillValue.forDate(date))
     77                             setValueAtLeastOnce = true
     78                         }
     79                     }
     80                     View.AUTOFILL_TYPE_TEXT -> {
     81                         savedAutofillValue?.textValue?.let { text ->
     82                             datasetBuilder.setValue(autofillId, AutofillValue.forText(text))
     83                             setValueAtLeastOnce = true
     84                         }
     85                     }
     86                     View.AUTOFILL_TYPE_TOGGLE -> {
     87                         savedAutofillValue?.toggleValue?.let { toggle ->
     88                             datasetBuilder.setValue(autofillId, AutofillValue.forToggle(toggle))
     89                             setValueAtLeastOnce = true
     90                         }
     91                     }
     92                     else -> Log.w(TAG, "Invalid autofill type - " + autofillType)
     93                 }
     94             }
     95         }
     96         return setValueAtLeastOnce
     97     }
     98 
     99     /**
    100      * @param autofillHints List of autofill hints, usually associated with a View or set of Views.
    101      * @return whether any of the filled fields on the page have at least 1 autofillHint that is
    102      * in the provided autofillHints.
    103      */
    104     fun helpsWithHints(autofillHints: List<String>): Boolean {
    105         for (autofillHint in autofillHints) {
    106             hintMap[autofillHint]?.let { savedAutofillValue ->
    107                 if (!savedAutofillValue.isNull()) {
    108                     return true
    109                 }
    110             }
    111         }
    112         return false
    113     }
    114 }
    115