Moar changes on Autofill samples.

- Renamed HeuristicsService to DebugService.
- Removed multi-steps support from MyService (it was broken anyways)
- Created a new simple, temporary service to handle multi-step logins.
- Added anti-pattern example for login without hints.
- Added anti-pattern example for autocomplete without using autofill callbacks.
- Added anti-pattern example for multi-step login using activities.
- Added edge-case example for custom theme that changes autofilled text.

Bug: 114236837
Test: manual verification

Change-Id: I7f0f63c090507c247f16eda0075cc20e6dc35139
diff --git a/input/autofill/AutofillFramework/Application/src/main/AndroidManifest.xml b/input/autofill/AutofillFramework/Application/src/main/AndroidManifest.xml
index 624eaee..59368c6 100644
--- a/input/autofill/AutofillFramework/Application/src/main/AndroidManifest.xml
+++ b/input/autofill/AutofillFramework/Application/src/main/AndroidManifest.xml
@@ -53,7 +53,12 @@
         <activity android:name="com.example.android.autofill.app.edgecases.MultipleStepsCreditCardActivity" />
         <activity android:name="com.example.android.autofill.app.commoncases.RecyclerViewActivity" />
         <activity android:name="com.example.android.autofill.app.antipatterns.BadViewStructureCreationSignInActivity" />
-
+        <activity android:name="com.example.android.autofill.app.antipatterns.UsernameOnlyActivity" />
+        <activity android:name="com.example.android.autofill.app.antipatterns.PasswordOnlyActivity" />
+        <activity android:name="com.example.android.autofill.app.antipatterns.HintlessSignInActivity" />
+        <activity android:name="com.example.android.autofill.app.antipatterns.CallbackLessAutoCompleteSignInActivity" />
+        <activity android:name="com.example.android.autofill.app.edgecases.CustomThemeSignInActivity"
+                  android:theme="@style/CustomAutofilledHighlightTheme" />
     </application>
 
 </manifest>
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/antipatterns/CallbackLessAutoCompleteSignInActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/antipatterns/CallbackLessAutoCompleteSignInActivity.java
new file mode 100644
index 0000000..9f28912
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/antipatterns/CallbackLessAutoCompleteSignInActivity.java
@@ -0,0 +1,109 @@
+/*
+ * 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.app.antipatterns;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.View;
+import android.view.autofill.AutofillManager;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+import android.widget.TextView;
+import android.widget.Toast;
+import com.example.android.autofill.app.R;
+import com.example.android.autofill.app.WelcomeActivity;
+import com.example.android.autofill.app.view.widget.InfoButton;
+
+import static com.example.android.autofill.app.Util.TAG;
+
+public class CallbackLessAutoCompleteSignInActivity extends AppCompatActivity {
+    private AutoCompleteTextView mUsernameAutoCompleteField;
+    private TextView mPasswordField;
+    private TextView mLoginButton;
+    private TextView mClearButton;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.login_with_autocomplete_activity);
+
+        TextView title = findViewById(R.id.standard_login_header);
+        title.setText(R.string.navigation_button_anti_pattern_callbackless_autocomplete_login_label);
+
+        InfoButton info = findViewById(R.id.imageButton);
+        info.setInfoText(getString(R.string.anti_pattern_callbackless_autocomplete_login_info));
+
+
+        mLoginButton = findViewById(R.id.login);
+        mClearButton = findViewById(R.id.clear);
+        mUsernameAutoCompleteField = findViewById(R.id.usernameField);
+        mPasswordField = findViewById(R.id.passwordField);
+        mLoginButton.setOnClickListener((v) -> login());
+        mClearButton.setOnClickListener((v) -> {
+            AutofillManager afm = getSystemService(AutofillManager.class);
+            if (afm != null) {
+                afm.cancel();
+            }
+            resetFields();
+        });
+        ArrayAdapter<CharSequence> mockAutocompleteAdapter = ArrayAdapter.createFromResource
+                (this, R.array.mock_autocomplete_sign_in_suggestions,
+                        android.R.layout.simple_dropdown_item_1line);
+        mUsernameAutoCompleteField.setAdapter(mockAutocompleteAdapter);
+        mUsernameAutoCompleteField.setThreshold(1);
+
+        // Show it right away
+        mUsernameAutoCompleteField.setOnFocusChangeListener((v, hasFocus) -> {
+            if (hasFocus) {
+                mUsernameAutoCompleteField.showDropDown();
+            }
+        });
+    }
+
+    private void resetFields() {
+        mUsernameAutoCompleteField.setText("");
+        mPasswordField.setText("");
+    }
+
+    /**
+     * Emulates a login action.
+     */
+    private void login() {
+        String username = mUsernameAutoCompleteField.getText().toString();
+        String password = mPasswordField.getText().toString();
+        boolean valid = isValidCredentials(username, password);
+        if (valid) {
+            Intent intent = WelcomeActivity.getStartActivityIntent(CallbackLessAutoCompleteSignInActivity.this);
+            startActivity(intent);
+            finish();
+        } else {
+            Toast.makeText(this, "Authentication failed.", Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    /**
+     * Dummy implementation for demo purposes. A real service should use secure mechanisms to
+     * authenticate users.
+     */
+    public boolean isValidCredentials(String username, String password) {
+        return username != null && password != null && username.equals(password);
+    }
+}
\ No newline at end of file
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/antipatterns/HintlessSignInActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/antipatterns/HintlessSignInActivity.java
new file mode 100644
index 0000000..dfb6d09
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/antipatterns/HintlessSignInActivity.java
@@ -0,0 +1,27 @@
+/*
+ * 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.app.antipatterns;
+
+import com.example.android.autofill.app.commoncases.StandardSignInActivity;
+import com.example.android.autofill.app.R;
+
+public class HintlessSignInActivity extends StandardSignInActivity {
+
+    @Override
+    protected int getContentView() {
+        return R.layout.hintless_login_activity;
+    }
+}
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/antipatterns/PasswordOnlyActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/antipatterns/PasswordOnlyActivity.java
new file mode 100644
index 0000000..44400ba
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/antipatterns/PasswordOnlyActivity.java
@@ -0,0 +1,56 @@
+/*
+ * 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.app.antipatterns;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.example.android.autofill.app.R;
+import com.example.android.autofill.app.WelcomeActivity;
+
+/**
+ * This activity is the second step in a multi-screen login workflow that uses 2 distinct activities
+ * for username and password, which causes 2 Autofill Save UI to be shown.
+ *
+ * <p>This is a bad pattern anyways&mdash;apps should use Fragments in such scenarios.
+ */
+/*
+ * TODO list
+ * - use ConstraintLayout
+ * - use strings.xml insteaf of hardcoded strings
+ * - add icon with information
+ * - extend AppCompatActivity
+ */
+public final class PasswordOnlyActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.password_only_activity);
+
+        findViewById(R.id.login).setOnClickListener((v) -> login());
+    }
+
+    protected int getContentView() {
+        return R.layout.password_only_activity;
+    }
+
+    void login() {
+        startActivity(new Intent(this, WelcomeActivity.class));
+        finish();
+    }
+}
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/antipatterns/UsernameOnlyActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/antipatterns/UsernameOnlyActivity.java
new file mode 100644
index 0000000..dc5dde1
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/antipatterns/UsernameOnlyActivity.java
@@ -0,0 +1,53 @@
+/*
+ * 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.app.antipatterns;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.util.Log;
+import android.view.autofill.AutofillManager;
+
+import com.example.android.autofill.app.R;
+
+/**
+ * This activity is the first step in a multi-screen login workflow that uses 2 distinct activities
+ * for username and password, which causes 2 Autofill Save UI to be shown.
+ *
+ * <p>This is a bad pattern anyways&mdash;apps should use Fragments in such scenarios.
+ */
+
+/*
+ * TODO list
+ * - use ConstraintLayout
+ * - use strings.xml insteaf of hardcoded strings
+ * - add icon with information
+ * - extend AppCompatActivity
+ */
+public class UsernameOnlyActivity extends Activity {
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        setContentView(R.layout.username_only_activity);
+        findViewById(R.id.next).setOnClickListener((v) -> next());
+    }
+
+    private void next() {
+        startActivity(new Intent(this, PasswordOnlyActivity.class));
+        finish();
+    }
+}
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 c333bce..3e3b5e9 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
@@ -36,7 +36,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        setContentView(R.layout.login_activity);
+        setContentView(getContentView());
         mUsernameEditText = findViewById(R.id.usernameField);
         mPasswordEditText = findViewById(R.id.passwordField);
         findViewById(R.id.login).setOnClickListener(new View.OnClickListener() {
@@ -57,6 +57,10 @@
         });
     }
 
