improve presentation of Autofill (#9), support credit card datasets created from templates & expiry date
This commit is contained in:
@@ -36,6 +36,11 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
|
|
||||||
|
android:maxWidth="28dp"
|
||||||
|
android:maxHeight="28dp"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
|
||||||
android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
|
android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
android:src="@drawable/ic_launcher" />
|
android:src="@drawable/ic_launcher" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -69,15 +69,16 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
public const string AppName = "@string/app_name_debug";
|
public const string AppName = "@string/app_name_debug";
|
||||||
|
public const int AppNameResource = Resource.String.app_name_debug;
|
||||||
#else
|
#else
|
||||||
public const string AppName = "@string/app_name";
|
public const string AppName = "@string/app_name";
|
||||||
|
public const int AppNameResource = Resource.String.app_name;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public const int AppNameResource = Resource.String.app_name;
|
|
||||||
public const string AppNameShort = "@string/short_app_name" + "DBG";
|
|
||||||
public const string AppLauncherTitle = "@string/app_name" + " Debug";
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
public const string PackagePart = "keepass2android_debug";
|
public const string PackagePart = "keepass2android_debug";
|
||||||
public const string Searchable = "@xml/searchable_debug";
|
public const string Searchable = "@xml/searchable_debug";
|
||||||
#else
|
#else
|
||||||
public const string PackagePart = "keepass2android";
|
public const string PackagePart = "keepass2android";
|
||||||
|
|||||||
@@ -33,16 +33,14 @@ namespace keepass2android.services.AutofillBase
|
|||||||
if (datasetAuth)
|
if (datasetAuth)
|
||||||
{
|
{
|
||||||
datasetBuilder = new Dataset.Builder
|
datasetBuilder = new Dataset.Builder
|
||||||
(NewRemoteViews(context.PackageName, datasetName,
|
(NewRemoteViews(context.PackageName, datasetName, intentBuilder.AppIconResource));
|
||||||
Resource.Drawable.ic_launcher));
|
|
||||||
IntentSender sender = intentBuilder.GetAuthIntentSenderForDataset(context, datasetName);
|
IntentSender sender = intentBuilder.GetAuthIntentSenderForDataset(context, datasetName);
|
||||||
datasetBuilder.SetAuthentication(sender);
|
datasetBuilder.SetAuthentication(sender);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
datasetBuilder = new Dataset.Builder
|
datasetBuilder = new Dataset.Builder
|
||||||
(NewRemoteViews(context.PackageName, datasetName,
|
(NewRemoteViews(context.PackageName, datasetName, intentBuilder.AppIconResource));
|
||||||
Resource.Drawable.ic_launcher));
|
|
||||||
}
|
}
|
||||||
var setValueAtLeastOnce = filledAutofillFieldCollection.ApplyToFields(autofillFields, datasetBuilder);
|
var setValueAtLeastOnce = filledAutofillFieldCollection.ApplyToFields(autofillFields, datasetBuilder);
|
||||||
if (setValueAtLeastOnce)
|
if (setValueAtLeastOnce)
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ namespace keepass2android.services.AutofillBase
|
|||||||
IntentSender GetAuthIntentSenderForResponse(Context context, string query);
|
IntentSender GetAuthIntentSenderForResponse(Context context, string query);
|
||||||
IntentSender GetAuthIntentSenderForDataset(Context context, string dataset);
|
IntentSender GetAuthIntentSenderForDataset(Context context, string dataset);
|
||||||
Intent GetRestartAppIntent(Context context);
|
Intent GetRestartAppIntent(Context context);
|
||||||
|
|
||||||
|
int AppIconResource { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class AutofillServiceBase: AutofillService
|
public abstract class AutofillServiceBase: AutofillService
|
||||||
@@ -67,7 +69,7 @@ namespace keepass2android.services.AutofillBase
|
|||||||
var responseBuilder = new FillResponse.Builder();
|
var responseBuilder = new FillResponse.Builder();
|
||||||
|
|
||||||
var sender = IntentBuilder.GetAuthIntentSenderForResponse(this, query);
|
var sender = IntentBuilder.GetAuthIntentSenderForResponse(this, query);
|
||||||
RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName, GetString(Resource.String.autofill_sign_in_prompt),Resource.Drawable.ic_launcher);
|
RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName, GetString(Resource.String.autofill_sign_in_prompt), AppNames.LauncherIcon);
|
||||||
|
|
||||||
var datasetBuilder = new Dataset.Builder(presentation);
|
var datasetBuilder = new Dataset.Builder(presentation);
|
||||||
datasetBuilder.SetAuthentication(sender);
|
datasetBuilder.SetAuthentication(sender);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using keepass2android.services.AutofillBase;
|
|||||||
using keepass2android.services.AutofillBase.model;
|
using keepass2android.services.AutofillBase.model;
|
||||||
using Keepass2android.Pluginsdk;
|
using Keepass2android.Pluginsdk;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
|
using KeePassLib.Utility;
|
||||||
|
|
||||||
namespace keepass2android.services.Kp2aAutofill
|
namespace keepass2android.services.Kp2aAutofill
|
||||||
{
|
{
|
||||||
@@ -55,21 +56,82 @@ namespace keepass2android.services.Kp2aAutofill
|
|||||||
};
|
};
|
||||||
fieldCollection.Add(field);
|
fieldCollection.Add(field);
|
||||||
}
|
}
|
||||||
//TODO add support for Keepass templates
|
if (IsCreditCard(pwEntry) && pwEntry.Expires)
|
||||||
//TODO add values like expiration?
|
{
|
||||||
//TODO if cc-exp is there, also set cc-exp-month etc.
|
DateTime expTime = pwEntry.ExpiryTime;
|
||||||
|
FilledAutofillField field =
|
||||||
|
new FilledAutofillField
|
||||||
|
{
|
||||||
|
AutofillHints = new[] { View.AutofillHintCreditCardExpirationDate },
|
||||||
|
DateValue = (long)(1000*TimeUtil.SerializeUnix(expTime)),
|
||||||
|
Protected = false
|
||||||
|
};
|
||||||
|
fieldCollection.Add(field);
|
||||||
|
|
||||||
|
field =
|
||||||
|
new FilledAutofillField
|
||||||
|
{
|
||||||
|
AutofillHints = new[] { View.AutofillHintCreditCardExpirationDay },
|
||||||
|
TextValue = expTime.Day.ToString(),
|
||||||
|
Protected = false
|
||||||
|
};
|
||||||
|
fieldCollection.Add(field);
|
||||||
|
|
||||||
|
field =
|
||||||
|
new FilledAutofillField
|
||||||
|
{
|
||||||
|
AutofillHints = new[] { View.AutofillHintCreditCardExpirationMonth },
|
||||||
|
TextValue = expTime.Month.ToString(),
|
||||||
|
Protected = false
|
||||||
|
};
|
||||||
|
fieldCollection.Add(field);
|
||||||
|
|
||||||
|
field =
|
||||||
|
new FilledAutofillField
|
||||||
|
{
|
||||||
|
AutofillHints = new[] { View.AutofillHintCreditCardExpirationYear },
|
||||||
|
TextValue = expTime.Year.ToString(),
|
||||||
|
Protected = false
|
||||||
|
};
|
||||||
|
fieldCollection.Add(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fieldCollection.DatasetName = pwEntry.Strings.ReadSafe(PwDefs.TitleField);
|
fieldCollection.DatasetName = pwEntry.Strings.ReadSafe(PwDefs.TitleField);
|
||||||
|
|
||||||
return fieldCollection;
|
return fieldCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Dictionary<string, string> keyToHint = new Dictionary<string, string>()
|
private bool IsCreditCard(PwEntry pwEntry)
|
||||||
{
|
{
|
||||||
{PwDefs.UserNameField, View.AutofillHintUsername },
|
return pwEntry.Strings.Exists("cc-number")
|
||||||
{PwDefs.PasswordField, View.AutofillHintPassword },
|
|| pwEntry.Strings.Exists("cc-csc")
|
||||||
{PwDefs.UrlField, W3cHints.URL },
|
|| pwEntry.Strings.Exists(GetString(Resource.String.TemplateField_CreditCard_CVV));
|
||||||
};
|
}
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, string> keyToHint = BuildKeyToHint();
|
||||||
|
|
||||||
|
private static Dictionary<string, string> BuildKeyToHint()
|
||||||
|
{
|
||||||
|
var result = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{PwDefs.UserNameField, View.AutofillHintUsername},
|
||||||
|
{PwDefs.PasswordField, View.AutofillHintPassword},
|
||||||
|
{PwDefs.UrlField, W3cHints.URL},
|
||||||
|
{
|
||||||
|
Android.App.Application.Context.GetString(Resource.String.TemplateField_CreditCard_CVV),
|
||||||
|
View.AutofillHintCreditCardSecurityCode
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Android.App.Application.Context.GetString(Resource.String.TemplateField_CreditCard_Owner),
|
||||||
|
W3cHints.CC_NAME
|
||||||
|
},
|
||||||
|
{Android.App.Application.Context.GetString(Resource.String.TemplateField_Number), View.AutofillHintCreditCardNumber},
|
||||||
|
{Android.App.Application.Context.GetString(Resource.String.TemplateField_IdCard_Name), View.AutofillHintName},
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private string GetCanonicalHintFromKp2aField(PwEntry pwEntry, string key)
|
private string GetCanonicalHintFromKp2aField(PwEntry pwEntry, string key)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using AutofillServiceBase = keepass2android.services.AutofillBase.AutofillServic
|
|||||||
|
|
||||||
namespace keepass2android.services
|
namespace keepass2android.services
|
||||||
{
|
{
|
||||||
[Service(Label = "Keepass2Android Autofill Service", Permission=Manifest.Permission.BindAutofillService)]
|
[Service(Label = AppNames.AppName, Permission=Manifest.Permission.BindAutofillService)]
|
||||||
[IntentFilter(new [] {"android.service.autofill.AutofillService"})]
|
[IntentFilter(new [] {"android.service.autofill.AutofillService"})]
|
||||||
[MetaData("android.autofill", Resource = "@xml/autofillservice")]
|
[MetaData("android.autofill", Resource = "@xml/autofillservice")]
|
||||||
[Register("keepass2android.services.Kp2aAutofillService")]
|
[Register("keepass2android.services.Kp2aAutofillService")]
|
||||||
|
|||||||
@@ -36,5 +36,10 @@ namespace keepass2android.services
|
|||||||
intent.AddFlags(ActivityFlags.ForwardResult);
|
intent.AddFlags(ActivityFlags.ForwardResult);
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int AppIconResource
|
||||||
|
{
|
||||||
|
get { return AppNames.LauncherIcon; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user