diff --git a/src/KeePass.sln b/src/KeePass.sln index dc4bfbc0..a2837f93 100644 --- a/src/KeePass.sln +++ b/src/KeePass.sln @@ -27,12 +27,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.FtpClient.Androi EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamsungPass", "SamsungPass\Xamarin.SamsungPass\SamsungPass\SamsungPass.csproj", "{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aAutofillBinding", "Kp2aAutofillBinding\Kp2aAutofillBinding.csproj", "{39D433EC-253C-44D8-89A0-85C06A41FB8C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aAutofillLib", "Kp2aAutofillLib\Kp2aAutofillLib.csproj", "{612D3DD7-995B-4484-8D40-1607889EF0B8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutofillTestApp", "AutofillTestApp\AutofillTestApp.csproj", "{C75CFA4A-F969-4E27-B9AC-A73706B10E39}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -289,90 +283,6 @@ Global {3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU {3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU {3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Debug|Win32.ActiveCfg = Debug|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Debug|Win32.Build.0 = Debug|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Debug|x64.ActiveCfg = Debug|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Debug|x64.Build.0 = Debug|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Release|Any CPU.Build.0 = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Release|Win32.ActiveCfg = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Release|Win32.Build.0 = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Release|x64.ActiveCfg = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.Release|x64.Build.0 = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU - {39D433EC-253C-44D8-89A0-85C06A41FB8C}.ReleaseNoNet|x64.Build.0 = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Debug|Win32.ActiveCfg = Debug|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Debug|Win32.Build.0 = Debug|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Debug|x64.ActiveCfg = Debug|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Debug|x64.Build.0 = Debug|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Release|Any CPU.Build.0 = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Release|Win32.ActiveCfg = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Release|Win32.Build.0 = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Release|x64.ActiveCfg = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.Release|x64.Build.0 = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU - {612D3DD7-995B-4484-8D40-1607889EF0B8}.ReleaseNoNet|x64.Build.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Debug|Win32.ActiveCfg = Debug|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Debug|Win32.Build.0 = Debug|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Debug|Win32.Deploy.0 = Debug|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Debug|x64.ActiveCfg = Debug|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Debug|x64.Build.0 = Debug|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Debug|x64.Deploy.0 = Debug|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Release|Any CPU.Build.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Release|Any CPU.Deploy.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Release|Win32.ActiveCfg = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Release|Win32.Build.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Release|Win32.Deploy.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Release|x64.ActiveCfg = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Release|x64.Build.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.Release|x64.Deploy.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.ReleaseNoNet|Win32.Deploy.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.ReleaseNoNet|x64.Build.0 = Release|Any CPU - {C75CFA4A-F969-4E27-B9AC-A73706B10E39}.ReleaseNoNet|x64.Deploy.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/keepass2android/Properties/AndroidManifest_debug.xml b/src/keepass2android/Properties/AndroidManifest_debug.xml index fa4d8262..41eebd8e 100644 --- a/src/keepass2android/Properties/AndroidManifest_debug.xml +++ b/src/keepass2android/Properties/AndroidManifest_debug.xml @@ -1,8 +1,8 @@  - + diff --git a/src/keepass2android/Properties/AndroidManifest_net.xml b/src/keepass2android/Properties/AndroidManifest_net.xml index a90903aa..11be5674 100644 --- a/src/keepass2android/Properties/AndroidManifest_net.xml +++ b/src/keepass2android/Properties/AndroidManifest_net.xml @@ -5,8 +5,8 @@ package="keepass2android.keepass2android" android:installLocation="auto"> - + diff --git a/src/keepass2android/Properties/AndroidManifest_nonet.xml b/src/keepass2android/Properties/AndroidManifest_nonet.xml index 8783c768..85bef5a3 100644 --- a/src/keepass2android/Properties/AndroidManifest_nonet.xml +++ b/src/keepass2android/Properties/AndroidManifest_nonet.xml @@ -6,6 +6,7 @@ android:installLocation="auto"> + diff --git a/src/keepass2android/Resources/layout/autofill_service_list_item.xml b/src/keepass2android/Resources/layout/autofill_service_list_item.xml new file mode 100644 index 00000000..8d06a671 --- /dev/null +++ b/src/keepass2android/Resources/layout/autofill_service_list_item.xml @@ -0,0 +1,40 @@ + + + + + + + + \ No newline at end of file diff --git a/src/keepass2android/Resources/values/config.xml b/src/keepass2android/Resources/values/config.xml index f2351554..29f65174 100644 --- a/src/keepass2android/Resources/values/config.xml +++ b/src/keepass2android/Resources/values/config.xml @@ -43,8 +43,8 @@ https://github.com/PhilippC/keepass2android/issues market://details?id=org.openintents.filemanager https://openintents.googlecode.com/files/FileManager-2.0.2.apk - KP2A Internal File Browsing Permission KP2A Search + KP2A Choose autofill dataset diff --git a/src/keepass2android/Resources/xml/autofillservice.xml b/src/keepass2android/Resources/xml/autofillservice.xml new file mode 100644 index 00000000..f47169a1 --- /dev/null +++ b/src/keepass2android/Resources/xml/autofillservice.xml @@ -0,0 +1,4 @@ + + diff --git a/src/keepass2android/keepass2android.csproj b/src/keepass2android/keepass2android.csproj index bbd12639..adedc61b 100644 --- a/src/keepass2android/keepass2android.csproj +++ b/src/keepass2android/keepass2android.csproj @@ -1,5 +1,6 @@  + Debug AnyCPU @@ -19,7 +20,8 @@ 1G false - 9e78b013 + + True @@ -103,17 +105,42 @@ - - ..\packages\Xamarin.Android.Support.v7.MediaRouter.21.0.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.MediaRouter.dll + + ..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.1.1\lib\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.dll - - ..\packages\Xamarin.Android.Support.v4.22.2.1.0\lib\MonoAndroid403\Xamarin.Android.Support.v4.dll + + ..\packages\Xamarin.Android.Support.Compat.25.1.1\lib\MonoAndroid70\Xamarin.Android.Support.Compat.dll - - ..\packages\Xamarin.Android.Support.v7.AppCompat.22.2.1.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.AppCompat.dll + + ..\packages\Xamarin.Android.Support.Core.UI.25.1.1\lib\MonoAndroid70\Xamarin.Android.Support.Core.UI.dll - - ..\packages\Xamarin.Android.Support.Design.22.2.1.0\lib\MonoAndroid403\Xamarin.Android.Support.Design.dll + + ..\packages\Xamarin.Android.Support.Core.Utils.25.1.1\lib\MonoAndroid70\Xamarin.Android.Support.Core.Utils.dll + + + ..\packages\Xamarin.Android.Support.Design.25.1.1\lib\MonoAndroid70\Xamarin.Android.Support.Design.dll + + + ..\packages\Xamarin.Android.Support.Fragment.25.1.1\lib\MonoAndroid70\Xamarin.Android.Support.Fragment.dll + + + ..\packages\Xamarin.Android.Support.Media.Compat.25.1.1\lib\MonoAndroid70\Xamarin.Android.Support.Media.Compat.dll + + + ..\packages\Xamarin.Android.Support.Transition.25.1.1\lib\MonoAndroid70\Xamarin.Android.Support.Transition.dll + + + ..\packages\Xamarin.Android.Support.v13.25.1.1\lib\MonoAndroid70\Xamarin.Android.Support.v13.dll + True + + + ..\packages\Xamarin.Android.Support.v7.AppCompat.25.1.1\lib\MonoAndroid70\Xamarin.Android.Support.v7.AppCompat.dll + + + ..\packages\Xamarin.Android.Support.v7.RecyclerView.25.1.1\lib\MonoAndroid70\Xamarin.Android.Support.v7.RecyclerView.dll + + + ..\packages\Xamarin.Android.Support.Vector.Drawable.25.1.1\lib\MonoAndroid70\Xamarin.Android.Support.Vector.Drawable.dll ..\packages\Xamarin.GooglePlayServices.Base.27.0.0.0\lib\MonoAndroid41\Xamarin.GooglePlayServices.Base.dll @@ -191,12 +218,16 @@ + + - + + + @@ -904,12 +935,6 @@ Designer - - - 22.2.0.0 - False - - @@ -1741,10 +1766,56 @@ + + + False + 25.1.1.0 + + + False + 25.1.1.0 + + + False + 25.1.1.0 + + + + + Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}". + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/keepass2android/packages.config b/src/keepass2android/packages.config index 1a50c8bb..2e6476f6 100644 --- a/src/keepass2android/packages.config +++ b/src/keepass2android/packages.config @@ -3,10 +3,19 @@ - - - - + + + + + + + + + + + + + diff --git a/src/keepass2android/services/AutofillBase/AutofillFieldMetadataCollection.cs b/src/keepass2android/services/AutofillBase/AutofillFieldMetadataCollection.cs index 96ac5b7f..8e38a148 100644 --- a/src/keepass2android/services/AutofillBase/AutofillFieldMetadataCollection.cs +++ b/src/keepass2android/services/AutofillBase/AutofillFieldMetadataCollection.cs @@ -12,7 +12,7 @@ namespace keepass2android.services.AutofillBase public class AutofillFieldMetadataCollection { List AutofillIds = new List(); - Dictionary> AutofillHintsToFieldsMap = new Dictionary>(); + Dictionary> AutofillHintsToFieldsMap = new Dictionary>(); public List AllAutofillHints { get; } public List FocusedAutofillHints { get; } int Size = 0; @@ -25,7 +25,7 @@ namespace keepass2android.services.AutofillBase AllAutofillHints = new List(); } - public void Add(keepass2android.services.AutofillBase.AutofillFieldMetadata autofillFieldMetadata) + public void Add(AutofillFieldMetadata autofillFieldMetadata) { SaveType |= autofillFieldMetadata.SaveType; Size++; diff --git a/src/keepass2android/services/AutofillBase/AutofillHelper.cs b/src/keepass2android/services/AutofillBase/AutofillHelper.cs index 22005b33..fbd42107 100644 --- a/src/keepass2android/services/AutofillBase/AutofillHelper.cs +++ b/src/keepass2android/services/AutofillBase/AutofillHelper.cs @@ -72,7 +72,7 @@ namespace keepass2android.services.AutofillBase /// Autofill fields. /// Client form data map. /// - public static FillResponse NewResponse(Context context, bool datasetAuth, keepass2android.services.AutofillBase.AutofillFieldMetadataCollection autofillFields, Dictionary clientFormDataMap, IAutofillIntentBuilder intentBuilder) + public static FillResponse NewResponse(Context context, bool datasetAuth, AutofillFieldMetadataCollection autofillFields, Dictionary clientFormDataMap, IAutofillIntentBuilder intentBuilder) { var responseBuilder = new FillResponse.Builder(); if (clientFormDataMap != null) diff --git a/src/keepass2android/services/AutofillBase/AutofillServiceBase.cs b/src/keepass2android/services/AutofillBase/AutofillServiceBase.cs index 9050110b..b6e5c627 100644 --- a/src/keepass2android/services/AutofillBase/AutofillServiceBase.cs +++ b/src/keepass2android/services/AutofillBase/AutofillServiceBase.cs @@ -9,11 +9,12 @@ namespace keepass2android.services.AutofillBase { public interface IAutofillIntentBuilder { - IntentSender GetAuthIntentSenderForResponse(Context context); + IntentSender GetAuthIntentSenderForResponse(Context context, string query); IntentSender GetAuthIntentSenderForDataset(Context context, string dataset); + Intent GetRestartAppIntent(Context context); } - public abstract class AutofillServiceBase: AutofillService, IAutofillIntentBuilder + public abstract class AutofillServiceBase: AutofillService { public AutofillServiceBase() { @@ -41,10 +42,11 @@ namespace keepass2android.services.AutofillBase Log.Warn(CommonUtil.Tag, "Cancel autofill not implemented yet."); }; // Parse AutoFill data in Activity + string query = null; var parser = new StructureParser(this, structure); try { - parser.ParseForFill(); + query = parser.ParseForFill(); } catch (Java.Lang.SecurityException e) { @@ -53,7 +55,7 @@ namespace keepass2android.services.AutofillBase return; } - keepass2android.services.AutofillBase.AutofillFieldMetadataCollection autofillFields = parser.AutofillFields; + AutofillFieldMetadataCollection autofillFields = parser.AutofillFields; var responseBuilder = new FillResponse.Builder(); // Check user's settings for authenticating Responses and Datasets. bool responseAuth = true; @@ -62,7 +64,7 @@ namespace keepass2android.services.AutofillBase { // If the entire Autofill Response is authenticated, AuthActivity is used // to generate Response. - var sender = GetAuthIntentSenderForResponse(this); + var sender = IntentBuilder.GetAuthIntentSenderForResponse(this, query); var presentation = keepass2android.services.AutofillBase.AutofillHelper .NewRemoteViews(PackageName, GetString(Resource.String.autofill_sign_in_prompt), Resource.Drawable.ic_launcher); @@ -73,7 +75,7 @@ namespace keepass2android.services.AutofillBase else { var datasetAuth = true; - var response = keepass2android.services.AutofillBase.AutofillHelper.NewResponse(this, datasetAuth, autofillFields, null, this); + var response = AutofillHelper.NewResponse(this, datasetAuth, autofillFields, null, IntentBuilder); callback.OnSuccess(response); } } @@ -95,7 +97,6 @@ namespace keepass2android.services.AutofillBase Log.Debug(CommonUtil.Tag, "onDisconnected"); } - public abstract IntentSender GetAuthIntentSenderForResponse(Context context); - public abstract IntentSender GetAuthIntentSenderForDataset(Context context, string dataset); + public abstract IAutofillIntentBuilder IntentBuilder{get;} } } diff --git a/src/keepass2android/services/AutofillBase/ChooseForAutofillActivityBase.cs b/src/keepass2android/services/AutofillBase/ChooseForAutofillActivityBase.cs new file mode 100644 index 00000000..de501975 --- /dev/null +++ b/src/keepass2android/services/AutofillBase/ChooseForAutofillActivityBase.cs @@ -0,0 +1,133 @@ +using System; +using Android.App; +using Android.App.Assist; +using Android.Content; +using Android.OS; +using Android.Service.Autofill; +using Android.Support.V7.App; +using Android.Util; +using Android.Views.Autofill; +using Android.Widget; +using Java.Util; +using keepass2android.services.AutofillBase.model; +using System.Collections.Generic; + +namespace keepass2android.services.AutofillBase +{ + + public abstract class ChooseForAutofillActivityBase : AppCompatActivity + { + protected Intent ReplyIntent; + + + public static string ExtraQueryString => "EXTRA_QUERY_STRING"; + + public int RequestCodeQuery => 663245; + + protected override void OnCreate(Bundle savedInstanceState) + { + base.OnCreate(savedInstanceState); + + //if launched from history, don't re-use the task. Proceed to FileSelect instead. + if (Intent.Flags.HasFlag(ActivityFlags.LaunchedFromHistory)) + { + Kp2aLog.Log("Forwarding to FileSelect. QueryCredentialsActivity started from history."); + RestartApp(); + return; + } + + string requestedUrl = Intent.GetStringExtra(ExtraQueryString); + if (requestedUrl == null) + { + Toast.MakeText(this, "Cannot execute query for null.", ToastLength.Long).Show(); + RestartApp(); + return; + } + + var i = GetQueryIntent(requestedUrl); + StartActivityForResult(i, RequestCodeQuery); + } + + protected abstract Intent GetQueryIntent(string requestedUrl); + + protected void RestartApp() + { + Intent intent = IntentBuilder.GetRestartAppIntent(this); + StartActivity(intent); + Finish(); + } + + + public override void Finish() + { + if (ReplyIntent != null) + { + SetResult(Result.Ok, ReplyIntent); + } + else + { + SetResult(Result.Canceled); + } + base.Finish(); + } + + void OnFailure() + { + Log.Warn(CommonUtil.Tag, "Failed auth."); + ReplyIntent = null; + } + + protected void OnSuccess(FilledAutofillFieldCollection clientFormDataMap) + { + var intent = Intent; + var forResponse = intent.GetBooleanExtra(CommonUtil.EXTRA_FOR_RESPONSE, true); + AssistStructure structure = (AssistStructure)intent.GetParcelableExtra(AutofillManager.ExtraAssistStructure); + StructureParser parser = new StructureParser(this, structure); + parser.ParseForFill(); + AutofillFieldMetadataCollection autofillFields = parser.AutofillFields; + ReplyIntent = new Intent(); + if (forResponse) + { + Dictionary dict = new Dictionary { {clientFormDataMap.DatasetName, clientFormDataMap }}; + SetResponseIntent(AutofillHelper.NewResponse(this, false, autofillFields, dict, IntentBuilder)); + } + else + { + SetDatasetIntent(AutofillHelper.NewDataset(this, autofillFields, clientFormDataMap, false, IntentBuilder)); + } + } + + protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) + { + base.OnActivityResult(requestCode, resultCode, data); + + if (requestCode == RequestCodeQuery) + { + if (resultCode != Result.Ok) + OnFailure(); + else + OnSuccess(GetDataset(data)); + Finish(); + + } + + } + + /// + /// Creates the FilledAutofillFieldCollection from the intent returned from the query activity + /// + protected abstract FilledAutofillFieldCollection GetDataset(Intent data); + + public abstract IAutofillIntentBuilder IntentBuilder { get; } + + protected void SetResponseIntent(FillResponse fillResponse) + { + ReplyIntent.PutExtra(AutofillManager.ExtraAuthenticationResult, fillResponse); + } + + protected void SetDatasetIntent(Dataset dataset) + { + ReplyIntent.PutExtra(AutofillManager.ExtraAuthenticationResult, dataset); + } + } +} \ No newline at end of file diff --git a/src/keepass2android/services/AutofillBase/StructureParser.cs b/src/keepass2android/services/AutofillBase/StructureParser.cs index 90444137..5966db3c 100644 --- a/src/keepass2android/services/AutofillBase/StructureParser.cs +++ b/src/keepass2android/services/AutofillBase/StructureParser.cs @@ -25,14 +25,14 @@ namespace keepass2android.services.AutofillBase AutofillFields = new keepass2android.services.AutofillBase.AutofillFieldMetadataCollection(); } - public void ParseForFill() + public string ParseForFill() { - Parse(true); + return Parse(true); } - public void ParseForSave() + public string ParseForSave() { - Parse(false); + return Parse(false); } /// @@ -40,7 +40,7 @@ namespace keepass2android.services.AutofillBase /// /// The parse. /// If set to true for fill. - void Parse(bool forFill) + string Parse(bool forFill) { Log.Debug(keepass2android.services.AutofillBase.CommonUtil.Tag, "Parsing structure for " + Structure.ActivityComponent); var nodes = Structure.WindowNodeCount; @@ -67,7 +67,8 @@ namespace keepass2android.services.AutofillBase { Log.Debug(keepass2android.services.AutofillBase.CommonUtil.Tag, "no web domain"); } - } + return webDomain; + } void ParseLocked(bool forFill, AssistStructure.ViewNode viewNode, ref string validWebdomain) { diff --git a/src/keepass2android/services/AutofillBase/model/FilledAutofillField.cs b/src/keepass2android/services/AutofillBase/model/FilledAutofillField.cs index f135a03e..8af0be3b 100644 --- a/src/keepass2android/services/AutofillBase/model/FilledAutofillField.cs +++ b/src/keepass2android/services/AutofillBase/model/FilledAutofillField.cs @@ -3,19 +3,12 @@ using Android.Views.Autofill; namespace keepass2android.services.AutofillBase.model { - /// - /// JSON serializable data class containing the same data as an {@link AutofillValue}. - /// public class FilledAutofillField { public string TextValue { get; set; } public long? DateValue { get; set; } public bool? ToggleValue { get; set; } - - /// - /// Does not need to be serialized into persistent storage, so it's not exposed. - /// - /// The autofill hints. + public string[] AutofillHints { get; set; } public FilledAutofillField() @@ -44,8 +37,6 @@ namespace keepass2android.services.AutofillBase.model } else if (autofillValue.IsText) { - // Using toString of AutofillValue.getTextValue in order to save it to - // SharedPreferences. TextValue = autofillValue.TextValue; } } @@ -63,7 +54,7 @@ namespace keepass2android.services.AutofillBase.model FilledAutofillField that = (FilledAutofillField)obj; - if (TextValue != null ? !TextValue.Equals(that.TextValue) : that.TextValue != null) + if (!TextValue?.Equals(that.TextValue) ?? that.TextValue != null) return false; if (DateValue != null ? !DateValue.Equals(that.DateValue) : that.DateValue != null) return false; diff --git a/src/keepass2android/services/AutofillBase/model/FilledAutofillFieldCollection.cs b/src/keepass2android/services/AutofillBase/model/FilledAutofillFieldCollection.cs index 320ce1ce..393874ea 100644 --- a/src/keepass2android/services/AutofillBase/model/FilledAutofillFieldCollection.cs +++ b/src/keepass2android/services/AutofillBase/model/FilledAutofillFieldCollection.cs @@ -6,22 +6,22 @@ using Android.Views.Autofill; namespace keepass2android.services.AutofillBase.model { - /// - /// FilledAutofillFieldCollection is the model that holds all of the data on a client app's page, - /// plus the dataset name associated with it. - /// - public class FilledAutofillFieldCollection + /// + /// FilledAutofillFieldCollection is the model that holds all of the data on a client app's page, + /// plus the dataset name associated with it. + /// + public class FilledAutofillFieldCollection { - public Dictionary HintMap { get; set; } + public Dictionary HintMap { get; set; } public string DatasetName { get; set; } - public FilledAutofillFieldCollection(Dictionary hintMap, string datasetName = "") + public FilledAutofillFieldCollection(Dictionary hintMap, string datasetName = "") { HintMap = hintMap; DatasetName = datasetName; } - public FilledAutofillFieldCollection() : this(new Dictionary()) + public FilledAutofillFieldCollection() : this(new Dictionary()) {} /// @@ -29,7 +29,7 @@ namespace keepass2android.services.AutofillBase.model /// /// The add. /// Filled autofill field. - public void Add(keepass2android.services.AutofillBase.model.FilledAutofillField filledAutofillField) + public void Add(FilledAutofillField filledAutofillField) { string[] autofillHints = filledAutofillField.AutofillHints; //TODO apply W3C transformation diff --git a/src/keepass2android/services/AutofillBase/model/W3cHints.cs b/src/keepass2android/services/AutofillBase/model/W3cHints.cs new file mode 100644 index 00000000..11941ea1 --- /dev/null +++ b/src/keepass2android/services/AutofillBase/model/W3cHints.cs @@ -0,0 +1,74 @@ +namespace keepass2android.services.AutofillBase.model +{ + public class W3cHints + { + + // Supported W3C autofill tokens (https://html.spec.whatwg.org/multipage/forms.html#autofill) + public static string HONORIFIC_PREFIX = "honorific-prefix"; + public static string NAME = "name"; + public static string GIVEN_NAME = "given-name"; + public static string ADDITIONAL_NAME = "additional-name"; + public static string FAMILY_NAME = "family-name"; + public static string HONORIFIC_SUFFIX = "honorific-suffix"; + public static string USERNAME = "username"; + public static string NEW_PASSWORD = "new-password"; + public static string CURRENT_PASSWORD = "current-password"; + public static string ORGANIZATION_TITLE = "organization-title"; + public static string ORGANIZATION = "organization"; + public static string STREET_ADDRESS = "street-address"; + public static string ADDRESS_LINE1 = "address-line1"; + public static string ADDRESS_LINE2 = "address-line2"; + public static string ADDRESS_LINE3 = "address-line3"; + public static string ADDRESS_LEVEL4 = "address-level4"; + public static string ADDRESS_LEVEL3 = "address-level3"; + public static string ADDRESS_LEVEL2 = "address-level2"; + public static string ADDRESS_LEVEL1 = "address-level1"; + public static string COUNTRY = "country"; + public static string COUNTRY_NAME = "country-name"; + public static string POSTAL_CODE = "postal-code"; + public static string CC_NAME = "cc-name"; + public static string CC_GIVEN_NAME = "cc-given-name"; + public static string CC_ADDITIONAL_NAME = "cc-additional-name"; + public static string CC_FAMILY_NAME = "cc-family-name"; + public static string CC_NUMBER = "cc-number"; + public static string CC_EXPIRATION = "cc-exp"; + public static string CC_EXPIRATION_MONTH = "cc-exp-month"; + public static string CC_EXPIRATION_YEAR = "cc-exp-year"; + public static string CC_CSC = "cc-csc"; + public static string CC_TYPE = "cc-type"; + public static string TRANSACTION_CURRENCY = "transaction-currency"; + public static string TRANSACTION_AMOUNT = "transaction-amount"; + public static string LANGUAGE = "language"; + public static string BDAY = "bday"; + public static string BDAY_DAY = "bday-day"; + public static string BDAY_MONTH = "bday-month"; + public static string BDAY_YEAR = "bday-year"; + public static string SEX = "sex"; + public static string URL = "url"; + public static string PHOTO = "photo"; + // Optional W3C prefixes + public static string PREFIX_SECTION = "section-"; + public static string SHIPPING = "shipping"; + public static string BILLING = "billing"; + // W3C prefixes below... + public static string PREFIX_HOME = "home"; + public static string PREFIX_WORK = "work"; + public static string PREFIX_FAX = "fax"; + public static string PREFIX_PAGER = "pager"; + // ... require those suffix + public static string TEL = "tel"; + public static string TEL_COUNTRY_CODE = "tel-country-code"; + public static string TEL_NATIONAL = "tel-national"; + public static string TEL_AREA_CODE = "tel-area-code"; + public static string TEL_LOCAL = "tel-local"; + public static string TEL_LOCAL_PREFIX = "tel-local-prefix"; + public static string TEL_LOCAL_SUFFIX = "tel-local-suffix"; + public static string TEL_EXTENSION = "tel_extension"; + public static string EMAIL = "email"; + public static string IMPP = "impp"; + + private W3cHints() + { + } + } +} \ No newline at end of file diff --git a/src/keepass2android/services/Kp2aAutofill/ChooseForAutofillActivity.cs b/src/keepass2android/services/Kp2aAutofill/ChooseForAutofillActivity.cs new file mode 100644 index 00000000..143a884f --- /dev/null +++ b/src/keepass2android/services/Kp2aAutofill/ChooseForAutofillActivity.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.Content.PM; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using keepass2android.services.AutofillBase; +using keepass2android.services.AutofillBase.model; +using Keepass2android.Pluginsdk; +using KeePassLib; + +namespace keepass2android.services.Kp2aAutofill +{ + [Activity(Label = "@string/app_name", + ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, + Theme = "@style/MyTheme_ActionBar", + Permission = "keepass2android." + AppNames.PackagePart + ".permission.Kp2aChooseAutofill")] + public class ChooseForAutofillActivity : ChooseForAutofillActivityBase + { + protected override Intent GetQueryIntent(string requestedUrl) + { + //launch FileSelectActivity (which is root of the stack (exception: we're even below!)) with the appropriate task. + //will return the results later + Intent i = new Intent(this, typeof(FileSelectActivity)); + //don't show user notifications when an entry is opened. + var task = new SearchUrlTask() { UrlToSearchFor = requestedUrl, ShowUserNotifications = false }; + task.ToIntent(i); + return i; + } + + protected override FilledAutofillFieldCollection GetDataset(Intent data) + { + if (!App.Kp2a.GetDb().Loaded || (App.Kp2a.QuickLocked)) + return null; + + string username = App.Kp2a.GetDb().LastOpenedEntry.Entry.Strings.ReadSafe(PwDefs.UserNameField); + string password = App.Kp2a.GetDb().LastOpenedEntry.Entry.Strings.ReadSafe(PwDefs.PasswordField); + + FilledAutofillField pwdField = + new FilledAutofillField + { + AutofillHints = new[] {W3cHints.NAME, W3cHints.EMAIL}, + TextValue = password + }; + + FilledAutofillField userField = new FilledAutofillField + { + AutofillHints = new[] {W3cHints.NEW_PASSWORD, W3cHints.CURRENT_PASSWORD}, + TextValue = username + }; + + FilledAutofillFieldCollection fieldCollection = new FilledAutofillFieldCollection(); + fieldCollection.HintMap = new Dictionary(); + fieldCollection.Add(userField); + fieldCollection.Add(pwdField); + + fieldCollection.DatasetName = App.Kp2a.GetDb().LastOpenedEntry.Entry.Strings.ReadSafe(PwDefs.TitleField); + + return fieldCollection; + } + + public override IAutofillIntentBuilder IntentBuilder => new Kp2aAutofillIntentBuilder(); + + } +} \ No newline at end of file diff --git a/src/keepass2android/services/Kp2aAutofillService.cs b/src/keepass2android/services/Kp2aAutofill/Kp2aAutofillService.cs similarity index 62% rename from src/keepass2android/services/Kp2aAutofillService.cs rename to src/keepass2android/services/Kp2aAutofill/Kp2aAutofillService.cs index 7cb1cfbf..fdb81185 100644 --- a/src/keepass2android/services/Kp2aAutofillService.cs +++ b/src/keepass2android/services/Kp2aAutofill/Kp2aAutofillService.cs @@ -3,6 +3,7 @@ using Android; using Android.App; using Android.Content; using Android.Runtime; +using keepass2android.services.AutofillBase; using AutofillServiceBase = keepass2android.services.AutofillBase.AutofillServiceBase; namespace keepass2android.services @@ -23,16 +24,6 @@ namespace keepass2android.services { } - public override IntentSender GetAuthIntentSenderForResponse(Context context) - { - Intent intent = new Intent(context, typeof(KeePass)); - return PendingIntent.GetActivity(context, 0, intent, PendingIntentFlags.CancelCurrent).IntentSender; - } - - public override IntentSender GetAuthIntentSenderForDataset(Context context, string dataset) - { - //TODO implement - return GetAuthIntentSenderForResponse(context); - } + public override IAutofillIntentBuilder IntentBuilder => new Kp2aAutofillIntentBuilder(); } } \ No newline at end of file diff --git a/src/keepass2android/services/Kp2aAutofillIntentBuilder.cs b/src/keepass2android/services/Kp2aAutofillIntentBuilder.cs new file mode 100644 index 00000000..d5c10b9c --- /dev/null +++ b/src/keepass2android/services/Kp2aAutofillIntentBuilder.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using keepass2android.services.AutofillBase; + +namespace keepass2android.services +{ + class Kp2aAutofillIntentBuilder: IAutofillIntentBuilder + { + + public IntentSender GetAuthIntentSenderForResponse(Context context, string query) + { + Intent intent = new Intent(context, typeof(KeePass)); + return PendingIntent.GetActivity(context, 0, intent, PendingIntentFlags.CancelCurrent).IntentSender; + } + + public IntentSender GetAuthIntentSenderForDataset(Context context, string dataset) + { + //TODO implement + //return GetAuthIntentSenderForResponse(context, null); + throw new NotImplementedException(); + } + + public Intent GetRestartAppIntent(Context context) + { + var intent = new Intent(context, typeof(FileSelectActivity)); + intent.AddFlags(ActivityFlags.ForwardResult); + return intent; + } + } +} \ No newline at end of file