aboutsummaryrefslogtreecommitdiff
path: root/input
diff options
context:
space:
mode:
authorDouglas Sigelbaum <sigelbaum@google.com>2017-12-13 12:13:36 -0800
committerDouglas Sigelbaum <sigelbaum@google.com>2018-01-22 15:11:43 -0800
commit591f74c8fbea899f7590351bc48141641266349b (patch)
treea26095c12d2eafeefa978e0b77d19684f610d30f /input
parente83dc7e94d3d93109fa78b7a744142d430d7367d (diff)
downloadandroid-591f74c8fbea899f7590351bc48141641266349b.tar.gz
Autofill sample: Refactor to allow for more heuristics.
* Moved default autofill hints and fake data to JSON that populates * local DB. * Made new tables in DB to represent heuristic types. * TODO: Fix bug where adding fake data doesn't work the first time. Bug: 71907097 Test: Manual Change-Id: Iffae737662e402cf17e63a6d5d0f0a276d6807bc
Diffstat (limited to 'input')
-rw-r--r--input/autofill/AutofillFramework/afservice/src/androidTest/java/com/example/android/autofill/service/data/source/local/AutofillDaoTest.java4
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AuthActivity.java57
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AutofillHintProperties.java4
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AutofillHints.java704
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/MyAutofillService.java115
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/W3cHints.java44
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientAutofillDataBuilder.java121
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadataBuilder.java13
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/FakeAutofillDataBuilder.java21
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/adapter/DatasetAdapter.java42
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/adapter/ResponseAdapter.java14
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/AutofillDataSource.java10
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/DefaultFieldTypesSource.java25
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/DefaultFieldTypesLocalJsonSource.java70
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/LocalAutofillDataSource.java61
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/dao/AutofillDao.java24
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/db/AutofillDatabase.java83
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/db/Converters.java100
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/AutofillHint.java41
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/DefaultFieldTypeWithHints.java73
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FakeData.java31
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FieldType.java81
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FieldTypeWithHints.java38
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FilledAutofillField.java21
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/settings/SettingsActivity.java50
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/res/raw/default_field_types1165
26 files changed, 2105 insertions, 907 deletions
diff --git a/input/autofill/AutofillFramework/afservice/src/androidTest/java/com/example/android/autofill/service/data/source/local/AutofillDaoTest.java b/input/autofill/AutofillFramework/afservice/src/androidTest/java/com/example/android/autofill/service/data/source/local/AutofillDaoTest.java
index 936da2b1..e8a501d2 100644
--- a/input/autofill/AutofillFramework/afservice/src/androidTest/java/com/example/android/autofill/service/data/source/local/AutofillDaoTest.java
+++ b/input/autofill/AutofillFramework/afservice/src/androidTest/java/com/example/android/autofill/service/data/source/local/AutofillDaoTest.java
@@ -74,7 +74,7 @@ public class AutofillDaoTest {
datasetWithFilledAutofillFields.filledAutofillFields =
Arrays.asList(mUsernameField, mPasswordField);
datasetWithFilledAutofillFields.filledAutofillFields
- .sort(Comparator.comparing(FilledAutofillField::getHint));
+ .sort(Comparator.comparing(FilledAutofillField::getFieldType));
// When inserting a page's autofill fields.
mDatabase.autofillDao().saveAutofillDataset(mDataset);
@@ -87,7 +87,7 @@ public class AutofillDaoTest {
List<DatasetWithFilledAutofillFields> loadedDatasets = mDatabase.autofillDao()
.getDatasets(allHints);
loadedDatasets.get(0).filledAutofillFields.sort(
- Comparator.comparing(FilledAutofillField::getHint));
+ Comparator.comparing(FilledAutofillField::getFieldType));
assertThat(loadedDatasets, contains(datasetWithFilledAutofillFields));
assertThat(loadedDatasets, hasSize(1));
}
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 2bcebaff..284769dd 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
@@ -36,14 +36,19 @@ 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.source.DefaultFieldTypesSource;
+import com.example.android.autofill.service.data.source.local.DefaultFieldTypesLocalJsonSource;
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;
import com.example.android.autofill.service.data.source.local.db.AutofillDatabase;
import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
import com.example.android.autofill.service.settings.MyPreferences;
import com.example.android.autofill.service.util.AppExecutors;
+import com.google.gson.GsonBuilder;
+import java.util.HashMap;
import java.util.List;
import static android.view.autofill.AutofillManager.EXTRA_ASSIST_STRUCTURE;
@@ -94,7 +99,11 @@ public class AuthActivity extends AppCompatActivity {
setContentView(R.layout.multidataset_service_auth_activity);
SharedPreferences sharedPreferences =
getSharedPreferences(LocalAutofillDataSource.SHARED_PREF_KEY, Context.MODE_PRIVATE);
- AutofillDao autofillDao = AutofillDatabase.getInstance(this).autofillDao();
+ DefaultFieldTypesSource defaultFieldTypesSource =
+ DefaultFieldTypesLocalJsonSource.getInstance(getResources(),
+ new GsonBuilder().create());
+ AutofillDao autofillDao = AutofillDatabase.getInstance(this,
+ defaultFieldTypesSource, new AppExecutors()).autofillDao();
mLocalAutofillDataSource = LocalAutofillDataSource.getInstance(sharedPreferences,
autofillDao, new AppExecutors());
mDalRepository = DigitalAssetLinksRepository.getInstance(getPackageManager());
@@ -139,21 +148,33 @@ public class AuthActivity extends AppCompatActivity {
boolean forResponse = intent.getBooleanExtra(EXTRA_FOR_RESPONSE, true);
AssistStructure structure = intent.getParcelableExtra(EXTRA_ASSIST_STRUCTURE);
ClientParser clientParser = new ClientParser(structure);
- ClientViewMetadataBuilder builder = new ClientViewMetadataBuilder(clientParser);
- mClientViewMetadata = builder.buildClientViewMetadata();
- mDatasetAdapter = new DatasetAdapter(clientParser);
- mResponseAdapter = new ResponseAdapter(this, mClientViewMetadata, mPackageName,
- mDatasetAdapter);
mReplyIntent = new Intent();
- if (forResponse) {
- fetchAllDatasetsAndSetIntent();
- } else {
- String datasetName = intent.getStringExtra(EXTRA_DATASET_NAME);
- fetchDatasetAndSetIntent(datasetName);
- }
+ mLocalAutofillDataSource.getFieldTypeByAutofillHints(new DataCallback<HashMap<String, FieldTypeWithHints>>() {
+ @Override
+ public void onLoaded(HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint) {
+ ClientViewMetadataBuilder builder = new ClientViewMetadataBuilder(clientParser,
+ fieldTypesByAutofillHint);
+ mClientViewMetadata = builder.buildClientViewMetadata();
+ mDatasetAdapter = new DatasetAdapter(clientParser);
+ mResponseAdapter = new ResponseAdapter(AuthActivity.this,
+ mClientViewMetadata, mPackageName, mDatasetAdapter);
+ if (forResponse) {
+ fetchAllDatasetsAndSetIntent(fieldTypesByAutofillHint);
+ } else {
+ String datasetName = intent.getStringExtra(EXTRA_DATASET_NAME);
+ fetchDatasetAndSetIntent(fieldTypesByAutofillHint, datasetName);
+ }
+ }
+
+ @Override
+ public void onDataNotAvailable(String msg, Object... params) {
+
+ }
+ });
}
- private void fetchDatasetAndSetIntent(String datasetName) {
+ private void fetchDatasetAndSetIntent(
+ HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint, String datasetName) {
mLocalAutofillDataSource.getAutofillDataset(mClientViewMetadata.getAllHints(),
datasetName, new DataCallback<DatasetWithFilledAutofillFields>() {
@Override
@@ -161,7 +182,8 @@ public class AuthActivity extends AppCompatActivity {
String datasetName = dataset.autofillDataset.getDatasetName();
RemoteViews remoteViews = RemoteViewsHelper.viewsWithNoAuth(
mPackageName, datasetName);
- setDatasetIntent(mDatasetAdapter.buildDataset(dataset, remoteViews));
+ setDatasetIntent(mDatasetAdapter.buildDataset(fieldTypesByAutofillHint,
+ dataset, remoteViews));
finish();
}
@@ -173,14 +195,15 @@ public class AuthActivity extends AppCompatActivity {
});
}
- private void fetchAllDatasetsAndSetIntent() {
+ private void fetchAllDatasetsAndSetIntent(
+ HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint) {
mLocalAutofillDataSource.getAutofillDatasets(mClientViewMetadata.getAllHints(),
new DataCallback<List<DatasetWithFilledAutofillFields>>() {
@Override
public void onLoaded(List<DatasetWithFilledAutofillFields> datasets) {
boolean datasetAuth = mPreferences.isDatasetAuth();
- FillResponse fillResponse = mResponseAdapter.buildResponse(datasets,
- datasetAuth);
+ FillResponse fillResponse = mResponseAdapter.buildResponse(
+ fieldTypesByAutofillHint, datasets, datasetAuth);
setResponseIntent(fillResponse);
finish();
}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AutofillHintProperties.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AutofillHintProperties.java
index 9b593426..8314eb30 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AutofillHintProperties.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AutofillHintProperties.java
@@ -85,4 +85,8 @@ public final class AutofillHintProperties {
public boolean isValidType(int type) {
return mValidTypes.contains(type);
}
+
+ public Set<Integer> getTypes() {
+ return mValidTypes;
+ }
}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AutofillHints.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AutofillHints.java
index 39b189c7..cd4231d1 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AutofillHints.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AutofillHints.java
@@ -15,18 +15,19 @@
*/
package com.example.android.autofill.service;
-import android.service.autofill.SaveInfo;
import android.support.annotation.NonNull;
-import android.view.View;
+import com.example.android.autofill.service.model.FakeData;
+import com.example.android.autofill.service.model.FieldType;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
import com.example.android.autofill.service.model.FilledAutofillField;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.HashMap;
import java.util.List;
import java.util.Objects;
+import java.util.UUID;
import static com.example.android.autofill.service.util.Util.logd;
import static com.example.android.autofill.service.util.Util.logw;
@@ -41,657 +42,64 @@ public final class AutofillHints {
public static final int[] PARTITIONS = {
PARTITION_OTHER, PARTITION_ADDRESS, PARTITION_EMAIL, PARTITION_CREDIT_CARD
};
- /* TODO: finish building fake data for all hints. */
- private static final ImmutableMap<String, AutofillHintProperties> sValidHints =
- new ImmutableMap.Builder<String, AutofillHintProperties>()
- .put(View.AUTOFILL_HINT_EMAIL_ADDRESS, new AutofillHintProperties(
- View.AUTOFILL_HINT_EMAIL_ADDRESS, SaveInfo.SAVE_DATA_TYPE_EMAIL_ADDRESS,
- PARTITION_EMAIL,
- (seed, datasetId) -> {
- String textValue = "email" + seed;
- return new FilledAutofillField(datasetId,
- View.AUTOFILL_HINT_EMAIL_ADDRESS, textValue);
-
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(View.AUTOFILL_HINT_NAME, new AutofillHintProperties(
- View.AUTOFILL_HINT_NAME, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "name" + seed;
- return new FilledAutofillField(datasetId, View.AUTOFILL_HINT_NAME,
- textValue);
-
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(View.AUTOFILL_HINT_USERNAME, new AutofillHintProperties(
- View.AUTOFILL_HINT_USERNAME, SaveInfo.SAVE_DATA_TYPE_USERNAME,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "login" + seed;
- return new FilledAutofillField(datasetId,
- View.AUTOFILL_HINT_USERNAME, textValue);
-
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(View.AUTOFILL_HINT_PASSWORD, new AutofillHintProperties(
- View.AUTOFILL_HINT_PASSWORD, SaveInfo.SAVE_DATA_TYPE_PASSWORD,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "login" + seed;
- return new FilledAutofillField(datasetId,
- View.AUTOFILL_HINT_PASSWORD, textValue);
-
- }, View.AUTOFILL_TYPE_TEXT))
- .put(View.AUTOFILL_HINT_PHONE, new AutofillHintProperties(
- View.AUTOFILL_HINT_PHONE, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "" + seed + "2345678910";
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_PHONE, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(View.AUTOFILL_HINT_POSTAL_ADDRESS, new AutofillHintProperties(
- View.AUTOFILL_HINT_POSTAL_ADDRESS, SaveInfo.SAVE_DATA_TYPE_ADDRESS,
- PARTITION_ADDRESS,
- (seed, datasetId) -> {
- String textValue =
- "" + seed + " Fake Ln, Fake, FA, FAA 10001";
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_POSTAL_ADDRESS, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(View.AUTOFILL_HINT_POSTAL_CODE, new AutofillHintProperties(
- View.AUTOFILL_HINT_POSTAL_CODE, SaveInfo.SAVE_DATA_TYPE_ADDRESS,
- PARTITION_ADDRESS,
- (seed, datasetId) -> {
- String textValue = "1000" + seed;
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_POSTAL_CODE, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(View.AUTOFILL_HINT_CREDIT_CARD_NUMBER, new AutofillHintProperties(
- View.AUTOFILL_HINT_CREDIT_CARD_NUMBER,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD,
- PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- String textValue = "" + seed + "234567";
- return new FilledAutofillField(
- datasetId,
- View.AUTOFILL_HINT_CREDIT_CARD_NUMBER, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(View.AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE, new AutofillHintProperties(
- View.AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD,
- PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- String textValue = "" + seed + seed + seed;
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE,
- textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE, new AutofillHintProperties(
- View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD, PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + seed);
- Long dateValue = calendar.getTimeInMillis();
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE,
- dateValue);
- }, View.AUTOFILL_TYPE_DATE))
- .put(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH, new AutofillHintProperties(
- View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD, PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- CharSequence[] months = monthRange();
- int month = seed % months.length;
- Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.MONTH, month);
- String textValue = Integer.toString(month);
- Long dateValue = calendar.getTimeInMillis();
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH,
- textValue, dateValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST,
- View.AUTOFILL_TYPE_DATE))
- .put(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR, new AutofillHintProperties(
- View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD, PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- Calendar calendar = Calendar.getInstance();
- int expYear = calendar.get(Calendar.YEAR) + seed;
- calendar.set(Calendar.YEAR, expYear);
- Long dateValue = calendar.getTimeInMillis();
- String textValue = Integer.toString(expYear);
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR,
- textValue, dateValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST,
- View.AUTOFILL_TYPE_DATE))
- .put(View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY, new AutofillHintProperties(
- View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD, PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- CharSequence[] days = dayRange();
- int day = seed % days.length;
- Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.DATE, day);
- String textValue = Integer.toString(day);
- Long dateValue = calendar.getTimeInMillis();
- return new FilledAutofillField(datasetId,
- View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY,
- textValue, dateValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST,
- View.AUTOFILL_TYPE_DATE))
- .put(W3cHints.HONORIFIC_PREFIX, new AutofillHintProperties(
- W3cHints.HONORIFIC_PREFIX, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- CharSequence[] examplePrefixes = {"Miss", "Ms.", "Mr.", "Mx.",
- "Sr.", "Dr.", "Lady", "Lord"};
- String textValueFromList =
- examplePrefixes[seed % examplePrefixes.length].toString();
- return new FilledAutofillField(
- datasetId, W3cHints.HONORIFIC_PREFIX, textValueFromList);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.GIVEN_NAME, new AutofillHintProperties(W3cHints.GIVEN_NAME,
- SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "name" + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.GIVEN_NAME, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.ADDITIONAL_NAME, new AutofillHintProperties(
- W3cHints.ADDITIONAL_NAME, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "addtlname" + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.ADDITIONAL_NAME, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.FAMILY_NAME, new AutofillHintProperties(
- W3cHints.FAMILY_NAME, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "famname" + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.FAMILY_NAME, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.HONORIFIC_SUFFIX, new AutofillHintProperties(
- W3cHints.HONORIFIC_SUFFIX, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- CharSequence[] exampleSuffixes = {"san", "kun", "chan", "sama"};
- String textValueFromListValue =
- exampleSuffixes[seed % exampleSuffixes.length].toString();
- return new FilledAutofillField(
- datasetId, W3cHints.HONORIFIC_SUFFIX,
- textValueFromListValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.NEW_PASSWORD, new AutofillHintProperties(
- W3cHints.NEW_PASSWORD, SaveInfo.SAVE_DATA_TYPE_PASSWORD,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "login" + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.NEW_PASSWORD, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.CURRENT_PASSWORD, new AutofillHintProperties(
- View.AUTOFILL_HINT_PASSWORD, SaveInfo.SAVE_DATA_TYPE_PASSWORD,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "login" + seed;
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_PASSWORD, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.ORGANIZATION_TITLE, new AutofillHintProperties(
- W3cHints.ORGANIZATION_TITLE, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "org" + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.ORGANIZATION_TITLE, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.ORGANIZATION, new AutofillHintProperties(W3cHints.ORGANIZATION,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "org" + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.ORGANIZATION, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.STREET_ADDRESS, new AutofillHintProperties(
- W3cHints.STREET_ADDRESS, SaveInfo.SAVE_DATA_TYPE_ADDRESS,
- PARTITION_ADDRESS,
- (seed, datasetId) -> {
- String textValue =
- "" + seed + " Fake Ln, Fake, FA, FAA 10001";
- return new FilledAutofillField(
- datasetId, W3cHints.STREET_ADDRESS, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.ADDRESS_LINE1, new AutofillHintProperties(W3cHints.ADDRESS_LINE1,
- SaveInfo.SAVE_DATA_TYPE_ADDRESS,
- PARTITION_ADDRESS,
- (seed, datasetId) -> {
- String textValue = "" + seed + " Fake Ln";
- return new FilledAutofillField(
- datasetId, W3cHints.ADDRESS_LINE1, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.ADDRESS_LINE2, new AutofillHintProperties(W3cHints.ADDRESS_LINE2,
- SaveInfo.SAVE_DATA_TYPE_ADDRESS, PARTITION_ADDRESS,
- (seed, datasetId) -> {
- String textValue = "Bldg. " + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.ADDRESS_LINE2, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.ADDRESS_LINE3, new AutofillHintProperties(W3cHints.ADDRESS_LINE3,
- SaveInfo.SAVE_DATA_TYPE_ADDRESS, PARTITION_ADDRESS,
- (seed, datasetId) -> {
- String textValue = "Suite " + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.ADDRESS_LINE3, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.ADDRESS_LEVEL4, new AutofillHintProperties(
- W3cHints.ADDRESS_LEVEL4, SaveInfo.SAVE_DATA_TYPE_ADDRESS,
- PARTITION_ADDRESS,
- (seed, datasetId) -> {
- String textValue = "city " + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.ADDRESS_LEVEL4, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.ADDRESS_LEVEL3, new AutofillHintProperties(
- W3cHints.ADDRESS_LEVEL3, SaveInfo.SAVE_DATA_TYPE_ADDRESS,
- PARTITION_ADDRESS,
- (seed, datasetId) -> {
- String textValue = "county " + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.ADDRESS_LEVEL3, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.ADDRESS_LEVEL2, new AutofillHintProperties(
- W3cHints.ADDRESS_LEVEL2, SaveInfo.SAVE_DATA_TYPE_ADDRESS,
- PARTITION_ADDRESS,
- (seed, datasetId) -> {
- String textValue = "state " + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.ADDRESS_LEVEL2, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.ADDRESS_LEVEL1, new AutofillHintProperties(
- W3cHints.ADDRESS_LEVEL1, SaveInfo.SAVE_DATA_TYPE_ADDRESS,
- PARTITION_ADDRESS,
- (seed, datasetId) -> {
- String textValue = "country " + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.ADDRESS_LEVEL1, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.COUNTRY, new AutofillHintProperties(W3cHints.COUNTRY,
- SaveInfo.SAVE_DATA_TYPE_ADDRESS, PARTITION_ADDRESS,
- (seed, datasetId) -> {
- String textValue = "country " + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.COUNTRY, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.COUNTRY_NAME, new AutofillHintProperties(W3cHints.COUNTRY_NAME,
- SaveInfo.SAVE_DATA_TYPE_ADDRESS, PARTITION_ADDRESS,
- (seed, datasetId) -> {
- CharSequence[] exampleCountries = {"USA", "Mexico", "Canada"};
- String textValue = exampleCountries[seed % exampleCountries.length]
- .toString();
- return new FilledAutofillField(
- datasetId, W3cHints.COUNTRY_NAME, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.POSTAL_CODE, new AutofillHintProperties(
- View.AUTOFILL_HINT_POSTAL_CODE, SaveInfo.SAVE_DATA_TYPE_ADDRESS,
- PARTITION_ADDRESS,
- (seed, datasetId) -> {
- String textValue = "" + seed + seed + seed + seed + seed;
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_POSTAL_CODE, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.CC_NAME, new AutofillHintProperties(W3cHints.CC_NAME,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD,
- PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- String textValue = "firstname" + seed + "lastname" + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.CC_NAME, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.CC_GIVEN_NAME, new AutofillHintProperties(W3cHints.CC_GIVEN_NAME,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD, PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- String textValue = "givenname" + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.CC_GIVEN_NAME, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.CC_ADDITIONAL_NAME, new AutofillHintProperties(
- W3cHints.CC_ADDITIONAL_NAME, SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD,
- PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- String textValue = "addtlname" + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.CC_ADDITIONAL_NAME, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.CC_FAMILY_NAME, new AutofillHintProperties(
- W3cHints.CC_FAMILY_NAME, SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD,
- PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- String textValue = "familyname" + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.CC_FAMILY_NAME, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.CC_NUMBER, new AutofillHintProperties(
- View.AUTOFILL_HINT_CREDIT_CARD_NUMBER,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD, PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- String textValue = "" + seed + "234567";
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_CREDIT_CARD_NUMBER,
- textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.CC_EXPIRATION, new AutofillHintProperties(
- View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD, PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + seed);
- Long dateValue = calendar.getTimeInMillis();
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE,
- dateValue);
- }, View.AUTOFILL_TYPE_DATE))
- .put(W3cHints.CC_EXPIRATION_MONTH, new AutofillHintProperties(
- View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD, PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- CharSequence[] months = monthRange();
- String textValueFromListValue = months[seed % months.length]
- .toString();
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH,
- textValueFromListValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.CC_EXPIRATION_YEAR, new AutofillHintProperties(
- View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD, PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- Calendar calendar = Calendar.getInstance();
- int expYear = calendar.get(Calendar.YEAR) + seed;
- calendar.set(Calendar.YEAR, expYear);
- Long dateValue = calendar.getTimeInMillis();
- String textValue = "" + expYear;
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR,
- textValue, dateValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.CC_CSC, new AutofillHintProperties(
- View.AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD, PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- String textValue = "" + seed + seed + seed;
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE,
- textValue);
-
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.CC_TYPE, new AutofillHintProperties(W3cHints.CC_TYPE,
- SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD, PARTITION_CREDIT_CARD,
- (seed, datasetId) -> {
- String textValue = "type" + seed;
- return new FilledAutofillField(
- datasetId, W3cHints.CC_TYPE, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.TRANSACTION_CURRENCY, new AutofillHintProperties(
- W3cHints.TRANSACTION_CURRENCY, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- CharSequence[] exampleCurrencies = {"USD", "CAD", "KYD", "CRC"};
- String textValueFromListValue =
- exampleCurrencies[seed % exampleCurrencies.length]
- .toString();
- return new FilledAutofillField(
- datasetId, W3cHints.TRANSACTION_CURRENCY,
- textValueFromListValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.TRANSACTION_AMOUNT, new AutofillHintProperties(
- W3cHints.TRANSACTION_AMOUNT, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "" + seed * 100;
- return new FilledAutofillField(
- datasetId, W3cHints.TRANSACTION_AMOUNT, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.LANGUAGE, new AutofillHintProperties(W3cHints.LANGUAGE,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- CharSequence[] exampleLanguages = {"Bulgarian", "Croatian", "Czech",
- "Danish", "Dutch", "English", "Estonian"};
- String textValueFromListValue =
- exampleLanguages[seed % exampleLanguages.length].toString();
- return new FilledAutofillField(
- datasetId, W3cHints.LANGUAGE, textValueFromListValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.BDAY, new AutofillHintProperties(W3cHints.BDAY,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- Calendar calendar = Calendar.getInstance();
- calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - seed * 10);
- calendar.set(Calendar.MONTH, seed % 12);
- calendar.set(Calendar.DATE, seed % 27);
- Long dateValue = calendar.getTimeInMillis();
- return new FilledAutofillField(datasetId, W3cHints.BDAY, dateValue);
- }, View.AUTOFILL_TYPE_DATE))
- .put(W3cHints.BDAY_DAY, new AutofillHintProperties(W3cHints.BDAY_DAY,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "" + seed % 27;
- return new FilledAutofillField(
- datasetId, W3cHints.BDAY_DAY, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.BDAY_MONTH, new AutofillHintProperties(W3cHints.BDAY_MONTH,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "" + seed % 12;
- return new FilledAutofillField(
- datasetId, W3cHints.BDAY_MONTH, textValue);
-
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.BDAY_YEAR, new AutofillHintProperties(W3cHints.BDAY_YEAR,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- int year = Calendar.getInstance().get(Calendar.YEAR) - seed * 10;
- String textValue = "" + year;
- return new FilledAutofillField(
- datasetId, W3cHints.BDAY_YEAR, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.SEX, new AutofillHintProperties(W3cHints.SEX,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "Other";
- return new FilledAutofillField(
- datasetId, W3cHints.SEX, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.URL, new AutofillHintProperties(W3cHints.URL,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "http://google.com";
- return new FilledAutofillField(
- datasetId, W3cHints.URL, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.PHOTO, new AutofillHintProperties(W3cHints.PHOTO,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- String textValue = "photo" + seed + ".jpg";
- return new FilledAutofillField(
- datasetId, W3cHints.PHOTO, textValue);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.PREFIX_SECTION, new AutofillHintProperties(
- W3cHints.PREFIX_SECTION, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.PREFIX_SECTION);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.SHIPPING, new AutofillHintProperties(W3cHints.SHIPPING,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_ADDRESS,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.SHIPPING);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.BILLING, new AutofillHintProperties(W3cHints.BILLING,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_ADDRESS,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.BILLING);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.PREFIX_HOME, new AutofillHintProperties(W3cHints.PREFIX_HOME,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.PREFIX_HOME);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.PREFIX_WORK, new AutofillHintProperties(W3cHints.PREFIX_WORK,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.PREFIX_WORK);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.PREFIX_FAX, new AutofillHintProperties(W3cHints.PREFIX_FAX,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.PREFIX_FAX);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.PREFIX_PAGER, new AutofillHintProperties(W3cHints.PREFIX_PAGER,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.PREFIX_PAGER);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.TEL, new AutofillHintProperties(W3cHints.TEL,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.TEL);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.TEL_COUNTRY_CODE, new AutofillHintProperties(
- W3cHints.TEL_COUNTRY_CODE, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.TEL_COUNTRY_CODE);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.TEL_NATIONAL, new AutofillHintProperties(W3cHints.TEL_NATIONAL,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.TEL_NATIONAL);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.TEL_AREA_CODE, new AutofillHintProperties(
- W3cHints.TEL_AREA_CODE, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.TEL_AREA_CODE);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.TEL_LOCAL, new AutofillHintProperties(
- W3cHints.TEL_LOCAL, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.TEL_LOCAL);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.TEL_LOCAL_PREFIX, new AutofillHintProperties(
- W3cHints.TEL_LOCAL_PREFIX, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.TEL_LOCAL_PREFIX);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.TEL_LOCAL_SUFFIX, new AutofillHintProperties(
- W3cHints.TEL_LOCAL_SUFFIX, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.TEL_LOCAL_SUFFIX);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.TEL_EXTENSION, new AutofillHintProperties(W3cHints.TEL_EXTENSION,
- SaveInfo.SAVE_DATA_TYPE_GENERIC, PARTITION_OTHER,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.TEL_EXTENSION);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .put(W3cHints.EMAIL, new AutofillHintProperties(
- View.AUTOFILL_HINT_EMAIL_ADDRESS, SaveInfo.SAVE_DATA_TYPE_GENERIC,
- PARTITION_EMAIL,
- (seed, datasetId) -> {
- String textValue = "email" + seed;
- return new FilledAutofillField(
- datasetId, View.AUTOFILL_HINT_EMAIL_ADDRESS, textValue);
- }, View.AUTOFILL_TYPE_TEXT))
- .put(W3cHints.IMPP, new AutofillHintProperties(W3cHints.IMPP,
- SaveInfo.SAVE_DATA_TYPE_EMAIL_ADDRESS, PARTITION_EMAIL,
- (seed, datasetId) -> {
- return new FilledAutofillField(
- datasetId, W3cHints.IMPP);
- }, View.AUTOFILL_TYPE_TEXT, View.AUTOFILL_TYPE_LIST))
- .build();
private AutofillHints() {
}
- public static boolean isValidTypeForHints(@NonNull String hint, int type) {
- if (sValidHints.containsKey(hint)) {
- boolean valid = sValidHints.get(hint).isValidType(type);
- if (valid) {
- return true;
+ public static FilledAutofillField generateFakeField(FieldTypeWithHints fieldTypeWithHints,
+ int seed, String datasetId) {
+ FakeData fakeData = fieldTypeWithHints.fieldType.getFakeData();
+ String fieldTypeName = fieldTypeWithHints.fieldType.getTypeName();
+ String text = null;
+ Long date = null;
+ Boolean toggle = null;
+ if (fakeData.strictExampleSet != null && fakeData.strictExampleSet.strings != null &&
+ fakeData.strictExampleSet.strings.size() > 0 &&
+ !fakeData.strictExampleSet.strings.get(0).isEmpty()) {
+ List<String> choices = fakeData.strictExampleSet.strings;
+ text = choices.get(seed % choices.size());
+ } else if (fakeData.textTemplate != null) {
+ text = fakeData.textTemplate.replace("seed", "" + seed)
+ .replace("curr_time", "" + Calendar.getInstance().getTimeInMillis());
+ } else if (fakeData.dateTemplate != null) {
+ if (fakeData.dateTemplate.contains("curr_time")) {
+ date = Calendar.getInstance().getTimeInMillis();
}
}
- return false;
- }
-
- public static boolean isValidHint(@NonNull String hint) {
- return sValidHints.containsKey(hint);
- }
-
- public static int getSaveTypeForHint(@NonNull String hint) {
- if (sValidHints.containsKey(hint)) {
- return sValidHints.get(hint).getSaveType();
- } else {
- return 0;
- }
- }
-
- public static FilledAutofillField generateFakeField(@NonNull String hint, int seed,
- String datasetId) {
- if (isValidHint(hint)) {
- return sValidHints.get(hint).generateFakeField(seed, datasetId);
- } else {
- return null;
- }
- }
-
- public static ImmutableSet<String> getHints() {
- return sValidHints.keySet();
+ FilledAutofillField filledAutofillField = new FilledAutofillField(datasetId, fieldTypeName,
+ text, date, toggle);
+ boolean isNull = filledAutofillField.isNull();
+ return filledAutofillField;
}
- public static List<String> convertToStoredHintNames(@NonNull List<String> hints) {
- return convertToStoredHintNames(hints, PARTITION_ALL);
+ public static String getFieldTypeNameFromAutofillHints(
+ HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint,
+ @NonNull List<String> hints) {
+ return getFieldTypeNameFromAutofillHints(fieldTypesByAutofillHint, hints, PARTITION_ALL);
}
- public static List<String> convertToStoredHintNames(@NonNull List<String> hints, int partition) {
- return removePrefixes(hints)
+ public static String getFieldTypeNameFromAutofillHints(
+ HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint,
+ @NonNull List<String> hints, int partition) {
+ List<String> fieldTypeNames = removePrefixes(hints)
.stream()
- .filter(sValidHints::containsKey)
- .map(sValidHints::get)
+ .filter(fieldTypesByAutofillHint::containsKey)
+ .map(fieldTypesByAutofillHint::get)
.filter(Objects::nonNull)
- .filter((properties) -> matchesPartition(properties, partition))
- .map(AutofillHintProperties::getAutofillHint)
+ .filter((fieldTypeWithHints) ->
+ matchesPartition(fieldTypeWithHints.fieldType.getPartition(), partition))
+ .map(FieldTypeWithHints::getFieldType).map(FieldType::getTypeName)
.collect(toList());
+ if (fieldTypeNames != null && fieldTypeNames.size() > 0) {
+ return fieldTypeNames.get(0);
+ } else {
+ return null;
+ }
}
- public static boolean matchesPartition(@NonNull String hint, int partition) {
- return isValidHint(hint) && matchesPartition(sValidHints.get(hint), partition);
- }
-
- private static boolean matchesPartition(@NonNull AutofillHintProperties properties,
- int partition) {
- return partition == PARTITION_ALL || properties.getPartition() == partition;
+ public static boolean matchesPartition(int partition, int otherPartition) {
+ return partition == PARTITION_ALL || otherPartition == PARTITION_ALL ||
+ partition == otherPartition;
}
private static List<String> removePrefixes(@NonNull List<String> hints) {
@@ -726,22 +134,6 @@ public final class AutofillHints {
return hintsWithoutPrefixes;
}
- private static CharSequence[] dayRange() {
- CharSequence[] days = new CharSequence[27];
- for (int i = 0; i < days.length; i++) {
- days[i] = Integer.toString(i);
- }
- return days;
- }
-
- private static CharSequence[] monthRange() {
- CharSequence[] months = new CharSequence[12];
- for (int i = 0; i < months.length; i++) {
- months[i] = Integer.toString(i);
- }
- return months;
- }
-
private static boolean isW3cSectionPrefix(@NonNull String hint) {
return hint.startsWith(W3cHints.PREFIX_SECTION);
}
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 14c0a142..b50c8482 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
@@ -19,7 +19,6 @@ import android.app.assist.AssistStructure;
import android.content.Context;
import android.content.IntentSender;
import android.content.SharedPreferences;
-import android.os.Bundle;
import android.os.CancellationSignal;
import android.service.autofill.AutofillService;
import android.service.autofill.FillCallback;
@@ -38,7 +37,9 @@ 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.source.DefaultFieldTypesSource;
import com.example.android.autofill.service.data.source.PackageVerificationDataSource;
+import com.example.android.autofill.service.data.source.local.DefaultFieldTypesLocalJsonSource;
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.SharedPrefsPackageVerificationRepository;
@@ -47,10 +48,13 @@ import com.example.android.autofill.service.data.source.local.db.AutofillDatabas
import com.example.android.autofill.service.model.DalCheck;
import com.example.android.autofill.service.model.DalInfo;
import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
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 com.google.gson.GsonBuilder;
+import java.util.HashMap;
import java.util.List;
import static com.example.android.autofill.service.util.Util.DalCheckRequirement;
@@ -80,7 +84,11 @@ public class MyAutofillService extends AutofillService {
Util.setLoggingLevel(mPreferences.getLoggingLevel());
SharedPreferences localAfDataSourceSharedPrefs =
getSharedPreferences(LocalAutofillDataSource.SHARED_PREF_KEY, Context.MODE_PRIVATE);
- AutofillDao autofillDao = AutofillDatabase.getInstance(this).autofillDao();
+ DefaultFieldTypesSource defaultFieldTypesSource =
+ DefaultFieldTypesLocalJsonSource.getInstance(getResources(),
+ new GsonBuilder().create());
+ AutofillDao autofillDao = AutofillDatabase.getInstance(this,
+ defaultFieldTypesSource, new AppExecutors()).autofillDao();
mLocalAutofillDataSource = LocalAutofillDataSource.getInstance(localAfDataSourceSharedPrefs,
autofillDao, new AppExecutors());
mDalRepository = DigitalAssetLinksRepository.getInstance(getPackageManager());
@@ -95,26 +103,48 @@ public class MyAutofillService extends AutofillService {
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(), datasetAdapter);
- String packageName = latestStructure.getActivityComponent().getPackageName();
- if (!mPackageVerificationRepository.putPackageSignatures(packageName)) {
- callback.onFailure(getString(R.string.invalid_package_signature));
- return;
- }
- if (logVerboseEnabled()) {
- 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 = mPreferences.isResponseAuth();
+ boolean datasetAuth = mPreferences.isDatasetAuth();
+ mLocalAutofillDataSource.getFieldTypeByAutofillHints(
+ new DataCallback<HashMap<String, FieldTypeWithHints>>() {
+ @Override
+ public void onLoaded(HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint) {
+ DatasetAdapter datasetAdapter = new DatasetAdapter(parser);
+ ClientViewMetadataBuilder clientViewMetadataBuilder =
+ new ClientViewMetadataBuilder(parser, fieldTypesByAutofillHint);
+ mClientViewMetadata = clientViewMetadataBuilder.buildClientViewMetadata();
+ mResponseAdapter = new ResponseAdapter(MyAutofillService.this,
+ mClientViewMetadata, getPackageName(), datasetAdapter);
+ String packageName = latestStructure.getActivityComponent().getPackageName();
+ if (!mPackageVerificationRepository.putPackageSignatures(packageName)) {
+ callback.onFailure(getString(R.string.invalid_package_signature));
+ return;
+ }
+ if (logVerboseEnabled()) {
+ logv("onFillRequest(): clientState=%s",
+ bundleToString(request.getClientState()));
+ dumpStructure(latestStructure);
+ }
+ cancellationSignal.setOnCancelListener(() ->
+ logw("Cancel autofill not implemented in this sample.")
+ );
+ fetchDataAndGenerateResponse(fieldTypesByAutofillHint, responseAuth,
+ datasetAuth, callback);
+ }
+
+ @Override
+ public void onDataNotAvailable(String msg, Object... params) {
+
+ }
+ });
+ }
+
+ private void fetchDataAndGenerateResponse(
+ HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint, boolean responseAuth,
+ boolean datasetAuth, FillCallback callback) {
if (responseAuth) {
// If the entire Autofill Response is authenticated, AuthActivity is used
// to generate Response.
@@ -126,13 +156,12 @@ public class MyAutofillService extends AutofillService {
callback.onSuccess(response);
}
} else {
- boolean datasetAuth = mPreferences.isDatasetAuth();
mLocalAutofillDataSource.getAutofillDatasets(mClientViewMetadata.getAllHints(),
new DataCallback<List<DatasetWithFilledAutofillFields>>() {
@Override
public void onLoaded(List<DatasetWithFilledAutofillFields> datasets) {
- FillResponse response = mResponseAdapter.buildResponse(datasets,
- datasetAuth);
+ FillResponse response = mResponseAdapter.buildResponse(
+ fieldTypesByAutofillHint, datasets, datasetAuth);
callback.onSuccess(response);
}
@@ -152,20 +181,32 @@ public class MyAutofillService extends AutofillService {
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 = latestStructure.getActivityComponent().getPackageName();
- if (!mPackageVerificationRepository.putPackageSignatures(packageName)) {
- callback.onFailure(getString(R.string.invalid_package_signature));
- return;
- }
- if (logVerboseEnabled()) {
- logv("onSaveRequest(): clientState=%s", bundleToString(clientState));
- }
- dumpStructure(latestStructure);
- checkWebDomainAndBuildAutofillData(packageName, callback);
+ mLocalAutofillDataSource.getFieldTypeByAutofillHints(
+ new DataCallback<HashMap<String, FieldTypeWithHints>>() {
+ @Override
+ public void onLoaded(HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint) {
+ mAutofillDataBuilder = new ClientAutofillDataBuilder(fieldTypesByAutofillHint, parser);
+ ClientViewMetadataBuilder clientViewMetadataBuilder =
+ new ClientViewMetadataBuilder(parser, fieldTypesByAutofillHint);
+ mClientViewMetadata = clientViewMetadataBuilder.buildClientViewMetadata();
+ String packageName = latestStructure.getActivityComponent().getPackageName();
+ if (!mPackageVerificationRepository.putPackageSignatures(packageName)) {
+ callback.onFailure(getString(R.string.invalid_package_signature));
+ return;
+ }
+ if (logVerboseEnabled()) {
+ logv("onSaveRequest(): clientState=%s",
+ bundleToString(request.getClientState()));
+ }
+ dumpStructure(latestStructure);
+ checkWebDomainAndBuildAutofillData(packageName, callback);
+ }
+
+ @Override
+ public void onDataNotAvailable(String msg, Object... params) {
+ loge("Should not happen - could not find field types.");
+ }
+ });
}
private void checkWebDomainAndBuildAutofillData(String packageName, SaveCallback callback) {
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/W3cHints.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/W3cHints.java
index 1721477c..fd8e9457 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/W3cHints.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/W3cHints.java
@@ -16,50 +16,6 @@
package com.example.android.autofill.service;
public final class W3cHints {
-
- // Supported W3C autofill tokens (https://html.spec.whatwg.org/multipage/forms.html#autofill)
- public static final String HONORIFIC_PREFIX = "honorific-prefix";
- public static final String NAME = "name";
- public static final String GIVEN_NAME = "given-name";
- public static final String ADDITIONAL_NAME = "additional-name";
- public static final String FAMILY_NAME = "family-name";
- public static final String HONORIFIC_SUFFIX = "honorific-suffix";
- public static final String USERNAME = "username";
- public static final String NEW_PASSWORD = "new-password";
- public static final String CURRENT_PASSWORD = "current-password";
- public static final String ORGANIZATION_TITLE = "organization-title";
- public static final String ORGANIZATION = "organization";
- public static final String STREET_ADDRESS = "street-address";
- public static final String ADDRESS_LINE1 = "address-line1";
- public static final String ADDRESS_LINE2 = "address-line2";
- public static final String ADDRESS_LINE3 = "address-line3";
- public static final String ADDRESS_LEVEL4 = "address-level4";
- public static final String ADDRESS_LEVEL3 = "address-level3";
- public static final String ADDRESS_LEVEL2 = "address-level2";
- public static final String ADDRESS_LEVEL1 = "address-level1";
- public static final String COUNTRY = "country";
- public static final String COUNTRY_NAME = "country-name";
- public static final String POSTAL_CODE = "postal-code";
- public static final String CC_NAME = "cc-name";
- public static final String CC_GIVEN_NAME = "cc-given-name";
- public static final String CC_ADDITIONAL_NAME = "cc-additional-name";
- public static final String CC_FAMILY_NAME = "cc-family-name";
- public static final String CC_NUMBER = "cc-number";
- public static final String CC_EXPIRATION = "cc-exp";
- public static final String CC_EXPIRATION_MONTH = "cc-exp-month";
- public static final String CC_EXPIRATION_YEAR = "cc-exp-year";
- public static final String CC_CSC = "cc-csc";
- public static final String CC_TYPE = "cc-type";
- public static final String TRANSACTION_CURRENCY = "transaction-currency";
- public static final String TRANSACTION_AMOUNT = "transaction-amount";
- public static final String LANGUAGE = "language";
- public static final String BDAY = "bday";
- public static final String BDAY_DAY = "bday-day";
- public static final String BDAY_MONTH = "bday-month";
- public static final String BDAY_YEAR = "bday-year";
- public static final String SEX = "sex";
- public static final String URL = "url";
- public static final String PHOTO = "photo";
// Optional W3C prefixes
public static final String PREFIX_SECTION = "section-";
public static final String SHIPPING = "shipping";
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 09c685e9..0ee922f3 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,7 +17,6 @@
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;
@@ -25,82 +24,42 @@ import android.view.autofill.AutofillValue;
import com.example.android.autofill.service.AutofillHints;
import com.example.android.autofill.service.ClientParser;
import com.example.android.autofill.service.model.AutofillDataset;
+import com.example.android.autofill.service.model.AutofillHint;
import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields;
+import com.example.android.autofill.service.model.FieldType;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
import com.example.android.autofill.service.model.FilledAutofillField;
-import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
-import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;
-import static com.example.android.autofill.service.AutofillHints.convertToStoredHintNames;
import static com.example.android.autofill.service.util.Util.loge;
public class ClientAutofillDataBuilder implements AutofillDataBuilder {
private final ClientParser mClientParser;
- private final Bundle mClientState;
+ private final HashMap<String, FieldTypeWithHints> mFieldTypesByAutofillHint;
- private AssistStructure.ViewNode usernameNode;
- private AssistStructure.ViewNode passwordNode;
-
- public ClientAutofillDataBuilder(ClientParser clientParser, Bundle clientState) {
+ public ClientAutofillDataBuilder(HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint,
+ ClientParser clientParser) {
mClientParser = clientParser;
- mClientState = clientState;
+ mFieldTypesByAutofillHint = fieldTypesByAutofillHint;
}
@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);
- DatasetWithFilledAutofillFields datasetWithFilledAutofillFields =
+ DatasetWithFilledAutofillFields dataset =
buildDatasetForPartition(autofillDataset, partition);
- if (datasetWithFilledAutofillFields != null) {
- listBuilder.add(datasetWithFilledAutofillFields);
+ if (dataset != null && dataset.filledAutofillFields != null) {
+ listBuilder.add(dataset);
}
}
return listBuilder.build();
@@ -118,21 +77,14 @@ public class ClientAutofillDataBuilder implements AutofillDataBuilder {
mClientParser.parse((node) ->
parseAutofillFields(node, datasetWithFilledAutofillFields, partition)
);
- if (datasetWithFilledAutofillFields.filledAutofillFields == null) {
- return null;
- } else {
- return datasetWithFilledAutofillFields;
- }
+ return datasetWithFilledAutofillFields;
+
}
private void parseAutofillFields(AssistStructure.ViewNode viewNode,
DatasetWithFilledAutofillFields datasetWithFilledAutofillFields, int partition) {
String[] hints = viewNode.getAutofillHints();
- if (hints == null) {
- return;
- }
- List<String> filteredHints = convertToStoredHintNames(Arrays.asList(hints), partition);
- if (filteredHints == null || filteredHints.size() == 0) {
+ if (hints == null || hints.length == 0) {
return;
}
AutofillValue autofillValue = viewNode.getAutofillValue();
@@ -156,44 +108,49 @@ public class ClientAutofillDataBuilder implements AutofillDataBuilder {
}
}
appendViewMetadata(datasetWithFilledAutofillFields,
- filteredHints, textValue, dateValue, toggleValue,
+ hints, partition, textValue, dateValue, toggleValue,
autofillOptions, listIndex);
}
private void appendViewMetadata(@NonNull DatasetWithFilledAutofillFields
- datasetWithFilledAutofillFields, @NonNull List<String> hints,
+ datasetWithFilledAutofillFields, @NonNull String[] hints, int partition,
@Nullable String textValue, @Nullable Long dateValue, @Nullable Boolean toggleValue,
@Nullable CharSequence[] autofillOptions, @Nullable Integer listIndex) {
- for (int i = 0; i < hints.size(); i++) {
- String hint = hints.get(i);
+ for (int i = 0; i < hints.length; i++) {
+ String hint = hints[i];
// Then check if the "actual" hint is supported.
- if (AutofillHints.isValidHint(hint)) {
- // Only add the field if the hint is supported by the type.
- if (textValue != null) {
- Preconditions.checkArgument(AutofillHints.isValidTypeForHints(hint,
- View.AUTOFILL_TYPE_TEXT),
- "Text is invalid type for hint '%s'", hint);
+ FieldTypeWithHints fieldTypeWithHints = mFieldTypesByAutofillHint.get(hint);
+ if (fieldTypeWithHints != null) {
+ FieldType fieldType = fieldTypeWithHints.fieldType;
+ if (!AutofillHints.matchesPartition(fieldType.getPartition(), partition)) {
+ continue;
}
+ // Only add the field if the hint is supported by the type.
+ if (textValue != null) {
+ if (!fieldType.getAutofillTypes().ints.contains(View.AUTOFILL_TYPE_TEXT)) {
+ loge("Text is invalid type for hint '%s'", hint);
+ }
+ }
if (autofillOptions != null && listIndex != null &&
autofillOptions.length > listIndex) {
- Preconditions.checkArgument(AutofillHints.isValidTypeForHints(hint,
- View.AUTOFILL_TYPE_LIST),
- "List is invalid type for hint '%s'", hint);
+ if (!fieldType.getAutofillTypes().ints.contains(View.AUTOFILL_TYPE_LIST)) {
+ loge("List is invalid type for hint '%s'", hint);
+ }
textValue = autofillOptions[listIndex].toString();
}
if (dateValue != null) {
- Preconditions.checkArgument(AutofillHints.isValidTypeForHints(hint,
- View.AUTOFILL_TYPE_DATE),
- "Date is invalid type for hint '%s'", hint);
+ if (!fieldType.getAutofillTypes().ints.contains(View.AUTOFILL_TYPE_DATE)) {
+ loge("Date is invalid type for hint '%s'", hint);
+ }
}
if (toggleValue != null) {
- Preconditions.checkArgument(AutofillHints.isValidTypeForHints(hint,
- View.AUTOFILL_TYPE_TOGGLE),
- "Toggle is invalid type for hint '%s'", hint);
+ if (!fieldType.getAutofillTypes().ints.contains(View.AUTOFILL_TYPE_TOGGLE)) {
+ loge("Toggle is invalid type for hint '%s'", hint);
+ }
}
String datasetId = datasetWithFilledAutofillFields.autofillDataset.getId();
datasetWithFilledAutofillFields.add(new FilledAutofillField(datasetId,
- hint, textValue, dateValue, toggleValue));
+ fieldType.getTypeName(), textValue, dateValue, toggleValue));
} else {
loge("Invalid hint: %s", hint);
}
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 0c54c020..71f931bd 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
@@ -23,17 +23,23 @@ import android.view.autofill.AutofillId;
import com.example.android.autofill.service.AutofillHints;
import com.example.android.autofill.service.ClientParser;
+import com.example.android.autofill.service.model.FieldType;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import static com.example.android.autofill.service.util.Util.logd;
public class ClientViewMetadataBuilder {
private ClientParser mClientParser;
+ private HashMap<String, FieldTypeWithHints> mFieldTypesByAutofillHint;
- public ClientViewMetadataBuilder(ClientParser parser) {
+ public ClientViewMetadataBuilder(ClientParser parser,
+ HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint) {
mClientParser = parser;
+ mFieldTypesByAutofillHint = fieldTypesByAutofillHint;
}
public ClientViewMetadata buildClientViewMetadata() {
@@ -68,9 +74,10 @@ public class ClientViewMetadataBuilder {
String[] hints = root.getAutofillHints();
if (hints != null) {
for (String hint : hints) {
- if (AutofillHints.isValidHint(hint)) {
+ FieldTypeWithHints fieldTypeWithHints = mFieldTypesByAutofillHint.get(hint);
+ if (fieldTypeWithHints != null && fieldTypeWithHints.fieldType != null) {
allHints.add(hint);
- autofillSaveType.value |= AutofillHints.getSaveTypeForHint(hint);
+ autofillSaveType.value |= fieldTypeWithHints.fieldType.getSaveInfo();
autofillIds.add(root.getAutofillId());
}
}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/FakeAutofillDataBuilder.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/FakeAutofillDataBuilder.java
index 580df901..bbe1a74e 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/FakeAutofillDataBuilder.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/FakeAutofillDataBuilder.java
@@ -17,8 +17,10 @@
package com.example.android.autofill.service.data;
import com.example.android.autofill.service.AutofillHints;
+import com.example.android.autofill.service.data.source.local.LocalAutofillDataSource;
import com.example.android.autofill.service.model.AutofillDataset;
import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
import com.example.android.autofill.service.model.FilledAutofillField;
import com.google.common.collect.ImmutableList;
@@ -26,9 +28,11 @@ import java.util.List;
import java.util.UUID;
public class FakeAutofillDataBuilder implements AutofillDataBuilder {
+ private final List<FieldTypeWithHints> mFieldTypesWithHints;
private final int mSeed;
- public FakeAutofillDataBuilder(int seed) {
+ public FakeAutofillDataBuilder(List<FieldTypeWithHints> fieldTypesWithHints, int seed) {
+ mFieldTypesWithHints = fieldTypesWithHints;
mSeed = seed;
}
@@ -41,7 +45,11 @@ public class FakeAutofillDataBuilder implements AutofillDataBuilder {
"dataset-" + datasetNumber + "." + partition);
DatasetWithFilledAutofillFields datasetWithFilledAutofillFields =
buildCollectionForPartition(autofillDataset, partition);
- listBuilder.add(datasetWithFilledAutofillFields);
+ if (datasetWithFilledAutofillFields != null &&
+ datasetWithFilledAutofillFields.filledAutofillFields != null &&
+ !datasetWithFilledAutofillFields.filledAutofillFields.isEmpty()) {
+ listBuilder.add(datasetWithFilledAutofillFields);
+ }
}
return listBuilder.build();
}
@@ -51,10 +59,11 @@ public class FakeAutofillDataBuilder implements AutofillDataBuilder {
DatasetWithFilledAutofillFields datasetWithFilledAutofillFields =
new DatasetWithFilledAutofillFields();
datasetWithFilledAutofillFields.autofillDataset = dataset;
- for (String hint : AutofillHints.getHints()) {
- if (AutofillHints.matchesPartition(hint, partition)) {
- FilledAutofillField fakeField = AutofillHints.generateFakeField(hint, mSeed,
- dataset.getId());
+ for (FieldTypeWithHints fieldTypeWithHints: mFieldTypesWithHints) {
+ if (AutofillHints.matchesPartition(fieldTypeWithHints.getFieldType().getPartition(),
+ partition)) {
+ FilledAutofillField fakeField =
+ AutofillHints.generateFakeField(fieldTypeWithHints, mSeed, dataset.getId());
datasetWithFilledAutofillFields.add(fakeField);
}
}
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 8f0cf714..7ad5ab3e 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
@@ -28,9 +28,12 @@ import android.widget.RemoteViews;
import com.example.android.autofill.service.AutofillHints;
import com.example.android.autofill.service.ClientParser;
import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields;
+import com.example.android.autofill.service.model.FieldType;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
import com.example.android.autofill.service.model.FilledAutofillField;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@@ -50,22 +53,26 @@ public class DatasetAdapter {
/**
* Wraps autofill data in a {@link Dataset} object which can then be sent back to the client.
*/
- public Dataset buildDataset(DatasetWithFilledAutofillFields datasetWithFilledAutofillFields,
+ public Dataset buildDataset(HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint,
+ DatasetWithFilledAutofillFields datasetWithFilledAutofillFields,
RemoteViews remoteViews) {
- return buildDataset(datasetWithFilledAutofillFields, remoteViews, null);
+ return buildDataset(fieldTypesByAutofillHint, datasetWithFilledAutofillFields, remoteViews,
+ null);
}
/**
* Wraps autofill data in a {@link Dataset} object with an IntentSender, which can then be
* sent back to the client.
*/
- public Dataset buildDataset(DatasetWithFilledAutofillFields datasetWithFilledAutofillFields,
+ public Dataset buildDataset(HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint,
+ DatasetWithFilledAutofillFields datasetWithFilledAutofillFields,
RemoteViews remoteViews, IntentSender intentSender) {
Dataset.Builder datasetBuilder = new Dataset.Builder(remoteViews);
if (intentSender != null) {
datasetBuilder.setAuthentication(intentSender);
}
- boolean setAtLeastOneValue = bindDataset(datasetWithFilledAutofillFields, datasetBuilder);
+ boolean setAtLeastOneValue = bindDataset(fieldTypesByAutofillHint,
+ datasetWithFilledAutofillFields, datasetBuilder);
if (!setAtLeastOneValue) {
return null;
}
@@ -75,30 +82,35 @@ public class DatasetAdapter {
/**
* Build an autofill {@link Dataset} using saved data and the client's AssistStructure.
*/
- private boolean bindDataset(DatasetWithFilledAutofillFields datasetWithFilledAutofillFields,
+ private boolean bindDataset(HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint,
+ DatasetWithFilledAutofillFields datasetWithFilledAutofillFields,
Dataset.Builder datasetBuilder) {
MutableBoolean setValueAtLeastOnce = new MutableBoolean(false);
- Map<String, FilledAutofillField> map = datasetWithFilledAutofillFields.filledAutofillFields
- .stream().collect(toMap(FilledAutofillField::getHint, Function.identity()));
+ Map<String, FilledAutofillField> filledAutofillFieldsByTypeName =
+ datasetWithFilledAutofillFields.filledAutofillFields.stream()
+ .collect(toMap(FilledAutofillField::getFieldTypeName, Function.identity()));
mClientParser.parse((node) ->
- parseAutofillFields(node, map, datasetBuilder, setValueAtLeastOnce)
+ parseAutofillFields(node, fieldTypesByAutofillHint, filledAutofillFieldsByTypeName,
+ datasetBuilder, setValueAtLeastOnce)
);
return setValueAtLeastOnce.value;
}
private void parseAutofillFields(AssistStructure.ViewNode viewNode,
- Map<String, FilledAutofillField> map, Dataset.Builder builder,
- MutableBoolean setValueAtLeastOnce) {
+ HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint,
+ Map<String, FilledAutofillField> filledAutofillFieldsByTypeName,
+ Dataset.Builder builder, MutableBoolean setValueAtLeastOnce) {
String[] rawHints = viewNode.getAutofillHints();
if (rawHints == null || rawHints.length == 0) {
logv("No af hints at ViewNode - %s", viewNode.getIdEntry());
return;
}
- List<String> hints = AutofillHints.convertToStoredHintNames(Arrays.asList(rawHints));
- // For simplicity, even if the viewNode has multiple autofill hints, only look at the first
- // one.
- String autofillHint = hints.get(0);
- FilledAutofillField field = map.get(autofillHint);
+ String fieldTypeName = AutofillHints.getFieldTypeNameFromAutofillHints(
+ fieldTypesByAutofillHint, Arrays.asList(rawHints));
+ if (fieldTypeName == null) {
+ return;
+ }
+ FilledAutofillField field = filledAutofillFieldsByTypeName.get(fieldTypeName);
if (field == null) {
return;
}
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 967d0ba9..bffd7cb1 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
@@ -28,7 +28,9 @@ import com.example.android.autofill.service.AuthActivity;
import com.example.android.autofill.service.RemoteViewsHelper;
import com.example.android.autofill.service.data.ClientViewMetadata;
import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
+import java.util.HashMap;
import java.util.List;
public class ResponseAdapter {
@@ -49,8 +51,8 @@ public class ResponseAdapter {
* Wraps autofill data in a Response object (essentially a series of Datasets) which can then
* be sent back to the client View.
*/
- public FillResponse buildResponse(List<DatasetWithFilledAutofillFields> datasets,
- boolean datasetAuth) {
+ public FillResponse buildResponse(HashMap<String, FieldTypeWithHints> fieldTypesByAutofillHint,
+ List<DatasetWithFilledAutofillFields> datasets, boolean datasetAuth) {
FillResponse.Builder responseBuilder = new FillResponse.Builder();
if (datasets != null) {
for (DatasetWithFilledAutofillFields datasetWithFilledAutofillFields : datasets) {
@@ -63,13 +65,13 @@ public class ResponseAdapter {
mContext, datasetName);
RemoteViews remoteViews = RemoteViewsHelper.viewsWithAuth(
mPackageName, datasetName);
- dataset = mDatasetAdapter.buildDataset(datasetWithFilledAutofillFields,
- remoteViews, intentSender);
+ dataset = mDatasetAdapter.buildDataset(fieldTypesByAutofillHint,
+ datasetWithFilledAutofillFields, remoteViews, intentSender);
} else {
RemoteViews remoteViews = RemoteViewsHelper.viewsWithNoAuth(
mPackageName, datasetName);
- dataset = mDatasetAdapter.buildDataset(datasetWithFilledAutofillFields,
- remoteViews);
+ dataset = mDatasetAdapter.buildDataset(fieldTypesByAutofillHint,
+ datasetWithFilledAutofillFields, remoteViews);
}
if (dataset != null) {
responseBuilder.addDataset(dataset);
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/AutofillDataSource.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/AutofillDataSource.java
index 31b30b44..eb2a5ada 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/AutofillDataSource.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/AutofillDataSource.java
@@ -17,7 +17,9 @@ package com.example.android.autofill.service.data.source;
import com.example.android.autofill.service.data.DataCallback;
import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
+import java.util.HashMap;
import java.util.List;
public interface AutofillDataSource {
@@ -44,6 +46,14 @@ public interface AutofillDataSource {
datasetsWithFilledAutofillFields);
/**
+ * Gets all autofill field types.
+ */
+ void getFieldTypes(DataCallback<List<FieldTypeWithHints>> fieldTypesCallback);
+
+ void getFieldTypeByAutofillHints(
+ DataCallback<HashMap<String, FieldTypeWithHints>> fieldTypeMapCallback);
+
+ /**
* Clears all data.
*/
void clear();
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/DefaultFieldTypesSource.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/DefaultFieldTypesSource.java
new file mode 100644
index 00000000..22cbeadc
--- /dev/null
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/DefaultFieldTypesSource.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.example.android.autofill.service.data.source;
+
+import com.example.android.autofill.service.model.DefaultFieldTypeWithHints;
+
+import java.util.List;
+
+public interface DefaultFieldTypesSource {
+ List<DefaultFieldTypeWithHints> getDefaultFieldTypes();
+}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/DefaultFieldTypesLocalJsonSource.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/DefaultFieldTypesLocalJsonSource.java
new file mode 100644
index 00000000..edda7d8e
--- /dev/null
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/DefaultFieldTypesLocalJsonSource.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.example.android.autofill.service.data.source.local;
+
+import android.content.res.Resources;
+
+import com.example.android.autofill.service.R;
+import com.example.android.autofill.service.data.source.DefaultFieldTypesSource;
+import com.example.android.autofill.service.model.DefaultFieldTypeWithHints;
+import com.example.android.autofill.service.model.FieldType;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import static com.example.android.autofill.service.util.Util.loge;
+
+public class DefaultFieldTypesLocalJsonSource implements DefaultFieldTypesSource {
+ private static DefaultFieldTypesLocalJsonSource sInstance;
+
+ private final Resources mResources;
+ private final Gson mGson;
+
+ private DefaultFieldTypesLocalJsonSource(Resources resources, Gson gson) {
+ mResources = resources;
+ mGson = gson;
+ }
+
+ public static DefaultFieldTypesLocalJsonSource getInstance(Resources resources, Gson gson) {
+ if (sInstance == null) {
+ sInstance = new DefaultFieldTypesLocalJsonSource(resources, gson);
+ }
+ return sInstance;
+ }
+
+ @Override
+ public List<DefaultFieldTypeWithHints> getDefaultFieldTypes() {
+ Type fieldTypeListType = TypeToken.getParameterized(List.class,
+ DefaultFieldTypeWithHints.class).getType();
+ InputStream is = mResources.openRawResource(R.raw.default_field_types);
+ List<DefaultFieldTypeWithHints> fieldTypes = null;
+ try(Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
+ fieldTypes = mGson.fromJson(reader, fieldTypeListType);
+ } catch (IOException e) {
+ loge(e, "Exception during deserialization of FieldTypes.");
+ }
+ return fieldTypes;
+ }
+}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/LocalAutofillDataSource.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/LocalAutofillDataSource.java
index 758b5123..c9b80958 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/LocalAutofillDataSource.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/LocalAutofillDataSource.java
@@ -24,11 +24,16 @@ import com.example.android.autofill.service.data.DataCallback;
import com.example.android.autofill.service.data.source.AutofillDataSource;
import com.example.android.autofill.service.data.source.local.dao.AutofillDao;
import com.example.android.autofill.service.model.AutofillDataset;
+import com.example.android.autofill.service.model.AutofillHint;
import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields;
+import com.example.android.autofill.service.model.FieldType;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
import com.example.android.autofill.service.model.FilledAutofillField;
import com.example.android.autofill.service.util.AppExecutors;
+import java.util.HashMap;
import java.util.List;
+import java.util.stream.Collectors;
import static com.example.android.autofill.service.util.Util.logw;
@@ -71,11 +76,14 @@ public class LocalAutofillDataSource implements AutofillDataSource {
@Override
public void getAutofillDatasets(List<String> allAutofillHints,
DataCallback<List<DatasetWithFilledAutofillFields>> datasetsCallback) {
- final List<String> storedAllAutofillHints =
- AutofillHints.convertToStoredHintNames(allAutofillHints);
mAppExecutors.diskIO().execute(() -> {
- List<DatasetWithFilledAutofillFields> datasetsWithFilledAutofillFields = mAutofillDao
- .getDatasets(storedAllAutofillHints);
+ final List<String> typeNames = getFieldTypesForAutofillHints(allAutofillHints)
+ .stream()
+ .map(FieldTypeWithHints::getFieldType)
+ .map(FieldType::getTypeName)
+ .collect(Collectors.toList());
+ List<DatasetWithFilledAutofillFields> datasetsWithFilledAutofillFields =
+ mAutofillDao.getDatasets(typeNames);
mAppExecutors.mainThread().execute(() ->
datasetsCallback.onLoaded(datasetsWithFilledAutofillFields)
);
@@ -122,6 +130,51 @@ public class LocalAutofillDataSource implements AutofillDataSource {
}
@Override
+ public void getFieldTypes(DataCallback<List<FieldTypeWithHints>> fieldTypesCallback) {
+ mAppExecutors.diskIO().execute(() -> {
+ List<FieldTypeWithHints> fieldTypeWithHints = mAutofillDao.getFieldTypesWithHints();
+ if (fieldTypeWithHints != null) {
+ fieldTypesCallback.onLoaded(fieldTypeWithHints);
+ } else {
+ fieldTypesCallback.onDataNotAvailable("Field Types not found.");
+ }
+ });
+ }
+
+ @Override
+ public void getFieldTypeByAutofillHints(
+ DataCallback<HashMap<String, FieldTypeWithHints>> fieldTypeMapCallback) {
+ mAppExecutors.diskIO().execute(() -> {
+ HashMap<String, FieldTypeWithHints> hintMap = getFieldTypeByAutofillHints();
+ if (hintMap != null) {
+ fieldTypeMapCallback.onLoaded(hintMap);
+ } else {
+ fieldTypeMapCallback.onDataNotAvailable("FieldTypes not found");
+ }
+ });
+ }
+
+ private HashMap<String, FieldTypeWithHints> getFieldTypeByAutofillHints() {
+ HashMap<String, FieldTypeWithHints> hintMap = new HashMap<>();
+ List<FieldTypeWithHints> fieldTypeWithHints =
+ mAutofillDao.getFieldTypesWithHints();
+ if (fieldTypeWithHints != null) {
+ for (FieldTypeWithHints fieldType : fieldTypeWithHints) {
+ for (AutofillHint hint : fieldType.autofillHints) {
+ hintMap.put(hint.mAutofillHint, fieldType);
+ }
+ }
+ return hintMap;
+ } else {
+ return null;
+ }
+ }
+
+ private List<FieldTypeWithHints> getFieldTypesForAutofillHints(List<String> autofillHints) {
+ return mAutofillDao.getFieldTypesForAutofillHints(autofillHints);
+ }
+
+ @Override
public void clear() {
mAppExecutors.diskIO().execute(() -> {
mAutofillDao.clearAll();
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 385638b0..9baffb46 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
@@ -22,7 +22,10 @@ import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query;
import com.example.android.autofill.service.model.AutofillDataset;
+import com.example.android.autofill.service.model.AutofillHint;
import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields;
+import com.example.android.autofill.service.model.FieldType;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
import com.example.android.autofill.service.model.FilledAutofillField;
import java.util.Collection;
@@ -38,7 +41,7 @@ public interface AutofillDao {
*/
@Query("SELECT DISTINCT id, datasetName FROM FilledAutofillField, AutofillDataset" +
" WHERE AutofillDataset.id = FilledAutofillField.datasetId" +
- " AND FilledAutofillField.hint IN (:allAutofillHints)")
+ " AND FilledAutofillField.fieldTypeName IN (:allAutofillHints)")
List<DatasetWithFilledAutofillFields> getDatasets(List<String> allAutofillHints);
/**
@@ -50,13 +53,22 @@ public interface AutofillDao {
* 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" +
+ @Query("SELECT DISTINCT id, datasetName FROM FilledAutofillField, AutofillDataset" +
" WHERE AutofillDataset.id = FilledAutofillField.datasetId" +
" AND AutofillDataset.datasetName = (:datasetName)" +
- " AND FilledAutofillField.hint IN (:allAutofillHints)")
+ " AND FilledAutofillField.fieldTypeName IN (:allAutofillHints)")
List<DatasetWithFilledAutofillFields> getDatasetsWithName(
List<String> allAutofillHints, String datasetName);
+ @Query("SELECT DISTINCT typeName, autofillTypes, saveInfo, partition, strictExampleSet, textTemplate, dateTemplate FROM FieldType, AutofillHint WHERE " +
+ "FieldType.typeName = AutofillHint.fieldTypeName")
+ List<FieldTypeWithHints> getFieldTypesWithHints();
+
+ @Query("SELECT DISTINCT typeName, autofillTypes, saveInfo, partition, strictExampleSet, textTemplate, dateTemplate FROM FieldType, AutofillHint WHERE " +
+ "FieldType.typeName = AutofillHint.fieldTypeName " +
+ "AND AutofillHint.autofillHint IN (:autofillHints)")
+ List<FieldTypeWithHints> getFieldTypesForAutofillHints(List<String> autofillHints);
+
/**
* @param autofillFields Collection of autofill fields to be saved to the db.
*/
@@ -66,6 +78,12 @@ public interface AutofillDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void saveAutofillDataset(AutofillDataset datasets);
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ void insertAutofillHints(List<AutofillHint> autofillHints);
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ void insertFieldTypes(List<FieldType> fieldTypes);
+
@Query("DELETE FROM AutofillDataset")
void clearAll();
} \ No newline at end of file
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/db/AutofillDatabase.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/db/AutofillDatabase.java
index 83eda9e6..178e375d 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/db/AutofillDatabase.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/db/AutofillDatabase.java
@@ -16,32 +16,97 @@
package com.example.android.autofill.service.data.source.local.db;
+import android.arch.persistence.db.SupportSQLiteDatabase;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
+import android.arch.persistence.room.TypeConverters;
import android.content.Context;
+import android.support.annotation.NonNull;
+import com.example.android.autofill.service.data.source.DefaultFieldTypesSource;
import com.example.android.autofill.service.data.source.local.dao.AutofillDao;
import com.example.android.autofill.service.model.AutofillDataset;
+import com.example.android.autofill.service.model.AutofillHint;
+import com.example.android.autofill.service.model.DefaultFieldTypeWithHints;
+import com.example.android.autofill.service.model.FakeData;
+import com.example.android.autofill.service.model.FieldType;
import com.example.android.autofill.service.model.FilledAutofillField;
+import com.example.android.autofill.service.util.AppExecutors;
-@Database(entities = {FilledAutofillField.class, AutofillDataset.class}, version = 1)
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.example.android.autofill.service.data.source.local.db.Converters.IntList;
+import static java.util.stream.Collectors.toList;
+
+@Database(entities = {
+ FilledAutofillField.class,
+ AutofillDataset.class,
+ FieldType.class,
+ AutofillHint.class
+}, version = 1)
+@TypeConverters({Converters.class})
public abstract class AutofillDatabase extends RoomDatabase {
private static final Object sLock = new Object();
private static AutofillDatabase sInstance;
- public static AutofillDatabase getInstance(Context context) {
- synchronized (sLock) {
- if (sInstance == null) {
- sInstance = Room.databaseBuilder(context.getApplicationContext(),
- AutofillDatabase.class, "AutofillSample.db")
- .build();
+ public static AutofillDatabase getInstance(Context context,
+ DefaultFieldTypesSource defaultFieldTypesSource,
+ AppExecutors appExecutors) {
+ if (sInstance == null) {
+ synchronized (sLock) {
+ if (sInstance == null) {
+ sInstance = Room.databaseBuilder(context.getApplicationContext(),
+ AutofillDatabase.class, "AutofillSample.db")
+ .addCallback(new RoomDatabase.Callback() {
+ @Override
+ public void onCreate(@NonNull SupportSQLiteDatabase db) {
+ appExecutors.diskIO().execute(() -> {
+ List<DefaultFieldTypeWithHints> fieldTypes =
+ defaultFieldTypesSource.getDefaultFieldTypes();
+ AutofillDatabase autofillDatabase =
+ getInstance(context, defaultFieldTypesSource,
+ appExecutors);
+ autofillDatabase.saveDefaultFieldTypes(fieldTypes);
+ });
+ }
+
+ @Override
+ public void onOpen(@NonNull SupportSQLiteDatabase db) {
+ super.onOpen(db);
+ }
+ })
+ .build();
+ }
}
- return sInstance;
}
+ return sInstance;
}
- public abstract AutofillDao autofillDao();
+ private void saveDefaultFieldTypes(List<DefaultFieldTypeWithHints> defaultFieldTypes) {
+ List<FieldType> storedFieldTypes = new ArrayList<>();
+ List<AutofillHint> storedAutofillHints = new ArrayList<>();
+ for (DefaultFieldTypeWithHints defaultType : defaultFieldTypes) {
+ DefaultFieldTypeWithHints.DefaultFieldType defaultFieldType = defaultType.fieldType;
+ List<String> autofillHints = defaultType.autofillHints;
+ IntList autofillTypes = new IntList(defaultFieldType.autofillTypes);
+ DefaultFieldTypeWithHints.DefaultFakeData defaultFakeData = defaultType.fieldType.fakeData;
+ FakeData fakeData = new FakeData(new Converters.StringList(
+ defaultFakeData.strictExampleSet), defaultFakeData.textTemplate,
+ defaultFakeData.dateTemplate);
+ FieldType storedFieldType = new FieldType(defaultFieldType.typeName, autofillTypes,
+ defaultFieldType.saveInfo, defaultFieldType.partition, fakeData);
+ storedFieldTypes.add(storedFieldType);
+ storedAutofillHints.addAll(autofillHints.stream()
+ .map((autofillHint) -> new AutofillHint(autofillHint,
+ storedFieldType.getTypeName())).collect(toList()));
+ }
+ AutofillDao autofillDao = autofillDao();
+ autofillDao.insertFieldTypes(storedFieldTypes);
+ autofillDao.insertAutofillHints(storedAutofillHints);
+ }
+ public abstract AutofillDao autofillDao();
} \ No newline at end of file
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/db/Converters.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/db/Converters.java
new file mode 100644
index 00000000..2829f8bd
--- /dev/null
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/db/Converters.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.example.android.autofill.service.data.source.local.db;
+
+import android.arch.persistence.room.TypeConverter;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static java.util.stream.Collectors.toList;
+
+/**
+ * Type converter for Room database.
+ */
+public class Converters {
+
+ /**
+ * If database returns a {@link String} containing a comma delimited list of ints, this converts
+ * the {@link String} to an {@link IntList}.
+ */
+ @TypeConverter
+ public static IntList storedStringToIntList(String value) {
+ List<String> strings = Arrays.asList(value.split("\\s*,\\s*"));
+ List<Integer> ints = strings.stream().map(Integer::parseInt).collect(toList());
+ return new IntList(ints);
+ }
+
+ /**
+ * Converts the {@link IntList} back into a String containing a comma delimited list of
+ * ints.
+ */
+ @TypeConverter
+ public static String intListToStoredString(IntList list) {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (Integer integer : list.ints) {
+ stringBuilder.append(integer).append(",");
+ }
+ return stringBuilder.toString();
+ }
+
+ /**
+ * If database returns a {@link String} containing a comma delimited list of Strings, this
+ * converts the {@link String} to a {@link StringList}.
+ */
+ @TypeConverter
+ public static StringList storedStringToStringList(String value) {
+ List<String> strings = Arrays.asList(value.split("\\s*,\\s*"));
+ return new StringList(strings);
+ }
+
+
+ /**
+ * Converts the {@link StringList} back into a {@link String} containing a comma delimited
+ * list of {@link String}s.
+ */
+ @TypeConverter
+ public static String stringListToStoredString(StringList list) {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (String string : list.strings) {
+ stringBuilder.append(string).append(",");
+ }
+ return stringBuilder.toString();
+ }
+
+ /**
+ * Wrapper class for {@code List<Integer>} so it can work with Room type converters.
+ */
+ public static class IntList {
+ public final List<Integer> ints;
+
+ public IntList(List<Integer> ints) {
+ this.ints = ints;
+ }
+ }
+
+ /**
+ * Wrapper class for {@code List<String>} so it can work with Room type converters.
+ */
+ public static class StringList {
+ public final List<String> strings;
+
+ public StringList(List<String> ints) {
+ this.strings = ints;
+ }
+ }
+}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/AutofillHint.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/AutofillHint.java
new file mode 100644
index 00000000..be4aa7d9
--- /dev/null
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/AutofillHint.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.example.android.autofill.service.model;
+
+import android.arch.persistence.room.ColumnInfo;
+import android.arch.persistence.room.Entity;
+import android.arch.persistence.room.ForeignKey;
+import android.support.annotation.NonNull;
+
+@Entity(primaryKeys = {"autofillHint"}, foreignKeys = @ForeignKey(
+ entity = FieldType.class, parentColumns = "typeName", childColumns = "fieldTypeName",
+ onDelete = ForeignKey.CASCADE))
+public class AutofillHint {
+
+ @NonNull
+ @ColumnInfo(name = "autofillHint")
+ public String mAutofillHint;
+
+ @NonNull
+ @ColumnInfo(name = "fieldTypeName")
+ public String mFieldTypeName;
+
+ public AutofillHint(@NonNull String autofillHint, @NonNull String fieldTypeName) {
+ this.mAutofillHint = autofillHint;
+ this.mFieldTypeName = fieldTypeName;
+ }
+}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/DefaultFieldTypeWithHints.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/DefaultFieldTypeWithHints.java
new file mode 100644
index 00000000..70ad382e
--- /dev/null
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/DefaultFieldTypeWithHints.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.example.android.autofill.service.model;
+
+import java.util.List;
+
+/**
+ * JSON model class, representing an autofillable field type. It is called "Default" because only
+ * default field types will be included in the packaged JSON. After the JSON is initially read and
+ * written to the DB, the field types can be dynamically added, modified, and removed.
+ *<p>
+ * It contains all of the metadata about the field type. For example, if the field type is
+ * "country", this is the JSON object associated with it:
+ <pre class="prettyprint">
+ {
+ "autofillHints": [
+ "country"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "countryseed"
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "country"
+ }
+ }
+ </pre>
+ */
+public class DefaultFieldTypeWithHints {
+ public DefaultFieldType fieldType;
+ public List<String> autofillHints;
+
+ public static class DefaultFieldType {
+ public String typeName;
+ public List<Integer> autofillTypes;
+ public int saveInfo;
+ public int partition;
+ public DefaultFakeData fakeData;
+ }
+
+ public static class DefaultFakeData {
+ public List<String> strictExampleSet;
+ public String textTemplate;
+ public String dateTemplate;
+
+ public DefaultFakeData(List<String> strictExampleSet, String textTemplate,
+ String dateTemplate) {
+ this.strictExampleSet = strictExampleSet;
+ this.textTemplate = textTemplate;
+ this.dateTemplate = dateTemplate;
+ }
+ }
+}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FakeData.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FakeData.java
new file mode 100644
index 00000000..5d0837b2
--- /dev/null
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FakeData.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.example.android.autofill.service.model;
+
+import com.example.android.autofill.service.data.source.local.db.Converters;
+
+public class FakeData {
+ public Converters.StringList strictExampleSet;
+ public String textTemplate;
+ public String dateTemplate;
+
+ public FakeData(Converters.StringList strictExampleSet, String textTemplate, String dateTemplate) {
+ this.strictExampleSet = strictExampleSet;
+ this.textTemplate = textTemplate;
+ this.dateTemplate = dateTemplate;
+ }
+} \ No newline at end of file
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FieldType.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FieldType.java
new file mode 100644
index 00000000..4d285f34
--- /dev/null
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FieldType.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.example.android.autofill.service.model;
+
+import android.arch.persistence.room.ColumnInfo;
+import android.arch.persistence.room.Embedded;
+import android.arch.persistence.room.Entity;
+import android.support.annotation.NonNull;
+
+import static com.example.android.autofill.service.data.source.local.db.Converters.IntList;
+
+@Entity(primaryKeys = {"typeName"})
+public class FieldType {
+ @NonNull
+ @ColumnInfo(name = "typeName")
+ private final String mTypeName;
+
+ @NonNull
+ @ColumnInfo(name = "autofillTypes")
+ private final IntList mAutofillTypes;
+
+ @NonNull
+ @ColumnInfo(name = "saveInfo")
+ private final Integer mSaveInfo;
+
+ @NonNull
+ @ColumnInfo(name = "partition")
+ private final Integer mPartition;
+
+ @NonNull
+ @Embedded
+ private final FakeData mFakeData;
+
+ public FieldType(@NonNull String typeName, @NonNull IntList autofillTypes,
+ @NonNull Integer saveInfo, @NonNull Integer partition, @NonNull FakeData fakeData) {
+ mTypeName = typeName;
+ mAutofillTypes = autofillTypes;
+ mSaveInfo = saveInfo;
+ mPartition = partition;
+ mFakeData = fakeData;
+ }
+
+ @NonNull
+ public String getTypeName() {
+ return mTypeName;
+ }
+
+ @NonNull
+ public IntList getAutofillTypes() {
+ return mAutofillTypes;
+ }
+
+ @NonNull
+ public Integer getSaveInfo() {
+ return mSaveInfo;
+ }
+
+ @NonNull
+ public Integer getPartition() {
+ return mPartition;
+ }
+
+ @NonNull
+ public FakeData getFakeData() {
+ return mFakeData;
+ }
+} \ No newline at end of file
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FieldTypeWithHints.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FieldTypeWithHints.java
new file mode 100644
index 00000000..308a50b5
--- /dev/null
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FieldTypeWithHints.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.example.android.autofill.service.model;
+
+import android.arch.persistence.room.Embedded;
+import android.arch.persistence.room.Relation;
+
+import java.util.List;
+
+public class FieldTypeWithHints {
+ @Embedded
+ public FieldType fieldType;
+
+ @Relation(parentColumn = "typeName", entityColumn = "fieldTypeName", entity = AutofillHint.class)
+ public List<AutofillHint> autofillHints;
+
+ public FieldType getFieldType() {
+ return fieldType;
+ }
+
+ public List<AutofillHint> getAutofillHints() {
+ return autofillHints;
+ }
+}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FilledAutofillField.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FilledAutofillField.java
index ba474d2e..5a71c15a 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FilledAutofillField.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/model/FilledAutofillField.java
@@ -23,9 +23,12 @@ import android.support.annotation.NonNull;
import javax.annotation.Nullable;
-@Entity(primaryKeys = {"datasetId", "hint"}, foreignKeys = @ForeignKey(
- entity = AutofillDataset.class, parentColumns = "id", childColumns = "datasetId",
- onDelete = ForeignKey.CASCADE))
+@Entity(primaryKeys = {"datasetId", "fieldTypeName"}, foreignKeys = {
+ @ForeignKey(entity = AutofillDataset.class, parentColumns = "id",
+ childColumns = "datasetId", onDelete = ForeignKey.CASCADE),
+ @ForeignKey(entity = FieldType.class, parentColumns = "typeName",
+ childColumns = "fieldTypeName", onDelete = ForeignKey.CASCADE)
+})
public class FilledAutofillField {
@NonNull
@@ -45,13 +48,13 @@ public class FilledAutofillField {
private final Boolean mToggleValue;
@NonNull
- @ColumnInfo(name = "hint")
- private final String mHint;
+ @ColumnInfo(name = "fieldTypeName")
+ private final String mFieldTypeName;
- public FilledAutofillField(@NonNull String datasetId, @NonNull String hint,
+ public FilledAutofillField(@NonNull String datasetId, @NonNull String fieldTypeName,
@Nullable String textValue, @Nullable Long dateValue, @Nullable Boolean toggleValue) {
mDatasetId = datasetId;
- mHint = hint;
+ mFieldTypeName = fieldTypeName;
mTextValue = textValue;
mDateValue = dateValue;
mToggleValue = toggleValue;
@@ -107,8 +110,8 @@ public class FilledAutofillField {
}
@NonNull
- public String getHint() {
- return mHint;
+ public String getFieldTypeName() {
+ return mFieldTypeName;
}
public boolean isNull() {
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/settings/SettingsActivity.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/settings/SettingsActivity.java
index 82222a80..a45a99ff 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/settings/SettingsActivity.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/settings/SettingsActivity.java
@@ -39,15 +39,20 @@ import android.widget.TextView;
import com.example.android.autofill.service.R;
import com.example.android.autofill.service.data.AutofillDataBuilder;
+import com.example.android.autofill.service.data.DataCallback;
import com.example.android.autofill.service.data.FakeAutofillDataBuilder;
+import com.example.android.autofill.service.data.source.DefaultFieldTypesSource;
import com.example.android.autofill.service.data.source.PackageVerificationDataSource;
+import com.example.android.autofill.service.data.source.local.DefaultFieldTypesLocalJsonSource;
import com.example.android.autofill.service.data.source.local.LocalAutofillDataSource;
import com.example.android.autofill.service.data.source.local.SharedPrefsPackageVerificationRepository;
import com.example.android.autofill.service.data.source.local.dao.AutofillDao;
import com.example.android.autofill.service.data.source.local.db.AutofillDatabase;
import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields;
+import com.example.android.autofill.service.model.FieldTypeWithHints;
import com.example.android.autofill.service.util.AppExecutors;
import com.example.android.autofill.service.util.Util;
+import com.google.gson.GsonBuilder;
import java.util.List;
@@ -71,11 +76,16 @@ public class SettingsActivity extends AppCompatActivity {
setContentView(R.layout.multidataset_service_settings_activity);
SharedPreferences localAfDataSourceSharedPrefs =
getSharedPreferences(LocalAutofillDataSource.SHARED_PREF_KEY, Context.MODE_PRIVATE);
- AutofillDao autofillDao = AutofillDatabase.getInstance(this).autofillDao();
+ DefaultFieldTypesSource defaultFieldTypesSource =
+ DefaultFieldTypesLocalJsonSource.getInstance(getResources(),
+ new GsonBuilder().create());
+ AutofillDao autofillDao = AutofillDatabase.getInstance(
+ this, defaultFieldTypesSource, new AppExecutors()).autofillDao();
mLocalAutofillDataSource = LocalAutofillDataSource.getInstance(localAfDataSourceSharedPrefs,
autofillDao, new AppExecutors());
mAutofillManager = getSystemService(AutofillManager.class);
- mPackageVerificationDataSource = SharedPrefsPackageVerificationRepository.getInstance(this);
+ mPackageVerificationDataSource =
+ SharedPrefsPackageVerificationRepository.getInstance(this);
mPreferences = MyPreferences.getInstance(this);
setupSettingsSwitch(R.id.settings_auth_responses_container,
R.id.settings_auth_responses_label,
@@ -194,27 +204,39 @@ public class SettingsActivity extends AppCompatActivity {
.setView(numberOfDatasetsPicker)
.setPositiveButton(R.string.settings_ok, (dialog, which) -> {
int numOfDatasets = numberOfDatasetsPicker.getValue();
- boolean success = buildAndSaveMockedAutofillFieldCollections(numOfDatasets);
- dialog.dismiss();
- if (success) {
- Snackbar.make(SettingsActivity.this.findViewById(R.id.settings_layout),
- SettingsActivity.this.getResources().getQuantityString(
- R.plurals.settings_add_data_success, numOfDatasets,
- numOfDatasets),
- Snackbar.LENGTH_SHORT).show();
- }
+ mLocalAutofillDataSource.getFieldTypes(new DataCallback<List<FieldTypeWithHints>>() {
+ @Override
+ public void onLoaded(List<FieldTypeWithHints> fieldTypes) {
+ boolean saved = buildAndSaveMockedAutofillFieldCollections(
+ fieldTypes, numOfDatasets);
+ dialog.dismiss();
+ if (saved) {
+ Snackbar.make(findViewById(R.id.settings_layout),
+ getResources().getQuantityString(
+ R.plurals.settings_add_data_success,
+ numOfDatasets, numOfDatasets),
+ Snackbar.LENGTH_SHORT).show();
+ }
+ }
+
+ @Override
+ public void onDataNotAvailable(String msg, Object... params) {
+
+ }
+ });
})
.create();
}
- public boolean buildAndSaveMockedAutofillFieldCollections(int numOfDatasets) {
+ public boolean buildAndSaveMockedAutofillFieldCollections(List<FieldTypeWithHints> fieldTypes,
+ int numOfDatasets) {
if (numOfDatasets < 0 || numOfDatasets > 10) {
logw("Number of Datasets (%d) out of range.", numOfDatasets);
- return false;
}
for (int i = 0; i < numOfDatasets; i++) {
int datasetNumber = mLocalAutofillDataSource.getDatasetNumber();
- AutofillDataBuilder autofillDataBuilder = new FakeAutofillDataBuilder(datasetNumber);
+ AutofillDataBuilder autofillDataBuilder =
+ new FakeAutofillDataBuilder(fieldTypes, datasetNumber);
List<DatasetWithFilledAutofillFields> datasetsWithFilledAutofillFields =
autofillDataBuilder.buildDatasetsByPartition(datasetNumber);
// Save datasets to database.
diff --git a/input/autofill/AutofillFramework/afservice/src/main/res/raw/default_field_types b/input/autofill/AutofillFramework/afservice/src/main/res/raw/default_field_types
new file mode 100644
index 00000000..637edead
--- /dev/null
+++ b/input/autofill/AutofillFramework/afservice/src/main/res/raw/default_field_types
@@ -0,0 +1,1165 @@
+[
+ {
+ "autofillHints": [
+ "country"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "countryseed"
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "country"
+ }
+ },
+ {
+ "autofillHints": [
+ "transaction-amount"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "seed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "transaction-amount"
+ }
+ },
+ {
+ "autofillHints": [
+ "cc-family-name"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "familynameseed"
+ },
+ "partition": 3,
+ "saveInfo": 4,
+ "typeName": "cc-family-name"
+ }
+ },
+ {
+ "autofillHints": [
+ "postal-code",
+ "postalCode"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "1000seed"
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "postalCode"
+ }
+ },
+ {
+ "autofillHints": [
+ "language"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [
+ "Bulgarian",
+ "Croatian",
+ "Czech",
+ "Danish",
+ "Dutch",
+ "English",
+ "Estonian"
+ ]
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "language"
+ }
+ },
+ {
+ "autofillHints": [
+ "tel-national"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "tel-nationalseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "tel-national"
+ }
+ },
+ {
+ "autofillHints": [
+ "transaction-currency"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [
+ "USD",
+ "CAD",
+ "KYD",
+ "CRC"
+ ]
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "transaction-currency"
+ }
+ },
+ {
+ "autofillHints": [
+ "billing"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "billingseed"
+ },
+ "partition": 1,
+ "saveInfo": 0,
+ "typeName": "billing"
+ }
+ },
+ {
+ "autofillHints": [
+ "emailAddress",
+ "email"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "emailAddressseed"
+ },
+ "partition": 2,
+ "saveInfo": 16,
+ "typeName": "emailAddress"
+ }
+ },
+ {
+ "autofillHints": [
+ "password",
+ "current-password"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "usernameseed"
+ },
+ "partition": 0,
+ "saveInfo": 1,
+ "typeName": "password"
+ }
+ },
+ {
+ "autofillHints": [
+ "honorific-suffix"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [
+ "san",
+ "kun",
+ "chan",
+ "sama"
+ ]
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "honorific-suffix"
+ }
+ },
+ {
+ "autofillHints": [
+ "shipping"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "shippingseed"
+ },
+ "partition": 1,
+ "saveInfo": 0,
+ "typeName": "shipping"
+ }
+ },
+ {
+ "autofillHints": [
+ "pager"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "pagerseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "pager"
+ }
+ },
+ {
+ "autofillHints": [
+ "impp"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "imppseed"
+ },
+ "partition": 2,
+ "saveInfo": 16,
+ "typeName": "impp"
+ }
+ },
+ {
+ "autofillHints": [
+ "bday-month"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "dateTemplate": "curr_time",
+ "strictExampleSet": [
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ "11",
+ "12"
+ ],
+ "textTemplate": "bday-monthseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "bday-month"
+ }
+ },
+ {
+ "autofillHints": [
+ "tel-local-prefix"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "tel-local-prefixseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "tel-local-prefix"
+ }
+ },
+ {
+ "autofillHints": [
+ "tel"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "telseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "tel"
+ }
+ },
+ {
+ "autofillHints": [
+ "fax"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "faxseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "fax"
+ }
+ },
+ {
+ "autofillHints": [
+ "honorific-prefix"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [
+ "Miss",
+ "Ms.",
+ "Mr.",
+ "Mx.",
+ "Sr.",
+ "Dr.",
+ "Lady",
+ "Lord"
+ ]
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "honorific-prefix"
+ }
+ },
+ {
+ "autofillHints": [
+ "bday-year"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "dateTemplate": "curr_time",
+ "strictExampleSet": []
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "bday-year"
+ }
+ },
+ {
+ "autofillHints": [
+ "creditCardExpirationMonth",
+ "cc-exp-month"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3,
+ 4
+ ],
+ "fakeData": {
+ "dateTemplate": "curr_time",
+ "strictExampleSet": [
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ "11",
+ "12"
+ ]
+ },
+ "partition": 3,
+ "saveInfo": 4,
+ "typeName": "creditCardExpirationMonth"
+ }
+ },
+ {
+ "autofillHints": [
+ "work"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "workseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "work"
+ }
+ },
+ {
+ "autofillHints": [
+ "cc-csc",
+ "creditCardSecurityCode"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "seedseedseed"
+ },
+ "partition": 3,
+ "saveInfo": 4,
+ "typeName": "creditCardSecurityCode"
+ }
+ },
+ {
+ "autofillHints": [
+ "cc-type"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "cc-typeseed"
+ },
+ "partition": 3,
+ "saveInfo": 4,
+ "typeName": "cc-type"
+ }
+ },
+ {
+ "autofillHints": [
+ "bday-day"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "dateTemplate": "curr_time",
+ "strictExampleSet": [],
+ "textTemplate": "seed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "bday-day"
+ }
+ },
+ {
+ "autofillHints": [
+ "address-line2"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "Bldg. seed"
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "address-line2"
+ }
+ },
+ {
+ "autofillHints": [
+ "address-line1"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "seed Fake Ln."
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "address-line1"
+ }
+ },
+ {
+ "autofillHints": [
+ "postalAddress"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "seed Fake Ln, Fake, FA, FAA 10001"
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "postalAddress"
+ }
+ },
+ {
+ "autofillHints": [
+ "address-line3"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "Suite seed"
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "address-line3"
+ }
+ },
+ {
+ "autofillHints": [
+ "phone"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "seed2345678910"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "phone"
+ }
+ },
+ {
+ "autofillHints": [
+ "tel_extension"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "tel_extensionseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "tel_extension"
+ }
+ },
+ {
+ "autofillHints": [
+ "creditCardNumber",
+ "cc-number"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "seed234567"
+ },
+ "partition": 3,
+ "saveInfo": 4,
+ "typeName": "creditCardNumber"
+ }
+ },
+ {
+ "autofillHints": [
+ "name"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "nameseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "name"
+ }
+ },
+ {
+ "autofillHints": [
+ "additional-name"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "additional-nameseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "additional-name"
+ }
+ },
+ {
+ "autofillHints": [
+ "tel-local"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "tel-localseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "tel-local"
+ }
+ },
+ {
+ "autofillHints": [
+ "bday"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 4
+ ],
+ "fakeData": {
+ "dateTemplate": "curr_time",
+ "strictExampleSet": []
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "bday"
+ }
+ },
+ {
+ "autofillHints": [
+ "street-address"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "street-addressseed"
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "street-address"
+ }
+ },
+ {
+ "autofillHints": [
+ "cc-given-name"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "cc-given-nameseed"
+ },
+ "partition": 3,
+ "saveInfo": 4,
+ "typeName": "cc-given-name"
+ }
+ },
+ {
+ "autofillHints": [
+ "creditCardExpirationDate",
+ "cc-exp"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 4
+ ],
+ "fakeData": {
+ "dateTemplate": "curr_time",
+ "strictExampleSet": []
+ },
+ "partition": 3,
+ "saveInfo": 4,
+ "typeName": "creditCardExpirationDate"
+ }
+ },
+ {
+ "autofillHints": [
+ "creditCardExpirationYear",
+ "cc-exp-year"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3,
+ 4
+ ],
+ "fakeData": {
+ "dateTemplate": "curr_time",
+ "strictExampleSet": [],
+ "textTemplate": "creditCardExpirationYearseed"
+ },
+ "partition": 3,
+ "saveInfo": 4,
+ "typeName": "creditCardExpirationYear"
+ }
+ },
+ {
+ "autofillHints": [
+ "organization-title"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "organization-titleseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "organization-title"
+ }
+ },
+ {
+ "autofillHints": [
+ "sex"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [
+ "Male",
+ "Female",
+ "Other"
+ ]
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "sex"
+ }
+ },
+ {
+ "autofillHints": [
+ "section-"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "section-seed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "section-"
+ }
+ },
+ {
+ "autofillHints": [
+ "country-name"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [
+ "USA",
+ "Mexico",
+ "Canada"
+ ]
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "country-name"
+ }
+ },
+ {
+ "autofillHints": [
+ "photo"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "photoseed.jpg"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "photo"
+ }
+ },
+ {
+ "autofillHints": [
+ "tel-area-code"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "tel-area-codeseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "tel-area-code"
+ }
+ },
+ {
+ "autofillHints": [
+ "new-password"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "new-passwordseed"
+ },
+ "partition": 0,
+ "saveInfo": 1,
+ "typeName": "new-password"
+ }
+ },
+ {
+ "autofillHints": [
+ "tel-local-suffix"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "tel-local-suffixseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "tel-local-suffix"
+ }
+ },
+ {
+ "autofillHints": [
+ "family-name"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "family-nameseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "family-name"
+ }
+ },
+ {
+ "autofillHints": [
+ "url"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "https://www.google.com/?count\u003dseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "url"
+ }
+ },
+ {
+ "autofillHints": [
+ "home"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "homeseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "home"
+ }
+ },
+ {
+ "autofillHints": [
+ "address-level4"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "address-level4seed"
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "address-level4"
+ }
+ },
+ {
+ "autofillHints": [
+ "address-level3"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "address-level3seed"
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "address-level3"
+ }
+ },
+ {
+ "autofillHints": [
+ "organization"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "organizationseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "organization"
+ }
+ },
+ {
+ "autofillHints": [
+ "cc-additional-name"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "cc-additional-nameseed"
+ },
+ "partition": 3,
+ "saveInfo": 4,
+ "typeName": "cc-additional-name"
+ }
+ },
+ {
+ "autofillHints": [
+ "address-level2"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "address-level2seed"
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "address-level2"
+ }
+ },
+ {
+ "autofillHints": [
+ "given-name"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "given-nameseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "given-name"
+ }
+ },
+ {
+ "autofillHints": [
+ "address-level1"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "address-level1seed"
+ },
+ "partition": 1,
+ "saveInfo": 2,
+ "typeName": "address-level1"
+ }
+ },
+ {
+ "autofillHints": [
+ "creditCardExpirationDay"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3,
+ 4
+ ],
+ "fakeData": {
+ "dateTemplate": "curr_time",
+ "strictExampleSet": [],
+ "textTemplate": "creditCardExpirationDayseed"
+ },
+ "partition": 3,
+ "saveInfo": 4,
+ "typeName": "creditCardExpirationDay"
+ }
+ },
+ {
+ "autofillHints": [
+ "cc-name"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "Firstnameseed Lastnameseed"
+ },
+ "partition": 3,
+ "saveInfo": 4,
+ "typeName": "cc-name"
+ }
+ },
+ {
+ "autofillHints": [
+ "username"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "usernameseed"
+ },
+ "partition": 0,
+ "saveInfo": 8,
+ "typeName": "username"
+ }
+ },
+ {
+ "autofillHints": [
+ "tel-country-code"
+ ],
+ "fieldType": {
+ "autofillTypes": [
+ 1,
+ 3
+ ],
+ "fakeData": {
+ "strictExampleSet": [],
+ "textTemplate": "tel-country-codeseed"
+ },
+ "partition": 0,
+ "saveInfo": 0,
+ "typeName": "tel-country-code"
+ }
+ }
+]