+    protected int getContentView() {
+        return R.layout.login_activity;
+    }
+
     private void resetFields() {
         mUsernameEditText.setText("");
         mPasswordEditText.setText("");
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/AbstractMultipleStepsActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/AbstractMultipleStepsActivity.java
index 2baf335..fc12baa 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/AbstractMultipleStepsActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/AbstractMultipleStepsActivity.java
@@ -20,6 +20,7 @@
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.autofill.AutofillManager;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.LinearLayout;
@@ -134,6 +135,10 @@
         mStatus.setText(message.toString());
         mContainer.removeAllViews();
         mFinished = true;
+        AutofillManager afm = getSystemService(AutofillManager.class);
+        if (afm != null) {
+            afm.commit();
+        }
         updateButtons();
     }
 
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CustomThemeSignInActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CustomThemeSignInActivity.java
new file mode 100644
index 0000000..dbb48e9
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofill/app/edgecases/CustomThemeSignInActivity.java
@@ -0,0 +1,40 @@
+/*
+ * 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.app.edgecases;
+
+import android.os.Bundle;
+import android.widget.TextView;
+
+import com.example.android.autofill.app.commoncases.StandardSignInActivity;
+import com.example.android.autofill.app.view.widget.InfoButton;
+import com.example.android.autofill.app.R;
+
+/**
+ * Same as {@link StandardSignInActivity}, but using a custom theme (defined in the manifest).
+ */
+public class CustomThemeSignInActivity extends StandardSignInActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        TextView title = findViewById(R.id.standard_login_header);
+        title.setText(R.string.navigation_button_custom_theme_login_label);
+
+        InfoButton info = findViewById(R.id.imageButton);
+        info.setInfoText(getString(R.string.custom_theme_login_info));
+    }
+}
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/drawable/custom_autofilled_highlight.xml b/input/autofill/AutofillFramework/Application/src/main/res/drawable/custom_autofilled_highlight.xml
new file mode 100644
index 0000000..f65c32a
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/res/drawable/custom_autofilled_highlight.xml
@@ -0,0 +1,18 @@
+<!--
+ * 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#4DFF0000" />
+</shape>
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 88a353d..83aac1e 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
@@ -109,5 +109,44 @@
             app:labelText="@string/navigation_button_anti_pattern_bad_view_structure_label"
             app:destinationActivityName="com.example.android.autofill.app.antipatterns.BadViewStructureCreationSignInActivity"/>
 
+        <com.example.android.autofill.app.view.widget.NavigationItem
+            android:id="@+id/multistepSignInAntiPatternButton"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:imageColor="@android:color/holo_red_dark"
+            app:infoText="@string/anti_pattern_multistep_signin_info"
+            app:itemLogo="@drawable/ic_disabled_black_24dp"
+            app:labelText="@string/navigation_button_anti_pattern_multistep_signin_label"
+            app:destinationActivityName="com.example.android.autofill.app.antipatterns.UsernameOnlyActivity"/>
+
+        <com.example.android.autofill.app.view.widget.NavigationItem
+            android:id="@+id/hintlessSignInAntiPatternButton"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:imageColor="@android:color/holo_red_dark"
+            app:infoText="@string/anti_pattern_hintless_signin_info"
+            app:itemLogo="@drawable/ic_disabled_black_24dp"
+            app:labelText="@string/navigation_button_anti_pattern_hintless_signin_label"
+            app:destinationActivityName="com.example.android.autofill.app.antipatterns.HintlessSignInActivity"/>
+
+        <com.example.android.autofill.app.view.widget.NavigationItem
+            android:id="@+id/callbacklessSignInAntiPatternButton"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:imageColor="@android:color/holo_red_dark"
+            app:infoText="@string/anti_pattern_callbackless_autocomplete_login_info"
+            app:itemLogo="@drawable/ic_disabled_black_24dp"
+            app:labelText="@string/navigation_button_anti_pattern_callbackless_autocomplete_login_label"
+            app:destinationActivityName="com.example.android.autofill.app.antipatterns.CallbackLessAutoCompleteSignInActivity"/>
+
+        <com.example.android.autofill.app.view.widget.NavigationItem
+            android:id="@+id/standardLoginWithCustomThemeButton"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:imageColor="@android:color/holo_blue_dark"
+            app:infoText="@string/custom_theme_login_info"
+            app:itemLogo="@drawable/ic_autocomplete_logo_24dp"
+            app:labelText="@string/navigation_button_custom_theme_login_label"
+            app:destinationActivityName="com.example.android.autofill.app.edgecases.CustomThemeSignInActivity"/>
     </LinearLayout>
 </ScrollView>
