aboutsummaryrefslogtreecommitdiff
path: root/input/autofill
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2018-01-05 00:40:05 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2018-01-05 00:40:05 +0000
commit0f601fda034e8c0806781ac55eddc16becbd4473 (patch)
treeaa4489b3e2718834d426089ec177440ed7dce007 /input/autofill
parent205c4890fd669514d3cf8a6b779a8c47d5a4310a (diff)
parentcec0c701a6c2c00a66bd1c7ec6dd26d13d95d4fd (diff)
downloadandroid-0f601fda034e8c0806781ac55eddc16becbd4473.tar.gz
Merge changes I4ec1d73e,Ib3d740c6,I6d7b029f,I6d6eee18
* changes: Save ClientViewMetadata between pages. Autofill sample: Add DAL check req levels to settings. Autofill sample: use string resources for failure messages. Autofill sample: Cancel autofill when clear button is pressed.
Diffstat (limited to 'input/autofill')
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardCompoundViewActivity.java5
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardDatePickerActivity.java5
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardSpinnersActivity.java5
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/StandardAutoCompleteSignInActivity.java4
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/StandardSignInActivity.java5
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CreditCardActivity.java5
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CreditCardAntiPatternActivity.java5
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/MultiplePartitionsActivity.java21
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/res/layout/fragment_edge_cases.xml2
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/res/layout/multiple_partitions_activity.xml3
-rw-r--r--input/autofill/AutofillFramework/afservice/build.gradle4
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/AuthActivity.java4
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/MyAutofillService.java29
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/StructureParser.java1
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadata.java171
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadataBuilder.java79
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/adapter/ResponseAdapter.java145
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/DigitalAssetLinksDataSource.java5
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/DigitalAssetLinksRepository.java56
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/settings/MyPreferences.java12
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/settings/SettingsActivity.java63
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/util/Util.java10
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/res/layout/multidataset_service_settings_activity.xml38
-rw-r--r--input/autofill/AutofillFramework/afservice/src/main/res/values/strings.xml10
24 files changed, 428 insertions, 259 deletions
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardCompoundViewActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardCompoundViewActivity.java
index c09745e7..b8df27d8 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardCompoundViewActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardCompoundViewActivity.java
@@ -51,7 +51,10 @@ public class CreditCardCompoundViewActivity extends AppCompatActivity {
findViewById(R.id.clearButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- getSystemService(AutofillManager.class).cancel();
+ AutofillManager afm = getSystemService(AutofillManager.class);
+ if (afm != null) {
+ afm.cancel();
+ }
resetFields();
}
});
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardDatePickerActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardDatePickerActivity.java
index f0bcdee8..4a158863 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardDatePickerActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardDatePickerActivity.java
@@ -53,7 +53,10 @@ public class CreditCardDatePickerActivity extends AppCompatActivity {
findViewById(R.id.clearButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- getSystemService(AutofillManager.class).cancel();
+ AutofillManager afm = getSystemService(AutofillManager.class);
+ if (afm != null) {
+ afm.cancel();
+ }
resetFields();
}
});
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardSpinnersActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardSpinnersActivity.java
index 99ec6007..bab53798 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardSpinnersActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/CreditCardSpinnersActivity.java
@@ -94,7 +94,10 @@ public class CreditCardSpinnersActivity extends AppCompatActivity {
findViewById(R.id.clear).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- getSystemService(AutofillManager.class).cancel();
+ AutofillManager afm = getSystemService(AutofillManager.class);
+ if (afm != null) {
+ afm.cancel();
+ }
resetFields();
}
});
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/StandardAutoCompleteSignInActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/StandardAutoCompleteSignInActivity.java
index acdb0f34..089c6b2d 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/StandardAutoCompleteSignInActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/StandardAutoCompleteSignInActivity.java
@@ -61,6 +61,10 @@ public class StandardAutoCompleteSignInActivity extends AppCompatActivity {
mClearButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
+ AutofillManager afm = getSystemService(AutofillManager.class);
+ if (afm != null) {
+ afm.cancel();
+ }
resetFields();
}
});
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/StandardSignInActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/StandardSignInActivity.java
index 6604ee40..c333bce1 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/StandardSignInActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/commoncases/StandardSignInActivity.java
@@ -20,6 +20,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
+import android.view.autofill.AutofillManager;
import android.widget.EditText;
import android.widget.Toast;
@@ -47,6 +48,10 @@ public class StandardSignInActivity extends AppCompatActivity {
findViewById(R.id.clear).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
+ AutofillManager afm = getSystemService(AutofillManager.class);
+ if (afm != null) {
+ afm.cancel();
+ }
resetFields();
}
});
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CreditCardActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CreditCardActivity.java
index c23daf7b..3e68a012 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CreditCardActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CreditCardActivity.java
@@ -53,7 +53,10 @@ public class CreditCardActivity extends AppCompatActivity {
findViewById(R.id.clearButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- getSystemService(AutofillManager.class).cancel();
+ AutofillManager afm = getSystemService(AutofillManager.class);
+ if (afm != null) {
+ afm.cancel();
+ }
resetFields();
}
});
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CreditCardAntiPatternActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CreditCardAntiPatternActivity.java
index c50994cb..edffcc05 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CreditCardAntiPatternActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CreditCardAntiPatternActivity.java
@@ -49,7 +49,10 @@ public class CreditCardAntiPatternActivity extends AppCompatActivity {
findViewById(R.id.clearButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- getSystemService(AutofillManager.class).cancel();
+ AutofillManager afm = getSystemService(AutofillManager.class);
+ if (afm != null) {
+ afm.cancel();
+ }
resetFields();
}
});
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/MultiplePartitionsActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/MultiplePartitionsActivity.java
index 3f4031ce..9e09b45b 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/MultiplePartitionsActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/MultiplePartitionsActivity.java
@@ -47,19 +47,14 @@ public class MultiplePartitionsActivity extends AppCompatActivity {
private ScrollableCustomVirtualView mCustomVirtualView;
private AutofillManager mAutofillManager;
-
private CustomVirtualView.Partition mCredentialsPartition;
private CustomVirtualView.Partition mCcPartition;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
setContentView(R.layout.multiple_partitions_activity);
-
mCustomVirtualView = findViewById(R.id.custom_view);
-
-
mCredentialsPartition =
mCustomVirtualView.addPartition(getString(R.string.partition_credentials));
mCredentialsPartition.addLine("username", View.AUTOFILL_TYPE_TEXT,
@@ -68,7 +63,6 @@ public class MultiplePartitionsActivity extends AppCompatActivity {
mCredentialsPartition.addLine("password", View.AUTOFILL_TYPE_TEXT,
getString(R.string.password_label),
" ", true, View.AUTOFILL_HINT_PASSWORD);
-
int ccExpirationType = View.AUTOFILL_TYPE_DATE;
// TODO: add a checkbox to switch between text / date instead
Intent intent = getIntent();
@@ -82,7 +76,6 @@ public class MultiplePartitionsActivity extends AppCompatActivity {
Toast.makeText(getApplicationContext(), typeMessage, Toast.LENGTH_LONG).show();
}
}
-
mCcPartition = mCustomVirtualView.addPartition(getString(R.string.partition_credit_card));
mCcPartition.addLine("ccNumber", View.AUTOFILL_TYPE_TEXT,
getString(R.string.credit_card_number_label),
@@ -102,13 +95,15 @@ public class MultiplePartitionsActivity extends AppCompatActivity {
mCcPartition.addLine("ccSecurityCode", View.AUTOFILL_TYPE_TEXT,
getString(R.string.credit_card_security_code_label),
" ", true, View.AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE);
-
- findViewById(R.id.clear).setOnClickListener((view) -> {
- resetFields();
- mCustomVirtualView.resetPositions();
- mAutofillManager.cancel();
- });
mAutofillManager = getSystemService(AutofillManager.class);
+ findViewById(R.id.clear).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ resetFields();
+ mCustomVirtualView.resetPositions();
+ mAutofillManager.cancel();
+ }
+ });
}
private void resetFields() {
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/layout/fragment_edge_cases.xml b/input/autofill/AutofillFramework/Application/src/main/res/layout/fragment_edge_cases.xml
index cca506fa..ab7c32aa 100644
--- a/input/autofill/AutofillFramework/Application/src/main/res/layout/fragment_edge_cases.xml
+++ b/input/autofill/AutofillFramework/Application/src/main/res/layout/fragment_edge_cases.xml
@@ -72,7 +72,6 @@
android:id="@+id/multistepSignInButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:visibility="gone"
app:imageColor="@android:color/holo_green_light"
app:infoText="@string/multi_step_signin_info"
app:itemLogo="@drawable/ic_person_black_24dp"
@@ -84,7 +83,6 @@
android:id="@+id/multistepCreditCardButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:visibility="gone"
app:imageColor="@android:color/holo_purple"
app:infoText="@string/multi_step_cc_info"
app:itemLogo="@drawable/ic_spinners_logo_24dp"
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/layout/multiple_partitions_activity.xml b/input/autofill/AutofillFramework/Application/src/main/res/layout/multiple_partitions_activity.xml
index 8b99e6a4..e0fae460 100644
--- a/input/autofill/AutofillFramework/Application/src/main/res/layout/multiple_partitions_activity.xml
+++ b/input/autofill/AutofillFramework/Application/src/main/res/layout/multiple_partitions_activity.xml
@@ -13,7 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
-->
-<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<android.support.constraint.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/input/autofill/AutofillFramework/afservice/build.gradle b/input/autofill/AutofillFramework/afservice/build.gradle
index 65020f48..f341b57b 100644
--- a/input/autofill/AutofillFramework/afservice/build.gradle
+++ b/input/autofill/AutofillFramework/afservice/build.gradle
@@ -1,11 +1,11 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 27
+ compileSdkVersion 26
defaultConfig {
minSdkVersion 26
- targetSdkVersion 27
+ targetSdkVersion 26
versionCode 1
versionName "1.0"
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 595643ff..65ca2e57 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
@@ -32,6 +32,7 @@ import android.widget.EditText;
import android.widget.RemoteViews;
import android.widget.Toast;
+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;
@@ -140,7 +141,8 @@ public class AuthActivity extends AppCompatActivity {
Bundle clientState = intent.getBundleExtra(AutofillManager.EXTRA_CLIENT_STATE);
AssistStructure structure = intent.getParcelableExtra(EXTRA_ASSIST_STRUCTURE);
StructureParser structureParser = new StructureParser(structure);
- mClientViewMetadata = new ClientViewMetadata(structureParser);
+ ClientViewMetadataBuilder builder = new ClientViewMetadataBuilder(structureParser);
+ mClientViewMetadata = builder.buildClientViewMetadata();
mDatasetAdapter = new DatasetAdapter(structureParser);
mResponseAdapter = new ResponseAdapter(this, mClientViewMetadata, mPackageName,
mDatasetAdapter, clientState);
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 96d307f8..4012dbe2 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
@@ -36,6 +36,7 @@ import android.widget.RemoteViews;
import com.example.android.autofill.service.data.AutofillDataBuilder;
import com.example.android.autofill.service.data.ClientAutofillDataBuilder;
import com.example.android.autofill.service.data.ClientViewMetadata;
+import com.example.android.autofill.service.data.ClientViewMetadataBuilder;
import com.example.android.autofill.service.data.DataCallback;
import com.example.android.autofill.service.data.adapter.DatasetAdapter;
import com.example.android.autofill.service.data.adapter.ResponseAdapter;
@@ -51,7 +52,7 @@ import com.example.android.autofill.service.model.DatasetWithFilledAutofillField
import com.example.android.autofill.service.settings.MyPreferences;
import com.example.android.autofill.service.util.AppExecutors;
import com.example.android.autofill.service.util.Util;
-
+import static com.example.android.autofill.service.util.Util.DalCheckRequirement;
import java.util.List;
import static com.example.android.autofill.service.data.adapter.ResponseAdapter.CLIENT_STATE_PARTIAL_ID_TEMPLATE;
@@ -61,6 +62,7 @@ import static com.example.android.autofill.service.util.Util.dumpStructure;
import static com.example.android.autofill.service.util.Util.findNodeByFilter;
import static com.example.android.autofill.service.util.Util.logVerboseEnabled;
import static com.example.android.autofill.service.util.Util.logd;
+import static com.example.android.autofill.service.util.Util.loge;
import static com.example.android.autofill.service.util.Util.logv;
import static com.example.android.autofill.service.util.Util.logw;
@@ -94,7 +96,8 @@ public class MyAutofillService extends AutofillService {
.get(request.getFillContexts().size() - 1).getStructure();
StructureParser parser = new StructureParser(structure);
mDatasetAdapter = new DatasetAdapter(parser);
- mClientViewMetadata = new ClientViewMetadata(parser);
+ ClientViewMetadataBuilder clientViewMetadataBuilder = new ClientViewMetadataBuilder(parser);
+ mClientViewMetadata = clientViewMetadataBuilder.buildClientViewMetadata();
mResponseAdapter = new ResponseAdapter(this, mClientViewMetadata,
getPackageName(), mDatasetAdapter, request.getClientState());
String packageName = structure.getActivityComponent().getPackageName();
@@ -149,10 +152,11 @@ public class MyAutofillService extends AutofillService {
AssistStructure structure = fillContexts.get(size - 1).getStructure();
StructureParser parser = new StructureParser(structure);
mAutofillDataBuilder = new ClientAutofillDataBuilder(parser);
- mClientViewMetadata = new ClientViewMetadata(parser);
+ ClientViewMetadataBuilder clientViewMetadataBuilder = new ClientViewMetadataBuilder(parser);
+ mClientViewMetadata = clientViewMetadataBuilder.buildClientViewMetadata();
String packageName = structure.getActivityComponent().getPackageName();
if (!mPackageVerificationRepository.putPackageSignatures(packageName)) {
- callback.onFailure(getApplicationContext().getString(R.string.invalid_package_signature));
+ callback.onFailure(getString(R.string.invalid_package_signature));
return;
}
Bundle clientState = request.getClientState();
@@ -202,14 +206,15 @@ public class MyAutofillService extends AutofillService {
private void checkWebDomainAndBuildAutofillData(String packageName, SaveCallback callback) {
String webDomain;
try {
- webDomain = mClientViewMetadata.buildWebDomain();
- } catch (SecurityException e) {
+ webDomain = mClientViewMetadata.getWebDomain();
+ } catch(SecurityException e) {
logw(e.getMessage());
- callback.onFailure(e.getMessage());
+ callback.onFailure(getString(R.string.security_exception));
return;
}
if (webDomain != null && webDomain.length() > 0) {
- mDalRepository.checkValid(new DalInfo(webDomain, packageName),
+ DalCheckRequirement req = MyPreferences.getInstance(this).getDalCheckRequirement();
+ mDalRepository.checkValid(req, new DalInfo(webDomain, packageName),
new DataCallback<DalCheck>() {
@Override
public void onLoaded(DalCheck dalCheck) {
@@ -217,16 +222,16 @@ public class MyAutofillService extends AutofillService {
logd("Domain %s is valid for %s", webDomain, packageName);
buildAndSaveAutofillData();
} else {
- callback.onFailure(String.format(
- "Could not associate web domain %s with app %s", webDomain,
- packageName));
+ loge("Could not associate web domain %s with app %s",
+ webDomain, packageName);
+ callback.onFailure(getString(R.string.dal_exception));
}
}
@Override
public void onDataNotAvailable(String msg, Object... params) {
logw(msg, params);
- callback.onFailure(String.format(msg, params));
+ callback.onFailure(getString(R.string.dal_exception));
}
});
} else {
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/StructureParser.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/StructureParser.java
index 54296f36..3e6676d8 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/StructureParser.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/StructureParser.java
@@ -57,7 +57,6 @@ public final class StructureParser {
}
}
-
public interface NodeProcessor {
void processNode(ViewNode node);
}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadata.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadata.java
index abc128f8..24de40c1 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadata.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadata.java
@@ -16,143 +16,96 @@
package com.example.android.autofill.service.data;
-import android.app.assist.AssistStructure;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.service.autofill.SaveInfo;
import android.view.autofill.AutofillId;
-import com.example.android.autofill.service.AutofillHints;
-import com.example.android.autofill.service.StructureParser;
-
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Arrays;
import java.util.List;
-import static com.example.android.autofill.service.util.Util.logd;
-
/**
- * In this simple implementation, the only view data we parse from the client are autofill hints
- * of the views in the view hierarchy, the hints of views that are focused, the corresponding
- * autofill IDs, and the {@link SaveInfo} based on the hints.
- * <p>
- * Note: this class is not thread safe.
+ * In this simple implementation, the only view data we collect from the client are autofill hints
+ * of the views in the view hierarchy, the corresponding autofill IDs, and the {@link SaveInfo}
+ * based on the hints.
*/
-public class ClientViewMetadata {
- private final StructureParser mStructureParser;
-
- private List<String> mCachedAllHints;
- private Integer mCachedSaveType;
- private SaveInfo mCachedSaveInfo;
- private List<AutofillId> mCachedAutofillIds;
-
- public ClientViewMetadata(StructureParser parser) {
- mStructureParser = parser;
- }
+public class ClientViewMetadata implements Parcelable {
- public List<String> getAllHints() {
- if (mCachedAllHints == null) {
- parseHints();
+ public static final Creator<ClientViewMetadata> CREATOR = new Creator<ClientViewMetadata>() {
+ @Override
+ public ClientViewMetadata createFromParcel(Parcel parcel) {
+ return new ClientViewMetadata(parcel);
}
- return mCachedAllHints;
- }
-
- private List<AutofillId> getAutofillIds() {
- if (mCachedAutofillIds == null) {
- AutofillSaveType autofillSaveType = new AutofillSaveType();
- List<AutofillId> autofillIds = new ArrayList<>();
- mStructureParser.parse((node) -> parseSaveTypeAndIds(node, autofillSaveType, autofillIds));
- mCachedSaveType = autofillSaveType.saveType;
- mCachedAutofillIds = autofillIds;
- }
- return mCachedAutofillIds;
- }
- public AutofillId[] getAutofillIdsArray() {
- List<AutofillId> autofillIds = getAutofillIds();
- if (autofillIds == null || autofillIds.isEmpty()) {
- return null;
+ @Override
+ public ClientViewMetadata[] newArray(int size) {
+ return new ClientViewMetadata[size];
}
- return autofillIds.toArray(new AutofillId[autofillIds.size()]);
+ };
+
+ private final List<String> mAllHints;
+ private final int mSaveType;
+ private final AutofillId[] mAutofillIds;
+ private final String mWebDomain;
+
+ public ClientViewMetadata(List<String> allHints, int saveType, AutofillId[] autofillIds,
+ String webDomain) {
+ mAllHints = allHints;
+ mSaveType = saveType;
+ mAutofillIds = autofillIds;
+ mWebDomain = webDomain;
}
- public SaveInfo getSaveInfo() {
- if (mCachedSaveInfo == null) {
- int saveType = getSaveType();
- AutofillId[] autofillIdsArray = getAutofillIdsArray();
- if (autofillIdsArray == null || autofillIdsArray.length == 0) {
- return null;
- }
- // TODO: on MR1, creates a new SaveType without required ids
- mCachedSaveInfo = new SaveInfo.Builder(saveType, autofillIdsArray).build();
+ private ClientViewMetadata(Parcel parcel) {
+ mAllHints = new ArrayList<>();
+ parcel.readList(mAllHints, String.class.getClassLoader());
+ mSaveType = parcel.readInt();
+ Parcelable[] ids = parcel.readParcelableArray(AutofillId.class.getClassLoader());
+ if (ids != null && ids.length > 0) {
+ mAutofillIds = Arrays.copyOf(ids, ids.length, AutofillId[].class);
+ } else {
+ mAutofillIds = null;
}
- return mCachedSaveInfo;
+ mWebDomain = parcel.readString();
}
- public int getSaveType() {
- if (mCachedSaveType == null) {
- AutofillSaveType autofillSaveType = new AutofillSaveType();
- List<AutofillId> autofillIds = new ArrayList<>();
- mStructureParser.parse((node) -> parseSaveTypeAndIds(node, autofillSaveType, autofillIds));
- mCachedSaveType = autofillSaveType.saveType;
- mCachedAutofillIds = autofillIds;
- }
- return mCachedSaveType;
+ public List<String> getAllHints() {
+ return mAllHints;
}
- public String buildWebDomain() {
- StringBuilder webDomainBuilder = new StringBuilder();
- mStructureParser.parse((node) -> parseWebDomain(node, webDomainBuilder));
- return webDomainBuilder.toString();
+ public AutofillId[] getAutofillIds() {
+ return mAutofillIds;
}
- private void parseWebDomain(AssistStructure.ViewNode viewNode, StringBuilder validWebDomain) {
- String webDomain = viewNode.getWebDomain();
- if (webDomain != null) {
- logd("child web domain: %s", webDomain);
- if (validWebDomain.length() > 0) {
- if (!webDomain.equals(validWebDomain.toString())) {
- throw new SecurityException("Found multiple web domains: valid= "
- + validWebDomain + ", child=" + webDomain);
- }
- } else {
- validWebDomain.append(webDomain);
- }
- }
- }
-
- private void parseSaveTypeAndIds(AssistStructure.ViewNode root,
- AutofillSaveType autofillSaveType, List<AutofillId> autofillIds) {
- String[] hints = root.getAutofillHints();
- if (hints != null) {
- for (String hint : hints) {
- if (AutofillHints.isValidHint(hint)) {
- autofillSaveType.saveType |= AutofillHints.getSaveTypeForHint(hint);
- autofillIds.add(root.getAutofillId());
- }
- }
- }
+ public int getSaveType() {
+ return mSaveType;
}
- private void parseHints() {
- List<String> allHints = new ArrayList<>();
- mStructureParser.parse((node) -> getHints(node, allHints));
- mCachedAllHints = allHints;
+ public String getWebDomain() {
+ return mWebDomain;
}
- private void getHints(AssistStructure.ViewNode node, List<String> allHints) {
- if (node.getAutofillHints() != null) {
- String[] hints = node.getAutofillHints();
- Collections.addAll(allHints, hints);
- }
+ @Override
+ public void writeToParcel(Parcel parcel, int i) {
+ parcel.writeList(mAllHints);
+ parcel.writeInt(mSaveType);
+ parcel.writeParcelableArray(mAutofillIds, 0);
+ parcel.writeString(mWebDomain);
}
- public void clearCache() {
- mCachedAllHints = null;
- mCachedSaveType = null;
- mCachedSaveInfo = null;
- mCachedAutofillIds = null;
+ @Override
+ public int describeContents() {
+ return 0;
}
- private class AutofillSaveType {
- int saveType;
+ @Override
+ public String toString() {
+ return "ClientViewMetadata{" +
+ "mAllHints=" + mAllHints +
+ ", mSaveType=" + mSaveType +
+ ", mAutofillIds=" + Arrays.toString(mAutofillIds) +
+ ", mWebDomain='" + mWebDomain + '\'' +
+ '}';
}
}
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
new file mode 100644
index 00000000..394cd72d
--- /dev/null
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/ClientViewMetadataBuilder.java
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+
+import android.app.assist.AssistStructure;
+import android.util.MutableInt;
+import android.view.autofill.AutofillId;
+
+import com.example.android.autofill.service.AutofillHints;
+import com.example.android.autofill.service.StructureParser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.example.android.autofill.service.util.Util.logd;
+
+public class ClientViewMetadataBuilder {
+ private StructureParser mStructureParser;
+
+ public ClientViewMetadataBuilder(StructureParser parser) {
+ mStructureParser = parser;
+ }
+
+ public ClientViewMetadata buildClientViewMetadata() {
+ List<String> allHints = new ArrayList<>();
+ MutableInt saveType = new MutableInt(0);
+ List<AutofillId> autofillIds = new ArrayList<>();
+ StringBuilder webDomainBuilder = new StringBuilder();
+ mStructureParser.parse((node) -> parseNode(node, allHints, saveType, autofillIds));
+ mStructureParser.parse((node) -> parseWebDomain(node, webDomainBuilder));
+ String webDomain = webDomainBuilder.toString();
+ AutofillId[] autofillIdsArray = autofillIds.toArray(new AutofillId[autofillIds.size()]);
+ return new ClientViewMetadata(allHints, saveType.value, autofillIdsArray, webDomain);
+ }
+
+ private void parseWebDomain(AssistStructure.ViewNode viewNode, StringBuilder validWebDomain) {
+ String webDomain = viewNode.getWebDomain();
+ if (webDomain != null) {
+ logd("child web domain: %s", webDomain);
+ if (validWebDomain.length() > 0) {
+ if (!webDomain.equals(validWebDomain.toString())) {
+ throw new SecurityException("Found multiple web domains: valid= "
+ + validWebDomain + ", child=" + webDomain);
+ }
+ } else {
+ validWebDomain.append(webDomain);
+ }
+ }
+ }
+
+ private void parseNode(AssistStructure.ViewNode root, List<String> allHints,
+ MutableInt autofillSaveType, List<AutofillId> autofillIds) {
+ String[] hints = root.getAutofillHints();
+ if (hints != null) {
+ for (String hint : hints) {
+ if (AutofillHints.isValidHint(hint)) {
+ allHints.add(hint);
+ autofillSaveType.value |= AutofillHints.getSaveTypeForHint(hint);
+ autofillIds.add(root.getAutofillId());
+ }
+ }
+ }
+ }
+}
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 39ebf702..974288d2 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
@@ -22,7 +22,6 @@ import android.os.Bundle;
import android.service.autofill.Dataset;
import android.service.autofill.FillResponse;
import android.service.autofill.SaveInfo;
-import android.view.View;
import android.view.autofill.AutofillId;
import android.widget.RemoteViews;
@@ -31,24 +30,21 @@ import com.example.android.autofill.service.RemoteViewsHelper;
import com.example.android.autofill.service.data.ClientViewMetadata;
import com.example.android.autofill.service.model.DatasetWithFilledAutofillFields;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.List;
-import static com.example.android.autofill.service.util.Util.bundleToString;
-import static com.example.android.autofill.service.util.Util.getSaveTypeAsString;
-import static com.example.android.autofill.service.util.Util.logDebugEnabled;
import static com.example.android.autofill.service.util.Util.logd;
public class ResponseAdapter {
public static final String CLIENT_STATE_PARTIAL_ID_TEMPLATE = "partial-%s";
// TODO: move to settings activity and document it
private static final boolean SUPPORT_MULTIPLE_STEPS = true;
-
+ static int pageno = 0;
private final Context mContext;
private final DatasetAdapter mDatasetAdapter;
private final String mPackageName;
private final ClientViewMetadata mClientViewMetadata;
- private final Bundle mPreviousClientState;
+ private final List<ClientViewMetadata> mPreviousClientViewMetadatas;
public ResponseAdapter(Context context, ClientViewMetadata clientViewMetadata,
String packageName, DatasetAdapter datasetAdapter, Bundle clientState) {
@@ -56,7 +52,15 @@ public class ResponseAdapter {
mClientViewMetadata = clientViewMetadata;
mDatasetAdapter = datasetAdapter;
mPackageName = packageName;
- mPreviousClientState = clientState;
+ mPreviousClientViewMetadatas = new ArrayList<>();
+ if (clientState != null) {
+ clientState.setClassLoader(getClass().getClassLoader());
+ for (int i = pageno - 1; i >= 0; i--) {
+ ClientViewMetadata previousPage = clientState.getParcelable("client-" + (pageno - 1));
+ mPreviousClientViewMetadatas.add(previousPage);
+ }
+ logd("previous client state == " + mPreviousClientViewMetadatas);
+ }
}
/**
@@ -91,74 +95,77 @@ public class ResponseAdapter {
}
}
}
-
+ Bundle clientState = new Bundle();
+ clientState.putParcelable("client-" + (pageno++), mClientViewMetadata);
int saveType = mClientViewMetadata.getSaveType();
- AutofillId[] autofillIds = mClientViewMetadata.getAutofillIdsArray();
- List<String> allHints = mClientViewMetadata.getAllHints();
- if (logDebugEnabled()) {
- logd("setPartialSaveInfo() for type %s: allHints=%s, ids=%s, clientState=%s",
- getSaveTypeAsString(saveType), allHints, Arrays.toString(autofillIds),
- bundleToString(mPreviousClientState));
- }
- // TODO: this should be more generic, but for now it's hardcode to support just activities
- // that have an username and a password in separate steps (like MultipleStepsSigninActivity)
- if ((saveType != SaveInfo.SAVE_DATA_TYPE_USERNAME
- && saveType != SaveInfo.SAVE_DATA_TYPE_PASSWORD)
- || autofillIds.length != 1 || allHints.size() != 1) {
- logd("Unsupported activity for partial info; returning full");
- SaveInfo saveInfo = mClientViewMetadata.getSaveInfo();
- if (saveInfo != null) {
- responseBuilder.setSaveInfo(mClientViewMetadata.getSaveInfo());
- return responseBuilder.build();
- } else {
- return null;
- }
- }
- int previousSaveType;
- String previousHint;
- if (saveType == SaveInfo.SAVE_DATA_TYPE_PASSWORD) {
- previousHint = View.AUTOFILL_HINT_USERNAME;
- previousSaveType = SaveInfo.SAVE_DATA_TYPE_USERNAME;
- } else {
- previousHint = View.AUTOFILL_HINT_PASSWORD;
- previousSaveType = SaveInfo.SAVE_DATA_TYPE_PASSWORD;
- }
- String previousKey = String.format(CLIENT_STATE_PARTIAL_ID_TEMPLATE, previousHint);
-
- AutofillId previousValue = mPreviousClientState == null ? null : mPreviousClientState
- .getParcelable(previousKey);
- logd("previous: %s=%s", previousKey, previousValue);
-
- Bundle newClientState = new Bundle();
- String key = String.format(CLIENT_STATE_PARTIAL_ID_TEMPLATE, allHints.get(0));
- AutofillId value = autofillIds[0];
- logd("New client state: %s = %s", key, value);
- newClientState.putParcelable(key, value);
-
- if (previousValue != null) {
- AutofillId[] newIds = new AutofillId[]{previousValue, value};
- int newSaveType = saveType | previousSaveType;
- logd("new values: type=%s, ids=%s",
- getSaveTypeAsString(newSaveType), Arrays.toString(newIds));
- newClientState.putAll(mPreviousClientState);
- responseBuilder.setSaveInfo(new SaveInfo.Builder(newSaveType, newIds)
- .setFlags(SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE)
- .build())
- .setClientState(newClientState);
-
- return responseBuilder.build();
- }
- responseBuilder.setClientState(newClientState);
- responseBuilder.setSaveInfo(mClientViewMetadata.getSaveInfo());
+ AutofillId[] autofillIds = mClientViewMetadata.getAutofillIds();
+ SaveInfo saveInfo = new SaveInfo.Builder(saveType, autofillIds).build();
+ responseBuilder.setSaveInfo(saveInfo);
+ responseBuilder.setClientState(clientState);
return responseBuilder.build();
+// int saveType = mClientViewMetadata.getSaveType();
+// AutofillId[] autofillIds = mClientViewMetadata.getAutofillIds();
+// List<String> allHints = mClientViewMetadata.getAllHints();
+// if (logDebugEnabled()) {
+// logd("setPartialSaveInfo() for type %s: allHints=%s, ids=%s, clientState=%s",
+// getSaveTypeAsString(saveType), allHints, Arrays.toString(autofillIds),
+// bundleToString(mPreviousClientState));
+// }
+// // TODO: this should be more generic, but for now it's hardcode to support just activities
+// // that have an username and a password in separate steps (like MultipleStepsSigninActivity)
+// if ((saveType != SaveInfo.SAVE_DATA_TYPE_USERNAME
+// && saveType != SaveInfo.SAVE_DATA_TYPE_PASSWORD)
+// || autofillIds.length != 1 || allHints.size() != 1) {
+// logd("Unsupported activity for partial info; returning full");
+// responseBuilder.setSaveInfo(mClientViewMetadata.getSaveInfo());
+// return responseBuilder.build();
+// }
+// int previousSaveType;
+// String previousHint;
+// if (saveType == SaveInfo.SAVE_DATA_TYPE_PASSWORD) {
+// previousHint = View.AUTOFILL_HINT_USERNAME;
+// previousSaveType = SaveInfo.SAVE_DATA_TYPE_USERNAME;
+// } else {
+// previousHint = View.AUTOFILL_HINT_PASSWORD;
+// previousSaveType = SaveInfo.SAVE_DATA_TYPE_PASSWORD;
+// }
+// String previousKey = String.format(CLIENT_STATE_PARTIAL_ID_TEMPLATE, previousHint);
+//
+// AutofillId previousValue = mPreviousClientState == null ? null : mPreviousClientState
+// .getParcelable(previousKey);
+// logd("previous: %s=%s", previousKey, previousValue);
+//
+// Bundle newClientState = new Bundle();
+// String key = String.format(CLIENT_STATE_PARTIAL_ID_TEMPLATE, allHints.get(0));
+// AutofillId value = autofillIds[0];
+// logd("New client state: %s = %s", key, value);
+// newClientState.putParcelable(key, value);
+//
+// if (previousValue != null) {
+// AutofillId[] newIds = new AutofillId[]{previousValue, value};
+// int newSaveType = saveType | previousSaveType;
+// logd("new values: type=%s, ids=%s",
+// getSaveTypeAsString(newSaveType), Arrays.toString(newIds));
+// newClientState.putAll(mPreviousClientState);
+// responseBuilder.setSaveInfo(new SaveInfo.Builder(newSaveType, newIds)
+// .setFlags(SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE)
+// .build())
+// .setClientState(newClientState);
+//
+// return responseBuilder.build();
+// }
+// responseBuilder.setClientState(newClientState);
+// responseBuilder.setSaveInfo(mClientViewMetadata.getSaveInfo());
+// return responseBuilder.build();
}
public FillResponse buildResponse(IntentSender sender, RemoteViews remoteViews) {
FillResponse.Builder responseBuilder = new FillResponse.Builder();
- AutofillId[] autofillIds = mClientViewMetadata.getAutofillIdsArray();
- SaveInfo saveInfo = mClientViewMetadata.getSaveInfo();
- responseBuilder.setAuthentication(autofillIds, sender, remoteViews);
+ int saveType = mClientViewMetadata.getSaveType();
+ AutofillId[] autofillIds = mClientViewMetadata.getAutofillIds();
+ SaveInfo saveInfo = new SaveInfo.Builder(saveType, autofillIds).build();
responseBuilder.setSaveInfo(saveInfo);
+ responseBuilder.setAuthentication(autofillIds, sender, remoteViews);
return responseBuilder.build();
}
}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/DigitalAssetLinksDataSource.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/DigitalAssetLinksDataSource.java
index c01573b0..00661a7f 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/DigitalAssetLinksDataSource.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/DigitalAssetLinksDataSource.java
@@ -19,6 +19,8 @@ import com.example.android.autofill.service.data.DataCallback;
import com.example.android.autofill.service.model.DalCheck;
import com.example.android.autofill.service.model.DalInfo;
+import static com.example.android.autofill.service.util.Util.DalCheckRequirement;
+
/**
* Data source for
* <a href="https://developers.google.com/digital-asset-links/">Digital Asset Links</a>.
@@ -28,7 +30,8 @@ public interface DigitalAssetLinksDataSource {
/**
* Checks if the association between a web domain and a package is valid.
*/
- void checkValid(DalInfo dalInfo, DataCallback<DalCheck> dalCheckCallback);
+ void checkValid(DalCheckRequirement dalCheckRequirement, DalInfo dalInfo,
+ DataCallback<DalCheck> dalCheckCallback);
/**
* Clears all cached data.
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/DigitalAssetLinksRepository.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/DigitalAssetLinksRepository.java
index dfcecab4..6303a1e7 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/DigitalAssetLinksRepository.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/data/source/local/DigitalAssetLinksRepository.java
@@ -19,12 +19,12 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
-import com.example.android.autofill.service.util.SecurityHelper;
-import com.example.android.autofill.service.data.source.DalService;
import com.example.android.autofill.service.data.DataCallback;
+import com.example.android.autofill.service.data.source.DalService;
import com.example.android.autofill.service.data.source.DigitalAssetLinksDataSource;
import com.example.android.autofill.service.model.DalCheck;
import com.example.android.autofill.service.model.DalInfo;
+import com.example.android.autofill.service.util.SecurityHelper;
import com.google.common.net.InternetDomainName;
import java.util.HashMap;
@@ -34,6 +34,10 @@ import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
+import static com.example.android.autofill.service.util.Util.DalCheckRequirement;
+import static com.example.android.autofill.service.util.Util.DalCheckRequirement.AllUrls;
+import static com.example.android.autofill.service.util.Util.DalCheckRequirement.Disabled;
+import static com.example.android.autofill.service.util.Util.DalCheckRequirement.LoginOnly;
import static com.example.android.autofill.service.util.Util.logd;
@@ -41,7 +45,6 @@ import static com.example.android.autofill.service.util.Util.logd;
* Singleton repository that caches the result of Digital Asset Links checks.
*/
public class DigitalAssetLinksRepository implements DigitalAssetLinksDataSource {
-
private static final String DAL_BASE_URL = "https://digitalassetlinks.googleapis.com";
private static final String PERMISSION_GET_LOGIN_CREDS = "common.get_login_creds";
private static final String PERMISSION_HANDLE_ALL_URLS = "common.handle_all_urls";
@@ -80,7 +83,15 @@ public class DigitalAssetLinksRepository implements DigitalAssetLinksDataSource
mCache.clear();
}
- public void checkValid(DalInfo dalInfo, DataCallback<DalCheck> dalCheckDataCallback) {
+ public void checkValid(DalCheckRequirement dalCheckRequirement, DalInfo dalInfo,
+ DataCallback<DalCheck> dalCheckDataCallback) {
+ if (dalCheckRequirement.equals(Disabled)) {
+ DalCheck dalCheck = new DalCheck();
+ dalCheck.linked = true;
+ dalCheckDataCallback.onLoaded(dalCheck);
+ return;
+ }
+
DalCheck dalCheck = mCache.get(dalInfo);
if (dalCheck != null) {
dalCheckDataCallback.onLoaded(dalCheck);
@@ -109,22 +120,27 @@ public class DigitalAssetLinksRepository implements DigitalAssetLinksDataSource
DalCheck dalCheck = response.body();
if (dalCheck == null || !dalCheck.linked) {
// get_login_creds check failed, so try handle_all_urls check
- mDalService.check(webDomain, PERMISSION_HANDLE_ALL_URLS, packageName,
- fingerprint).enqueue(new Callback<DalCheck>() {
- @Override
- public void onResponse(@NonNull Call<DalCheck> call,
- @NonNull Response<DalCheck> response) {
- DalCheck dalCheck = response.body();
- mCache.put(dalInfo, dalCheck);
- dalCheckDataCallback.onLoaded(dalCheck);
- }
-
- @Override
- public void onFailure(@NonNull Call<DalCheck> call,
- @NonNull Throwable t) {
- dalCheckDataCallback.onDataNotAvailable(t.getMessage());
- }
- });
+ if (dalCheckRequirement.equals(LoginOnly)) {
+ dalCheckDataCallback.onDataNotAvailable(
+ "DAL: Login creds check failed.");
+ } else if (dalCheckRequirement.equals(AllUrls)) {
+ mDalService.check(webDomain, PERMISSION_HANDLE_ALL_URLS,
+ packageName, fingerprint).enqueue(new Callback<DalCheck>() {
+ @Override
+ public void onResponse(@NonNull Call<DalCheck> call,
+ @NonNull Response<DalCheck> response) {
+ DalCheck dalCheck = response.body();
+ mCache.put(dalInfo, dalCheck);
+ dalCheckDataCallback.onLoaded(dalCheck);
+ }
+
+ @Override
+ public void onFailure(@NonNull Call<DalCheck> call,
+ @NonNull Throwable t) {
+ dalCheckDataCallback.onDataNotAvailable(t.getMessage());
+ }
+ });
+ }
} else {
// get_login_creds check succeeded, so we're finished.
mCache.put(dalInfo, dalCheck);
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/settings/MyPreferences.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/settings/MyPreferences.java
index 73fa3acf..8770ef83 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/settings/MyPreferences.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/settings/MyPreferences.java
@@ -28,6 +28,7 @@ public class MyPreferences {
private static final String DATASET_AUTH_KEY = "dataset_auth";
private static final String MASTER_PASSWORD_KEY = "master_password";
private static final String LOGGING_LEVEL = "logging_level";
+ private static final String DAL_CHECK_REQUIRED = "dal_check_required";
private static MyPreferences sInstance;
private final SharedPreferences mPrefs;
@@ -90,11 +91,20 @@ public class MyPreferences {
}
public Util.LogLevel getLoggingLevel() {
- return Util.LogLevel.values()[mPrefs.getInt(LOGGING_LEVEL, Util.LogLevel.OFF.ordinal())];
+ return Util.LogLevel.values()[mPrefs.getInt(LOGGING_LEVEL, Util.LogLevel.Off.ordinal())];
}
public void setLoggingLevel(Util.LogLevel level) {
mPrefs.edit().putInt(LOGGING_LEVEL, level.ordinal()).apply();
Util.setLoggingLevel(level);
}
+
+ public Util.DalCheckRequirement getDalCheckRequirement() {
+ return Util.DalCheckRequirement.values()[mPrefs.getInt(DAL_CHECK_REQUIRED,
+ Util.DalCheckRequirement.AllUrls.ordinal())];
+ }
+
+ public void setDalCheckRequired(Util.DalCheckRequirement level) {
+ mPrefs.edit().putInt(DAL_CHECK_REQUIRED, level.ordinal()).apply();
+ }
}
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 5ccc13ae..82222a80 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
@@ -51,6 +51,9 @@ import com.example.android.autofill.service.util.Util;
import java.util.List;
+import static com.example.android.autofill.service.util.Util.DalCheckRequirement.AllUrls;
+import static com.example.android.autofill.service.util.Util.DalCheckRequirement.Disabled;
+import static com.example.android.autofill.service.util.Util.DalCheckRequirement.LoginOnly;
import static com.example.android.autofill.service.util.Util.logd;
import static com.example.android.autofill.service.util.Util.logw;
@@ -60,6 +63,7 @@ public class SettingsActivity extends AppCompatActivity {
private AutofillManager mAutofillManager;
private LocalAutofillDataSource mLocalAutofillDataSource;
private PackageVerificationDataSource mPackageVerificationDataSource;
+ private MyPreferences mPreferences;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -72,18 +76,17 @@ public class SettingsActivity extends AppCompatActivity {
autofillDao, new AppExecutors());
mAutofillManager = getSystemService(AutofillManager.class);
mPackageVerificationDataSource = SharedPrefsPackageVerificationRepository.getInstance(this);
-
- final MyPreferences preferences = MyPreferences.getInstance(this);
+ mPreferences = MyPreferences.getInstance(this);
setupSettingsSwitch(R.id.settings_auth_responses_container,
R.id.settings_auth_responses_label,
R.id.settings_auth_responses_switch,
- preferences.isResponseAuth(),
- (compoundButton, isResponseAuth) -> preferences.setResponseAuth(isResponseAuth));
+ mPreferences.isResponseAuth(),
+ (compoundButton, isResponseAuth) -> mPreferences.setResponseAuth(isResponseAuth));
setupSettingsSwitch(R.id.settings_auth_datasets_container,
R.id.settings_auth_datasets_label,
R.id.settings_auth_datasets_switch,
- preferences.isDatasetAuth(),
- (compoundButton, isDatasetAuth) -> preferences.setDatasetAuth(isDatasetAuth));
+ mPreferences.isDatasetAuth(),
+ (compoundButton, isDatasetAuth) -> mPreferences.setDatasetAuth(isDatasetAuth));
setupSettingsButton(R.id.settings_add_data_container,
R.id.settings_add_data_label,
R.id.settings_add_data_icon,
@@ -96,7 +99,7 @@ public class SettingsActivity extends AppCompatActivity {
R.id.settings_auth_credentials_label,
R.id.settings_auth_credentials_icon,
(view) -> {
- if (preferences.getMasterPassword() != null) {
+ if (mPreferences.getMasterPassword() != null) {
buildCurrentCredentialsDialog().show();
} else {
buildNewCredentialsDialog().show();
@@ -108,29 +111,55 @@ public class SettingsActivity extends AppCompatActivity {
mAutofillManager.hasEnabledAutofillServices(),
(compoundButton, serviceSet) -> setService(serviceSet));
RadioGroup loggingLevelContainer = findViewById(R.id.loggingLevelContainer);
- Util.LogLevel loggingLevel = preferences.getLoggingLevel();
+ Util.LogLevel loggingLevel = mPreferences.getLoggingLevel();
Util.setLoggingLevel(loggingLevel);
switch (loggingLevel) {
- case OFF:
+ case Off:
loggingLevelContainer.check(R.id.loggingOff);
break;
- case DEBUG:
+ case Debug:
loggingLevelContainer.check(R.id.loggingDebug);
break;
- case VERBOSE:
+ case Verbose:
loggingLevelContainer.check(R.id.loggingVerbose);
break;
}
loggingLevelContainer.setOnCheckedChangeListener((group, checkedId) -> {
switch (checkedId) {
case R.id.loggingOff:
- preferences.setLoggingLevel(Util.LogLevel.OFF);
+ mPreferences.setLoggingLevel(Util.LogLevel.Off);
break;
case R.id.loggingDebug:
- preferences.setLoggingLevel(Util.LogLevel.DEBUG);
+ mPreferences.setLoggingLevel(Util.LogLevel.Debug);
break;
case R.id.loggingVerbose:
- preferences.setLoggingLevel(Util.LogLevel.VERBOSE);
+ mPreferences.setLoggingLevel(Util.LogLevel.Verbose);
+ break;
+ }
+ });
+ RadioGroup dalCheckRequirementContainer = findViewById(R.id.dalCheckRequirementContainer);
+ Util.DalCheckRequirement dalCheckRequirement = mPreferences.getDalCheckRequirement();
+ switch (dalCheckRequirement) {
+ case Disabled:
+ dalCheckRequirementContainer.check(R.id.dalDisabled);
+ break;
+ case LoginOnly:
+ dalCheckRequirementContainer.check(R.id.dalLoginOnly);
+ break;
+ case AllUrls:
+ dalCheckRequirementContainer.check(R.id.dalAllUrls);
+ break;
+ }
+ dalCheckRequirementContainer.setOnCheckedChangeListener((group, checkedId) -> {
+ switch (checkedId) {
+ case R.id.dalDisabled:
+ mPreferences.setDalCheckRequired(Disabled);
+ break;
+ case R.id.dalLoginOnly:
+ mPreferences.setDalCheckRequired(LoginOnly);
+ break;
+ case R.id.dalAllUrls:
+ mPreferences.setDalCheckRequired(AllUrls);
break;
}
});
@@ -144,7 +173,7 @@ public class SettingsActivity extends AppCompatActivity {
.setPositiveButton(R.string.settings_ok, (dialog, which) -> {
mLocalAutofillDataSource.clear();
mPackageVerificationDataSource.clear();
- MyPreferences.getInstance(SettingsActivity.this).clearCredentials();
+ mPreferences.clearCredentials();
dialog.dismiss();
})
.create();
@@ -212,7 +241,7 @@ public class SettingsActivity extends AppCompatActivity {
@Override
public void onClick(DialogInterface dialog, int which) {
String password = currentPasswordField.getText().toString();
- if (MyPreferences.getInstance(SettingsActivity.this).getMasterPassword()
+ if (mPreferences.getMasterPassword()
.equals(password)) {
buildNewCredentialsDialog().show();
dialog.dismiss();
@@ -232,7 +261,7 @@ public class SettingsActivity extends AppCompatActivity {
.setView(newPasswordField)
.setPositiveButton(R.string.settings_ok, (dialog, which) -> {
String password = newPasswordField.getText().toString();
- MyPreferences.getInstance(SettingsActivity.this).setMasterPassword(password);
+ mPreferences.setMasterPassword(password);
dialog.dismiss();
})
.create();
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/util/Util.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/util/Util.java
index d7b5b45b..53943138 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/util/Util.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/util/Util.java
@@ -42,7 +42,7 @@ public final class Util {
public static final NodeFilter AUTOFILL_ID_FILTER = (node, id) ->
id.equals(node.getAutofillId());
private static final String TAG = "AutofillSample";
- public static LogLevel sLoggingLevel = LogLevel.OFF;
+ public static LogLevel sLoggingLevel = LogLevel.Off;
private static void bundleToString(StringBuilder builder, Bundle data) {
final Set<String> keySet = data.keySet();
@@ -252,11 +252,11 @@ public final class Util {
}
public static boolean logDebugEnabled() {
- return sLoggingLevel.ordinal() >= LogLevel.DEBUG.ordinal();
+ return sLoggingLevel.ordinal() >= LogLevel.Debug.ordinal();
}
public static boolean logVerboseEnabled() {
- return sLoggingLevel.ordinal() >= LogLevel.VERBOSE.ordinal();
+ return sLoggingLevel.ordinal() >= LogLevel.Verbose.ordinal();
}
public static void logw(String message, Object... params) {
@@ -279,7 +279,9 @@ public final class Util {
sLoggingLevel = level;
}
- public enum LogLevel {OFF, DEBUG, VERBOSE}
+ public enum LogLevel {Off, Debug, Verbose}
+
+ public enum DalCheckRequirement {Disabled, LoginOnly, AllUrls}
/**
* Helper interface used to filter Assist nodes.
diff --git a/input/autofill/AutofillFramework/afservice/src/main/res/layout/multidataset_service_settings_activity.xml b/input/autofill/AutofillFramework/afservice/src/main/res/layout/multidataset_service_settings_activity.xml
index bfbf5f81..ce77e27a 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/res/layout/multidataset_service_settings_activity.xml
+++ b/input/autofill/AutofillFramework/afservice/src/main/res/layout/multidataset_service_settings_activity.xml
@@ -163,6 +163,44 @@
style="@style/Settings.Header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:text="@string/settings_dal_header" />
+
+ <RadioGroup
+ android:id="@+id/dalCheckRequirementContainer"
+ style="@style/Settings.Container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <RadioButton
+ android:id="@+id/dalDisabled"
+ style="@style/Settings.Label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/a11y_min_touch_target_dimen"
+ android:text="@string/settings_dal_disabled" />
+
+ <RadioButton
+ android:id="@+id/dalLoginOnly"
+ style="@style/Settings.Label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/a11y_min_touch_target_dimen"
+ android:text="@string/settings_dal_login_only" />
+
+ <RadioButton
+ android:id="@+id/dalAllUrls"
+ style="@style/Settings.Label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/a11y_min_touch_target_dimen"
+ android:text="@string/settings_dal_all_urls" />
+ </RadioGroup>
+
+ <TextView
+ style="@style/Settings.Header"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:text="@string/settings_logging_header" />
<RadioGroup
diff --git a/input/autofill/AutofillFramework/afservice/src/main/res/values/strings.xml b/input/autofill/AutofillFramework/afservice/src/main/res/values/strings.xml
index 9d41f97f..da0e0a8c 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/res/values/strings.xml
+++ b/input/autofill/AutofillFramework/afservice/src/main/res/values/strings.xml
@@ -1,11 +1,13 @@
<resources>
<string name="invalid_package_signature">Invalid package signature</string>
+ <string name="security_exception">Web domain security exception.</string>
+ <string name="dal_exception">DAL verification failure.</string>
<string name="autofill_sign_in_prompt">Tap to sign in.</string>
<string name="authentication_name">Autofill Authentication</string>
<string name="settings_name">Autofill Settings</string>
<string name="settings_cancel">Cancel</string>
<string name="settings_save">Save</string>
- <string name="settings_authenticate_responses">Authenticate responses</string>
+ <string name="settings_authenticate_responses">Authenticate Responses</string>
<string name="settings_authenticate_datasets">Authenticate Datasets</string>
<string name="settings_add_data_label">Add fake Autofill data</string>
<string name="settings_add_data_title">Add Autofill Datasets</string>
@@ -25,6 +27,12 @@
<string name="settings_logging_off">Off</string>
<string name="settings_logging_debug">Debug</string>
<string name="settings_logging_verbose">Verbose</string>
+
+ <string name="settings_dal_header">DAL Check Requirement</string>
+ <string name="settings_dal_disabled">Disabled</string>
+ <string name="settings_dal_login_only">Login Credentials Only</string>
+ <string name="settings_dal_all_urls">Handle All URLs</string>
+
<string name="settings_enable_header">Enable/Disable</string>
<string name="settings_set_service">Set default Autofill service</string>
<string name="settings_disable_service">Disable Autofill services</string>