5
5
package mozilla.components.feature.autofill.handler
6
6
7
7
import android.annotation.SuppressLint
8
- import android.app.PendingIntent
9
8
import android.app.assist.AssistStructure
10
9
import android.content.Context
11
- import android.content.Intent
12
- import android.content.IntentSender
13
10
import android.os.Build
14
- import android.service.autofill.Dataset
15
11
import android.service.autofill.FillRequest
16
12
import android.service.autofill.FillResponse
17
- import android.view.autofill.AutofillValue
18
- import android.widget.RemoteViews
19
13
import androidx.annotation.RequiresApi
20
- import mozilla.components.concept.storage.Login
21
14
import mozilla.components.feature.autofill.AutofillConfiguration
22
- import mozilla.components.feature.autofill.R
23
- import mozilla.components.feature.autofill.structure.ParsedStructure
15
+ import mozilla.components.feature.autofill.response.dataset.DatasetBuilder
16
+ import mozilla.components.feature.autofill.response.dataset.LoginDatasetBuilder
17
+ import mozilla.components.feature.autofill.response.fill.AuthFillResponseBuilder
18
+ import mozilla.components.feature.autofill.response.fill.FillResponseBuilder
19
+ import mozilla.components.feature.autofill.response.fill.LoginFillResponseBuilder
20
+ import mozilla.components.feature.autofill.structure.RawStructure
24
21
import mozilla.components.feature.autofill.structure.getLookupDomain
25
22
import mozilla.components.feature.autofill.structure.parseStructure
26
23
@@ -34,24 +31,16 @@ internal class FillRequestHandler(
34
31
private val context : Context ,
35
32
private val configuration : AutofillConfiguration
36
33
) {
37
- /* *
38
- * Handles the given [FillRequest] and returns a matching [FillResponse] or `null` if this
39
- * request could not be handled.
40
- */
41
- suspend fun handle (request : FillRequest , forceUnlock : Boolean = false): FillResponse ? {
42
- return handle(request.fillContexts.last().structure, forceUnlock)
43
- }
44
-
45
34
/* *
46
35
* Handles a fill request for the given [AssistStructure] and returns a matching [FillResponse]
47
36
* or `null` if the request could not be handled or the passed in [AssistStructure] is `null`.
48
37
*/
49
38
@SuppressLint(" InlinedApi" )
50
39
@Suppress(" ReturnCount" )
51
40
suspend fun handle (
52
- structure : AssistStructure ? ,
41
+ structure : RawStructure ? ,
53
42
forceUnlock : Boolean = false
54
- ): FillResponse ? {
43
+ ): FillResponseBuilder ? {
55
44
if (structure == null ) {
56
45
return null
57
46
}
@@ -70,25 +59,19 @@ internal class FillRequestHandler(
70
59
}
71
60
72
61
return if (! configuration.lock.keepUnlocked() && ! forceUnlock) {
73
- createAuthResponse(context, configuration, parsedStructure)
62
+ AuthFillResponseBuilder ( parsedStructure)
74
63
} else {
75
- createLoginsResponse(
76
- context,
77
- configuration,
78
- parsedStructure,
79
- logins,
80
- needsConfirmation
81
- )
64
+ LoginFillResponseBuilder (parsedStructure, logins, needsConfirmation)
82
65
}
83
66
}
84
67
85
68
/* *
86
- * Handles a fill request for the given [AssistStructure ] and returns only a [Dataset ] for the
87
- * given [loginId] - or `null` if the request could not be handled or the passed in
88
- * [AssistStructure ] is `null`
69
+ * Handles a fill request for the given [RawStructure ] and returns only a [DatasetBuilder ] for
70
+ * the given [loginId] - or `null` if the request could not be handled or the passed in
71
+ * [RawStructure ] is `null`
89
72
*/
90
73
@Suppress(" ReturnCount" )
91
- suspend fun handleConfirmation (structure : AssistStructure ? , loginId : String ): Dataset ? {
74
+ suspend fun handleConfirmation (structure : RawStructure ? , loginId : String ): DatasetBuilder ? {
92
75
if (structure == null ) {
93
76
return null
94
77
}
@@ -103,133 +86,6 @@ internal class FillRequestHandler(
103
86
104
87
val login = logins.firstOrNull { login -> login.guid == loginId } ? : return null
105
88
106
- return createDataSetResponse(
107
- context,
108
- configuration,
109
- login,
110
- parsedStructure,
111
- needsConfirmation = false
112
- )
113
- }
114
- }
115
-
116
- @RequiresApi(Build .VERSION_CODES .O )
117
- private fun createAuthResponse (
118
- context : Context ,
119
- configuration : AutofillConfiguration ,
120
- parsedStructure : ParsedStructure
121
- ): FillResponse {
122
- val builder = FillResponse .Builder ()
123
-
124
- val autofillIds = listOfNotNull(parsedStructure.usernameId, parsedStructure.passwordId)
125
-
126
- val authPresentation = RemoteViews (context.packageName, android.R .layout.simple_list_item_1).apply {
127
- setTextViewText(
128
- android.R .id.text1,
129
- context.getString(R .string.mozac_feature_autofill_popup_unlock_application, configuration.applicationName)
130
- )
131
- }
132
-
133
- val authIntent = Intent (context, configuration.unlockActivity)
134
-
135
- val intentSender: IntentSender = PendingIntent .getActivity(
136
- context,
137
- configuration.activityRequestCode,
138
- authIntent,
139
- PendingIntent .FLAG_CANCEL_CURRENT
140
- ).intentSender
141
-
142
- builder.setAuthentication(autofillIds.toTypedArray(), intentSender, authPresentation)
143
-
144
- return builder.build()
145
- }
146
-
147
- @RequiresApi(Build .VERSION_CODES .O )
148
- private fun createLoginsResponse (
149
- context : Context ,
150
- configuration : AutofillConfiguration ,
151
- parsedStructure : ParsedStructure ,
152
- logins : List <Login >,
153
- needsConfirmation : Boolean
154
- ): FillResponse {
155
- val builder = FillResponse .Builder ()
156
-
157
- logins.forEachIndexed { index, login ->
158
- val dataset = createDataSetResponse(
159
- context,
160
- configuration,
161
- login,
162
- parsedStructure,
163
- needsConfirmation,
164
- requestOffset = index
165
- )
166
- builder.addDataset(dataset)
167
- }
168
-
169
- return builder.build()
170
- }
171
-
172
- @RequiresApi(Build .VERSION_CODES .O )
173
- @Suppress(" LongParameterList" )
174
- private fun createDataSetResponse (
175
- context : Context ,
176
- configuration : AutofillConfiguration ,
177
- login : Login ,
178
- parsedStructure : ParsedStructure ,
179
- needsConfirmation : Boolean ,
180
- requestOffset : Int = 0
181
- ): Dataset {
182
- val dataset = Dataset .Builder ()
183
-
184
- val usernamePresentation = RemoteViews (context.packageName, android.R .layout.simple_list_item_1)
185
- usernamePresentation.setTextViewText(android.R .id.text1, login.usernamePresentationOrFallback(context))
186
- val passwordPresentation = RemoteViews (context.packageName, android.R .layout.simple_list_item_1)
187
- passwordPresentation.setTextViewText(android.R .id.text1, login.passwordPresentation(context))
188
-
189
- parsedStructure.usernameId?.let { id ->
190
- dataset.setValue(
191
- id,
192
- if (needsConfirmation) null else AutofillValue .forText(login.username),
193
- usernamePresentation
194
- )
195
- }
196
-
197
- parsedStructure.passwordId?.let { id ->
198
- dataset.setValue(
199
- id,
200
- if (needsConfirmation) null else AutofillValue .forText(login.password),
201
- passwordPresentation
202
- )
89
+ return LoginDatasetBuilder (parsedStructure, login, needsConfirmation = false )
203
90
}
204
-
205
- if (needsConfirmation) {
206
- val confirmIntent = Intent (context, configuration.confirmActivity)
207
- confirmIntent.putExtra(EXTRA_LOGIN_ID , login.guid)
208
-
209
- val intentSender: IntentSender = PendingIntent .getActivity(
210
- context,
211
- configuration.activityRequestCode + requestOffset,
212
- confirmIntent,
213
- PendingIntent .FLAG_CANCEL_CURRENT
214
- ).intentSender
215
-
216
- dataset.setAuthentication(intentSender)
217
- }
218
-
219
- return dataset.build()
220
- }
221
-
222
- private fun Login.usernamePresentationOrFallback (context : Context ): String {
223
- return if (username.isNotEmpty()) {
224
- username
225
- } else {
226
- context.getString(R .string.mozac_feature_autofill_popup_no_username)
227
- }
228
- }
229
-
230
- private fun Login.passwordPresentation (context : Context ): String {
231
- return context.getString(
232
- R .string.mozac_feature_autofill_popup_password,
233
- usernamePresentationOrFallback(context)
234
- )
235
91
}
0 commit comments