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 android.service.autofill; 17 18 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; 19 20 import android.annotation.CallSuper; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.SdkConstant; 24 import android.app.Service; 25 import android.content.Intent; 26 import android.os.BaseBundle; 27 import android.os.CancellationSignal; 28 import android.os.Handler; 29 import android.os.IBinder; 30 import android.os.ICancellationSignal; 31 import android.os.Looper; 32 import android.os.RemoteException; 33 import android.provider.Settings; 34 import android.util.Log; 35 import android.view.View; 36 import android.view.ViewStructure; 37 import android.view.autofill.AutofillId; 38 import android.view.autofill.AutofillManager; 39 import android.view.autofill.AutofillValue; 40 41 import com.android.internal.os.IResultReceiver; 42 43 /** 44 * An {@code AutofillService} is a service used to automatically fill the contents of the screen 45 * on behalf of a given user - for more information about autofill, read 46 * <a href="{@docRoot}preview/features/autofill.html">Autofill Framework</a>. 47 * 48 * <p>An {@code AutofillService} is only bound to the Android System for autofill purposes if: 49 * <ol> 50 * <li>It requires the {@code android.permission.BIND_AUTOFILL_SERVICE} permission in its 51 * manifest. 52 * <li>The user explicitly enables it using Android Settings (the 53 * {@link Settings#ACTION_REQUEST_SET_AUTOFILL_SERVICE} intent can be used to launch such 54 * Settings screen). 55 * </ol> 56 * 57 * <a name="BasicUsage"></a> 58 * <h3>Basic usage</h3> 59 * 60 * <p>The basic autofill process is defined by the workflow below: 61 * <ol> 62 * <li>User focus an editable {@link View}. 63 * <li>View calls {@link AutofillManager#notifyViewEntered(android.view.View)}. 64 * <li>A {@link ViewStructure} representing all views in the screen is created. 65 * <li>The Android System binds to the service and calls {@link #onConnected()}. 66 * <li>The service receives the view structure through the 67 * {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)}. 68 * <li>The service replies through {@link FillCallback#onSuccess(FillResponse)}. 69 * <li>The Android System calls {@link #onDisconnected()} and unbinds from the 70 * {@code AutofillService}. 71 * <li>The Android System displays an autofill UI with the options sent by the service. 72 * <li>The user picks an option. 73 * <li>The proper views are autofilled. 74 * </ol> 75 * 76 * <p>This workflow was designed to minimize the time the Android System is bound to the service; 77 * for each call, it: binds to service, waits for the reply, and unbinds right away. Furthermore, 78 * those calls are considered stateless: if the service needs to keep state between calls, it must 79 * do its own state management (keeping in mind that the service's process might be killed by the 80 * Android System when unbound; for example, if the device is running low in memory). 81 * 82 * <p>Typically, the 83 * {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} will: 84 * <ol> 85 * <li>Parse the view structure looking for autofillable views (for example, using 86 * {@link android.app.assist.AssistStructure.ViewNode#getAutofillHints()}. 87 * <li>Match the autofillable views with the user's data. 88 * <li>Create a {@link Dataset} for each set of user's data that match those fields. 89 * <li>Fill the dataset(s) with the proper {@link AutofillId}s and {@link AutofillValue}s. 90 * <li>Add the dataset(s) to the {@link FillResponse} passed to 91 * {@link FillCallback#onSuccess(FillResponse)}. 92 * </ol> 93 * 94 * <p>For example, for a login screen with username and password views where the user only has one 95 * account in the service, the response could be: 96 * 97 * <pre class="prettyprint"> 98 * new FillResponse.Builder() 99 * .addDataset(new Dataset.Builder() 100 * .setValue(id1, AutofillValue.forText("homer"), createPresentation("homer")) 101 * .setValue(id2, AutofillValue.forText("D'OH!"), createPresentation("password for homer")) 102 * .build()) 103 * .build(); 104 * </pre> 105 * 106 * <p>But if the user had 2 accounts instead, the response could be: 107 * 108 * <pre class="prettyprint"> 109 * new FillResponse.Builder() 110 * .addDataset(new Dataset.Builder() 111 * .setValue(id1, AutofillValue.forText("homer"), createPresentation("homer")) 112 * .setValue(id2, AutofillValue.forText("D'OH!"), createPresentation("password for homer")) 113 * .build()) 114 * .addDataset(new Dataset.Builder() 115 * .setValue(id1, AutofillValue.forText("flanders"), createPresentation("flanders")) 116 * .setValue(id2, AutofillValue.forText("OkelyDokelyDo"), createPresentation("password for flanders")) 117 * .build()) 118 * .build(); 119 * </pre> 120 * 121 * <p>If the service does not find any autofillable view in the view structure, it should pass 122 * {@code null} to {@link FillCallback#onSuccess(FillResponse)}; if the service encountered an error 123 * processing the request, it should call {@link FillCallback#onFailure(CharSequence)}. For 124 * performance reasons, it's paramount that the service calls either 125 * {@link FillCallback#onSuccess(FillResponse)} or {@link FillCallback#onFailure(CharSequence)} for 126 * each {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} received - if it 127 * doesn't, the request will eventually time out and be discarded by the Android System. 128 * 129 * <a name="SavingUserData"></a> 130 * <h3>Saving user data</h3> 131 * 132 * <p>If the service is also interested on saving the data filled by the user, it must set a 133 * {@link SaveInfo} object in the {@link FillResponse}. See {@link SaveInfo} for more details and 134 * examples. 135 * 136 * <a name="UserAuthentication"></a> 137 * <h3>User authentication</h3> 138 * 139 * <p>The service can provide an extra degree of security by requiring the user to authenticate 140 * before an app can be autofilled. The authentication is typically required in 2 scenarios: 141 * <ul> 142 * <li>To unlock the user data (for example, using a main password or fingerprint 143 * authentication) - see 144 * {@link FillResponse.Builder#setAuthentication(AutofillId[], android.content.IntentSender, android.widget.RemoteViews)}. 145 * <li>To unlock a specific dataset (for example, by providing a CVC for a credit card) - see 146 * {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}. 147 * </ul> 148 * 149 * <p>When using authentication, it is recommended to encrypt only the sensitive data and leave 150 * labels unencrypted, so they can be used on presentation views. For example, if the user has a 151 * home and a work address, the {@code Home} and {@code Work} labels should be stored unencrypted 152 * (since they don't have any sensitive data) while the address data per se could be stored in an 153 * encrypted storage. Then when the user chooses the {@code Home} dataset, the platform starts 154 * the authentication flow, and the service can decrypt the sensitive data. 155 * 156 * <p>The authentication mechanism can also be used in scenarios where the service needs multiple 157 * steps to determine the datasets that can fill a screen. For example, when autofilling a financial 158 * app where the user has accounts for multiple banks, the workflow could be: 159 * 160 * <ol> 161 * <li>The first {@link FillResponse} contains datasets with the credentials for the financial 162 * app, plus a "fake" dataset whose presentation says "Tap here for banking apps credentials". 163 * <li>When the user selects the fake dataset, the service displays a dialog with available 164 * banking apps. 165 * <li>When the user select a banking app, the service replies with a new {@link FillResponse} 166 * containing the datasets for that bank. 167 * </ol> 168 * 169 * <p>Another example of multiple-steps dataset selection is when the service stores the user 170 * credentials in "vaults": the first response would contain fake datasets with the vault names, 171 * and the subsequent response would contain the app credentials stored in that vault. 172 * 173 * <a name="DataPartioning"></a> 174 * <h3>Data partitioning</h3> 175 * 176 * <p>The autofillable views in a screen should be grouped in logical groups called "partitions". 177 * Typical partitions are: 178 * <ul> 179 * <li>Credentials (username/email address, password). 180 * <li>Address (street, city, state, zip code, etc). 181 * <li>Payment info (credit card number, expiration date, and verification code). 182 * </ul> 183 * <p>For security reasons, when a screen has more than one partition, it's paramount that the 184 * contents of a dataset do not spawn multiple partitions, specially when one of the partitions 185 * contains data that is not specific to the application being autofilled. For example, a dataset 186 * should not contain fields for username, password, and credit card information. The reason for 187 * this rule is that a malicious app could draft a view structure where the credit card fields 188 * are not visible, so when the user selects a dataset from the username UI, the credit card info is 189 * released to the application without the user knowledge. Similarly, it's recommended to always 190 * protect a dataset that contains sensitive information by requiring dataset authentication 191 * (see {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}), and to include 192 * info about the "primary" field of the partition in the custom presentation for "secondary" 193 * fields—that would prevent a malicious app from getting the "primary" fields without the 194 * user realizing they're being released (for example, a malicious app could have fields for a 195 * credit card number, verification code, and expiration date crafted in a way that just the latter 196 * is visible; by explicitly indicating the expiration date is related to a given credit card 197 * number, the service would be providing a visual clue for the users to check what would be 198 * released upon selecting that field). 199 * 200 * <p>When the service detects that a screen has multiple partitions, it should return a 201 * {@link FillResponse} with just the datasets for the partition that originated the request (i.e., 202 * the partition that has the {@link android.app.assist.AssistStructure.ViewNode} whose 203 * {@link android.app.assist.AssistStructure.ViewNode#isFocused()} returns {@code true}); then if 204 * the user selects a field from a different partition, the Android System will make another 205 * {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} call for that partition, 206 * and so on. 207 * 208 * <p>Notice that when the user autofill a partition with the data provided by the service and the 209 * user did not change these fields, the autofilled value is sent back to the service in the 210 * subsequent calls (and can be obtained by calling 211 * {@link android.app.assist.AssistStructure.ViewNode#getAutofillValue()}). This is useful in the 212 * cases where the service must create datasets for a partition based on the choice made in a 213 * previous partition. For example, the 1st response for a screen that have credentials and address 214 * partitions could be: 215 * 216 * <pre class="prettyprint"> 217 * new FillResponse.Builder() 218 * .addDataset(new Dataset.Builder() // partition 1 (credentials) 219 * .setValue(id1, AutofillValue.forText("homer"), createPresentation("homer")) 220 * .setValue(id2, AutofillValue.forText("D'OH!"), createPresentation("password for homer")) 221 * .build()) 222 * .addDataset(new Dataset.Builder() // partition 1 (credentials) 223 * .setValue(id1, AutofillValue.forText("flanders"), createPresentation("flanders")) 224 * .setValue(id2, AutofillValue.forText("OkelyDokelyDo"), createPresentation("password for flanders")) 225 * .build()) 226 * .setSaveInfo(new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_PASSWORD, 227 * new AutofillId[] { id1, id2 }) 228 * .build()) 229 * .build(); 230 * </pre> 231 * 232 * <p>Then if the user selected {@code flanders}, the service would get a new 233 * {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} call, with the values of 234 * the fields {@code id1} and {@code id2} prepopulated, so the service could then fetch the address 235 * for the Flanders account and return the following {@link FillResponse} for the address partition: 236 * 237 * <pre class="prettyprint"> 238 * new FillResponse.Builder() 239 * .addDataset(new Dataset.Builder() // partition 2 (address) 240 * .setValue(id3, AutofillValue.forText("744 Evergreen Terrace"), createPresentation("744 Evergreen Terrace")) // street 241 * .setValue(id4, AutofillValue.forText("Springfield"), createPresentation("Springfield")) // city 242 * .build()) 243 * .setSaveInfo(new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_PASSWORD | SaveInfo.SAVE_DATA_TYPE_ADDRESS, 244 * new AutofillId[] { id1, id2 }) // username and password 245 * .setOptionalIds(new AutofillId[] { id3, id4 }) // state and zipcode 246 * .build()) 247 * .build(); 248 * </pre> 249 * 250 * <p>When the service returns multiple {@link FillResponse}, the last one overrides the previous; 251 * that's why the {@link SaveInfo} in the 2nd request above has the info for both partitions. 252 * 253 * <a name="PackageVerification"></a> 254 * <h3>Package verification</h3> 255 * 256 * <p>When autofilling app-specific data (like username and password), the service must verify 257 * the authenticity of the request by obtaining all signing certificates of the app being 258 * autofilled, and only fulfilling the request when they match the values that were 259 * obtained when the data was first saved — such verification is necessary to avoid phishing 260 * attempts by apps that were sideloaded in the device with the same package name of another app. 261 * Here's an example on how to achieve that by hashing the signing certificates: 262 * 263 * <pre class="prettyprint"> 264 * private String getCertificatesHash(String packageName) throws Exception { 265 * PackageManager pm = mContext.getPackageManager(); 266 * PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); 267 * ArrayList<String> hashes = new ArrayList<>(info.signatures.length); 268 * for (Signature sig : info.signatures) { 269 * byte[] cert = sig.toByteArray(); 270 * MessageDigest md = MessageDigest.getInstance("SHA-256"); 271 * md.update(cert); 272 * hashes.add(toHexString(md.digest())); 273 * } 274 * Collections.sort(hashes); 275 * StringBuilder hash = new StringBuilder(); 276 * for (int i = 0; i < hashes.size(); i++) { 277 * hash.append(hashes.get(i)); 278 * } 279 * return hash.toString(); 280 * } 281 * </pre> 282 * 283 * <p>If the service did not store the signing certificates data the first time the data was saved 284 * — for example, because the data was created by a previous version of the app that did not 285 * use the Autofill Framework — the service should warn the user that the authenticity of the 286 * app cannot be confirmed (see an example on how to show such warning in the 287 * <a href="#WebSecurityDisclaimer">Web security</a> section below), and if the user agrees, 288 * then the service could save the data from the signing ceriticates for future use. 289 * 290 * <a name="IgnoringViews"></a> 291 * <h3>Ignoring views</h3> 292 * 293 * <p>If the service find views that cannot be autofilled (for example, a text field representing 294 * the response to a Captcha challenge), it should mark those views as ignored by 295 * calling {@link FillResponse.Builder#setIgnoredIds(AutofillId...)} so the system does not trigger 296 * a new {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} when these views are 297 * focused. 298 * 299 * <a name="WebSecurity"></a> 300 * <h3>Web security</h3> 301 * 302 * <p>When handling autofill requests that represent web pages (typically 303 * view structures whose root's {@link android.app.assist.AssistStructure.ViewNode#getClassName()} 304 * is a {@link android.webkit.WebView}), the service should take the following steps to verify if 305 * the structure can be autofilled with the data associated with the app requesting it: 306 * 307 * <ol> 308 * <li>Use the {@link android.app.assist.AssistStructure.ViewNode#getWebDomain()} to get the 309 * source of the document. 310 * <li>Get the canonical domain using the 311 * <a href="https://publicsuffix.org/">Public Suffix List</a> (see example below). 312 * <li>Use <a href="https://developers.google.com/digital-asset-links/">Digital Asset Links</a> 313 * to obtain the package name and certificate fingerprint of the package corresponding to 314 * the canonical domain. 315 * <li>Make sure the certificate fingerprint matches the value returned by Package Manager 316 * (see "Package verification" section above). 317 * </ol> 318 * 319 * <p>Here's an example on how to get the canonical domain using 320 * <a href="https://github.com/google/guava">Guava</a>: 321 * 322 * <pre class="prettyprint"> 323 * private static String getCanonicalDomain(String domain) { 324 * InternetDomainName idn = InternetDomainName.from(domain); 325 * while (idn != null && !idn.isTopPrivateDomain()) { 326 * idn = idn.parent(); 327 * } 328 * return idn == null ? null : idn.toString(); 329 * } 330 * </pre> 331 * 332 * <a name="WebSecurityDisclaimer"></a> 333 * <p>If the association between the web domain and app package cannot be verified through the steps 334 * above, but the service thinks that it is appropriate to fill persisted credentials that are 335 * stored for the web domain, the service should warn the user about the potential data 336 * leakage first, and ask for the user to confirm. For example, the service could: 337 * 338 * <ol> 339 * <li>Create a dataset that requires 340 * {@link Dataset.Builder#setAuthentication(android.content.IntentSender) authentication} to 341 * unlock. 342 * <li>Include the web domain in the custom presentation for the 343 * {@link Dataset.Builder#setValue(AutofillId, AutofillValue, android.widget.RemoteViews) 344 * dataset value}. 345 * <li>When the user selects that dataset, show a disclaimer dialog explaining that the app is 346 * requesting credentials for a web domain, but the service could not verify if the app owns 347 * that domain. If the user agrees, then the service can unlock the dataset. 348 * <li>Similarly, when adding a {@link SaveInfo} object for the request, the service should 349 * include the above disclaimer in the {@link SaveInfo.Builder#setDescription(CharSequence)}. 350 * </ol> 351 * 352 * <p>This same procedure could also be used when the autofillable data is contained inside an 353 * {@code IFRAME}, in which case the WebView generates a new autofill context when a node inside 354 * the {@code IFRAME} is focused, with the root node containing the {@code IFRAME}'s {@code src} 355 * attribute on {@link android.app.assist.AssistStructure.ViewNode#getWebDomain()}. A typical and 356 * legitimate use case for this scenario is a financial app that allows the user 357 * to login on different bank accounts. For example, a financial app {@code my_financial_app} could 358 * use a WebView that loads contents from {@code banklogin.my_financial_app.com}, which contains an 359 * {@code IFRAME} node whose {@code src} attribute is {@code login.some_bank.com}. When fulfilling 360 * that request, the service could add an 361 * {@link Dataset.Builder#setAuthentication(android.content.IntentSender) authenticated dataset} 362 * whose presentation displays "Username for some_bank.com" and 363 * "Password for some_bank.com". Then when the user taps one of these options, the service 364 * shows the disclaimer dialog explaining that selecting that option would release the 365 * {@code login.some_bank.com} credentials to the {@code my_financial_app}; if the user agrees, 366 * then the service returns an unlocked dataset with the {@code some_bank.com} credentials. 367 * 368 * <p><b>Note:</b> The autofill service could also add well-known browser apps into an allowlist and 369 * skip the verifications above, as long as the service can verify the authenticity of the browser 370 * app by checking its signing certificate. 371 * 372 * <a name="MultipleStepsSave"></a> 373 * <h3>Saving when data is split in multiple screens</h3> 374 * 375 * Apps often split the user data in multiple screens in the same activity, specially in 376 * activities used to create a new user account. For example, the first screen asks for a username, 377 * and if the username is available, it moves to a second screen, which asks for a password. 378 * 379 * <p>It's tricky to handle save for autofill in these situations, because the autofill service must 380 * wait until the user enters both fields before the autofill save UI can be shown. But it can be 381 * done by following the steps below: 382 * 383 * <ol> 384 * <li>In the first 385 * {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback) fill request}, the service 386 * adds a {@link FillResponse.Builder#setClientState(android.os.Bundle) client state bundle} in 387 * the response, containing the autofill ids of the partial fields present in the screen. 388 * <li>In the second 389 * {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback) fill request}, the service 390 * retrieves the {@link FillRequest#getClientState() client state bundle}, gets the autofill ids 391 * set in the previous request from the client state, and adds these ids and the 392 * {@link SaveInfo#FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE} to the {@link SaveInfo} used in the second 393 * response. 394 * <li>In the {@link #onSaveRequest(SaveRequest, SaveCallback) save request}, the service uses the 395 * proper {@link FillContext fill contexts} to get the value of each field (there is one fill 396 * context per fill request). 397 * </ol> 398 * 399 * <p>For example, in an app that uses 2 steps for the username and password fields, the workflow 400 * would be: 401 * <pre class="prettyprint"> 402 * // On first fill request 403 * AutofillId usernameId = // parse from AssistStructure; 404 * Bundle clientState = new Bundle(); 405 * clientState.putParcelable("usernameId", usernameId); 406 * fillCallback.onSuccess( 407 * new FillResponse.Builder() 408 * .setClientState(clientState) 409 * .setSaveInfo(new SaveInfo 410 * .Builder(SaveInfo.SAVE_DATA_TYPE_USERNAME, new AutofillId[] {usernameId}) 411 * .build()) 412 * .build()); 413 * 414 * // On second fill request 415 * Bundle clientState = fillRequest.getClientState(); 416 * AutofillId usernameId = clientState.getParcelable("usernameId"); 417 * AutofillId passwordId = // parse from AssistStructure 418 * clientState.putParcelable("passwordId", passwordId); 419 * fillCallback.onSuccess( 420 * new FillResponse.Builder() 421 * .setClientState(clientState) 422 * .setSaveInfo(new SaveInfo 423 * .Builder(SaveInfo.SAVE_DATA_TYPE_USERNAME | SaveInfo.SAVE_DATA_TYPE_PASSWORD, 424 * new AutofillId[] {usernameId, passwordId}) 425 * .setFlags(SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE) 426 * .build()) 427 * .build()); 428 * 429 * // On save request 430 * Bundle clientState = saveRequest.getClientState(); 431 * AutofillId usernameId = clientState.getParcelable("usernameId"); 432 * AutofillId passwordId = clientState.getParcelable("passwordId"); 433 * List<FillContext> fillContexts = saveRequest.getFillContexts(); 434 * 435 * FillContext usernameContext = fillContexts.get(0); 436 * ViewNode usernameNode = findNodeByAutofillId(usernameContext.getStructure(), usernameId); 437 * AutofillValue username = usernameNode.getAutofillValue().getTextValue().toString(); 438 * 439 * FillContext passwordContext = fillContexts.get(1); 440 * ViewNode passwordNode = findNodeByAutofillId(passwordContext.getStructure(), passwordId); 441 * AutofillValue password = passwordNode.getAutofillValue().getTextValue().toString(); 442 * 443 * save(username, password); 444 * </pre> 445 * 446 * <a name="Privacy"></a> 447 * <h3>Privacy</h3> 448 * 449 * <p>The {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} method is called 450 * without the user content. The Android system strips some properties of the 451 * {@link android.app.assist.AssistStructure.ViewNode view nodes} passed to this call, but not all 452 * of them. For example, the data provided in the {@link android.view.ViewStructure.HtmlInfo} 453 * objects set by {@link android.webkit.WebView} is never stripped out. 454 * 455 * <p>Because this data could contain PII (Personally Identifiable Information, such as username or 456 * email address), the service should only use it locally (i.e., in the app's process) for 457 * heuristics purposes, but it should not be sent to external servers. 458 * 459 * <a name="FieldClassification"></a> 460 * <h3>Metrics and field classification</h3> 461 * 462 * <p>The service can call {@link #getFillEventHistory()} to get metrics representing the user 463 * actions, and then use these metrics to improve its heuristics. 464 * 465 * <p>Prior to Android {@link android.os.Build.VERSION_CODES#P}, the metrics covered just the 466 * scenarios where the service knew how to autofill an activity, but Android 467 * {@link android.os.Build.VERSION_CODES#P} introduced a new mechanism called field classification, 468 * which allows the service to dynamically classify the meaning of fields based on the existing user 469 * data known by the service. 470 * 471 * <p>Typically, field classification can be used to detect fields that can be autofilled with 472 * user data that is not associated with a specific app—such as email and physical 473 * address. Once the service identifies that a such field was manually filled by the user, the 474 * service could use this signal to improve its heuristics on subsequent requests (for example, by 475 * infering which resource ids are associated with known fields). 476 * 477 * <p>The field classification workflow involves 4 steps: 478 * 479 * <ol> 480 * <li>Set the user data through {@link AutofillManager#setUserData(UserData)}. This data is 481 * cached until the system restarts (or the service is disabled), so it doesn't need to be set for 482 * all requests. 483 * <li>Identify which fields should be analysed by calling 484 * {@link FillResponse.Builder#setFieldClassificationIds(AutofillId...)}. 485 * <li>Verify the results through {@link FillEventHistory.Event#getFieldsClassification()}. 486 * <li>Use the results to dynamically create {@link Dataset} or {@link SaveInfo} objects in 487 * subsequent requests. 488 * </ol> 489 * 490 * <p>The field classification is an expensive operation and should be used carefully, otherwise it 491 * can reach its rate limit and get blocked by the Android System. Ideally, it should be used just 492 * in cases where the service could not determine how an activity can be autofilled, but it has a 493 * strong suspicious that it could. For example, if an activity has four or more fields and one of 494 * them is a list, chances are that these are address fields (like address, city, state, and 495 * zip code). 496 * 497 * <a name="CompatibilityMode"></a> 498 * <h3>Compatibility mode</h3> 499 * 500 * <p>Apps that use standard Android widgets support autofill out-of-the-box and need to do 501 * very little to improve their user experience (annotating autofillable views and providing 502 * autofill hints). However, some apps (typically browsers) do their own rendering and the rendered 503 * content may contain semantic structure that needs to be surfaced to the autofill framework. The 504 * platform exposes APIs to achieve this, however it could take some time until these apps implement 505 * autofill support. 506 * 507 * <p>To enable autofill for such apps the platform provides a compatibility mode in which the 508 * platform would fall back to the accessibility APIs to generate the state reported to autofill 509 * services and fill data. This mode needs to be explicitly requested for a given package up 510 * to a specified max version code allowing clean migration path when the target app begins to 511 * support autofill natively. Note that enabling compatibility may degrade performance for the 512 * target package and should be used with caution. The platform supports creating an allowlist for 513 * including which packages can be targeted in compatibility mode to ensure this mode is used only 514 * when needed and as long as needed. 515 * 516 * <p>You can request compatibility mode for packages of interest in the meta-data resource 517 * associated with your service. Below is a sample service declaration: 518 * 519 * <pre> <service android:name=".MyAutofillService" 520 * android:permission="android.permission.BIND_AUTOFILL_SERVICE"> 521 * <intent-filter> 522 * <action android:name="android.service.autofill.AutofillService" /> 523 * </intent-filter> 524 * <meta-data android:name="android.autofill" android:resource="@xml/autofillservice" /> 525 * </service></pre> 526 * 527 * <p>In the XML file you can specify one or more packages for which to enable compatibility 528 * mode. Below is a sample meta-data declaration: 529 * 530 * <pre> <autofill-service xmlns:android="http://schemas.android.com/apk/res/android"> 531 * <compatibility-package android:name="foo.bar.baz" android:maxLongVersionCode="1000000000"/> 532 * </autofill-service></pre> 533 * 534 * <p>Notice that compatibility mode has limitations such as: 535 * <ul> 536 * <li>No manual autofill requests. Hence, the {@link FillRequest} 537 * {@link FillRequest#getFlags() flags} never have the {@link FillRequest#FLAG_MANUAL_REQUEST} flag. 538 * <li>The value of password fields are most likely masked—for example, {@code ****} instead 539 * of {@code 1234}. Hence, you must be careful when using these values to avoid updating the user 540 * data with invalid input. For example, when you parse the {@link FillRequest} and detect a 541 * password field, you could check if its 542 * {@link android.app.assist.AssistStructure.ViewNode#getInputType() 543 * input type} has password flags and if so, don't add it to the {@link SaveInfo} object. 544 * <li>The autofill context is not always {@link AutofillManager#commit() committed} when an HTML 545 * form is submitted. Hence, you must use other mechanisms to trigger save, such as setting the 546 * {@link SaveInfo#FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE} flag on {@link SaveInfo.Builder#setFlags(int)} 547 * or using {@link SaveInfo.Builder#setTriggerId(AutofillId)}. 548 * <li>Browsers often provide their own autofill management system. When both the browser and 549 * the platform render an autofill dialog at the same time, the result can be confusing to the user. 550 * Such browsers typically offer an option for users to disable autofill, so your service should 551 * also allow users to disable compatiblity mode for specific apps. That way, it is up to the user 552 * to decide which autofill mechanism—the browser's or the platform's—should be used. 553 * </ul> 554 */ 555 public abstract class AutofillService extends Service { 556 private static final String TAG = "AutofillService"; 557 558 /** 559 * The {@link Intent} that must be declared as handled by the service. 560 * To be supported, the service must also require the 561 * {@link android.Manifest.permission#BIND_AUTOFILL_SERVICE} permission so 562 * that other applications can not abuse it. 563 */ 564 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) 565 public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillService"; 566 567 /** 568 * Name under which a AutoFillService component publishes information about itself. 569 * This meta-data should reference an XML resource containing a 570 * <code><{@link 571 * android.R.styleable#AutofillService autofill-service}></code> tag. 572 * This is a a sample XML file configuring an AutoFillService: 573 * <pre> <autofill-service 574 * android:settingsActivity="foo.bar.SettingsActivity" 575 * . . . 576 * /></pre> 577 */ 578 public static final String SERVICE_META_DATA = "android.autofill"; 579 580 /** 581 * Name of the {@link FillResponse} extra used to return a delayed fill response. 582 * 583 * <p>Please see {@link FillRequest#getDelayedFillIntentSender()} on how to send a delayed 584 * fill response to framework.</p> 585 */ 586 public static final String EXTRA_FILL_RESPONSE = "android.service.autofill.extra.FILL_RESPONSE"; 587 588 /** 589 * Name of the {@link IResultReceiver} extra used to return the primary result of a request. 590 * 591 * @hide 592 */ 593 public static final String EXTRA_RESULT = "result"; 594 595 /** 596 * Name of the {@link IResultReceiver} extra used to return the error reason of a request. 597 * 598 * @hide 599 */ 600 public static final String EXTRA_ERROR = "error"; 601 602 /** 603 * Name of the key used to mark whether the fill response is for a webview. 604 * 605 * @hide 606 */ 607 public static final String WEBVIEW_REQUESTED_CREDENTIAL_KEY = "webview_requested_credential"; 608 609 610 private final IAutoFillService mInterface = new IAutoFillService.Stub() { 611 @Override 612 public void onConnectedStateChanged(boolean connected) { 613 mHandler.sendMessage(obtainMessage( 614 connected ? AutofillService::onConnected : AutofillService::onDisconnected, 615 AutofillService.this)); 616 } 617 618 @Override 619 public void onFillRequest(FillRequest request, IFillCallback callback) { 620 ICancellationSignal transport = CancellationSignal.createTransport(); 621 try { 622 callback.onCancellable(transport); 623 } catch (RemoteException e) { 624 e.rethrowFromSystemServer(); 625 } 626 mHandler.sendMessage(obtainMessage( 627 AutofillService::onFillRequest, 628 AutofillService.this, request, CancellationSignal.fromTransport(transport), 629 new FillCallback(callback, request.getId()))); 630 } 631 632 @Override 633 public void onConvertCredentialRequest( 634 @NonNull ConvertCredentialRequest convertCredentialRequest, 635 @NonNull IConvertCredentialCallback convertCredentialCallback) { 636 mHandler.sendMessage(obtainMessage( 637 AutofillService::onConvertCredentialRequest, 638 AutofillService.this, convertCredentialRequest, 639 new ConvertCredentialCallback(convertCredentialCallback))); 640 } 641 642 @Override 643 public void onFillCredentialRequest(FillRequest request, IFillCallback callback, 644 IBinder autofillClientCallback) { 645 ICancellationSignal transport = CancellationSignal.createTransport(); 646 try { 647 callback.onCancellable(transport); 648 } catch (RemoteException e) { 649 e.rethrowFromSystemServer(); 650 } 651 mHandler.sendMessage(obtainMessage( 652 AutofillService::onFillCredentialRequest, 653 AutofillService.this, request, CancellationSignal.fromTransport(transport), 654 new FillCallback(callback, request.getId()), 655 autofillClientCallback)); 656 } 657 658 @Override 659 public void onSaveRequest(SaveRequest request, ISaveCallback callback) { 660 mHandler.sendMessage(obtainMessage( 661 AutofillService::onSaveRequest, 662 AutofillService.this, request, new SaveCallback(callback))); 663 } 664 665 @Override 666 public void onSavedPasswordCountRequest(IResultReceiver receiver) { 667 mHandler.sendMessage(obtainMessage( 668 AutofillService::onSavedDatasetsInfoRequest, 669 AutofillService.this, 670 new SavedDatasetsInfoCallbackImpl(receiver, SavedDatasetsInfo.TYPE_PASSWORDS))); 671 } 672 }; 673 674 private Handler mHandler; 675 676 @CallSuper 677 @Override onCreate()678 public void onCreate() { 679 super.onCreate(); 680 mHandler = new Handler(Looper.getMainLooper(), null, true); 681 BaseBundle.setShouldDefuse(true); 682 } 683 684 @Override onBind(Intent intent)685 public final IBinder onBind(Intent intent) { 686 if (SERVICE_INTERFACE.equals(intent.getAction())) { 687 return mInterface.asBinder(); 688 } 689 Log.w(TAG, "Tried to bind to wrong intent (should be " + SERVICE_INTERFACE + ": " + intent); 690 return null; 691 } 692 693 /** 694 * Called when the Android system connects to service. 695 * 696 * <p>You should generally do initialization here rather than in {@link #onCreate}. 697 */ onConnected()698 public void onConnected() { 699 } 700 701 /** 702 * Called by the Android system do decide if a screen can be autofilled by the service. 703 * 704 * <p>Service must call one of the {@link FillCallback} methods (like 705 * {@link FillCallback#onSuccess(FillResponse)} 706 * or {@link FillCallback#onFailure(CharSequence)}) 707 * to notify the result of the request. 708 * 709 * @param request the {@link FillRequest request} to handle. 710 * See {@link FillResponse} for examples of multiple-sections requests. 711 * @param cancellationSignal signal for observing cancellation requests. The system will use 712 * this to notify you that the fill result is no longer needed and you should stop 713 * handling this fill request in order to save resources. 714 * @param callback object used to notify the result of the request. 715 */ onFillRequest(@onNull FillRequest request, @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback)716 public abstract void onFillRequest(@NonNull FillRequest request, 717 @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback); 718 719 /** 720 * Variant of onFillRequest for internal credential manager proxy autofill service only. 721 * 722 * @hide 723 */ onFillCredentialRequest(@onNull FillRequest request, @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback, @NonNull IBinder autofillClientCallback)724 public void onFillCredentialRequest(@NonNull FillRequest request, 725 @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback, 726 @NonNull IBinder autofillClientCallback) {} 727 728 /** 729 * Called by the Android system to convert a credential manager response to a dataset 730 * 731 * @param convertCredentialRequest the request that has the original credential manager response 732 * @param convertCredentialCallback callback used to notify the result of the request. 733 * 734 * @hide 735 */ onConvertCredentialRequest( @onNull ConvertCredentialRequest convertCredentialRequest, @NonNull ConvertCredentialCallback convertCredentialCallback)736 public void onConvertCredentialRequest( 737 @NonNull ConvertCredentialRequest convertCredentialRequest, 738 @NonNull ConvertCredentialCallback convertCredentialCallback){} 739 740 /** 741 * Called when the user requests the service to save the contents of a screen. 742 * 743 * <p>If the service could not handle the request right away—for example, because it must 744 * launch an activity asking the user to authenticate first or because the network is 745 * down—the service could keep the {@link SaveRequest request} and reuse it later, 746 * but the service <b>must always</b> call {@link SaveCallback#onSuccess()} or 747 * {@link SaveCallback#onSuccess(android.content.IntentSender)} right away. 748 * 749 * <p><b>Note:</b> To retrieve the actual value of fields input by the user, the service 750 * should call 751 * {@link android.app.assist.AssistStructure.ViewNode#getAutofillValue()}; if it calls 752 * {@link android.app.assist.AssistStructure.ViewNode#getText()} or other methods, there is no 753 * guarantee such method will return the most recent value of the field. 754 * 755 * @param request the {@link SaveRequest request} to handle. 756 * See {@link FillResponse} for examples of multiple-sections requests. 757 * @param callback object used to notify the result of the request. 758 */ onSaveRequest(@onNull SaveRequest request, @NonNull SaveCallback callback)759 public abstract void onSaveRequest(@NonNull SaveRequest request, 760 @NonNull SaveCallback callback); 761 762 /** 763 * Called from system settings to display information about the datasets the user saved to this 764 * service. 765 * 766 * <p>There is no timeout for the request, but it's recommended to return the result within a 767 * few seconds, or the user may navigate away from the activity that would display the result. 768 * 769 * @param callback callback for responding to the request 770 */ onSavedDatasetsInfoRequest(@onNull SavedDatasetsInfoCallback callback)771 public void onSavedDatasetsInfoRequest(@NonNull SavedDatasetsInfoCallback callback) { 772 callback.onError(SavedDatasetsInfoCallback.ERROR_UNSUPPORTED); 773 } 774 775 /** 776 * Called when the Android system disconnects from the service. 777 * 778 * <p> At this point this service may no longer be an active {@link AutofillService}. 779 * It should not make calls on {@link AutofillManager} that requires the caller to be 780 * the current service. 781 */ onDisconnected()782 public void onDisconnected() { 783 } 784 785 /** 786 * Gets the events that happened after the last 787 * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)} 788 * call. 789 * 790 * <p>This method is typically used to keep track of previous user actions to optimize further 791 * requests. For example, the service might return email addresses in alphabetical order by 792 * default, but change that order based on the address the user picked on previous requests. 793 * 794 * <p>The history is not persisted over reboots, and it's cleared every time the service 795 * replies to a {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} by calling 796 * {@link FillCallback#onSuccess(FillResponse)} or {@link FillCallback#onFailure(CharSequence)} 797 * (if the service doesn't call any of these methods, the history will clear out after some 798 * pre-defined time). Hence, the service should call {@link #getFillEventHistory()} before 799 * finishing the {@link FillCallback}. 800 * 801 * @return The history or {@code null} if there are no events. 802 * 803 * @throws RuntimeException if the event history could not be retrieved. 804 */ getFillEventHistory()805 @Nullable public final FillEventHistory getFillEventHistory() { 806 final AutofillManager afm = getSystemService(AutofillManager.class); 807 808 if (afm == null) { 809 return null; 810 } else { 811 return afm.getFillEventHistory(); 812 } 813 } 814 } 815