aboutsummaryrefslogtreecommitdiff
path: root/input
diff options
context:
space:
mode:
authorDouglas Sigelbaum <sigelbaum@google.com>2017-05-16 08:49:27 -0700
committerDouglas Sigelbaum <sigelbaum@google.com>2017-05-16 18:07:18 -0700
commitc641d78425eebd911c539ed56a5b48a7e5b3ffff (patch)
tree3c3941cd3e11bd05103fff9652b4c9bb04189779 /input
parent9a56c2387d179d15f8567f57eed3c45c0271204e (diff)
downloadandroid-c641d78425eebd911c539ed56a5b48a7e5b3ffff.tar.gz
Neatening up autofill settings.
Also added auth and option to clear data to settings, and fixed failed master-login issue. Test: manual Bug: 38182790, 37492778 Change-Id: I9f303f9573e4cba57626cc23b5c1dab102983b95
Diffstat (limited to 'input')
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/AndroidManifest.xml5
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/CreditCardActivity.java20
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/LoginActivity.java12
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/MainActivity.java3
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/VirtualLoginActivity.java3
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/AuthActivity.java14
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/datasource/AutofillRepository.java5
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/datasource/LocalAutofillRepository.java8
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/model/ClientFormData.java5
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/settings/MyPreferences.java53
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/settings/SettingsActivity.java172
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/res/drawable/ic_delete_forever_black_24dp.xml5
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/res/drawable/ic_person_black_24dp.xml5
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/res/layout/settings_activity.xml178
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/res/layout/settings_authentication_dialog.xml11
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/res/values/dimens.xml6
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/res/values/strings.xml17
-rw-r--r--input/autofill/AutofillFramework/Application/src/main/res/values/styles.xml27
18 files changed, 410 insertions, 139 deletions
diff --git a/input/autofill/AutofillFramework/Application/src/main/AndroidManifest.xml b/input/autofill/AutofillFramework/Application/src/main/AndroidManifest.xml
index e7d748e0..d17dce13 100644
--- a/input/autofill/AutofillFramework/Application/src/main/AndroidManifest.xml
+++ b/input/autofill/AutofillFramework/Application/src/main/AndroidManifest.xml
@@ -25,7 +25,7 @@
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
- android:theme="@style/AppTheme">
+ android:theme="@style/Theme.AppCompat.Light">
<activity
android:name=".app.MainActivity"
android:label="AF Main"
@@ -90,7 +90,8 @@
-->
<service
android:name=".service.MyAutofillService"
- android:permission="android.permission.BIND_AUTOFILL">
+ android:permission="android.permission.BIND_AUTOFILL"
+ android:label="Sample Autofill Service">
<meta-data
android:name="android.autofill"
android:resource="@xml/autofill_service" />
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/CreditCardActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/CreditCardActivity.java
index 6f5a2f3a..a82de4c8 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/CreditCardActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/CreditCardActivity.java
@@ -15,24 +15,18 @@
*/
package com.example.android.autofillframework.app;
-import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.support.annotation.IdRes;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.NonNull;
+import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
-import android.widget.EditText;
import android.widget.Spinner;
import com.example.android.autofillframework.R;
-import java.util.List;
-
-public class CreditCardActivity extends Activity {
+public class CreditCardActivity extends AppCompatActivity {
private Spinner mCcExpirationDaySpinner;
private Spinner mCcExpirationMonthSpinner;
@@ -51,11 +45,11 @@ public class CreditCardActivity extends Activity {
setContentView(R.layout.credit_card_activity);
- mSubmitButton = findViewById(R.id.submit);
- mClearButton = findViewById(R.id.clear);
- mCcExpirationDaySpinner = findViewById(R.id.expirationDay);
- mCcExpirationMonthSpinner = findViewById(R.id.expirationMonth);
- mCcExpirationYearSpinner = findViewById(R.id.expirationYear);
+ mSubmitButton = (Button) findViewById(R.id.submit);
+ mClearButton = (Button) findViewById(R.id.clear);
+ mCcExpirationDaySpinner = (Spinner) findViewById(R.id.expirationDay);
+ mCcExpirationMonthSpinner = (Spinner) findViewById(R.id.expirationMonth);
+ mCcExpirationYearSpinner = (Spinner) findViewById(R.id.expirationYear);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> dayAdapter = ArrayAdapter.createFromResource
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/LoginActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/LoginActivity.java
index 051572a4..3ec87da0 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/LoginActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/LoginActivity.java
@@ -15,10 +15,10 @@
*/
package com.example.android.autofillframework.app;
-import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
@@ -26,7 +26,7 @@ import android.widget.Toast;
import com.example.android.autofillframework.R;
-public class LoginActivity extends Activity {
+public class LoginActivity extends AppCompatActivity {
private EditText mUsernameEditText;
private EditText mPasswordEditText;
@@ -44,10 +44,10 @@ public class LoginActivity extends Activity {
setContentView(R.layout.login_activity);
- mLoginButton = findViewById(R.id.login);
- mClearButton = findViewById(R.id.clear);
- mUsernameEditText = findViewById(R.id.usernameField);
- mPasswordEditText = findViewById(R.id.passwordField);
+ mLoginButton = (Button) findViewById(R.id.login);
+ mClearButton = (Button) findViewById(R.id.clear);
+ mUsernameEditText = (EditText) findViewById(R.id.usernameField);
+ mPasswordEditText = (EditText) findViewById(R.id.passwordField);
mLoginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/MainActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/MainActivity.java
index 88c07eac..4b27010b 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/MainActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/MainActivity.java
@@ -19,6 +19,7 @@ import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
import android.view.View;
import com.example.android.autofillframework.R;
@@ -26,7 +27,7 @@ import com.example.android.autofillframework.R;
/**
* This is used to launch sample activities that showcase autofill.
*/
-public class MainActivity extends Activity {
+public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/VirtualLoginActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/VirtualLoginActivity.java
index 744da2d3..5a4a4f4e 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/VirtualLoginActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/app/VirtualLoginActivity.java
@@ -19,13 +19,14 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
import com.example.android.autofillframework.R;
-public class VirtualLoginActivity extends Activity {
+public class VirtualLoginActivity extends AppCompatActivity {
private CustomVirtualView mCustomVirtualView;
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/AuthActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/AuthActivity.java
index 5c00a304..9fc87969 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/AuthActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/AuthActivity.java
@@ -37,6 +37,7 @@ import com.example.android.autofillframework.R;
import com.example.android.autofillframework.service.datasource.LocalAutofillRepository;
import com.example.android.autofillframework.service.model.AutofillFieldsCollection;
import com.example.android.autofillframework.service.model.ClientFormData;
+import com.example.android.autofillframework.service.settings.MyPreferences;
import java.util.HashMap;
@@ -63,8 +64,7 @@ public class AuthActivity extends Activity {
static IntentSender getAuthIntentSenderForResponse(Context context) {
final Intent intent = new Intent(context, AuthActivity.class);
- return PendingIntent.getActivity(context, 0, intent,
- PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT)
+ return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)
.getIntentSender();
}
@@ -73,8 +73,7 @@ public class AuthActivity extends Activity {
intent.putExtra(EXTRA_DATASET_NAME, datasetName);
intent.putExtra(EXTRA_FOR_RESPONSE, false);
return PendingIntent.getActivity(context, ++sDatasetPendingIntentId, intent,
- PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT)
- .getIntentSender();
+ PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender();
}
@Override
@@ -103,10 +102,11 @@ public class AuthActivity extends Activity {
}
private void login() {
- // TODO set master username/password in Settings.
Editable password = mMasterPassword.getText();
- Log.d(TAG, "login: " + password);
- if (password.length() == 0) {
+ Log.d(TAG, "PW entered: " + password);
+ Log.d(TAG, "Correct: " + MyPreferences.getInstance(AuthActivity.this).getMasterPassword());
+ if (password.toString()
+ .equals(MyPreferences.getInstance(AuthActivity.this).getMasterPassword())) {
onSuccess();
} else {
Toast.makeText(this, "Password incorrect", Toast.LENGTH_SHORT).show();
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/datasource/AutofillRepository.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/datasource/AutofillRepository.java
index 5061210a..c79f61dc 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/datasource/AutofillRepository.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/datasource/AutofillRepository.java
@@ -33,4 +33,9 @@ public interface AutofillRepository {
* Saves LoginCredential under this datasetName.
*/
void saveClientFormData(ClientFormData clientFormData);
+
+ /**
+ * Clear all data.
+ */
+ void clear();
}
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/datasource/LocalAutofillRepository.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/datasource/LocalAutofillRepository.java
index d7d7a3e0..8336fe1e 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/datasource/LocalAutofillRepository.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/datasource/LocalAutofillRepository.java
@@ -44,7 +44,8 @@ public class LocalAutofillRepository implements AutofillRepository {
// TODO prepend with autofill data set in Settings.
private LocalAutofillRepository(Context context) {
- mPrefs = context.getSharedPreferences(SHARED_PREF_KEY, Context.MODE_PRIVATE);
+ mPrefs = context.getApplicationContext()
+ .getSharedPreferences(SHARED_PREF_KEY, Context.MODE_PRIVATE);
}
public static LocalAutofillRepository getInstance(Context context) {
@@ -95,6 +96,11 @@ public class LocalAutofillRepository implements AutofillRepository {
incrementDatasetNumber();
}
+ @Override
+ public void clear() {
+ mPrefs.edit().remove(CLIENT_FORM_DATA_KEY).apply();
+ }
+
private Set<String> getAllAutofillDataStringSet() {
return mPrefs.getStringSet(CLIENT_FORM_DATA_KEY, new ArraySet<String>());
}
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/model/ClientFormData.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/model/ClientFormData.java
index 5a7e76aa..7a3e7ac1 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/model/ClientFormData.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/model/ClientFormData.java
@@ -113,7 +113,8 @@ public final class ClientFormData {
for (int autofillFieldIndex = 0; autofillFieldIndex < autofillFields.size(); autofillFieldIndex++) {
AutofillField autofillField = autofillFields.get(autofillFieldIndex);
AutofillId autofillId = autofillField.getId();
- switch (autofillField.getAutofillType()) {
+ int autofillType = autofillField.getAutofillType();
+ switch (autofillType) {
case View.AUTOFILL_TYPE_LIST:
int listValue = autofillField.getAutofillOptionIndex(hintMap.get(hint).getTextValue());
datasetBuilder.setValue(autofillId, AutofillValue.forList(listValue));
@@ -132,7 +133,7 @@ public final class ClientFormData {
break;
case View.AUTOFILL_TYPE_NONE:
default:
- Log.w(TAG, "Invalid autofill saveType");
+ Log.w(TAG, "Invalid autofill type - " + autofillType);
break;
}
}
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/settings/MyPreferences.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/settings/MyPreferences.java
index 1425e7f6..3926530e 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/settings/MyPreferences.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/settings/MyPreferences.java
@@ -19,14 +19,15 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.service.autofill.Dataset;
import android.service.autofill.FillResponse;
-import android.util.Log;
+import android.support.annotation.NonNull;
public class MyPreferences {
private static final String TAG = "MyPreferences";
- private static final String PREF_NUMBER_DATASET = "number_datasets";
- private static final String PREF_RESPONSE_AUTH = "response_auth";
- private static final String PREF_DATASET_AUTH = "dataset_auth";
+ private static final String RESPONSE_AUTH_KEY = "response_auth";
+ private static final String DATASET_AUTH_KEY = "dataset_auth";
+ private static final String MASTER_PASSWORD_KEY = "master_password";
+
private static MyPreferences sInstance;
private final SharedPreferences mPrefs;
@@ -43,34 +44,48 @@ public class MyPreferences {
}
/**
- * Gets the number of {@link Dataset}s that should be added to a {@link FillResponse}.
+ * Gets whether {@link FillResponse}s should require authentication.
*/
- public int getNumberDatasets() {
- return mPrefs.getInt(PREF_NUMBER_DATASET, 2);
+ public boolean isResponseAuth() {
+ return mPrefs.getBoolean(RESPONSE_AUTH_KEY, false);
}
/**
- * Gets whether {@link FillResponse}s should require authentication.
+ * Enables/disables authentication for the entire autofill {@link FillResponse}.
*/
- public boolean isResponseAuth() {
- return mPrefs.getBoolean(PREF_RESPONSE_AUTH, false);
+ public void setResponseAuth(boolean responseAuth) {
+ mPrefs.edit().putBoolean(RESPONSE_AUTH_KEY, responseAuth).apply();
}
-
/**
* Gets whether {@link Dataset}s should require authentication.
*/
public boolean isDatasetAuth() {
- return mPrefs.getBoolean(PREF_DATASET_AUTH, false);
+ return mPrefs.getBoolean(DATASET_AUTH_KEY, false);
}
- public void bulkEdit(int numberDatasets, boolean responseAuth, boolean datasetAuth) {
- Log.v(TAG, "bulk edit:" + numberDatasets + ":" + responseAuth + ":" + datasetAuth);
- mPrefs.edit()
- .putInt(PREF_NUMBER_DATASET, numberDatasets)
- .putBoolean(PREF_RESPONSE_AUTH, responseAuth)
- .putBoolean(PREF_DATASET_AUTH, datasetAuth)
- .apply();
+ /**
+ * Enables/disables authentication for individual autofill {@link Dataset}s.
+ */
+ public void setDatasetAuth(boolean datasetAuth) {
+ mPrefs.edit().putBoolean(DATASET_AUTH_KEY, datasetAuth).apply();
+ }
+
+ /**
+ * Gets autofill master username.
+ */
+ public String getMasterPassword() {
+ return mPrefs.getString(MASTER_PASSWORD_KEY, null);
+ }
+
+ /**
+ * Sets autofill master password.
+ */
+ public void setMasterPassword(@NonNull String masterPassword) {
+ mPrefs.edit().putString(MASTER_PASSWORD_KEY, masterPassword).apply();
+ }
+ public void clearCredentials() {
+ mPrefs.edit().remove(MASTER_PASSWORD_KEY).apply();
}
}
diff --git a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/settings/SettingsActivity.java b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/settings/SettingsActivity.java
index e771d185..21bb7be0 100644
--- a/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/settings/SettingsActivity.java
+++ b/input/autofill/AutofillFramework/Application/src/main/java/com/example/android/autofillframework/service/settings/SettingsActivity.java
@@ -15,58 +15,162 @@
*/
package com.example.android.autofillframework.service.settings;
-import android.app.Activity;
+import android.content.DialogInterface;
import android.os.Bundle;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+import android.view.LayoutInflater;
import android.view.View;
-import android.widget.Button;
-import android.widget.CheckBox;
+import android.view.ViewGroup;
+import android.widget.CompoundButton;
import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.Switch;
+import android.widget.TextView;
import com.example.android.autofillframework.R;
+import com.example.android.autofillframework.service.datasource.LocalAutofillRepository;
-import java.util.Locale;
-
-public class SettingsActivity extends Activity {
-
- private EditText mNumberDatasets;
- private CheckBox mResponseAuth;
- private CheckBox mDatasetAuth;
- private Button mSave;
- private Button mCancel;
+public class SettingsActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_activity);
- mNumberDatasets = findViewById(R.id.number_datasets);
- mResponseAuth = findViewById(R.id.response_auth);
- mDatasetAuth = findViewById(R.id.dataset_auth);
- mSave = findViewById(R.id.save);
- mCancel = findViewById(R.id.cancel);
+ final MyPreferences preferences = MyPreferences.getInstance(this);
+ setupSettingsSwitch(R.id.settings_auth_responses_container,
+ R.id.settings_auth_responses_label,
+ R.id.settings_auth_responses_switch,
+ preferences.isResponseAuth(),
+ new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
+ preferences.setResponseAuth(b);
+ }
+ });
+ setupSettingsSwitch(R.id.settings_auth_datasets_container,
+ R.id.settings_auth_datasets_label,
+ R.id.settings_auth_datasets_switch,
+ preferences.isDatasetAuth(),
+ new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
+ preferences.setDatasetAuth(b);
+ }
+ });
+ setupSettingsButton(R.id.settings_clear_data_container,
+ R.id.settings_clear_data_label,
+ R.id.settings_clear_data_icon,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ buildClearDataDialog().show();
+ }
+ });
- final MyPreferences p = MyPreferences.getInstance(this);
+ setupSettingsButton(R.id.settings_auth_credentials_container,
+ R.id.settings_auth_credentials_label,
+ R.id.settings_auth_credentials_icon,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (MyPreferences.getInstance(SettingsActivity.this).getMasterPassword() != null) {
+ buildCurrentCredentialsDialog().show();
+ } else {
+ buildNewCredentialsDialog().show();
+ }
+ }
+ });
+ }
- mNumberDatasets.setText(String.format(Locale.getDefault(), "%d", p.getNumberDatasets()));
- mDatasetAuth.setChecked(p.isDatasetAuth());
- mResponseAuth.setChecked(p.isResponseAuth());
+ private AlertDialog buildClearDataDialog() {
+ return new AlertDialog.Builder(SettingsActivity.this)
+ .setMessage(R.string.settings_clear_data_confirmation)
+ .setTitle(R.string.settings_clear_data_confirmation_title)
+ .setNegativeButton(R.string.cancel, null)
+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ LocalAutofillRepository.getInstance
+ (SettingsActivity.this).clear();
+ MyPreferences.getInstance(SettingsActivity.this)
+ .clearCredentials();
+ dialog.dismiss();
+ }
+ })
+ .create();
+ }
- mSave.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- MyPreferences.getInstance(SettingsActivity.this).bulkEdit(
- Integer.parseInt(mNumberDatasets.getText().toString()),
- mResponseAuth.isChecked(),
- mDatasetAuth.isChecked());
- finish();
- }
- });
+ private AlertDialog.Builder prepareCredentialsDialog() {
+ return new AlertDialog.Builder(SettingsActivity.this)
+ .setTitle(R.string.settings_auth_change_credentials_title)
+ .setNegativeButton(R.string.cancel, null);
+ }
+
+ private AlertDialog buildCurrentCredentialsDialog() {
+ final EditText currentPasswordField = LayoutInflater
+ .from(SettingsActivity.this)
+ .inflate(R.layout.settings_authentication_dialog, null)
+ .findViewById(R.id.master_password_field);
+ return prepareCredentialsDialog()
+ .setMessage(R.string.settings_auth_enter_current_password)
+ .setView(currentPasswordField)
+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String password = currentPasswordField.getText().toString();
+ if (MyPreferences.getInstance(SettingsActivity.this).getMasterPassword()
+ .equals(password)) {
+ buildNewCredentialsDialog().show();
+ dialog.dismiss();
+ }
+ }
+ })
+ .create();
+ }
- mCancel.setOnClickListener(new View.OnClickListener() {
+ private AlertDialog buildNewCredentialsDialog() {
+ final EditText newPasswordField = LayoutInflater
+ .from(SettingsActivity.this)
+ .inflate(R.layout.settings_authentication_dialog, null)
+ .findViewById(R.id.master_password_field);
+ return prepareCredentialsDialog()
+ .setMessage(R.string.settings_auth_enter_new_password)
+ .setView(newPasswordField)
+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String password = newPasswordField.getText().toString();
+ MyPreferences.getInstance(SettingsActivity.this).setMasterPassword(password);
+ dialog.dismiss();
+ }
+ })
+ .create();
+ }
+
+ private void setupSettingsSwitch(int containerId, int labelId, int switchId, boolean checked,
+ CompoundButton.OnCheckedChangeListener checkedChangeListener) {
+ ViewGroup container = (ViewGroup) findViewById(containerId);
+ String switchLabel = ((TextView) container.findViewById(labelId)).getText().toString();
+ final Switch switchView = container.findViewById(switchId);
+ switchView.setContentDescription(switchLabel);
+ switchView.setChecked(checked);
+ container.setOnClickListener(new View.OnClickListener() {
@Override
- public void onClick(View view) {
- finish();
+ public void onClick(View v) {
+ switchView.performClick();
}
});
+ switchView.setOnCheckedChangeListener(checkedChangeListener);
+ }
+
+ private void setupSettingsButton(int containerId, int labelId, int imageViewId,
+ final View.OnClickListener onClickListener) {
+ ViewGroup container = (ViewGroup) findViewById(containerId);
+ String buttonLabel = ((TextView) container.findViewById(labelId)).getText().toString();
+ final ImageView imageView = container.findViewById(imageViewId);
+ imageView.setContentDescription(buttonLabel);
+ container.setOnClickListener(onClickListener);
}
}
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/drawable/ic_delete_forever_black_24dp.xml b/input/autofill/AutofillFramework/Application/src/main/res/drawable/ic_delete_forever_black_24dp.xml
new file mode 100644
index 00000000..06d61218
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/res/drawable/ic_delete_forever_black_24dp.xml
@@ -0,0 +1,5 @@
+<vector android:alpha="0.50" android:height="24dp"
+ android:viewportHeight="24.0" android:viewportWidth="24.0"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#FF000000" android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2L18,7L6,7v12zM8.46,11.88l1.41,-1.41L12,12.59l2.12,-2.12 1.41,1.41L13.41,14l2.12,2.12 -1.41,1.41L12,15.41l-2.12,2.12 -1.41,-1.41L10.59,14l-2.13,-2.12zM15.5,4l-1,-1h-5l-1,1L5,4v2h14L19,4z"/>
+</vector>
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/drawable/ic_person_black_24dp.xml b/input/autofill/AutofillFramework/Application/src/main/res/drawable/ic_person_black_24dp.xml
new file mode 100644
index 00000000..7a0dcd36
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/res/drawable/ic_person_black_24dp.xml
@@ -0,0 +1,5 @@
+<vector android:alpha="0.50" android:height="24dp"
+ android:viewportHeight="24.0" android:viewportWidth="24.0"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#FF000000" android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
+</vector>
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/layout/settings_activity.xml b/input/autofill/AutofillFramework/Application/src/main/res/layout/settings_activity.xml
index 5a0f7283..5a3076da 100644
--- a/input/autofill/AutofillFramework/Application/src/main/res/layout/settings_activity.xml
+++ b/input/autofill/AutofillFramework/Application/src/main/res/layout/settings_activity.xml
@@ -1,71 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- * 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.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/settingsLayout"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:orientation="vertical">
+ Copyright 2017 Google Inc. All rights reserved.
+
+ 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.v4.widget.NestedScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scrollbarStyle="insideOverlay"
+ android:scrollbars="vertical"
+ android:importantForAutofill="no">
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
-
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="@dimen/spacing_large"
+ android:paddingTop="@dimen/spacing_large">
<TextView
+ style="@style/Settings.Header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Number datasets: " />
+ android:text="@string/settings_authentication_header"/>
- <EditText
- android:id="@+id/number_datasets"
- android:layout_width="50dip"
- android:layout_height="wrap_content"
- android:inputType="number"
- android:maxLength="1" />
- </LinearLayout>
+ <LinearLayout
+ android:id="@+id/settings_auth_responses_container"
+ style="@style/Settings.Container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
- <CheckBox
- android:id="@+id/response_auth"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="Authenticate responses" />
+ <TextView
+ android:id="@+id/settings_auth_responses_label"
+ style="@style/Settings.Label"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:importantForAccessibility="no"
+ android:text="@string/settings_authenticate_responses" />
- <CheckBox
- android:id="@+id/dataset_auth"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="Authenticate datasets" />
+ <Switch
+ android:id="@+id/settings_auth_responses_switch"
+ style="@style/Settings.Switch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/a11y_min_touch_target_dimen"
+ android:layout_marginStart="@dimen/padding_normal" />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
+ </LinearLayout>
- <Button
- android:id="@+id/cancel"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Cancel" />
+ <LinearLayout
+ android:id="@+id/settings_auth_datasets_container"
+ style="@style/Settings.Container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:id="@+id/settings_auth_datasets_label"
+ style="@style/Settings.Label"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:importantForAccessibility="no"
+ android:text="@string/settings_authenticate_datasets" />
+
+ <Switch
+ android:id="@+id/settings_auth_datasets_switch"
+ style="@style/Settings.Switch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/a11y_min_touch_target_dimen"
+ android:layout_marginStart="@dimen/padding_normal" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/settings_auth_credentials_container"
+ style="@style/Settings.Container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:id="@+id/settings_auth_credentials_label"
+ style="@style/Settings.Label"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/settings_auth_credentials_label" />
- <Button
- android:id="@+id/save"
+ <ImageView
+ android:id="@+id/settings_auth_credentials_icon"
+ style="@style/Settings.Switch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/a11y_min_touch_target_dimen"
+ android:layout_marginStart="@dimen/padding_normal"
+ android:src="@drawable/ic_person_black_24dp"/>
+ </LinearLayout>
+
+ <TextView
+ style="@style/Settings.Header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Save" />
+ android:paddingTop="@dimen/spacing_normal"
+ android:text="@string/settings_data_header"/>
+
+ <LinearLayout
+ android:id="@+id/settings_clear_data_container"
+ style="@style/Settings.Container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:id="@+id/settings_clear_data_label"
+ style="@style/Settings.Label"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/settings_clear_data_label" />
+
+ <ImageView
+ android:id="@+id/settings_clear_data_icon"
+ style="@style/Settings.Switch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/a11y_min_touch_target_dimen"
+ android:layout_marginStart="@dimen/padding_normal"
+ android:src="@drawable/ic_delete_forever_black_24dp"/>
+ </LinearLayout>
</LinearLayout>
-</LinearLayout> \ No newline at end of file
+</android.support.v4.widget.NestedScrollView>
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/layout/settings_authentication_dialog.xml b/input/autofill/AutofillFramework/Application/src/main/res/layout/settings_authentication_dialog.xml
new file mode 100644
index 00000000..edb293f1
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/res/layout/settings_authentication_dialog.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<EditText xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/master_password_field"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="@dimen/spacing_normal"
+ android:importantForAutofill="no"
+ android:padding="@dimen/spacing_normal">
+
+ <requestFocus />
+</EditText>
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/values/dimens.xml b/input/autofill/AutofillFramework/Application/src/main/res/values/dimens.xml
index d9e5ea5c..961725d5 100644
--- a/input/autofill/AutofillFramework/Application/src/main/res/values/dimens.xml
+++ b/input/autofill/AutofillFramework/Application/src/main/res/values/dimens.xml
@@ -19,4 +19,10 @@
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
+ <dimen name="spacing_normal">8dp</dimen>
+ <dimen name="spacing_micro">4dp</dimen>
+ <dimen name="padding_normal">16dp</dimen>
+ <dimen name="padding_normal_button">12dp</dimen>
+ <dimen name="spacing_large">32dp</dimen>
+ <dimen name="a11y_min_touch_target_dimen">48dp</dimen>
</resources>
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 71c5bede..b5611ae1 100644
--- a/input/autofill/AutofillFramework/Application/src/main/res/values/strings.xml
+++ b/input/autofill/AutofillFramework/Application/src/main/res/values/strings.xml
@@ -27,6 +27,23 @@
<string name="credit_card_number_label">CC Number</string>
<string name="credit_card_expiration_label">CC Exp</string>
<string name="credit_card_security_code_label">CC Security Code</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_datasets">Authenticate datasets</string>
+ <string name="settings_clear_data_label">Clear all data (including credentials)</string>
+ <string name="settings_clear_data_confirmation">Are you sure you want to delete all autofill
+ data from the sample service?
+ </string>
+ <string name="settings_clear_data_confirmation_title">Confirmation</string>
+ <string name="ok">OK</string>
+ <string name="cancel">Cancel</string>
+ <string name="settings_authentication_header">Authentication</string>
+ <string name="settings_data_header">Data</string>
+ <string name="settings_auth_credentials_label">Update credentials</string>
+ <string name="settings_auth_enter_current_password">Enter current password</string>
+ <string name="settings_auth_enter_new_password">Enter new password</string>
+ <string name="settings_auth_change_credentials_title">Change credentials</string>
<string-array name="month_array">
<item>Jan</item>
<item>Feb</item>
diff --git a/input/autofill/AutofillFramework/Application/src/main/res/values/styles.xml b/input/autofill/AutofillFramework/Application/src/main/res/values/styles.xml
new file mode 100644
index 00000000..73fccaf3
--- /dev/null
+++ b/input/autofill/AutofillFramework/Application/src/main/res/values/styles.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <style name="Settings.Label" parent="">
+ <item name="android:ellipsize">end</item>
+ <item name="android:lines">1</item>
+ <item name="android:paddingBottom">@dimen/spacing_normal</item>
+ <item name="android:paddingTop">@dimen/spacing_normal</item>
+ </style>
+ <style name="Settings.Container" parent="">
+ <item name="android:background">?android:selectableItemBackground</item>
+ <item name="android:gravity">center_vertical</item>
+ <item name="android:minHeight">?android:listPreferredItemHeightSmall</item>
+ <item name="android:orientation">horizontal</item>
+ <item name="android:paddingEnd">?android:listPreferredItemPaddingEnd</item>
+ <item name="android:paddingStart">?android:listPreferredItemPaddingStart</item>
+ </style>
+ <style name="Settings.Switch" parent="">
+ <!-- We make the parent view clickable instead for better touch feedback -->
+ <item name="android:background">@null</item>
+ <item name="android:clickable">false</item>
+ </style>
+
+ <style name="Settings.Header" parent="@style/TextAppearance.AppCompat.Large">
+ <item name="android:paddingStart">?android:listPreferredItemPaddingStart</item>
+ <item name="android:paddingBottom">@dimen/spacing_normal</item>
+ </style>
+</resources> \ No newline at end of file