\ No newline at end of file
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/layout/hintless_login_activity.xml b/input/autofill/AutofillFramework/Application/src/main/res/layout/hintless_login_activity.xml
new file mode 100644
index 0000000..433ec30
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/res/layout/hintless_login_activity.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ * 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.
+-->
+<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/authLayout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin">
+
+    <TextView
+        android:id="@+id/standard_login_header"
+        style="@style/TextAppearance.AppCompat.Large"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:gravity="center"
+        android:text="@string/navigation_button_anti_pattern_hintless_signin_label"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/imageButton"
+        app:layout_constraintHorizontal_bias="0.5"
+        app:layout_constraintHorizontal_chainStyle="spread"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <com.example.android.autofill.app.view.widget.InfoButton
+        android:id="@+id/imageButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/spacing_normal"
+        android:background="@drawable/ic_info_black_24dp"
+        app:dialogText="@string/anti_pattern_hintless_signin_info"
+        app:layout_constraintBottom_toBottomOf="@+id/standard_login_header"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.5"
+        app:layout_constraintStart_toEndOf="@+id/standard_login_header"
+        app:layout_constraintTop_toTopOf="@+id/standard_login_header" />
+
+    <TextView
+        android:id="@+id/usernameLabel"
+        style="@style/TextAppearance.AppCompat.Body1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/spacing_normal"
+        android:layout_marginStart="@dimen/spacing_normal"
+        android:layout_marginTop="@dimen/spacing_large"
+        android:labelFor="@+id/obscureFieldId"
+        android:text="@string/username_label"
+        app:layout_constraintEnd_toStartOf="@+id/obscureFieldId"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/standard_login_header" />
+
+    <EditText
+        android:id="@+id/obscureFieldId"
+        android:layout_width="@dimen/text_field_width"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/spacing_normal"
+        android:layout_marginStart="@dimen/spacing_normal"
+        android:layout_marginTop="@dimen/spacing_normal"
+        android:inputType="text"
+        app:layout_constraintBottom_toBottomOf="@+id/usernameLabel"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/usernameLabel"
+        app:layout_constraintTop_toTopOf="@+id/usernameLabel" />
+
+    <TextView
+        android:id="@+id/passwordLabel"
+        style="@style/TextAppearance.AppCompat.Body1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/spacing_normal"
+        android:layout_marginStart="@dimen/spacing_normal"
+        android:layout_marginTop="@dimen/spacing_large"
+        android:labelFor="@+id/anotherObscureFieldId"
+        android:text="@string/password_label"
+        app:layout_constraintEnd_toStartOf="@+id/anotherObscureFieldId"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/usernameLabel" />
+
+    <EditText
+        android:id="@+id/anotherObscureFieldId"
+        android:layout_width="@dimen/text_field_width"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/spacing_normal"
+        android:layout_marginStart="@dimen/spacing_normal"
+        android:layout_marginTop="@dimen/spacing_normal"
+        android:inputType="textPassword"
+        app:layout_constraintBottom_toBottomOf="@+id/passwordLabel"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/passwordLabel"
+        app:layout_constraintTop_toTopOf="@+id/passwordLabel" />
+
+    <TextView
+        android:id="@+id/clear"
+        style="@style/Widget.AppCompat.Button.Borderless"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/spacing_normal"
+        android:layout_marginTop="@dimen/spacing_normal"
+        android:text="@string/clear_label"
+        android:textColor="@android:color/holo_blue_dark"
+        app:layout_constraintEnd_toStartOf="@+id/login"
+        app:layout_constraintHorizontal_bias="0.5"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/anotherObscureFieldId" />
+
+    <TextView
+        android:id="@+id/login"
+        style="@style/Widget.AppCompat.Button.Borderless"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/spacing_normal"
+        android:layout_marginStart="@dimen/spacing_normal"
+        android:text="@string/login_label"
+        android:textColor="@android:color/holo_blue_dark"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.5"
+        app:layout_constraintStart_toEndOf="@+id/clear"
+        app:layout_constraintTop_toTopOf="@+id/clear" />
+
+</android.support.constraint.ConstraintLayout>
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/layout/password_only_activity.xml b/input/autofill/AutofillFramework/Application/src/main/res/layout/password_only_activity.xml
new file mode 100644
index 0000000..a0fbd1d
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/res/layout/password_only_activity.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:focusable="true"
+    android:focusableInTouchMode="true"
+    android:orientation="vertical" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal" >
+
+        <TextView
+            android:id="@+id/password_label"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Password" />
+
+        <EditText
+            android:id="@+id/password"
+            android:autofillHints="password"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:inputType="textPassword" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal" >
+
+        <Button
+            android:id="@+id/login"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Login" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/layout/username_only_activity.xml b/input/autofill/AutofillFramework/Application/src/main/res/layout/username_only_activity.xml
new file mode 100644
index 0000000..5ce2887
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/res/layout/username_only_activity.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:focusable="true"
+    android:focusableInTouchMode="true"
+    android:orientation="vertical" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal" >
+
+        <TextView
+            android:id="@+id/username_label"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Username" />
+
+        <EditText
+            android:id="@+id/username"
+            android:autofillHints="username"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal" >
+
+        <Button
+            android:id="@+id/next"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Next" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/values/strings.xml b/input/autofill/AutofillFramework/Application/src/main/res/values/strings.xml
index fbd8a31..8b40483 100644
--- a/input/autofill/AutofillFramework/Application/src/main/res/values/strings.xml
+++ b/input/autofill/AutofillFramework/Application/src/main/res/values/strings.xml
@@ -34,6 +34,10 @@
     <string name="navigation_button_anti_pattern_bad_view_structure_label">Bad View Structure Creation Anti Pattern</string>
     <string name="navigation_button_multistep_signin_label">Multi-Step Sign In</string>
     <string name="navigation_button_multistep_cc_label">Multi-Step Credit Card Check Out</string>
+    <string name="navigation_button_anti_pattern_multistep_signin_label">Multi-Step Sign In Anti Pattern</string>
+    <string name="navigation_button_anti_pattern_hintless_signin_label">Hintless Sign In Anti Pattern</string>
+    <string name="navigation_button_anti_pattern_callbackless_autocomplete_login_label">Auto Complete without Autofill Integration Anti Pattern</string>
+    <string name="navigation_button_custom_theme_login_label">Sign In Using Custom Theme</string>
     <string name="username_label">Username</string>
     <string name="password_label">Password</string>
     <string name="welcome_text">Success!</string>
@@ -136,6 +140,9 @@
         structure is created onStart() instead of onCreate(), which causes autofill to misbehave
         when the autofill service requires authentication.
     </string>
+    <string name="anti_pattern_hintless_signin_info">This is a sample login page that uses standard EditTexts
+        from the UI toolkit, but without annotating them with android:autofillHints.
+    </string>
 
     <string name="multi_step_signin_info">
         <!--TODO-->
@@ -145,6 +152,18 @@
         <!--TODO-->
     </string>
 
+    <string name="anti_pattern_multistep_signin_info">
+        <!--TODO-->
+    </string>
+
+    <string name="anti_pattern_callbackless_autocomplete_login_info">
+        <!--TODO-->
+    </string>
+
+    <string name="custom_theme_login_info">
+        <!--TODO-->
+    </string>
+
     <string name="partition_credentials">Credentials</string>
     <string name="partition_credit_card">Credit Card</string>
 
