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