start working on Oreo AutofillService (issue #9):
* upgraded target version to 26 * added service, parses autofill structure but does not yet retrieve/fill passwords
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -153,3 +153,4 @@ intermediates
|
||||
/src/java/Kp2aAccServiceLib/app/app.iml
|
||||
/src/java/Kp2aAccServiceLib/gradle
|
||||
adbprompt.ps1
|
||||
/src/java/KP2ASoftkeyboard_AS/build/android-profile/*.rawproto
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<RootNamespace>AndroidFileChooserBinding</RootNamespace>
|
||||
<AssemblyName>AndroidFileChooserBinding</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<AssemblyName>JavaFileStorageBindings</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<RootNamespace>KP2AKdbLibraryBinding</RootNamespace>
|
||||
<AssemblyName>KP2AKdbLibraryBinding</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27004.2009
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}"
|
||||
EndProject
|
||||
@@ -27,6 +27,12 @@ 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
|
||||
@@ -283,10 +289,97 @@ 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
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {2B48EDA2-ABCE-4DB5-A609-DFDF5FAAE767}
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
Policies = $0
|
||||
$0.DotNetNamingPolicy = $1
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
|
||||
<AndroidResgenClass>Resource</AndroidResgenClass>
|
||||
<AssemblyName>KeePassLib2Android</AssemblyName>
|
||||
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<NuGetPackageImportStamp>8482b288</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>true</AndroidUseLatestPlatformSdk>
|
||||
<NuGetPackageImportStamp>06ffb71c</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
|
||||
<AssemblyName>Kp2aKeyboardBinding</AssemblyName>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<AssemblyName>PluginSdkBinding</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -53,8 +53,8 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<LibraryProjectZip Include="..\java\Keepass2AndroidPluginSDK2\app\build\outputs\aar\app-debug.aar">
|
||||
<Link>Jars\app-debug.aar</Link>
|
||||
<LibraryProjectZip Include="..\java\Keepass2AndroidPluginSDK2\app\build\outputs\aar\Keepass2AndroidPluginSDK2-debug.aar">
|
||||
<Link>Jars\Keepass2AndroidPluginSDK2-debug.aar</Link>
|
||||
</LibraryProjectZip>
|
||||
<None Include="Jars\AboutJars.txt" />
|
||||
<None Include="Additions\AboutAdditions.txt" />
|
||||
|
||||
Submodule src/SamsungPass updated: 95bc88e182...53d6fee0e2
@@ -13,7 +13,7 @@
|
||||
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<AssemblyName>ZlibAndroid</AssemblyName>
|
||||
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
||||
@@ -5,7 +5,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.2'
|
||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Mon May 22 10:43:15 CEST 2017
|
||||
#Mon Dec 18 11:13:13 CET 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
apply plugin: 'com.android.library'
|
||||
android {
|
||||
compileSdkVersion 'Google Inc.:Google APIs:23'
|
||||
buildToolsVersion '23.0.1'
|
||||
buildToolsVersion '26.0.2'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 8
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
</application>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
@@ -4,7 +4,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.2.3'
|
||||
classpath 'com.android.tools.build:gradle:2.2.1'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Wed Apr 10 15:27:10 PDT 2013
|
||||
#Mon Dec 18 11:08:40 CET 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
|
||||
|
||||
@@ -1030,4 +1030,7 @@ Initial public release
|
||||
<string name="ClearClipboardWarning">Make sure this works on your system and consider using the built-in keyboard if not.</string>
|
||||
<string name="PluginDescription">Description provided by the plugin:</string>
|
||||
|
||||
<string name="autofill_sign_in_prompt">Fill with Keepass2Android</string>
|
||||
<string name="invalid_link_association">Could not associate web domain %1$s with app %2$s</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
<AssemblyName>keepass2android</AssemblyName>
|
||||
<newfilesearch>OnLoad</newfilesearch>
|
||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
|
||||
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<MandroidI18n />
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
<AndroidUseLatestPlatformSdk>true</AndroidUseLatestPlatformSdk>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<NuGetPackageImportStamp>9e78b013</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
@@ -41,10 +41,12 @@
|
||||
<AndroidSupportedAbis>armeabi,armeabi-v7a,x86</AndroidSupportedAbis>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
|
||||
<BundleAssemblies>False</BundleAssemblies>
|
||||
<BundleAssemblies>false</BundleAssemblies>
|
||||
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi>
|
||||
<AndroidEnableMultiDex>false</AndroidEnableMultiDex>
|
||||
<EnableProguard>true</EnableProguard>
|
||||
<AotAssemblies>false</AotAssemblies>
|
||||
<EnableLLVM>false</EnableLLVM>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
@@ -185,6 +187,16 @@
|
||||
<Compile Include="fileselect\FileDbHelper.cs" />
|
||||
<Compile Include="search\SearchProvider.cs" />
|
||||
<Compile Include="SelectStorageLocationActivity.cs" />
|
||||
<Compile Include="services\AutofillBase\AutofillFieldMetadata.cs" />
|
||||
<Compile Include="services\AutofillBase\AutofillFieldMetadataCollection.cs" />
|
||||
<Compile Include="services\AutofillBase\AutofillHelper.cs" />
|
||||
<Compile Include="services\AutofillBase\AutofillServiceBase.cs" />
|
||||
<Compile Include="services\AutofillBase\CommonUtil.cs" />
|
||||
<Compile Include="services\AutofillBase\Kp2aDigitalAssetLinksDataSource.cs" />
|
||||
<Compile Include="services\AutofillBase\model\FilledAutofillField.cs" />
|
||||
<Compile Include="services\AutofillBase\model\FilledAutofillFieldCollection.cs" />
|
||||
<Compile Include="services\AutofillBase\StructureParser.cs" />
|
||||
<Compile Include="services\Kp2aAutofillService.cs" />
|
||||
<Compile Include="services\OngoingNotificationsService.cs" />
|
||||
<Compile Include="settings\Argon2Preference.cs" />
|
||||
<Compile Include="settings\DatabaseSettingsActivity.cs" />
|
||||
@@ -1723,6 +1735,12 @@
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_picture.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\autofillservice.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\layout\autofill_service_list_item.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" />
|
||||
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using Android.App.Assist;
|
||||
using Android.Service.Autofill;
|
||||
using Android.Views;
|
||||
using Android.Views.Autofill;
|
||||
|
||||
namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
/// <summary>
|
||||
/// A stripped down version of a {@link ViewNode} that contains only autofill-relevant metadata. It
|
||||
/// also contains a {@code mSaveType} flag that is calculated based on the {@link ViewNode}]'s
|
||||
/// autofill hints.
|
||||
/// </summary>
|
||||
public class AutofillFieldMetadata
|
||||
{
|
||||
public SaveDataType SaveType { get; set; }
|
||||
|
||||
public string[] AutofillHints { get; set; }
|
||||
|
||||
public AutofillId AutofillId { get; }
|
||||
public AutofillType AutofillType { get; }
|
||||
string[] AutofillOptions { get; }
|
||||
public bool Focused { get; }
|
||||
|
||||
public AutofillFieldMetadata(AssistStructure.ViewNode view)
|
||||
{
|
||||
AutofillId = view.AutofillId;
|
||||
AutofillType = view.AutofillType;
|
||||
AutofillOptions = view.GetAutofillOptions();
|
||||
Focused = view.IsFocused;
|
||||
//TODO port and use AutoFillHints
|
||||
SetHints(AutofillHelper.FilterForSupportedHints(view.GetAutofillHints()));
|
||||
}
|
||||
|
||||
void SetHints(string[] value)
|
||||
{
|
||||
AutofillHints = value;
|
||||
UpdateSaveTypeFromHints();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When the ViewNode is a list that the user needs to choose a string from (i.e. a
|
||||
/// spinner), this is called to return the index of a specific item in the list.
|
||||
/// </summary>
|
||||
/// <returns>The autofill option index.</returns>
|
||||
/// <param name="value">Value.</param>
|
||||
public int GetAutofillOptionIndex(String value)
|
||||
{
|
||||
for (int i = 0; i < AutofillOptions.Length; i++)
|
||||
{
|
||||
if (AutofillOptions[i].Equals(value))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void UpdateSaveTypeFromHints()
|
||||
{
|
||||
SaveType = 0;
|
||||
if (AutofillHints == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var hint in AutofillHints)
|
||||
{
|
||||
switch (hint)
|
||||
{
|
||||
case View.AutofillHintCreditCardExpirationDate:
|
||||
case View.AutofillHintCreditCardExpirationDay:
|
||||
case View.AutofillHintCreditCardExpirationMonth:
|
||||
case View.AutofillHintCreditCardExpirationYear:
|
||||
case View.AutofillHintCreditCardNumber:
|
||||
case View.AutofillHintCreditCardSecurityCode:
|
||||
SaveType |= SaveDataType.CreditCard;
|
||||
break;
|
||||
case View.AutofillHintEmailAddress:
|
||||
SaveType |= SaveDataType.EmailAddress;
|
||||
break;
|
||||
case View.AutofillHintPhone:
|
||||
case View.AutofillHintName:
|
||||
SaveType |= SaveDataType.Generic;
|
||||
break;
|
||||
case View.AutofillHintPassword:
|
||||
SaveType |= SaveDataType.Password;
|
||||
SaveType &= ~SaveDataType.EmailAddress;
|
||||
SaveType &= ~SaveDataType.Username;
|
||||
break;
|
||||
case View.AutofillHintPostalAddress:
|
||||
case View.AutofillHintPostalCode:
|
||||
SaveType |= SaveDataType.Address;
|
||||
break;
|
||||
case View.AutofillHintUsername:
|
||||
SaveType |= SaveDataType.Username;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Android.Service.Autofill;
|
||||
using Android.Views.Autofill;
|
||||
|
||||
namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Data structure that stores a collection of AutofillFieldMetadatas. Contains all of the
|
||||
/// client's View hierarchy autofill-relevant metadata.
|
||||
/// </summary>
|
||||
public class AutofillFieldMetadataCollection
|
||||
{
|
||||
List<AutofillId> AutofillIds = new List<AutofillId>();
|
||||
Dictionary<string, List<keepass2android.services.AutofillBase.AutofillFieldMetadata>> AutofillHintsToFieldsMap = new Dictionary<string, List<keepass2android.services.AutofillBase.AutofillFieldMetadata>>();
|
||||
public List<string> AllAutofillHints { get; }
|
||||
public List<string> FocusedAutofillHints { get; }
|
||||
int Size = 0;
|
||||
public SaveDataType SaveType { get; set; }
|
||||
|
||||
public AutofillFieldMetadataCollection()
|
||||
{
|
||||
SaveType = 0;
|
||||
FocusedAutofillHints = new List<string>();
|
||||
AllAutofillHints = new List<string>();
|
||||
}
|
||||
|
||||
public void Add(keepass2android.services.AutofillBase.AutofillFieldMetadata autofillFieldMetadata)
|
||||
{
|
||||
SaveType |= autofillFieldMetadata.SaveType;
|
||||
Size++;
|
||||
AutofillIds.Add(autofillFieldMetadata.AutofillId);
|
||||
var hintsList = autofillFieldMetadata.AutofillHints;
|
||||
AllAutofillHints.AddRange(hintsList);
|
||||
if (autofillFieldMetadata.Focused)
|
||||
{
|
||||
FocusedAutofillHints.AddRange(hintsList);
|
||||
}
|
||||
foreach (var hint in autofillFieldMetadata.AutofillHints)
|
||||
{
|
||||
if (!AutofillHintsToFieldsMap.ContainsKey(hint))
|
||||
{
|
||||
AutofillHintsToFieldsMap.Add(hint, new List<keepass2android.services.AutofillBase.AutofillFieldMetadata>());
|
||||
}
|
||||
AutofillHintsToFieldsMap[hint].Add(autofillFieldMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
public AutofillId[] GetAutofillIds()
|
||||
{
|
||||
return AutofillIds.ToArray();
|
||||
}
|
||||
|
||||
public List<keepass2android.services.AutofillBase.AutofillFieldMetadata> GetFieldsForHint(String hint)
|
||||
{
|
||||
return AutofillHintsToFieldsMap[hint];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
151
src/keepass2android/services/AutofillBase/AutofillHelper.cs
Normal file
151
src/keepass2android/services/AutofillBase/AutofillHelper.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Android.Content;
|
||||
using Android.Service.Autofill;
|
||||
using Android.Util;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using FilledAutofillFieldCollection = keepass2android.services.AutofillBase.model.FilledAutofillFieldCollection;
|
||||
|
||||
//TODO compare port
|
||||
namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a class containing helper methods for building Autofill Datasets and Responses.
|
||||
/// </summary>
|
||||
public class AutofillHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps autofill data in a LoginCredential Dataset object which can then be sent back to the
|
||||
/// client View.
|
||||
/// </summary>
|
||||
/// <returns>The dataset.</returns>
|
||||
/// <param name="context">Context.</param>
|
||||
/// <param name="autofillFields">Autofill fields.</param>
|
||||
/// <param name="filledAutofillFieldCollection">Filled autofill field collection.</param>
|
||||
/// <param name="datasetAuth">If set to <c>true</c> dataset auth.</param>
|
||||
public static Dataset NewDataset(Context context,
|
||||
keepass2android.services.AutofillBase.AutofillFieldMetadataCollection autofillFields, FilledAutofillFieldCollection filledAutofillFieldCollection, bool datasetAuth, IAutofillIntentBuilder intentBuilder)
|
||||
{
|
||||
var datasetName = filledAutofillFieldCollection.DatasetName;
|
||||
if (datasetName != null)
|
||||
{
|
||||
Dataset.Builder datasetBuilder;
|
||||
if (datasetAuth)
|
||||
{
|
||||
datasetBuilder = new Dataset.Builder
|
||||
(NewRemoteViews(context.PackageName, datasetName,
|
||||
Resource.Drawable.ic_launcher));
|
||||
IntentSender sender = intentBuilder.GetAuthIntentSenderForDataset(context, datasetName);
|
||||
datasetBuilder.SetAuthentication(sender);
|
||||
}
|
||||
else
|
||||
{
|
||||
datasetBuilder = new Dataset.Builder
|
||||
(NewRemoteViews(context.PackageName, datasetName,
|
||||
Resource.Drawable.ic_launcher));
|
||||
}
|
||||
var setValueAtLeastOnce = filledAutofillFieldCollection.ApplyToFields(autofillFields, datasetBuilder);
|
||||
if (setValueAtLeastOnce)
|
||||
{
|
||||
return datasetBuilder.Build();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RemoteViews NewRemoteViews(string packageName, string remoteViewsText,int drawableId)
|
||||
{
|
||||
RemoteViews presentation = new RemoteViews(packageName, Resource.Layout.autofill_service_list_item);
|
||||
presentation.SetTextViewText(Resource.Id.text, remoteViewsText);
|
||||
presentation.SetImageViewResource(Resource.Id.icon, drawableId);
|
||||
return presentation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps autofill data in a Response object (essentially a series of Datasets) which can then
|
||||
/// be sent back to the client View.
|
||||
/// </summary>
|
||||
/// <returns>The response.</returns>
|
||||
/// <param name="context">Context.</param>
|
||||
/// <param name="datasetAuth">If set to <c>true</c> dataset auth.</param>
|
||||
/// <param name="autofillFields">Autofill fields.</param>
|
||||
/// <param name="clientFormDataMap">Client form data map.</param>
|
||||
/// <param name="intentBuilder"></param>
|
||||
public static FillResponse NewResponse(Context context, bool datasetAuth, keepass2android.services.AutofillBase.AutofillFieldMetadataCollection autofillFields, Dictionary<string, FilledAutofillFieldCollection> clientFormDataMap, IAutofillIntentBuilder intentBuilder)
|
||||
{
|
||||
var responseBuilder = new FillResponse.Builder();
|
||||
if (clientFormDataMap != null)
|
||||
{
|
||||
var datasetNames = clientFormDataMap.Keys;
|
||||
foreach (var datasetName in datasetNames)
|
||||
{
|
||||
var filledAutofillFieldCollection = clientFormDataMap[datasetName];
|
||||
if (filledAutofillFieldCollection != null)
|
||||
{
|
||||
var dataset = NewDataset(context, autofillFields, filledAutofillFieldCollection, datasetAuth, intentBuilder);
|
||||
if (dataset != null)
|
||||
{
|
||||
responseBuilder.AddDataset(dataset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (autofillFields.SaveType != 0)
|
||||
{
|
||||
var autofillIds = autofillFields.GetAutofillIds();
|
||||
responseBuilder.SetSaveInfo
|
||||
(new SaveInfo.Builder(autofillFields.SaveType, autofillIds).Build());
|
||||
return responseBuilder.Build();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Debug(CommonUtil.Tag, "These fields are not meant to be saved by autofill.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] FilterForSupportedHints(string[] hints)
|
||||
{
|
||||
var filteredHints = new string[hints.Length];
|
||||
int i = 0;
|
||||
foreach (var hint in hints)
|
||||
{
|
||||
if (IsValidHint(hint))
|
||||
{
|
||||
filteredHints[i++] = hint;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Debug(CommonUtil.Tag, "Invalid autofill hint: " + hint);
|
||||
}
|
||||
}
|
||||
var finalFilteredHints = new string[i];
|
||||
Array.Copy(filteredHints, 0, finalFilteredHints, 0, i);
|
||||
return finalFilteredHints;
|
||||
}
|
||||
|
||||
public static bool IsValidHint(String hint)
|
||||
{
|
||||
switch (hint)
|
||||
{
|
||||
case View.AutofillHintCreditCardExpirationDate:
|
||||
case View.AutofillHintCreditCardExpirationDay:
|
||||
case View.AutofillHintCreditCardExpirationMonth:
|
||||
case View.AutofillHintCreditCardExpirationYear:
|
||||
case View.AutofillHintCreditCardNumber:
|
||||
case View.AutofillHintCreditCardSecurityCode:
|
||||
case View.AutofillHintEmailAddress:
|
||||
case View.AutofillHintPhone:
|
||||
case View.AutofillHintName:
|
||||
case View.AutofillHintPassword:
|
||||
case View.AutofillHintPostalAddress:
|
||||
case View.AutofillHintPostalCode:
|
||||
case View.AutofillHintUsername:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
101
src/keepass2android/services/AutofillBase/AutofillServiceBase.cs
Normal file
101
src/keepass2android/services/AutofillBase/AutofillServiceBase.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Service.Autofill;
|
||||
using Android.Util;
|
||||
|
||||
namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
public interface IAutofillIntentBuilder
|
||||
{
|
||||
IntentSender GetAuthIntentSenderForResponse(Context context);
|
||||
IntentSender GetAuthIntentSenderForDataset(Context context, string dataset);
|
||||
}
|
||||
|
||||
public abstract class AutofillServiceBase: AutofillService, IAutofillIntentBuilder
|
||||
{
|
||||
public AutofillServiceBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public AutofillServiceBase(IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override void OnFillRequest(FillRequest request, CancellationSignal cancellationSignal, FillCallback callback)
|
||||
{
|
||||
Log.Debug(CommonUtil.Tag, "onFillRequest");
|
||||
var structure = request.FillContexts[request.FillContexts.Count - 1].Structure;
|
||||
|
||||
//TODO package signature verification?
|
||||
|
||||
var clientState = request.ClientState;
|
||||
Log.Debug(CommonUtil.Tag, "onFillRequest(): data=" + CommonUtil.BundleToString(clientState));
|
||||
|
||||
|
||||
cancellationSignal.CancelEvent += (sender, e) => {
|
||||
Log.Warn(CommonUtil.Tag, "Cancel autofill not implemented yet.");
|
||||
};
|
||||
// Parse AutoFill data in Activity
|
||||
var parser = new StructureParser(this, structure);
|
||||
try
|
||||
{
|
||||
parser.ParseForFill();
|
||||
}
|
||||
catch (Java.Lang.SecurityException e)
|
||||
{
|
||||
Log.Warn(CommonUtil.Tag, "Security exception handling request");
|
||||
callback.OnFailure(e.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
keepass2android.services.AutofillBase.AutofillFieldMetadataCollection autofillFields = parser.AutofillFields;
|
||||
var responseBuilder = new FillResponse.Builder();
|
||||
// Check user's settings for authenticating Responses and Datasets.
|
||||
bool responseAuth = true;
|
||||
var autofillIds = autofillFields.GetAutofillIds();
|
||||
if (responseAuth && autofillIds.Length != 0)
|
||||
{
|
||||
// If the entire Autofill Response is authenticated, AuthActivity is used
|
||||
// to generate Response.
|
||||
var sender = GetAuthIntentSenderForResponse(this);
|
||||
var presentation = keepass2android.services.AutofillBase.AutofillHelper
|
||||
.NewRemoteViews(PackageName, GetString(Resource.String.autofill_sign_in_prompt),
|
||||
Resource.Drawable.ic_launcher);
|
||||
responseBuilder
|
||||
.SetAuthentication(autofillIds, sender, presentation);
|
||||
callback.OnSuccess(responseBuilder.Build());
|
||||
}
|
||||
else
|
||||
{
|
||||
var datasetAuth = true;
|
||||
var response = keepass2android.services.AutofillBase.AutofillHelper.NewResponse(this, datasetAuth, autofillFields, null, this);
|
||||
callback.OnSuccess(response);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSaveRequest(SaveRequest request, SaveCallback callback)
|
||||
{
|
||||
//TODO implement
|
||||
callback.OnFailure("not implemented");
|
||||
}
|
||||
|
||||
|
||||
public override void OnConnected()
|
||||
{
|
||||
Log.Debug(CommonUtil.Tag, "onConnected");
|
||||
}
|
||||
|
||||
public override void OnDisconnected()
|
||||
{
|
||||
Log.Debug(CommonUtil.Tag, "onDisconnected");
|
||||
}
|
||||
|
||||
public abstract IntentSender GetAuthIntentSenderForResponse(Context context);
|
||||
public abstract IntentSender GetAuthIntentSenderForDataset(Context context, string dataset);
|
||||
}
|
||||
}
|
||||
47
src/keepass2android/services/AutofillBase/CommonUtil.cs
Normal file
47
src/keepass2android/services/AutofillBase/CommonUtil.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Android.OS;
|
||||
using Java.Util;
|
||||
|
||||
namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
public class CommonUtil
|
||||
{
|
||||
public const string Tag = "Kp2aAutofill";
|
||||
public const bool Debug = true;
|
||||
public const string EXTRA_DATASET_NAME = "dataset_name";
|
||||
public const string EXTRA_FOR_RESPONSE = "for_response";
|
||||
|
||||
static void BundleToString(StringBuilder builder, Bundle data)
|
||||
{
|
||||
var keySet = data.KeySet();
|
||||
builder.Append("[Bundle with ").Append(keySet.Count).Append(" keys:");
|
||||
foreach (var key in keySet)
|
||||
{
|
||||
builder.Append(' ').Append(key).Append('=');
|
||||
Object value = data.Get(key);
|
||||
if (value is Bundle)
|
||||
{
|
||||
BundleToString(builder, (Bundle)value);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append((value is Object[])
|
||||
? Arrays.ToString((bool[])value) : value);
|
||||
}
|
||||
}
|
||||
builder.Append(']');
|
||||
}
|
||||
|
||||
public static string BundleToString(Bundle data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
return "N/A";
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
BundleToString(builder, data);
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Android.Content;
|
||||
|
||||
namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
|
||||
internal class Kp2aDigitalAssetLinksDataSource
|
||||
{
|
||||
private static Kp2aDigitalAssetLinksDataSource instance;
|
||||
|
||||
private Kp2aDigitalAssetLinksDataSource() { }
|
||||
|
||||
public static Kp2aDigitalAssetLinksDataSource Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = new Kp2aDigitalAssetLinksDataSource();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid(Context context, string webDomain, string packageName)
|
||||
{
|
||||
//TODO implement
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
115
src/keepass2android/services/AutofillBase/StructureParser.cs
Normal file
115
src/keepass2android/services/AutofillBase/StructureParser.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using Android.App.Assist;
|
||||
using Android.Content;
|
||||
using Android.Util;
|
||||
using FilledAutofillFieldCollection = keepass2android.services.AutofillBase.model.FilledAutofillFieldCollection;
|
||||
|
||||
namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Parser for an AssistStructure object. This is invoked when the Autofill Service receives an
|
||||
/// AssistStructure from the client Activity, representing its View hierarchy. In this sample, it
|
||||
/// parses the hierarchy and collects autofill metadata from {@link ViewNode}s along the way.
|
||||
/// </summary>
|
||||
public sealed class StructureParser
|
||||
{
|
||||
public Context mContext { get; }
|
||||
public keepass2android.services.AutofillBase.AutofillFieldMetadataCollection AutofillFields { get; set; }
|
||||
AssistStructure Structure;
|
||||
public FilledAutofillFieldCollection ClientFormData { get; set; }
|
||||
|
||||
public StructureParser(Context context, AssistStructure structure)
|
||||
{
|
||||
mContext = context;
|
||||
Structure = structure;
|
||||
AutofillFields = new keepass2android.services.AutofillBase.AutofillFieldMetadataCollection();
|
||||
}
|
||||
|
||||
public void ParseForFill()
|
||||
{
|
||||
Parse(true);
|
||||
}
|
||||
|
||||
public void ParseForSave()
|
||||
{
|
||||
Parse(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Traverse AssistStructure and add ViewNode metadata to a flat list.
|
||||
/// </summary>
|
||||
/// <returns>The parse.</returns>
|
||||
/// <param name="forFill">If set to <c>true</c> for fill.</param>
|
||||
void Parse(bool forFill)
|
||||
{
|
||||
Log.Debug(keepass2android.services.AutofillBase.CommonUtil.Tag, "Parsing structure for " + Structure.ActivityComponent);
|
||||
var nodes = Structure.WindowNodeCount;
|
||||
ClientFormData = new FilledAutofillFieldCollection();
|
||||
String webDomain = null;
|
||||
for (int i = 0; i < nodes; i++)
|
||||
{
|
||||
var node = Structure.GetWindowNodeAt(i);
|
||||
var view = node.RootViewNode;
|
||||
ParseLocked(forFill, view, ref webDomain);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(webDomain))
|
||||
{
|
||||
String packageName = Structure.ActivityComponent.PackageName;
|
||||
bool valid = Kp2aDigitalAssetLinksDataSource.Instance.IsValid(mContext, webDomain, packageName);
|
||||
if (!valid)
|
||||
{
|
||||
throw new Java.Lang.SecurityException(mContext.GetString(
|
||||
Resource.String.invalid_link_association, webDomain, packageName));
|
||||
}
|
||||
Log.Debug(keepass2android.services.AutofillBase.CommonUtil.Tag, $"Domain {webDomain} is valid for {packageName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Debug(keepass2android.services.AutofillBase.CommonUtil.Tag, "no web domain");
|
||||
}
|
||||
}
|
||||
|
||||
void ParseLocked(bool forFill, AssistStructure.ViewNode viewNode, ref string validWebdomain)
|
||||
{
|
||||
String webDomain = viewNode.WebDomain;
|
||||
if (webDomain != null)
|
||||
{
|
||||
Log.Debug(keepass2android.services.AutofillBase.CommonUtil.Tag, $"child web domain: {webDomain}");
|
||||
if (!string.IsNullOrEmpty(validWebdomain))
|
||||
{
|
||||
if (webDomain == validWebdomain)
|
||||
{
|
||||
throw new Java.Lang.SecurityException($"Found multiple web domains: valid= {validWebdomain}, child={webDomain}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
validWebdomain = webDomain;
|
||||
}
|
||||
}
|
||||
|
||||
if (viewNode.GetAutofillHints() != null && viewNode.GetAutofillHints().Length > 0)
|
||||
{
|
||||
if (forFill)
|
||||
{
|
||||
AutofillFields.Add(new keepass2android.services.AutofillBase.AutofillFieldMetadata(viewNode));
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO implement
|
||||
throw new NotImplementedException("TODO: Port and use AutoFill hints");
|
||||
//ClientFormData.Add(new FilledAutofillField(viewNode));
|
||||
}
|
||||
}
|
||||
var childrenSize = viewNode.ChildCount;
|
||||
if (childrenSize > 0)
|
||||
{
|
||||
for (int i = 0; i < childrenSize; i++)
|
||||
{
|
||||
ParseLocked(forFill, viewNode.GetChildAt(i), ref validWebdomain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using Android.App.Assist;
|
||||
using Android.Views.Autofill;
|
||||
|
||||
namespace keepass2android.services.AutofillBase.model
|
||||
{
|
||||
/// <summary>
|
||||
/// JSON serializable data class containing the same data as an {@link AutofillValue}.
|
||||
/// </summary>
|
||||
public class FilledAutofillField
|
||||
{
|
||||
public string TextValue { get; set; }
|
||||
public long? DateValue { get; set; }
|
||||
public bool? ToggleValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Does not need to be serialized into persistent storage, so it's not exposed.
|
||||
/// </summary>
|
||||
/// <value>The autofill hints.</value>
|
||||
public string[] AutofillHints { get; set; }
|
||||
|
||||
public FilledAutofillField()
|
||||
{}
|
||||
|
||||
public FilledAutofillField(AssistStructure.ViewNode viewNode)
|
||||
{
|
||||
AutofillHints = AutofillHelper.FilterForSupportedHints(viewNode.GetAutofillHints());
|
||||
|
||||
//TODO port updated FilledAutofillField?
|
||||
AutofillValue autofillValue = viewNode.AutofillValue;
|
||||
if (autofillValue != null)
|
||||
{
|
||||
if (autofillValue.IsList)
|
||||
{
|
||||
string[] autofillOptions = viewNode.GetAutofillOptions();
|
||||
int index = autofillValue.ListValue;
|
||||
if (autofillOptions != null && autofillOptions.Length > 0)
|
||||
{
|
||||
TextValue = autofillOptions[index];
|
||||
}
|
||||
}
|
||||
else if (autofillValue.IsDate)
|
||||
{
|
||||
DateValue = autofillValue.DateValue;
|
||||
}
|
||||
else if (autofillValue.IsText)
|
||||
{
|
||||
// Using toString of AutofillValue.getTextValue in order to save it to
|
||||
// SharedPreferences.
|
||||
TextValue = autofillValue.TextValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNull()
|
||||
{
|
||||
return TextValue == null && DateValue == null && ToggleValue == null;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (this == obj) return true;
|
||||
if (obj == null || GetType() != obj.GetType()) return false;
|
||||
|
||||
FilledAutofillField that = (FilledAutofillField)obj;
|
||||
|
||||
if (TextValue != null ? !TextValue.Equals(that.TextValue) : that.TextValue != null)
|
||||
return false;
|
||||
if (DateValue != null ? !DateValue.Equals(that.DateValue) : that.DateValue != null)
|
||||
return false;
|
||||
return ToggleValue != null ? ToggleValue.Equals(that.ToggleValue) : that.ToggleValue == null;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var result = TextValue != null ? TextValue.GetHashCode() : 0;
|
||||
result = 31 * result + (DateValue != null ? DateValue.GetHashCode() : 0);
|
||||
result = 31 * result + (ToggleValue != null ? ToggleValue.GetHashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
using System.Collections.Generic;
|
||||
using Android.Service.Autofill;
|
||||
using Android.Util;
|
||||
using Android.Views;
|
||||
using Android.Views.Autofill;
|
||||
|
||||
namespace keepass2android.services.AutofillBase.model
|
||||
{
|
||||
/// <summary>
|
||||
/// FilledAutofillFieldCollection is the model that holds all of the data on a client app's page,
|
||||
/// plus the dataset name associated with it.
|
||||
/// </summary>
|
||||
public class FilledAutofillFieldCollection
|
||||
{
|
||||
public Dictionary<string, keepass2android.services.AutofillBase.model.FilledAutofillField> HintMap { get; set; }
|
||||
public string DatasetName { get; set; }
|
||||
|
||||
public FilledAutofillFieldCollection(Dictionary<string, keepass2android.services.AutofillBase.model.FilledAutofillField> hintMap, string datasetName = "")
|
||||
{
|
||||
HintMap = hintMap;
|
||||
DatasetName = datasetName;
|
||||
}
|
||||
|
||||
public FilledAutofillFieldCollection() : this(new Dictionary<string, keepass2android.services.AutofillBase.model.FilledAutofillField>())
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filledAutofillField to the collection, indexed by all of its hints.
|
||||
/// </summary>
|
||||
/// <returns>The add.</returns>
|
||||
/// <param name="filledAutofillField">Filled autofill field.</param>
|
||||
public void Add(keepass2android.services.AutofillBase.model.FilledAutofillField filledAutofillField)
|
||||
{
|
||||
string[] autofillHints = filledAutofillField.AutofillHints;
|
||||
//TODO apply W3C transformation
|
||||
foreach (string hint in autofillHints)
|
||||
{
|
||||
HintMap.Add(hint, filledAutofillField);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates a Dataset.Builder with appropriate values for each AutofillId
|
||||
/// in a AutofillFieldMetadataCollection.
|
||||
///
|
||||
/// In other words, it constructs an autofill Dataset.Builder
|
||||
/// by applying saved values (from this FilledAutofillFieldCollection)
|
||||
/// to Views specified in a AutofillFieldMetadataCollection, which represents the current
|
||||
/// page the user is on.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if to fields was applyed, <c>false</c> otherwise.</returns>
|
||||
/// <param name="autofillFieldMetadataCollection">Autofill field metadata collection.</param>
|
||||
/// <param name="datasetBuilder">Dataset builder.</param>
|
||||
public bool ApplyToFields(AutofillFieldMetadataCollection autofillFieldMetadataCollection,
|
||||
Dataset.Builder datasetBuilder)
|
||||
{
|
||||
bool setValueAtLeastOnce = false;
|
||||
List<string> allHints = autofillFieldMetadataCollection.AllAutofillHints;
|
||||
for (int hintIndex = 0; hintIndex < allHints.Count; hintIndex++)
|
||||
{
|
||||
string hint = allHints[hintIndex];
|
||||
List<AutofillFieldMetadata> fillableAutofillFields = autofillFieldMetadataCollection.GetFieldsForHint(hint);
|
||||
if (fillableAutofillFields == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (int autofillFieldIndex = 0; autofillFieldIndex < fillableAutofillFields.Count; autofillFieldIndex++)
|
||||
{
|
||||
keepass2android.services.AutofillBase.model.FilledAutofillField filledAutofillField = HintMap[hint];
|
||||
if (filledAutofillField == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
AutofillFieldMetadata autofillFieldMetadata = fillableAutofillFields[autofillFieldIndex];
|
||||
var autofillId = autofillFieldMetadata.AutofillId;
|
||||
var autofillType = autofillFieldMetadata.AutofillType;
|
||||
switch (autofillType)
|
||||
{
|
||||
case AutofillType.List:
|
||||
var listValue = autofillFieldMetadata.GetAutofillOptionIndex(filledAutofillField.TextValue);
|
||||
if (listValue != -1)
|
||||
{
|
||||
datasetBuilder.SetValue(autofillId, AutofillValue.ForList(listValue));
|
||||
setValueAtLeastOnce = true;
|
||||
}
|
||||
break;
|
||||
case AutofillType.Date:
|
||||
var dateValue = filledAutofillField.DateValue;
|
||||
datasetBuilder.SetValue(autofillId, AutofillValue.ForDate((long)dateValue));
|
||||
setValueAtLeastOnce = true;
|
||||
break;
|
||||
case AutofillType.Text:
|
||||
var textValue = filledAutofillField.TextValue;
|
||||
if (textValue != null)
|
||||
{
|
||||
datasetBuilder.SetValue(autofillId, AutofillValue.ForText(textValue));
|
||||
setValueAtLeastOnce = true;
|
||||
}
|
||||
break;
|
||||
case AutofillType.Toggle:
|
||||
var toggleValue = filledAutofillField.ToggleValue;
|
||||
if (toggleValue != null)
|
||||
{
|
||||
datasetBuilder.SetValue(autofillId, AutofillValue.ForToggle(toggleValue.Value));
|
||||
setValueAtLeastOnce = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log.Warn(CommonUtil.Tag, "Invalid autofill type - " + autofillType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return setValueAtLeastOnce;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes in a list of autofill hints (`autofillHints`), usually associated with a View or set of
|
||||
/// Views. Returns whether any of the filled fields on the page have at least 1 of these
|
||||
/// `autofillHint`s.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if with hints was helpsed, <c>false</c> otherwise.</returns>
|
||||
/// <param name="autofillHints">Autofill hints.</param>
|
||||
public bool HelpsWithHints(List<string> autofillHints)
|
||||
{
|
||||
for (int i = 0; i < autofillHints.Count; i++)
|
||||
{
|
||||
var autofillHint = autofillHints[i];
|
||||
if (HintMap.ContainsKey(autofillHint) && !HintMap[autofillHint].IsNull())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
38
src/keepass2android/services/Kp2aAutofillService.cs
Normal file
38
src/keepass2android/services/Kp2aAutofillService.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using Android;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Runtime;
|
||||
using AutofillServiceBase = keepass2android.services.AutofillBase.AutofillServiceBase;
|
||||
|
||||
namespace keepass2android.services
|
||||
{
|
||||
[Service(Label = "Keepass2Android Autofill Service", Permission=Manifest.Permission.BindAutofillService)]
|
||||
[IntentFilter(new [] {"android.service.autofill.AutofillService"})]
|
||||
[MetaData("android.autofill", Resource = "@xml/autofillservice")]
|
||||
[Register("keepass2android.services.Kp2aAutofillService")]
|
||||
public class Kp2aAutofillService: AutofillServiceBase
|
||||
{
|
||||
public Kp2aAutofillService()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Kp2aAutofillService(IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Submodule src/netftpandroid updated: 62733d714f...040e8bbe56
Reference in New Issue
Block a user