@@ -169,8 +188,7 @@
     </plurals>
 
     <string-array name="mock_autocomplete_sign_in_suggestions">
-        <item>user-1</item>
-        <item>user-2</item>
+        <item>app_provided_user</item>
     </string-array>
 
     <string-array name="month_array">
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/values/styles.xml b/input/autofill/AutofillFramework/Application/src/main/res/values/styles.xml
index 303a44d..e7549ac 100644
--- a/input/autofill/AutofillFramework/Application/src/main/res/values/styles.xml
+++ b/input/autofill/AutofillFramework/Application/src/main/res/values/styles.xml
@@ -19,6 +19,10 @@
         <!-- Customize your theme here. -->
     </style>
 
+    <style name="CustomAutofilledHighlightTheme" parent="AppTheme">
+        <item name="android:autofilledHighlight">@drawable/custom_autofilled_highlight</item>
+    </style>
+
     <style name="CustomDatePickerDialogTheme" parent="android:Theme.Material.Light.Dialog">
         <item name="android:datePickerStyle">@style/MyDatePickerStyle</item>
     </style>
diff --git a/input/autofill/AutofillFramework/afservice/src/main/AndroidManifest.xml b/input/autofill/AutofillFramework/afservice/src/main/AndroidManifest.xml
index 8c0b775..9bfff73 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/AndroidManifest.xml
+++ b/input/autofill/AutofillFramework/afservice/src/main/AndroidManifest.xml
@@ -36,12 +36,21 @@
         </service>
 
         <service
-            android:name=".simple.HeuristicsService"
-            android:label="Heuristics Autofill Service"
+            android:name=".simple.DebugService"
+            android:label="Debug Autofill Service"
             android:permission="android.permission.BIND_AUTOFILL_SERVICE">
             <meta-data
                 android:name="android.autofill"
-                android:resource="@xml/heuristics_service"/>
+                android:resource="@xml/debug_service"/>
+            <intent-filter>
+                <action android:name="android.service.autofill.AutofillService" />
+            </intent-filter>
+        </service>
+
+        <service
+            android:name=".simple.MultiStepsService"
+            android:label="Multiple-steps Service"
+            android:permission="android.permission.BIND_AUTOFILL_SERVICE">
             <intent-filter>
                 <action android:name="android.service.autofill.AutofillService" />
             </intent-filter>
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 8770ef8..6a723f0 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
@@ -29,6 +29,7 @@
     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 final String NUMBER_DATASETS = "number_datasets";
     private static MyPreferences sInstance;
     private final SharedPreferences mPrefs;
 
@@ -107,4 +108,12 @@
     public void setDalCheckRequired(Util.DalCheckRequirement level) {
         mPrefs.edit().putInt(DAL_CHECK_REQUIRED, level.ordinal()).apply();
     }
