1 /*
<lambda>null2  * 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