diff options
author | Douglas Sigelbaum <sigelbaum@google.com> | 2017-12-04 17:37:45 -0800 |
---|---|---|
committer | Douglas Sigelbaum <sigelbaum@google.com> | 2018-01-12 21:13:42 +0000 |
commit | 481adedd3dc5728cb285262eee7879004ce3492c (patch) | |
tree | d9978ffa5b7f4fe821461005081fe6851c4d4aa2 /input | |
parent | 8450ba9b9be087c5fb94476c5c9ce589f72ee869 (diff) | |
download | android-481adedd3dc5728cb285262eee7879004ce3492c.tar.gz |
Adding support for multi-page.
Bug: 71907097
Test: manual
Change-Id: I9630d554f7e2a466446a99d09d55690af760ad37
Diffstat (limited to 'input')
12 files changed, 141 insertions, 241 deletions
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AuthActivity.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AuthActivity.java index 65ca2e57..2bcebaff 100644 --- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AuthActivity.java +++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AuthActivity.java @@ -27,16 +27,15 @@ import android.service.autofill.FillResponse; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.text.Editable; -import android.view.autofill.AutofillManager; import android.widget.EditText; import android.widget.RemoteViews; import android.widget.Toast; +import com.example.android.autofill.service.data.ClientViewMetadata; import com.example.android.autofill.service.data.ClientViewMetadataBuilder; import com.example.android.autofill.service.data.DataCallback; import com.example.android.autofill.service.data.adapter.DatasetAdapter; import com.example.android.autofill.service.data.adapter.ResponseAdapter; -import com.example.android.autofill.service.data.ClientViewMetadata; import com.example.android.autofill.service.data.source.local.DigitalAssetLinksRepository; import com.example.android.autofill.service.data.source.local.LocalAutofillDataSource; import com.example.android.autofill.service.data.source.local.dao.AutofillDao; @@ -138,14 +137,13 @@ public class AuthActivity extends AppCompatActivity { private void onSuccess() { Intent intent = getIntent(); boolean forResponse = intent.getBooleanExtra(EXTRA_FOR_RESPONSE, true); - Bundle clientState = intent.getBundleExtra(AutofillManager.EXTRA_CLIENT_STATE); AssistStructure structure = intent.getParcelableExtra(EXTRA_ASSIST_STRUCTURE); - StructureParser structureParser = new StructureParser(structure); - ClientViewMetadataBuilder builder = new ClientViewMetadataBuilder(structureParser); + ClientParser clientParser = new ClientParser(structure); + ClientViewMetadataBuilder builder = new ClientViewMetadataBuilder(clientParser); mClientViewMetadata = builder.buildClientViewMetadata(); - mDatasetAdapter = new DatasetAdapter(structureParser); + mDatasetAdapter = new DatasetAdapter(clientParser); mResponseAdapter = new ResponseAdapter(this, mClientViewMetadata, mPackageName, - mDatasetAdapter, clientState); + mDatasetAdapter); mReplyIntent = new Intent(); if (forResponse) { fetchAllDatasetsAndSetIntent(); diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/StructureParser.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/ClientParser.java index 3e6676d8..048c0018 100644 --- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/StructureParser.java +++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/ClientParser.java @@ -20,18 +20,25 @@ import android.app.assist.AssistStructure; import android.support.annotation.NonNull; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.List; import static android.app.assist.AssistStructure.ViewNode; /** * Wrapper for {@link AssistStructure} to make it easy to parse. */ -public final class StructureParser { - private final AssistStructure mStructure; +public final class ClientParser { + private final List<AssistStructure> mStructures; + + public ClientParser(@NonNull List<AssistStructure> structures) { + Preconditions.checkNotNull(structures); + mStructures = structures; + } - public StructureParser(@NonNull AssistStructure structure) { - Preconditions.checkNotNull(structure); - mStructure = structure; + public ClientParser(@NonNull AssistStructure structure) { + this(ImmutableList.of(structure)); } /** @@ -40,10 +47,12 @@ public final class StructureParser { * @param processor contains action to be performed on each {@link ViewNode}. */ public void parse(NodeProcessor processor) { - int nodes = mStructure.getWindowNodeCount(); - for (int i = 0; i < nodes; i++) { - AssistStructure.ViewNode viewNode = mStructure.getWindowNodeAt(i).getRootViewNode(); - traverseRoot(viewNode, processor); + for (AssistStructure structure : mStructures) { + int nodes = structure.getWindowNodeCount(); + for (int i = 0; i < nodes; i++) { + AssistStructure.ViewNode viewNode = structure.getWindowNodeAt(i).getRootViewNode(); + traverseRoot(viewNode, processor); + } } } diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/MyAutofillService.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/MyAutofillService.java index 4012dbe2..14c0a142 100644 --- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/MyAutofillService.java +++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/MyAutofillService.java @@ -29,8 +29,6 @@ import android.service.autofill.FillResponse; import android.service.autofill.SaveCallback; import android.service.autofill.SaveRequest; import android.support.annotation.NonNull; -import android.view.View; -import android.view.autofill.AutofillId; import android.widget.RemoteViews; import com.example.android.autofill.service.data.AutofillDataBuilder; @@ -52,19 +50,18 @@ import com.example.android.autofill.service.model.DatasetWithFilledAutofillField import com.example.android.autofill.service.settings.MyPreferences; import com.example.android.autofill.service.util.AppExecutors; import com.example.android.autofill.service.util.Util; -import static com.example.android.autofill.service.util.Util.DalCheckRequirement; + import java.util.List; -import static com.example.android.autofill.service.data.adapter.ResponseAdapter.CLIENT_STATE_PARTIAL_ID_TEMPLATE; -import static com.example.android.autofill.service.util.Util.AUTOFILL_ID_FILTER; +import static com.example.android.autofill.service.util.Util.DalCheckRequirement; import static com.example.android.autofill.service.util.Util.bundleToString; import static com.example.android.autofill.service.util.Util.dumpStructure; -import static com.example.android.autofill.service.util.Util.findNodeByFilter; import static com.example.android.autofill.service.util.Util.logVerboseEnabled; import static com.example.android.autofill.service.util.Util.logd; import static com.example.android.autofill.service.util.Util.loge; import static com.example.android.autofill.service.util.Util.logv; import static com.example.android.autofill.service.util.Util.logw; +import static java.util.stream.Collectors.toList; public class MyAutofillService extends AutofillService { @@ -72,14 +69,15 @@ public class MyAutofillService extends AutofillService { private DigitalAssetLinksRepository mDalRepository; private PackageVerificationDataSource mPackageVerificationRepository; private AutofillDataBuilder mAutofillDataBuilder; - private DatasetAdapter mDatasetAdapter; private ResponseAdapter mResponseAdapter; private ClientViewMetadata mClientViewMetadata; + private MyPreferences mPreferences; @Override public void onCreate() { super.onCreate(); - Util.setLoggingLevel(MyPreferences.getInstance(this).getLoggingLevel()); + mPreferences = MyPreferences.getInstance(this); + Util.setLoggingLevel(mPreferences.getLoggingLevel()); SharedPreferences localAfDataSourceSharedPrefs = getSharedPreferences(LocalAutofillDataSource.SHARED_PREF_KEY, Context.MODE_PRIVATE); AutofillDao autofillDao = AutofillDatabase.getInstance(this).autofillDao(); @@ -92,29 +90,31 @@ public class MyAutofillService extends AutofillService { @Override public void onFillRequest(@NonNull FillRequest request, @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback) { - AssistStructure structure = request.getFillContexts() - .get(request.getFillContexts().size() - 1).getStructure(); - StructureParser parser = new StructureParser(structure); - mDatasetAdapter = new DatasetAdapter(parser); + List<FillContext> fillContexts = request.getFillContexts(); + List<AssistStructure> structures = + fillContexts.stream().map(FillContext::getStructure).collect(toList()); + AssistStructure latestStructure = fillContexts.get(fillContexts.size() - 1).getStructure(); + ClientParser parser = new ClientParser(structures); + DatasetAdapter datasetAdapter = new DatasetAdapter(parser); ClientViewMetadataBuilder clientViewMetadataBuilder = new ClientViewMetadataBuilder(parser); mClientViewMetadata = clientViewMetadataBuilder.buildClientViewMetadata(); mResponseAdapter = new ResponseAdapter(this, mClientViewMetadata, - getPackageName(), mDatasetAdapter, request.getClientState()); - String packageName = structure.getActivityComponent().getPackageName(); + getPackageName(), datasetAdapter); + String packageName = latestStructure.getActivityComponent().getPackageName(); if (!mPackageVerificationRepository.putPackageSignatures(packageName)) { callback.onFailure(getString(R.string.invalid_package_signature)); return; } - final Bundle clientState = request.getClientState(); if (logVerboseEnabled()) { - logv("onFillRequest(): clientState=%s", bundleToString(clientState)); - dumpStructure(structure); + logv("onFillRequest(): clientState=%s", + bundleToString(request.getClientState())); + dumpStructure(latestStructure); } cancellationSignal.setOnCancelListener(() -> logw("Cancel autofill not implemented in this sample.") ); // Check user's settings for authenticating Responses and Datasets. - boolean responseAuth = MyPreferences.getInstance(this).isResponseAuth(); + boolean responseAuth = mPreferences.isResponseAuth(); if (responseAuth) { // If the entire Autofill Response is authenticated, AuthActivity is used // to generate Response. @@ -126,7 +126,7 @@ public class MyAutofillService extends AutofillService { callback.onSuccess(response); } } else { - boolean datasetAuth = MyPreferences.getInstance(this).isDatasetAuth(); + boolean datasetAuth = mPreferences.isDatasetAuth(); mLocalAutofillDataSource.getAutofillDatasets(mClientViewMetadata.getAllHints(), new DataCallback<List<DatasetWithFilledAutofillFields>>() { @Override @@ -148,58 +148,23 @@ public class MyAutofillService extends AutofillService { @Override public void onSaveRequest(@NonNull SaveRequest request, @NonNull SaveCallback callback) { List<FillContext> fillContexts = request.getFillContexts(); - int size = fillContexts.size(); - AssistStructure structure = fillContexts.get(size - 1).getStructure(); - StructureParser parser = new StructureParser(structure); - mAutofillDataBuilder = new ClientAutofillDataBuilder(parser); + List<AssistStructure> structures = + fillContexts.stream().map(FillContext::getStructure).collect(toList()); + AssistStructure latestStructure = fillContexts.get(fillContexts.size() - 1).getStructure(); + ClientParser parser = new ClientParser(structures); + Bundle clientState = request.getClientState(); + mAutofillDataBuilder = new ClientAutofillDataBuilder(parser, clientState); ClientViewMetadataBuilder clientViewMetadataBuilder = new ClientViewMetadataBuilder(parser); mClientViewMetadata = clientViewMetadataBuilder.buildClientViewMetadata(); - String packageName = structure.getActivityComponent().getPackageName(); + String packageName = latestStructure.getActivityComponent().getPackageName(); if (!mPackageVerificationRepository.putPackageSignatures(packageName)) { callback.onFailure(getString(R.string.invalid_package_signature)); return; } - Bundle clientState = request.getClientState(); if (logVerboseEnabled()) { logv("onSaveRequest(): clientState=%s", bundleToString(clientState)); } - dumpStructure(structure); - - // TODO: hardcode check for partial username - if (clientState != null) { - String usernameKey = String.format(CLIENT_STATE_PARTIAL_ID_TEMPLATE, - View.AUTOFILL_HINT_USERNAME); - AutofillId usernameId = clientState.getParcelable(usernameKey); - logd("client state for %s: %s", usernameKey, usernameId); - if (usernameId != null) { - String passwordKey = String.format(CLIENT_STATE_PARTIAL_ID_TEMPLATE, - View.AUTOFILL_HINT_PASSWORD); - AutofillId passwordId = clientState.getParcelable(passwordKey); - - logd("Scanning %d contexts for username ID %s and password ID %s.", size, - usernameId, passwordId); - AssistStructure.ViewNode usernameNode = - findNodeByFilter(fillContexts, usernameId, AUTOFILL_ID_FILTER); - AssistStructure.ViewNode passwordNode = - findNodeByFilter(fillContexts, passwordId, AUTOFILL_ID_FILTER); - String username = null, password = null; - if (usernameNode != null) { - username = usernameNode.getAutofillValue().getTextValue().toString(); - } - if (passwordNode != null) { - password = passwordNode.getAutofillValue().getTextValue().toString(); - } - - if (username != null && password != null) { - logd("user: %s, pass: %s", username, password); - // TODO: save it - callback.onFailure("TODO: save " + username + "/" + password); - return; - } else { - logw(" missing user (%s) or pass (%s)", username, password); - } - } - } + dumpStructure(latestStructure); checkWebDomainAndBuildAutofillData(packageName, callback); } @@ -207,13 +172,13 @@ public class MyAutofillService extends AutofillService { String webDomain; try { webDomain = mClientViewMetadata.getWebDomain(); - } catch(SecurityException e) { + } catch (SecurityException e) { logw(e.getMessage()); callback.onFailure(getString(R.string.security_exception)); return; } if (webDomain != null && webDomain.length() > 0) { - DalCheckRequirement req = MyPreferences.getInstance(this).getDalCheckRequirement(); + DalCheckRequirement req = mPreferences.getDalCheckRequirement(); mDalRepository.checkValid(req, new DalInfo(webDomain, packageName), new DataCallback<DalCheck>() { @Override diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientAutofillDataBuilder.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientAutofillDataBuilder.java index 5d18ae0c..09c685e9 100644 --- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientAutofillDataBuilder.java +++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientAutofillDataBuilder.java @@ -17,12 +17,13 @@ package com.example.android.autofill.service.data; import android.app.assist.AssistStructure; +import android.os.Bundle; import android.support.annotation.NonNull; import android.view.View; import android.view.autofill.AutofillValue; import com.example.android.autofill.service.AutofillHints; -import com.example.android.autofill.service.StructureParser; +import com.example.android.autofill.service.ClientParser; import com.example.android.autofill.service.model.AutofillDataset; import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields; import com.example.android.autofill.service.model.FilledAutofillField; @@ -39,16 +40,60 @@ import static com.example.android.autofill.service.AutofillHints.convertToStored import static com.example.android.autofill.service.util.Util.loge; public class ClientAutofillDataBuilder implements AutofillDataBuilder { - private final StructureParser mStructureParser; + private final ClientParser mClientParser; + private final Bundle mClientState; - public ClientAutofillDataBuilder(StructureParser structureParser) { - mStructureParser = structureParser; + private AssistStructure.ViewNode usernameNode; + private AssistStructure.ViewNode passwordNode; + + public ClientAutofillDataBuilder(ClientParser clientParser, Bundle clientState) { + mClientParser = clientParser; + mClientState = clientState; } @Override public List<DatasetWithFilledAutofillFields> buildDatasetsByPartition(int datasetNumber) { ImmutableList.Builder<DatasetWithFilledAutofillFields> listBuilder = new ImmutableList.Builder<>(); +// if (mClientState != null) { +// mClientState.setClassLoader(ClientViewMetadata.class.getClassLoader()); +// ArrayList<ClientViewMetadata> clientViewMetadataList = mClientState.getParcelableArrayList( +// ResponseAdapter.CLIENT_STATES_KEY); +// if (clientViewMetadataList != null && clientViewMetadataList.size() == 2) { +// ClientViewMetadata usernameMetadata = clientViewMetadataList.get(0); +// ClientViewMetadata passwordMetadata = clientViewMetadataList.get(1); +// boolean possibleMultiPage = +// usernameMetadata.getMultiPageMetadata().isPartOfMultiPage() && +// passwordMetadata.getMultiPageMetadata().isPartOfMultiPage(); +// AutofillId usernameId = usernameMetadata.getMultiPageMetadata().getUsernameId(); +// AutofillId passwordId = passwordMetadata.getMultiPageMetadata().getPasswordId(); +// if (possibleMultiPage && usernameId != null && passwordId != null) { +// mClientParser.parse((node) -> { +// if (usernameId.equals(node.getAutofillId())) { +// usernameNode = node; +// } else if (passwordId.equals(node.getAutofillId())) { +// passwordNode = node; +// } +// }); +// String username = null, password = null; +// if (usernameNode != null && usernameNode.getAutofillValue() != null) { +// username = usernameNode.getAutofillValue().getTextValue().toString(); +// } +// if (passwordNode != null && passwordNode.getAutofillValue() != null) { +// password = passwordNode.getAutofillValue().getTextValue().toString(); +// } +// +// if (username != null && password != null) { +// logd("user: %s, pass: %s", username, password); +// // TODO: save it +// } else { +// logw(" missing user (%s) or pass (%s)", username, password); +// } +// } +// } +// } + + for (int partition : AutofillHints.PARTITIONS) { AutofillDataset autofillDataset = new AutofillDataset(UUID.randomUUID().toString(), "dataset-" + datasetNumber + "." + partition); @@ -70,7 +115,7 @@ public class ClientAutofillDataBuilder implements AutofillDataBuilder { DatasetWithFilledAutofillFields datasetWithFilledAutofillFields = new DatasetWithFilledAutofillFields(); datasetWithFilledAutofillFields.autofillDataset = dataset; - mStructureParser.parse((node) -> + mClientParser.parse((node) -> parseAutofillFields(node, datasetWithFilledAutofillFields, partition) ); if (datasetWithFilledAutofillFields.filledAutofillFields == null) { diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadata.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadata.java index 24de40c1..21508aff 100644 --- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadata.java +++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadata.java @@ -16,12 +16,9 @@ package com.example.android.autofill.service.data; -import android.os.Parcel; -import android.os.Parcelable; import android.service.autofill.SaveInfo; import android.view.autofill.AutofillId; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -30,20 +27,7 @@ import java.util.List; * of the views in the view hierarchy, the corresponding autofill IDs, and the {@link SaveInfo} * based on the hints. */ -public class ClientViewMetadata implements Parcelable { - - public static final Creator<ClientViewMetadata> CREATOR = new Creator<ClientViewMetadata>() { - @Override - public ClientViewMetadata createFromParcel(Parcel parcel) { - return new ClientViewMetadata(parcel); - } - - @Override - public ClientViewMetadata[] newArray(int size) { - return new ClientViewMetadata[size]; - } - }; - +public class ClientViewMetadata { private final List<String> mAllHints; private final int mSaveType; private final AutofillId[] mAutofillIds; @@ -57,19 +41,6 @@ public class ClientViewMetadata implements Parcelable { mWebDomain = webDomain; } - private ClientViewMetadata(Parcel parcel) { - mAllHints = new ArrayList<>(); - parcel.readList(mAllHints, String.class.getClassLoader()); - mSaveType = parcel.readInt(); - Parcelable[] ids = parcel.readParcelableArray(AutofillId.class.getClassLoader()); - if (ids != null && ids.length > 0) { - mAutofillIds = Arrays.copyOf(ids, ids.length, AutofillId[].class); - } else { - mAutofillIds = null; - } - mWebDomain = parcel.readString(); - } - public List<String> getAllHints() { return mAllHints; } @@ -87,19 +58,6 @@ public class ClientViewMetadata implements Parcelable { } @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeList(mAllHints); - parcel.writeInt(mSaveType); - parcel.writeParcelableArray(mAutofillIds, 0); - parcel.writeString(mWebDomain); - } - - @Override - public int describeContents() { - return 0; - } - - @Override public String toString() { return "ClientViewMetadata{" + "mAllHints=" + mAllHints + diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadataBuilder.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadataBuilder.java index 394cd72d..0c54c020 100644 --- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadataBuilder.java +++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadataBuilder.java @@ -22,7 +22,7 @@ import android.util.MutableInt; import android.view.autofill.AutofillId; import com.example.android.autofill.service.AutofillHints; -import com.example.android.autofill.service.StructureParser; +import com.example.android.autofill.service.ClientParser; import java.util.ArrayList; import java.util.List; @@ -30,10 +30,10 @@ import java.util.List; import static com.example.android.autofill.service.util.Util.logd; public class ClientViewMetadataBuilder { - private StructureParser mStructureParser; + private ClientParser mClientParser; - public ClientViewMetadataBuilder(StructureParser parser) { - mStructureParser = parser; + public ClientViewMetadataBuilder(ClientParser parser) { + mClientParser = parser; } public ClientViewMetadata buildClientViewMetadata() { @@ -41,8 +41,8 @@ public class ClientViewMetadataBuilder { MutableInt saveType = new MutableInt(0); List<AutofillId> autofillIds = new ArrayList<>(); StringBuilder webDomainBuilder = new StringBuilder(); - mStructureParser.parse((node) -> parseNode(node, allHints, saveType, autofillIds)); - mStructureParser.parse((node) -> parseWebDomain(node, webDomainBuilder)); + mClientParser.parse((node) -> parseNode(node, allHints, saveType, autofillIds)); + mClientParser.parse((node) -> parseWebDomain(node, webDomainBuilder)); String webDomain = webDomainBuilder.toString(); AutofillId[] autofillIdsArray = autofillIds.toArray(new AutofillId[autofillIds.size()]); return new ClientViewMetadata(allHints, saveType.value, autofillIdsArray, webDomain); diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/adapter/DatasetAdapter.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/adapter/DatasetAdapter.java index 043f4e36..8f0cf714 100644 --- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/adapter/DatasetAdapter.java +++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/adapter/DatasetAdapter.java @@ -19,7 +19,6 @@ package com.example.android.autofill.service.data.adapter; import android.app.assist.AssistStructure; import android.content.IntentSender; import android.service.autofill.Dataset; -import android.support.annotation.NonNull; import android.util.MutableBoolean; import android.view.View; import android.view.autofill.AutofillId; @@ -27,7 +26,7 @@ import android.view.autofill.AutofillValue; import android.widget.RemoteViews; import com.example.android.autofill.service.AutofillHints; -import com.example.android.autofill.service.StructureParser; +import com.example.android.autofill.service.ClientParser; import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields; import com.example.android.autofill.service.model.FilledAutofillField; @@ -36,32 +35,16 @@ import java.util.List; import java.util.Map; import java.util.function.Function; +import static com.example.android.autofill.service.util.Util.indexOf; import static com.example.android.autofill.service.util.Util.logv; import static com.example.android.autofill.service.util.Util.logw; import static java.util.stream.Collectors.toMap; public class DatasetAdapter { - private final StructureParser mStructureParser; + private final ClientParser mClientParser; - public DatasetAdapter(StructureParser structureParser) { - mStructureParser = structureParser; - } - - /** - * Helper method for getting the index of a CharSequence object in an array. - */ - private static int indexOf(@NonNull CharSequence[] array, CharSequence charSequence) { - int index = -1; - if (charSequence == null) { - return index; - } - for (int i = 0; i < array.length; i++) { - if (charSequence.equals(array[i])) { - index = i; - break; - } - } - return index; + public DatasetAdapter(ClientParser clientParser) { + mClientParser = clientParser; } /** @@ -97,7 +80,7 @@ public class DatasetAdapter { MutableBoolean setValueAtLeastOnce = new MutableBoolean(false); Map<String, FilledAutofillField> map = datasetWithFilledAutofillFields.filledAutofillFields .stream().collect(toMap(FilledAutofillField::getHint, Function.identity())); - mStructureParser.parse((node) -> + mClientParser.parse((node) -> parseAutofillFields(node, map, datasetBuilder, setValueAtLeastOnce) ); return setValueAtLeastOnce.value; diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/adapter/ResponseAdapter.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/adapter/ResponseAdapter.java index 974288d2..967d0ba9 100644 --- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/adapter/ResponseAdapter.java +++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/adapter/ResponseAdapter.java @@ -18,7 +18,6 @@ package com.example.android.autofill.service.data.adapter; import android.content.Context; import android.content.IntentSender; -import android.os.Bundle; import android.service.autofill.Dataset; import android.service.autofill.FillResponse; import android.service.autofill.SaveInfo; @@ -30,37 +29,20 @@ import com.example.android.autofill.service.RemoteViewsHelper; import com.example.android.autofill.service.data.ClientViewMetadata; import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields; -import java.util.ArrayList; import java.util.List; -import static com.example.android.autofill.service.util.Util.logd; - public class ResponseAdapter { - public static final String CLIENT_STATE_PARTIAL_ID_TEMPLATE = "partial-%s"; - // TODO: move to settings activity and document it - private static final boolean SUPPORT_MULTIPLE_STEPS = true; - static int pageno = 0; private final Context mContext; private final DatasetAdapter mDatasetAdapter; private final String mPackageName; private final ClientViewMetadata mClientViewMetadata; - private final List<ClientViewMetadata> mPreviousClientViewMetadatas; public ResponseAdapter(Context context, ClientViewMetadata clientViewMetadata, - String packageName, DatasetAdapter datasetAdapter, Bundle clientState) { + String packageName, DatasetAdapter datasetAdapter) { mContext = context; mClientViewMetadata = clientViewMetadata; mDatasetAdapter = datasetAdapter; mPackageName = packageName; - mPreviousClientViewMetadatas = new ArrayList<>(); - if (clientState != null) { - clientState.setClassLoader(getClass().getClassLoader()); - for (int i = pageno - 1; i >= 0; i--) { - ClientViewMetadata previousPage = clientState.getParcelable("client-" + (pageno - 1)); - mPreviousClientViewMetadatas.add(previousPage); - } - logd("previous client state == " + mPreviousClientViewMetadatas); - } } /** @@ -95,68 +77,11 @@ public class ResponseAdapter { } } } - Bundle clientState = new Bundle(); - clientState.putParcelable("client-" + (pageno++), mClientViewMetadata); - int saveType = mClientViewMetadata.getSaveType(); + int saveType = 0; AutofillId[] autofillIds = mClientViewMetadata.getAutofillIds(); SaveInfo saveInfo = new SaveInfo.Builder(saveType, autofillIds).build(); responseBuilder.setSaveInfo(saveInfo); - responseBuilder.setClientState(clientState); return responseBuilder.build(); -// int saveType = mClientViewMetadata.getSaveType(); -// AutofillId[] autofillIds = mClientViewMetadata.getAutofillIds(); -// List<String> allHints = mClientViewMetadata.getAllHints(); -// if (logDebugEnabled()) { -// logd("setPartialSaveInfo() for type %s: allHints=%s, ids=%s, clientState=%s", -// getSaveTypeAsString(saveType), allHints, Arrays.toString(autofillIds), -// bundleToString(mPreviousClientState)); -// } -// // TODO: this should be more generic, but for now it's hardcode to support just activities -// // that have an username and a password in separate steps (like MultipleStepsSigninActivity) -// if ((saveType != SaveInfo.SAVE_DATA_TYPE_USERNAME -// && saveType != SaveInfo.SAVE_DATA_TYPE_PASSWORD) -// || autofillIds.length != 1 || allHints.size() != 1) { -// logd("Unsupported activity for partial info; returning full"); -// responseBuilder.setSaveInfo(mClientViewMetadata.getSaveInfo()); -// return responseBuilder.build(); -// } -// int previousSaveType; -// String previousHint; -// if (saveType == SaveInfo.SAVE_DATA_TYPE_PASSWORD) { -// previousHint = View.AUTOFILL_HINT_USERNAME; -// previousSaveType = SaveInfo.SAVE_DATA_TYPE_USERNAME; -// } else { -// previousHint = View.AUTOFILL_HINT_PASSWORD; -// previousSaveType = SaveInfo.SAVE_DATA_TYPE_PASSWORD; -// } -// String previousKey = String.format(CLIENT_STATE_PARTIAL_ID_TEMPLATE, previousHint); -// -// AutofillId previousValue = mPreviousClientState == null ? null : mPreviousClientState -// .getParcelable(previousKey); -// logd("previous: %s=%s", previousKey, previousValue); -// -// Bundle newClientState = new Bundle(); -// String key = String.format(CLIENT_STATE_PARTIAL_ID_TEMPLATE, allHints.get(0)); -// AutofillId value = autofillIds[0]; -// logd("New client state: %s = %s", key, value); -// newClientState.putParcelable(key, value); -// -// if (previousValue != null) { -// AutofillId[] newIds = new AutofillId[]{previousValue, value}; -// int newSaveType = saveType | previousSaveType; -// logd("new values: type=%s, ids=%s", -// getSaveTypeAsString(newSaveType), Arrays.toString(newIds)); -// newClientState.putAll(mPreviousClientState); -// responseBuilder.setSaveInfo(new SaveInfo.Builder(newSaveType, newIds) -// .setFlags(SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE) -// .build()) -// .setClientState(newClientState); -// -// return responseBuilder.build(); -// } -// responseBuilder.setClientState(newClientState); -// responseBuilder.setSaveInfo(mClientViewMetadata.getSaveInfo()); -// return responseBuilder.build(); } public FillResponse buildResponse(IntentSender sender, RemoteViews remoteViews) { diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/SharedPrefsPackageVerificationRepository.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/SharedPrefsPackageVerificationRepository.java index 5c462137..0d43c1fe 100644 --- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/SharedPrefsPackageVerificationRepository.java +++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/SharedPrefsPackageVerificationRepository.java @@ -20,8 +20,8 @@ import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import com.example.android.autofill.service.util.SecurityHelper; import com.example.android.autofill.service.data.source.PackageVerificationDataSource; +import com.example.android.autofill.service.util.SecurityHelper; import static com.example.android.autofill.service.util.Util.logd; import static com.example.android.autofill.service.util.Util.logw; diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/dao/AutofillDao.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/dao/AutofillDao.java index 00856ae6..385638b0 100644 --- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/dao/AutofillDao.java +++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/dao/AutofillDao.java @@ -33,8 +33,8 @@ public interface AutofillDao { /** * Fetches a list of datasets associated to autofill fields on the page. * - * @param allAutofillHints Filtering parameter; represents all of the hints associated with - * all of the views on the page. + * @param allAutofillHints Filtering parameter; represents all of the hints associated with + * all of the views on the page. */ @Query("SELECT DISTINCT id, datasetName FROM FilledAutofillField, AutofillDataset" + " WHERE AutofillDataset.id = FilledAutofillField.datasetId" + @@ -46,9 +46,9 @@ public interface AutofillDao { * if that dataset has an autofill field associate with the view the user is focused on, and * if that dataset's name matches the name passed in. * - * @param allAutofillHints Filtering parameter; represents all of the hints associated with - * all of the views on the page. - * @param datasetName Filtering parameter; only return datasets with this name. + * @param allAutofillHints Filtering parameter; represents all of the hints associated with + * all of the views on the page. + * @param datasetName Filtering parameter; only return datasets with this name. */ @Query("SELECT DISTINCT id, datasetname FROM FilledAutofillField, AutofillDataset" + " WHERE AutofillDataset.id = FilledAutofillField.datasetId" + diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/util/Util.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/util/Util.java index 53943138..a86deea5 100644 --- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/util/Util.java +++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/util/Util.java @@ -279,6 +279,23 @@ public final class Util { sLoggingLevel = level; } + /** + * Helper method for getting the index of a CharSequence object in an array. + */ + public static int indexOf(@NonNull CharSequence[] array, CharSequence charSequence) { + int index = -1; + if (charSequence == null) { + return index; + } + for (int i = 0; i < array.length; i++) { + if (charSequence.equals(array[i])) { + index = i; + break; + } + } + return index; + } + public enum LogLevel {Off, Debug, Verbose} public enum DalCheckRequirement {Disabled, LoginOnly, AllUrls} diff --git a/input/autofill/AutofillFramework/build.gradle b/input/autofill/AutofillFramework/build.gradle index 0dafc513..5e6d6a3f 100644 --- a/input/autofill/AutofillFramework/build.gradle +++ b/input/autofill/AutofillFramework/build.gradle @@ -5,7 +5,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.0' + classpath 'com.android.tools.build:gradle:3.0.1' } } |