+
+    public int getNumberDatasets(int defaultNumber) {
+        return mPrefs.getInt(NUMBER_DATASETS, defaultNumber);
+    }
+
+    public void setNumberDatasets(int number) {
+        mPrefs.edit().putInt(NUMBER_DATASETS, number).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 1fd87df..500ceec 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
@@ -206,6 +206,7 @@
                 .setView(numberOfDatasetsPicker)
                 .setPositiveButton(R.string.settings_ok, (dialog, which) -> {
                     int numOfDatasets = numberOfDatasetsPicker.getValue();
+                    mPreferences.setNumberDatasets(numOfDatasets);
                     mLocalAutofillDataSource.getFieldTypes(new DataCallback<List<FieldTypeWithHeuristics>>() {
                         @Override
                         public void onLoaded(List<FieldTypeWithHeuristics> fieldTypes) {
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/DebugService.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/DebugService.java
new file mode 100644
index 0000000..501801e
--- /dev/null
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/DebugService.java
@@ -0,0 +1,319 @@
+/*
+ * 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.simple;
+
+import static com.example.android.autofill.service.simple.BasicService.getLatestAssistStructure;
+import static com.example.android.autofill.service.simple.BasicService.newDatasetPresentation;
+
+import android.app.assist.AssistStructure;
+import android.app.assist.AssistStructure.ViewNode;
+import android.content.Context;
+import android.content.IntentSender;
+import android.os.CancellationSignal;
+import android.service.autofill.AutofillService;
+import android.service.autofill.Dataset;
+import android.service.autofill.FillCallback;
+import android.service.autofill.FillRequest;
+import android.service.autofill.FillResponse;
+import android.service.autofill.SaveCallback;
+import android.service.autofill.SaveInfo;
+import android.service.autofill.SaveRequest;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.view.View;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+import android.widget.RemoteViews;
+import android.widget.Toast;
+
+import com.example.android.autofill.service.MyAutofillService;
+import com.example.android.autofill.service.settings.MyPreferences;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * A basic service that provides autofill data for pretty much any input field, even those not
+ * annotated with autfoill hints.
+ *
+ * <p>The goal of this class is to provide a simple autofill service implementation that can be used
+ * to debug how other apps interact with autofill, it should <strong>not</strong> be used as a
+ * reference for real autofill service implementations because it lacks fundamental security
+ * requirements such as data partitioning and package verification &mdashthese requirements are
+ * fullfilled by {@link MyAutofillService}.
+ */
+public class DebugService extends AutofillService {
+
+    private static final String TAG = "DebugService";
+
+    private boolean mAuthenticateResponses;
+    private boolean mAuthenticateDatasets;
+    private int mNumberDatasets;
+
+    @Override
+    public void onConnected() {
+        super.onConnected();
+
+        // TODO(b/114236837): use its own preferences?
+        MyPreferences pref = MyPreferences.getInstance(getApplicationContext());
+        mAuthenticateResponses = pref.isResponseAuth();
+        mAuthenticateDatasets = pref.isDatasetAuth();
+        mNumberDatasets = pref.getNumberDatasets(4);
+
+        Log.d(TAG, "onConnected(): numberDatasets=" + mNumberDatasets
+                + ", authResponses=" + mAuthenticateResponses
+                + ", authDatasets=" + mAuthenticateDatasets);
+    }
+
+    @Override
+    public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal,
+            FillCallback callback) {
+        Log.d(TAG, "onFillRequest()");
+
+        // Find autofillable fields
+        AssistStructure structure = getLatestAssistStructure(request);
+        ArrayMap<String, AutofillId> fields = getAutofillableFields(structure);
+        Log.d(TAG, "autofillable fields:" + fields);
+
+        if (fields.isEmpty()) {
+            toast("No autofill hints found");
+            callback.onSuccess(null);
+            return;
+        }
+
+        // Create response...
+        FillResponse response;
+        if (mAuthenticateResponses) {
+            int size = fields.size();
+            String[] hints = new String[size];
+            AutofillId[] ids = new AutofillId[size];
+            for (int i = 0; i < size; i++) {
+                hints[i] = fields.keyAt(i);
+                ids[i] = fields.valueAt(i);
+            }
+
+            IntentSender authentication = SimpleAuthActivity.newIntentSenderForResponse(this, hints,
+                    ids, mAuthenticateDatasets);
+            RemoteViews presentation = newDatasetPresentation(getPackageName(),
+                        "Tap to auth response");
+
+            response = new FillResponse.Builder()
+                    .setAuthentication(ids, authentication, presentation).build();
+        } else {
+            response = createResponse(this, fields, mNumberDatasets,mAuthenticateDatasets);
+        }
+
+        // ... and return it
+        callback.onSuccess(response);
+    }
+
+    @Override
+    public void onSaveRequest(SaveRequest request, SaveCallback callback) {
+        Log.d(TAG, "onSaveRequest()");
+        toast("Save not supported");
+        callback.onSuccess();
+    }
+
+    /**
+     * Parses the {@link AssistStructure} representing the activity being autofilled, and returns a
+     * map of autofillable fields (represented by their autofill ids) mapped by the hint associate
+     * with them.
+     *
+     * <p>An autofillable field is a {@link ViewNode} whose {@link #getHint(ViewNode)} metho
+     */
+    @NonNull
+    private ArrayMap<String, AutofillId> getAutofillableFields(@NonNull AssistStructure structure) {
+        ArrayMap<String, AutofillId> fields = new ArrayMap<>();
+        int nodes = structure.getWindowNodeCount();
+        for (int i = 0; i < nodes; i++) {
+            ViewNode node = structure.getWindowNodeAt(i).getRootViewNode();
+            addAutofillableFields(fields, node);
+        }
+        return fields;
+    }
+
+    /**
+     * Adds any autofillable view from the {@link ViewNode} and its descendants to the map.
+     */
+    private void addAutofillableFields(@NonNull Map<String, AutofillId> fields,
+            @NonNull ViewNode node) {
+        String hint = getHint(node);
+        if (hint != null) {
+            AutofillId id = node.getAutofillId();
+            if (!fields.containsKey(hint)) {
+                Log.v(TAG, "Setting hint '" + hint + "' on " + id);
+                fields.put(hint, id);
+            } else {
+                Log.v(TAG, "Ignoring hint '" + hint + "' on " + id
+                        + " because it was already set");
+            }
+        }
+        int childrenSize = node.getChildCount();
+        for (int i = 0; i < childrenSize; i++) {
+            addAutofillableFields(fields, node.getChildAt(i));
+        }
+    }
+
+    @Nullable
+    protected String getHint(@NonNull ViewNode node) {
+
+        // First try the explicit autofill hints...
+
+        String[] hints = node.getAutofillHints();
+        if (hints != null) {
+            // We're simple, we only care about the first hint
+            return hints[0].toLowerCase();
+        }
+
+        // Then try some rudimentary heuristics based on other node properties
+
+        String viewHint = node.getHint();
+        String hint = inferHint(node, viewHint);
+        if (hint != null) {
+            Log.d(TAG, "Found hint using view hint(" + viewHint + "): " + hint);
+            return hint;
+        } else if (!TextUtils.isEmpty(viewHint)) {
+            Log.v(TAG, "No hint using view hint: " + viewHint);
+        }
+
+        String resourceId = node.getIdEntry();
+        hint = inferHint(node, resourceId);
+        if (hint != null) {
+            Log.d(TAG, "Found hint using resourceId(" + resourceId + "): " + hint);
+            return hint;
+        } else if (!TextUtils.isEmpty(resourceId)) {
+            Log.v(TAG, "No hint using resourceId: " + resourceId);
+        }
+
+        CharSequence text = node.getText();
+        CharSequence className = node.getClassName();
+        if (text != null && className != null && className.toString().contains("EditText")) {
+            hint = inferHint(node, text.toString());
+            if (hint != null) {
+                // NODE: text should not be logged, as it could contain PII
+                Log.d(TAG, "Found hint using text(" + text + "): " + hint);
+                return hint;
+            }
+        } else if (!TextUtils.isEmpty(text)) {
+            // NODE: text should not be logged, as it could contain PII
+            Log.v(TAG, "No hint using text: " + text + " and class " + className);
+        }
+        return null;
+    }
+
+    /**
+     * Uses heuristics to infer an autofill hint from a {@code string}.
+     *
+     * @return standard autofill hint, or {@code null} when it could not be inferred.
+     */
+    @Nullable
+    protected String inferHint(ViewNode node, @Nullable String actualHint) {
+        if (actualHint == null) return null;
+
+        String hint = actualHint.toLowerCase();
+        if (hint.contains("label") || hint.contains("container")) {
+            Log.v(TAG, "Ignoring 'label/container' hint: " + hint);
+            return null;
+        }
+
+        if (hint.contains("password")) return View.AUTOFILL_HINT_PASSWORD;
+        if (hint.contains("username")
+                || (hint.contains("login") && hint.contains("id")))
+            return View.AUTOFILL_HINT_USERNAME;
+        if (hint.contains("email")) return View.AUTOFILL_HINT_EMAIL_ADDRESS;
+        if (hint.contains("name")) return View.AUTOFILL_HINT_NAME;
+        if (hint.contains("phone")) return View.AUTOFILL_HINT_PHONE;
+
+        // When everything else fails, return the full string - this is helpful to help app
+        // developers visualize when autofill is triggered when it shouldn't (for example, in a
+        // chat conversation window), so they can mark the root view of such activities with
+        // android:importantForAutofill=noExcludeDescendants
+        if (node.isEnabled() && node.getAutofillType() != View.AUTOFILL_TYPE_NONE) {
+            Log.v(TAG, "Falling back to " + actualHint);
+            return actualHint;
+        }
+        return null;
+    }
+
+    static FillResponse createResponse(@NonNull Context context,
+            @NonNull ArrayMap<String, AutofillId> fields, int numDatasets,
+            boolean authenticateDatasets) {
+        String packageName = context.getPackageName();
+        FillResponse.Builder response = new FillResponse.Builder();
+        // 1.Add the dynamic datasets
+        for (int i = 1; i <= numDatasets; i++) {
+            Dataset unlockedDataset = newUnlockedDataset(fields, packageName, i);
+            if (authenticateDatasets) {
+                Dataset.Builder lockedDataset = new Dataset.Builder();
+                for (Entry<String, AutofillId> field : fields.entrySet()) {
+                    String hint = field.getKey();
+                    AutofillId id = field.getValue();
+                    String value = i + "-" + hint;
+                    IntentSender authentication =
+                            SimpleAuthActivity.newIntentSenderForDataset(context, unlockedDataset);
+                    RemoteViews presentation = newDatasetPresentation(packageName,
+                            "Tap to auth " + value);
+                    lockedDataset.setValue(id, null, presentation)
+                            .setAuthentication(authentication);
+                }
+                response.addDataset(lockedDataset.build());
+            } else {
+                response.addDataset(unlockedDataset);
+            }
+        }
+
+        // 2.Add save info
+        Collection<AutofillId> ids = fields.values();
+        AutofillId[] requiredIds = new AutofillId[ids.size()];
+        ids.toArray(requiredIds);
+        response.setSaveInfo(
+                // We're simple, so we're generic
+                new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_GENERIC, requiredIds).build());
+
+        // 3.Profit!
+        return response.build();
+    }
+
+    static Dataset newUnlockedDataset(@NonNull Map<String, AutofillId> fields,
+            @NonNull String packageName, int i) {
+        Dataset.Builder dataset = new Dataset.Builder();
+        for (Entry<String, AutofillId> field : fields.entrySet()) {
+            String hint = field.getKey();
+            AutofillId id = field.getValue();
+            String value = i + "-" + hint;
+
+            // We're simple - our dataset values are hardcoded as "N-hint" (for example,
+            // "1-username", "2-username") and they're displayed as such, except if they're a
+            // password
+            String displayValue = hint.contains("password") ? "password for #" + i : value;
+            RemoteViews presentation = newDatasetPresentation(packageName, displayValue);
+            dataset.setValue(id, AutofillValue.forText(value), presentation);
+        }
+
+        return dataset.build();
+    }
+
+    /**
+     * Displays a toast with the given message.
+     */
+    private void toast(@NonNull CharSequence message) {
+        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
+    }
+}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/HeuristicsService.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/HeuristicsService.java
index 2cc6572..bddc149 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/HeuristicsService.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/HeuristicsService.java
@@ -15,303 +15,11 @@
  */
 package com.example.android.autofill.service.simple;
 
-import static com.example.android.autofill.service.simple.BasicService.getLatestAssistStructure;
-import static com.example.android.autofill.service.simple.BasicService.newDatasetPresentation;
-
-import android.app.assist.AssistStructure;
-import android.app.assist.AssistStructure.ViewNode;
-import android.content.Context;
-import android.content.IntentSender;
-import android.os.CancellationSignal;
-import android.service.autofill.AutofillService;
-import android.service.autofill.Dataset;
-import android.service.autofill.FillCallback;
-import android.service.autofill.FillRequest;
-import android.service.autofill.FillResponse;
-import android.service.autofill.SaveCallback;
-import android.service.autofill.SaveInfo;
-import android.service.autofill.SaveRequest;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.view.View;
-import android.view.autofill.AutofillId;
-import android.view.autofill.AutofillValue;
-import android.widget.RemoteViews;
-import android.widget.Toast;
-
-import com.example.android.autofill.service.MyAutofillService;
-import com.example.android.autofill.service.settings.MyPreferences;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Map.Entry;
-
 /**
- * A basic service that uses some rudimentary heuristics to identify fields that are not explicitly
- * marked with autofill hints.
- *
- * <p>The goal of this class is to provide a simple autofill service implementation that is easy
- * to understand and extend, but it should <strong>not</strong> be used as-is on real apps because
- * it lacks fundamental security requirements such as data partitioning and package verification
- * &mdashthese requirements are fullfilled by {@link MyAutofillService}.
+ * @deprecated this class was renamed to {@link DebugService}, but it's still in the project because
+ * it's linked from the Autofill guide docs site.
  */
-public class HeuristicsService extends AutofillService {
+@Deprecated
+public final class HeuristicsService {
 
-    private static final String TAG = "HeuristicsService";
-
-    private boolean mAuthenticateResponses;
-    private boolean mAuthenticateDatasets;
-    private int mNumberDatasets = 4;
-
-    @Override
-    public void onConnected() {
-        super.onConnected();
-
-        // TODO(b/114236837): use its own preferences?
-        MyPreferences pref = MyPreferences.getInstance(getApplicationContext());
-        mAuthenticateResponses = pref.isResponseAuth();
-        mAuthenticateDatasets = pref.isDatasetAuth();
-        // TODO(b/114236837): get number dataset from preferences
-
-        Log.d(TAG, "onConnected(): numberDatasets=" + mNumberDatasets
-                + ", authResponses=" + mAuthenticateResponses
-                + ", authDatasets=" + mAuthenticateDatasets);
-    }
-
-    @Override
-    public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal,
-            FillCallback callback) {
-        Log.d(TAG, "onFillRequest()");
-
-        // Find autofillable fields
-        AssistStructure structure = getLatestAssistStructure(request);
-        ArrayMap<String, AutofillId> fields = getAutofillableFields(structure);
-        Log.d(TAG, "autofillable fields:" + fields);
-
-        if (fields.isEmpty()) {
-            toast("No autofill hints found");
-            callback.onSuccess(null);
-            return;
-        }
-
-        // Create response...
-        FillResponse response;
-        if (mAuthenticateResponses) {
-            int size = fields.size();
-            String[] hints = new String[size];
-            AutofillId[] ids = new AutofillId[size];
-            for (int i = 0; i < size; i++) {
-                hints[i] = fields.keyAt(i);
-                ids[i] = fields.valueAt(i);
-            }
-
-            IntentSender authentication = SimpleAuthActivity.newIntentSenderForResponse(this, hints,
-                    ids, mAuthenticateDatasets);
-            RemoteViews presentation = newDatasetPresentation(getPackageName(),
-                        "Tap to auth response");
-
-            response = new FillResponse.Builder()
-                    .setAuthentication(ids, authentication, presentation).build();
-        } else {
-            response = createResponse(this, fields, mNumberDatasets,mAuthenticateDatasets);
-        }
-
-        // ... and return it
-        callback.onSuccess(response);
-    }
-
-    @Override
-    public void onSaveRequest(SaveRequest request, SaveCallback callback) {
-        Log.d(TAG, "onSaveRequest()");
-        toast("Save not supported");
-        callback.onSuccess();
-    }
-
-    /**
-     * Parses the {@link AssistStructure} representing the activity being autofilled, and returns a
-     * map of autofillable fields (represented by their autofill ids) mapped by the hint associate
-     * with them.
-     *
-     * <p>An autofillable field is a {@link ViewNode} whose {@link #getHint(ViewNode)} metho
-     */
-    @NonNull
-    private ArrayMap<String, AutofillId> getAutofillableFields(@NonNull AssistStructure structure) {
-        ArrayMap<String, AutofillId> fields = new ArrayMap<>();
-        int nodes = structure.getWindowNodeCount();
-        for (int i = 0; i < nodes; i++) {
-            ViewNode node = structure.getWindowNodeAt(i).getRootViewNode();
-            addAutofillableFields(fields, node);
-        }
-        return fields;
-    }
-
-    /**
-     * Adds any autofillable view from the {@link ViewNode} and its descendants to the map.
-     */
-    private void addAutofillableFields(@NonNull Map<String, AutofillId> fields,
-            @NonNull ViewNode node) {
-        String hint = getHint(node);
-        if (hint != null) {
-            AutofillId id = node.getAutofillId();
-            if (!fields.containsKey(hint)) {
-                Log.v(TAG, "Setting hint '" + hint + "' on " + id);
-                fields.put(hint, id);
-            } else {
-                Log.v(TAG, "Ignoring hint '" + hint + "' on " + id
-                        + " because it was already set");
-            }
-        }
-        int childrenSize = node.getChildCount();
-        for (int i = 0; i < childrenSize; i++) {
-            addAutofillableFields(fields, node.getChildAt(i));
-        }
-    }
-
-    @Nullable
-    protected String getHint(@NonNull ViewNode node) {
-
-        // First try the explicit autofill hints...
-
-        String[] hints = node.getAutofillHints();
-        if (hints != null) {
-            // We're simple, we only care about the first hint
-            return hints[0].toLowerCase();
-        }
-
-        // Then try some rudimentary heuristics based on other node properties
-
-        String viewHint = node.getHint();
-        String hint = inferHint(node, viewHint);
-        if (hint != null) {
-            Log.d(TAG, "Found hint using view hint(" + viewHint + "): " + hint);
-            return hint;
-        } else if (!TextUtils.isEmpty(viewHint)) {
-            Log.v(TAG, "No hint using view hint: " + viewHint);
-        }
-
-        String resourceId = node.getIdEntry();
-        hint = inferHint(node, resourceId);
-        if (hint != null) {
-            Log.d(TAG, "Found hint using resourceId(" + resourceId + "): " + hint);
-            return hint;
-        } else if (!TextUtils.isEmpty(resourceId)) {
-            Log.v(TAG, "No hint using resourceId: " + resourceId);
-        }
-
-        CharSequence text = node.getText();
-        CharSequence className = node.getClassName();
-        if (text != null && className != null && className.toString().contains("EditText")) {
-            hint = inferHint(node, text.toString());
-            if (hint != null) {
-                // NODE: text should not be logged, as it could contain PII
-                Log.d(TAG, "Found hint using text(" + text + "): " + hint);
-                return hint;
-            }
-        } else if (!TextUtils.isEmpty(text)) {
-            // NODE: text should not be logged, as it could contain PII
-            Log.v(TAG, "No hint using text: " + text + " and class " + className);
-        }
-        return null;
-    }
-
-    /**
-     * Uses heuristics to infer an autofill hint from a {@code string}.
-     *
-     * @return standard autofill hint, or {@code null} when it could not be inferred.
-     */
-    @Nullable
-    protected String inferHint(ViewNode node, @Nullable String string) {
-        if (string == null) return null;
-
-        string = string.toLowerCase();
-        if (string.contains("label")) {
-            Log.v(TAG, "Ignoring 'label' hint: " + string);
-            return null;
-        }
-        if (string.contains("password")) return View.AUTOFILL_HINT_PASSWORD;
-        if (string.contains("username")
-                || (string.contains("login") && string.contains("id")))
-            return View.AUTOFILL_HINT_USERNAME;
-        if (string.contains("email")) return View.AUTOFILL_HINT_EMAIL_ADDRESS;
-        if (string.contains("name")) return View.AUTOFILL_HINT_NAME;
-        if (string.contains("phone")) return View.AUTOFILL_HINT_PHONE;
-
-        // When everything else fails, return the full string - this is helpful to help app
-        // developers visualize when autofill is triggered when it shouldn't (for example, in a
-        // chat conversation window), so they can mark the root view of such activities with
-        // android:importantForAutofill=noExcludeDescendants
-        if (node.isEnabled() && node.getAutofillType() != View.AUTOFILL_TYPE_NONE) {
-            Log.v(TAG, "Falling back to " + string);
-            return string;
-        }
-        return null;
-    }
-
-    static FillResponse createResponse(@NonNull Context context,
-            @NonNull ArrayMap<String, AutofillId> fields, int numDatasets,
-            boolean authenticateDatasets) {
-        String packageName = context.getPackageName();
-        FillResponse.Builder response = new FillResponse.Builder();
-        // 1.Add the dynamic datasets
-        for (int i = 1; i <= numDatasets; i++) {
-            Dataset unlockedDataset = newUnlockedDataset(fields, packageName, i);
-            if (authenticateDatasets) {
-                Dataset.Builder lockedDataset = new Dataset.Builder();
-                for (Entry<String, AutofillId> field : fields.entrySet()) {
-                    String hint = field.getKey();
-                    AutofillId id = field.getValue();
-                    String value = i + "-" + hint;
-                    IntentSender authentication =
-                            SimpleAuthActivity.newIntentSenderForDataset(context, unlockedDataset);
-                    RemoteViews presentation = newDatasetPresentation(packageName,
-                            "Tap to auth " + value);
-                    lockedDataset.setValue(id, null, presentation)
-                            .setAuthentication(authentication);
-                }
-                response.addDataset(lockedDataset.build());
-            } else {
-                response.addDataset(unlockedDataset);
-            }
-        }
-
-        // 2.Add save info
-        Collection<AutofillId> ids = fields.values();
-        AutofillId[] requiredIds = new AutofillId[ids.size()];
-        ids.toArray(requiredIds);
-        response.setSaveInfo(
-                // We're simple, so we're generic
-                new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_GENERIC, requiredIds).build());
-
-        // 3.Profit!
-        return response.build();
-    }
-
-    static Dataset newUnlockedDataset(@NonNull Map<String, AutofillId> fields,
-            @NonNull String packageName, int i) {
-        Dataset.Builder dataset = new Dataset.Builder();
-        for (Entry<String, AutofillId> field : fields.entrySet()) {
-            String hint = field.getKey();
-            AutofillId id = field.getValue();
-            String value = i + "-" + hint;
-
-            // We're simple - our dataset values are hardcoded as "N-hint" (for example,
-            // "1-username", "2-username") and they're displayed as such, except if they're a
-            // password
-            String displayValue = hint.contains("password") ? "password for #" + i : value;
-            RemoteViews presentation = newDatasetPresentation(packageName, displayValue);
-            dataset.setValue(id, AutofillValue.forText(value), presentation);
-        }
-
-        return dataset.build();
-    }
-
-    /**
-     * Displays a toast with the given message.
-     */
-    private void toast(@NonNull CharSequence message) {
-        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
-    }
 }
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/MultiStepsService.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/MultiStepsService.java
new file mode 100644
index 0000000..a4bc338
--- /dev/null
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/MultiStepsService.java
@@ -0,0 +1,180 @@
+/*
+ * 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.simple;
+
+import static com.example.android.autofill.service.simple.BasicService.getLatestAssistStructure;
+import static com.example.android.autofill.service.simple.BasicService.newDatasetPresentation;
+
+import android.app.assist.AssistStructure;
+import android.app.assist.AssistStructure.ViewNode;
+import android.content.Context;
+import android.content.IntentSender;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.service.autofill.AutofillService;
+import android.service.autofill.Dataset;
+import android.service.autofill.FillCallback;
+import android.service.autofill.FillRequest;
+import android.service.autofill.FillResponse;
+import android.service.autofill.SaveCallback;
+import android.service.autofill.SaveInfo;
+import android.service.autofill.SaveRequest;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.view.View;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+import android.widget.RemoteViews;
+import android.widget.Toast;
+
+import com.example.android.autofill.service.MyAutofillService;
+import com.example.android.autofill.service.settings.MyPreferences;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * A basic service used to demonstrate multi-steps workflows (such as
+ * {@code MultipleStepsSignInActivity} and {@code MultipleStepsCreditCardActivity}) by saving the
+ * save type from previous requests in the client state bundle that's passed along to next requests.
+ *
+ * <p>This class should <strong>not</strong> be used as a reference for real autofill service
+ * implementations because it lacks fundamental security requirements such as data partitioning and
+ * package verification &mdashthese requirements are fullfilled by {@link MyAutofillService}.
+ */
+public class MultiStepsService extends AutofillService {
+
+    private static final String TAG = "MultiStepsService";
+    private static final String SAVE_TYPE_KEY = "saveType";
+
+    @Override
+    public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal,
+            FillCallback callback) {
+        int saveType = SaveInfo.SAVE_DATA_TYPE_GENERIC;
+        Bundle clientState = request.getClientState();
+        if (clientState != null) {
+            saveType = clientState.getInt(SAVE_TYPE_KEY, saveType);
+        }
+        Log.d(TAG, "onFillRequest(): saveType=" + saveType);
+
+        // Find autofillable fields
+        AssistStructure structure = getLatestAssistStructure(request);
+        ArrayMap<String, AutofillId> fields = getAutofillableFields(structure);
+        Log.d(TAG, "autofillable fields:" + fields);
+
+        if (fields.isEmpty()) {
+            toast("No autofill hints found");
+            callback.onSuccess(null);
+            return;
+        }
+
+        Collection<AutofillId> ids = fields.values();
+        AutofillId[] requiredIds = new AutofillId[ids.size()];
+        ids.toArray(requiredIds);
+        for (int i = 0; i < fields.size(); i++) {
+            String hint = fields.keyAt(i);
+            switch (hint) {
+                case View.AUTOFILL_HINT_USERNAME:
+                    saveType |= SaveInfo.SAVE_DATA_TYPE_USERNAME;
+                    break;
+                case View.AUTOFILL_HINT_EMAIL_ADDRESS:
+                    saveType |= SaveInfo.SAVE_DATA_TYPE_EMAIL_ADDRESS;
+                    break;
+                case View.AUTOFILL_HINT_PASSWORD:
+                    saveType |= SaveInfo.SAVE_DATA_TYPE_PASSWORD;
+                    break;
+                case View.AUTOFILL_HINT_CREDIT_CARD_NUMBER:
+                case View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE:
+                case View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY:
+                case View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH:
+                case View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR:
+                case View.AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE:
+                    saveType |= SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD;
+                    break;
+                case View.AUTOFILL_HINT_POSTAL_ADDRESS:
+                case View.AUTOFILL_HINT_POSTAL_CODE:
+                    saveType |= SaveInfo.SAVE_DATA_TYPE_ADDRESS;
+                    break;
+                default:
+                    Log.d(TAG, "Ignoring hint '" + hint + "'");
+            }
+        }
+
+        Log.d(TAG, "new saveType=" + saveType);
+        if (clientState == null) {
+            // Initial request
+            clientState = new Bundle();
+        }
+        // NOTE: to simplify, we're saving just the saveType, but a real service implementation
+        // would have to save the previous values as well, so they can be used later (for example,
+        // it would have to save the username in the first request so it's used to save the
+        // username + password combo in the second request.
+        clientState.putInt(SAVE_TYPE_KEY, saveType);
+
+        // Create response...
+        callback.onSuccess(new FillResponse.Builder()
+                .setClientState(clientState)
+                .setSaveInfo(new SaveInfo.Builder(saveType, requiredIds).build())
+                .build());
+    }
+
+    @Override
+    public void onSaveRequest(SaveRequest request, SaveCallback callback) {
+        Log.d(TAG, "onSaveRequest()");
+        toast("Save not supported");
+        callback.onSuccess();
+    }
+
+    @NonNull
+    private ArrayMap<String, AutofillId> getAutofillableFields(@NonNull AssistStructure structure) {
+        ArrayMap<String, AutofillId> fields = new ArrayMap<>();
+        int nodes = structure.getWindowNodeCount();
+        for (int i = 0; i < nodes; i++) {
+            ViewNode node = structure.getWindowNodeAt(i).getRootViewNode();
+            addAutofillableFields(fields, node);
+        }
+        return fields;
+    }
+
+    private void addAutofillableFields(@NonNull Map<String, AutofillId> fields,
+            @NonNull ViewNode node) {
+        String[] hints = node.getAutofillHints();
+        if (hints != null) {
+            // We're simple, we only care about the first hint
+            String hint = hints[0];
+            AutofillId id = node.getAutofillId();
+            if (!fields.containsKey(hint)) {
+                Log.v(TAG, "Setting hint '" + hint + "' on " + id);
+                fields.put(hint, id);
+            } else {
+                Log.v(TAG, "Ignoring hint '" + hint + "' on " + id
+                        + " because it was already set");
+            }
+        }
+        int childrenSize = node.getChildCount();
+        for (int i = 0; i < childrenSize; i++) {
+            addAutofillableFields(fields, node.getChildAt(i));
+        }
+    }
+
+    private void toast(@NonNull CharSequence message) {
+        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
+    }
+}
diff --git a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/SimpleAuthActivity.java b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/SimpleAuthActivity.java
index 4ff97a7..048b140 100644
--- a/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/SimpleAuthActivity.java
+++ b/input/autofill/AutofillFramework/afservice/src/main/java/com/example/android/autofill/service/simple/SimpleAuthActivity.java
@@ -76,7 +76,7 @@
                 fields.put(hints[i], (AutofillId) ids[i]);
             }
             FillResponse response =
-                    HeuristicsService.createResponse(this, fields, 1, authenticateDatasets);
+                    DebugService.createResponse(this, fields, 1, authenticateDatasets);
             replyIntent.putExtra(EXTRA_AUTHENTICATION_RESULT, response);
 
         }
diff --git a/input/autofill/AutofillFramework/afservice/src/main/res/xml/heuristics_service.xml b/input/autofill/AutofillFramework/afservice/src/main/res/xml/debug_service.xml
similarity index 100%
rename from input/autofill/AutofillFramework/afservice/src/main/res/xml/heuristics_service.xml
rename to input/autofill/AutofillFramework/afservice/src/main/res/xml/debug_service.xml