diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-03-07 08:27:08 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-03-07 08:27:08 +0000 |
commit | f169b672994660513cc1639361d30b33263d9d36 (patch) | |
tree | 95fd3da71bccafcd3c05829e0a9e91ea7f347995 | |
parent | f6baabd613265634aa26792423013b0c7225f745 (diff) | |
parent | 849dd8a02a6e2a6963e20623cba0eaa6f19db502 (diff) | |
download | experimental-f169b672994660513cc1639361d30b33263d9d36.tar.gz |
Snap for 4638586 from 849dd8a02a6e2a6963e20623cba0eaa6f19db502 to pi-releaseandroid-wear-9.0.0_r9android-wear-9.0.0_r8android-wear-9.0.0_r7android-wear-9.0.0_r6android-wear-9.0.0_r5android-wear-9.0.0_r4android-wear-9.0.0_r34android-wear-9.0.0_r33android-wear-9.0.0_r32android-wear-9.0.0_r31android-wear-9.0.0_r30android-wear-9.0.0_r3android-wear-9.0.0_r29android-wear-9.0.0_r28android-wear-9.0.0_r27android-wear-9.0.0_r26android-wear-9.0.0_r25android-wear-9.0.0_r24android-wear-9.0.0_r23android-wear-9.0.0_r22android-wear-9.0.0_r21android-wear-9.0.0_r20android-wear-9.0.0_r2android-wear-9.0.0_r19android-wear-9.0.0_r18android-wear-9.0.0_r17android-wear-9.0.0_r16android-wear-9.0.0_r15android-wear-9.0.0_r14android-wear-9.0.0_r13android-wear-9.0.0_r12android-wear-9.0.0_r11android-wear-9.0.0_r10android-wear-9.0.0_r1android-vts-9.0_r9android-vts-9.0_r8android-vts-9.0_r7android-vts-9.0_r6android-vts-9.0_r5android-vts-9.0_r4android-vts-9.0_r19android-vts-9.0_r18android-vts-9.0_r17android-vts-9.0_r16android-vts-9.0_r15android-vts-9.0_r14android-vts-9.0_r13android-vts-9.0_r12android-vts-9.0_r11android-vts-9.0_r10android-security-9.0.0_r76android-security-9.0.0_r75android-security-9.0.0_r74android-security-9.0.0_r73android-security-9.0.0_r72android-security-9.0.0_r71android-security-9.0.0_r70android-security-9.0.0_r69android-security-9.0.0_r68android-security-9.0.0_r67android-security-9.0.0_r66android-security-9.0.0_r65android-security-9.0.0_r64android-security-9.0.0_r63android-security-9.0.0_r62android-cts-9.0_r9android-cts-9.0_r8android-cts-9.0_r7android-cts-9.0_r6android-cts-9.0_r5android-cts-9.0_r4android-cts-9.0_r3android-cts-9.0_r20android-cts-9.0_r2android-cts-9.0_r19android-cts-9.0_r18android-cts-9.0_r17android-cts-9.0_r16android-cts-9.0_r15android-cts-9.0_r14android-cts-9.0_r13android-cts-9.0_r12android-cts-9.0_r11android-cts-9.0_r10android-cts-9.0_r1android-9.0.0_r9android-9.0.0_r8android-9.0.0_r7android-9.0.0_r61android-9.0.0_r60android-9.0.0_r6android-9.0.0_r59android-9.0.0_r58android-9.0.0_r57android-9.0.0_r56android-9.0.0_r55android-9.0.0_r54android-9.0.0_r53android-9.0.0_r52android-9.0.0_r51android-9.0.0_r50android-9.0.0_r5android-9.0.0_r49android-9.0.0_r48android-9.0.0_r3android-9.0.0_r2android-9.0.0_r18android-9.0.0_r17android-9.0.0_r10android-9.0.0_r1security-pi-releasepie-vts-releasepie-security-releasepie-s2-releasepie-release-2pie-releasepie-r2-s2-releasepie-r2-s1-releasepie-r2-releasepie-platform-releasepie-gsipie-cuttlefish-testingpie-cts-release
Change-Id: I1cc9bf3e806e01c0904698715e3948c67e3b5a6b
-rw-r--r-- | FillService/AndroidManifest.xml | 8 | ||||
-rw-r--r-- | FillService/res/xml/autofill_service_config.xml | 20 | ||||
-rw-r--r-- | FillService/src/foo/bar/fill/FillService.java | 120 |
3 files changed, 114 insertions, 34 deletions
diff --git a/FillService/AndroidManifest.xml b/FillService/AndroidManifest.xml index f9128e1..da039b6 100644 --- a/FillService/AndroidManifest.xml +++ b/FillService/AndroidManifest.xml @@ -4,10 +4,16 @@ <application> <service android:name=".FillService" - android:permission="android.permission.BIND_AUTOFILL"> + android:permission="android.permission.BIND_AUTOFILL_SERVICE"> <intent-filter> <action android:name="android.service.autofill.AutofillService" /> </intent-filter> + + <meta-data + android:name="android.autofill" + android:resource="@xml/autofill_service_config"> + </meta-data> + </service> <activity android:name=".AuthActivity"/> diff --git a/FillService/res/xml/autofill_service_config.xml b/FillService/res/xml/autofill_service_config.xml new file mode 100644 index 0000000..dd73a19 --- /dev/null +++ b/FillService/res/xml/autofill_service_config.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2018 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<autofill-service xmlns:android="http://schemas.android.com/apk/res/android"> + <compatibility-package android:name="com.android.chrome" android:maxLongVersionCode="1000000000" android:urlBarResourceId="url_bar"/> + <compatibility-package android:name="com.chrome.beta" android:maxLongVersionCode="1000000000" android:urlBarResourceId="url_bar"/> +</autofill-service> diff --git a/FillService/src/foo/bar/fill/FillService.java b/FillService/src/foo/bar/fill/FillService.java index c253e7c..6eebac1 100644 --- a/FillService/src/foo/bar/fill/FillService.java +++ b/FillService/src/foo/bar/fill/FillService.java @@ -24,6 +24,7 @@ import android.app.assist.AssistStructure.WindowNode; import android.app.assist.AssistStructure.ViewNode; import android.content.Intent; import android.content.IntentSender; +import android.content.pm.PackageManager; import android.os.CancellationSignal; import android.service.autofill.AutofillService; import android.service.autofill.Dataset; @@ -33,16 +34,24 @@ import android.service.autofill.FillResponse; import android.service.autofill.SaveCallback; import android.service.autofill.SaveInfo; import android.service.autofill.SaveRequest; +import android.util.Log; import android.view.View; import android.view.autofill.AutofillId; +import android.view.autofill.AutofillManager; import android.view.autofill.AutofillValue; +import android.widget.EditText; import android.widget.RemoteViews; +import java.util.ArrayList; +import java.util.List; import java.util.function.Predicate; +import android.widget.TextView; import foo.bar.fill.R; public class FillService extends AutofillService { + private static final String LOG_TAG = "FillService"; + static final boolean TEST_RESPONSE_AUTH = false; public static final String RESPONSE_ID = "RESPONSE_ID"; @@ -76,8 +85,20 @@ public class FillService extends AutofillService { @NonNull FillCallback callback) { AssistStructure structure = request.getFillContexts().get(0).getStructure(); - ViewNode username = findUsername(structure); - ViewNode password = findPassword(structure); + dumpNodeTree(structure); + +// ViewNode username = findUsername(structure); +// ViewNode password = findPassword(structure); + + ViewNode username = null; + ViewNode password = null; + final List<ViewNode> inputs = findTextInputs(structure); + if (inputs.size() > 1) { + username = inputs.get(0); + password = inputs.get(1); + } + + Log.i(LOG_TAG, "found username+username:" + (username != null && password != null)); if (username != null && password != null) { final FillResponse response; @@ -134,46 +155,48 @@ public class FillService extends AutofillService { .setValue(password.getAutofillId(), AutofillValue.forText(DATASET1_PASSWORD)) .build()) - .addDataset(new Dataset.Builder(presentation2) - .setValue(username.getAutofillId(), - AutofillValue.forText(DATASET2_USERNAME)) - .setValue(password.getAutofillId(), - AutofillValue.forText(DATASET2_PASSWORD)) -// .setAuthentication(sender) - .build()) - .addDataset(new Dataset.Builder(presentation3) - .setValue(username.getAutofillId(), - AutofillValue.forText(DATASET3_USERNAME)) - .setValue(password.getAutofillId(), - AutofillValue.forText(DATASET3_PASSWORD)) -// .setAuthentication(sender) - .build()) - .addDataset(new Dataset.Builder(presentation4) - .setValue(username.getAutofillId(), - AutofillValue.forText(DATASET4_USERNAME)) - .setValue(password.getAutofillId(), - AutofillValue.forText(DATASET4_PASSWORD)) +// .addDataset(new Dataset.Builder(presentation2) +// .setValue(username.getAutofillId(), +// AutofillValue.forText(DATASET2_USERNAME)) +// .setValue(password.getAutofillId(), +// AutofillValue.forText(DATASET2_PASSWORD)) +//// .setAuthentication(sender) +// .build()) +// .addDataset(new Dataset.Builder(presentation3) +// .setValue(username.getAutofillId(), +// AutofillValue.forText(DATASET3_USERNAME)) +// .setValue(password.getAutofillId(), +// AutofillValue.forText(DATASET3_PASSWORD)) +//// .setAuthentication(sender) +// .build()) +// .addDataset(new Dataset.Builder(presentation4) +// .setValue(username.getAutofillId(), +// AutofillValue.forText(DATASET4_USERNAME)) +// .setValue(password.getAutofillId(), +// AutofillValue.forText(DATASET4_PASSWORD)) +//// .setAuthentication(sender) +// .build()) +// .addDataset(new Dataset.Builder(presentation5) +// .setValue(username.getAutofillId(), +// AutofillValue.forText(DATASET5_USERNAME)) +// .setValue(password.getAutofillId(), +// AutofillValue.forText(DATASET5_PASSWORD)) // .setAuthentication(sender) - .build()) - .addDataset(new Dataset.Builder(presentation5) - .setValue(username.getAutofillId(), - AutofillValue.forText(DATASET5_USERNAME)) - .setValue(password.getAutofillId(), - AutofillValue.forText(DATASET5_PASSWORD)) - .setAuthentication(sender) - .build()) +// .build()) .setSaveInfo(new SaveInfo.Builder( SaveInfo.SAVE_DATA_TYPE_PASSWORD | SaveInfo.SAVE_DATA_TYPE_USERNAME, new AutofillId[] {username.getAutofillId(), password.getAutofillId()}) + .setFlags(SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE) .build()) .build(); } callback.onSuccess(response); } else { - callback.onFailure("Whoops"); + //callback.onFailure("Whoops"); + callback.onSuccess(null); } } @@ -184,20 +207,51 @@ public class FillService extends AutofillService { ViewNode password = findPassword(structure); } + static void dumpNodeTree(AssistStructure structure) { + findByPredicate(structure, (node) -> { + if (node.getAutofillValue() != null) { + Log.e("class:" + LOG_TAG, node.getClassName() + " value:" + node.getAutofillValue()); + } +// Log.e(LOG_TAG, (node.getAutofillValue() != null && node.getAutofillValue().isText()) +// ? node.getAutofillValue().getTextValue().toString() + "-" +node.getAutofillId() : "NOPE"); + return false; + }); + } + + List<ViewNode > findTextInputs(AssistStructure structure) { + final List<ViewNode> inputs = new ArrayList<>(); + findByPredicate(structure, (node) -> { + if (node.getClassName().equals(EditText.class.getName())) { + inputs.add(node); + } + return false; + }); + return inputs; + } + static ViewNode findUsername(AssistStructure structure) { return findByPredicate(structure, (node) -> node.getAutofillType() == View.AUTOFILL_TYPE_TEXT - && "username".equals(node.getIdEntry()) + && (autofillTextValueContains(node, "username") + || "username".equals(node.getIdEntry())) ); } static ViewNode findPassword(AssistStructure structure) { return findByPredicate(structure, (node) -> - node.getAutofillType() == View.AUTOFILL_TYPE_TEXT - && "password".equals(node.getIdEntry()) + node.getAutofillType() == View.AUTOFILL_TYPE_TEXT + && (autofillTextValueContains(node, "password") + || "password".equals(node.getIdEntry())) ); } + private static boolean autofillTextValueContains(ViewNode node, String text) { + return node.getAutofillValue() != null + && node.getAutofillValue().getTextValue() != null + && node.getAutofillValue().getTextValue().toString().toLowerCase() + .contains(text.toLowerCase()); + } + private static ViewNode findByPredicate(AssistStructure structure, Predicate<ViewNode> predicate) { final int windowCount = structure.getWindowNodeCount(); |