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