diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index bafa83ef..ecdf0f19 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,6 +1,10 @@
name: Build keepass2android app
-on: [push, pull_request]
+on:
+ push:
+ branches:
+ - master
+ pull_request:
jobs:
# macos:
@@ -10,16 +14,15 @@ jobs:
# runs-on: macos-12
# steps:
- # - uses: actions/checkout@v3
-
- # - name: Fetch submodules
- # run: git submodule init && git submodule update
+ # - uses: actions/checkout@v4
+ # with:
+ # submodules: true
# - name: Setup Gradle
- # uses: gradle/gradle-build-action@v2
+ # uses: gradle/actions/setup-gradle@v3
# - name: Cache NuGet packages
- # uses: actions/cache@v3
+ # uses: actions/cache@v4
# with:
# path: ~/.nuget/packages
# key: ${{ runner.os }}-nuget-${{ hashFiles('src/**/*.csproj', 'src/**/packages.config') }}
@@ -52,7 +55,7 @@ jobs:
# # $VM_ASSETS/select-xamarin-sdk-v2.sh --mono=6.12 --android=11.2
# - name: Switch to JDK-11
- # uses: actions/setup-java@v3
+ # uses: actions/setup-java@v4
# with:
# java-version: '11'
# distribution: 'temurin'
@@ -82,7 +85,7 @@ jobs:
# make apk Flavor=Net
# - name: Archive production artifacts (net)
- # uses: actions/upload-artifact@v3
+ # uses: actions/upload-artifact@v4
# with:
# name: signed APK ('net' built on ${{ github.job }})
# path: |
@@ -100,7 +103,7 @@ jobs:
# make apk Flavor=NoNet
# - name: Archive production artifacts (nonet)
- # uses: actions/upload-artifact@v3
+ # uses: actions/upload-artifact@v4
# with:
# name: signed APK ('nonet' built on ${{ github.job }})
# path: |
@@ -130,16 +133,15 @@ jobs:
# # Build Artifact of xamarin.android-oss dated 2022-02-16, master branch (= version 12.2.99)
# xamarin_url: https://artprodcus3.artifacts.visualstudio.com/Ad0adf05a-e7d7-4b65-96fe-3f3884d42038/6fd3d886-57a5-4e31-8db7-52a1b47c07a8/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL3hhbWFyaW4vcHJvamVjdElkLzZmZDNkODg2LTU3YTUtNGUzMS04ZGI3LTUyYTFiNDdjMDdhOC9idWlsZElkLzU0OTUzL2FydGlmYWN0TmFtZS9pbnN0YWxsZXJzLXVuc2lnbmVkKy0rTGludXg1/content?format=zip
# steps:
- # - uses: actions/checkout@v3
-
- # - name: Fetch submodules
- # run: git submodule init && git submodule update
+ # - uses: actions/checkout@v4
+ # with:
+ # submodules: true
# - name: Setup Gradle
- # uses: gradle/gradle-build-action@v2
+ # uses: gradle/actions/setup-gradle@v3
# - name: Cache NuGet packages
- # uses: actions/cache@v3
+ # uses: actions/cache@v4
# with:
# path: ~/.nuget/packages
# key: ${{ runner.os }}-nuget-${{ hashFiles('src/**/*.csproj', 'src/**/packages.config') }}
@@ -148,7 +150,7 @@ jobs:
# - name: Cache Xamarin.Android packages
# id: xamarin_cache
- # uses: actions/cache@v3
+ # uses: actions/cache@v4
# with:
# path: ~/xamarin.android-oss
# key: ${{ runner.os }}-xamarin.android-oss-${{ env.xamarin_url }}
@@ -183,7 +185,7 @@ jobs:
# echo "$HOME/xamarin.android-oss/bin/Release/bin" >> $GITHUB_PATH
# - name: Switch to JDK-11
- # uses: actions/setup-java@v3
+ # uses: actions/setup-java@v4
# with:
# java-version: '11'
# distribution: 'temurin'
@@ -217,7 +219,7 @@ jobs:
# make apk Flavor=Net
# - name: Archive production artifacts (net)
- # uses: actions/upload-artifact@v3
+ # uses: actions/upload-artifact@v4
# with:
# name: signed APK ('net' built on ${{ github.job }})
# path: |
@@ -235,7 +237,7 @@ jobs:
# make apk Flavor=NoNet
# - name: Archive production artifacts (nonet)
- # uses: actions/upload-artifact@v3
+ # uses: actions/upload-artifact@v4
# with:
# name: signed APK ('nonet' built on ${{ github.job }})
# path: |
@@ -254,39 +256,38 @@ jobs:
runs-on: windows-2022
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
+ with:
+ submodules: true
- name: Setup Gradle
- uses: gradle/gradle-build-action@v2
+ uses: gradle/actions/setup-gradle@v3
- name: Cache NuGet packages
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('src/**/*.csproj', 'src/**/packages.config') }}
restore-keys: |
${{ runner.os }}-nuget-
- - name: Fetch submodules
- run: git submodule init && git submodule update
-
# Workaround an issue when building on windows-2022. Error was
# D8 : OpenJDK 64-Bit Server VM warning : INFO: os::commit_memory(0x00000000ae400000, 330301440, 0) failed; error='The paging file is too small for this operation to complete' (DOS error/errno=1455) [D:\a\keepass2android\keepass2android\src\keepass2android\keepass2android-app.csproj]
# C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.D8.targets(81,5): error MSB6006: "java.exe" exited with code 1. [D:\a\keepass2android\keepass2android\src\keepass2android\keepass2android-app.csproj]
- name: Configure Pagefile
- uses: al-cheb/configure-pagefile-action@v1.3
+ uses: al-cheb/configure-pagefile-action@a3b6ebd6b634da88790d9c58d4b37a7f4a7b8708 # v1.4
with:
minimum-size: 8GB
- name: Add msbuild to PATH
- uses: microsoft/setup-msbuild@v1.1
+ uses: microsoft/setup-msbuild@v2
# If we want to also have nmake, use this instead
#uses: ilammy/msvc-dev-cmd@v1
- - name: Switch to JDK-11
- uses: actions/setup-java@v3
+ - name: Switch to JDK-17
+ uses: actions/setup-java@v4
with:
- java-version: '11'
+ java-version: '17'
distribution: 'temurin'
- name: Display java version
@@ -320,7 +321,7 @@ jobs:
make apk Flavor=Net
- name: Archive production artifacts (net)
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: signed APK ('net' built on ${{ github.job }})
path: |
@@ -333,7 +334,7 @@ jobs:
run: |
make msbuild Flavor=NoNet
- name: Test Autofill
- working-directory: ./src/Kp2aAutofillParserTest
+ working-directory: ./src/Kp2aAutofillParser.Tests
run: dotnet test
- name: Build APK (nonet)
@@ -341,7 +342,7 @@ jobs:
make apk Flavor=NoNet
- name: Archive production artifacts (nonet)
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: signed APK ('nonet' built on ${{ github.job }})
path: |
diff --git a/.gitignore b/.gitignore
index 57fd4e7e..47b55426 100644
--- a/.gitignore
+++ b/.gitignore
@@ -176,3 +176,5 @@ src/java/Keepass2AndroidPluginSDK2/build/generated/mockable-Google-Inc.-Google-A
/src/ActionViewFilterTest
/docs/gdrive-verification
/src/MegaTest
+*.dtbcache.json
+/src/keepass2android-app/AndroidManifest.xml
diff --git a/Makefile b/Makefile
index eab24163..cd6a01b2 100644
--- a/Makefile
+++ b/Makefile
@@ -120,14 +120,38 @@ ifneq ($(Configuration),)
else
$(warning Configuration environment variable not set.)
endif
+
+DELETE_MANIFEST_LINK :=
+CREATE_MANIFEST_LINK :=
+
+MANIFEST_FILE :=
ifneq ($(Flavor),)
MSBUILD_PARAM += -p:Flavor="$(Flavor)"
+ ifneq ($(Flavor),)
+ ifeq ($(Flavor),Debug)
+ MANIFEST_FILE := AndroidManifest_debug.xml
+ endif
+ ifeq ($(Flavor),Net)
+ MANIFEST_FILE := AndroidManifest_net.xml
+ endif
+ ifeq ($(Flavor),NoNet)
+ MANIFEST_FILE := AndroidManifest_nonet.xml
+ endif
+ ifeq ($(detected_OS),Windows)
+ DELETE_MANIFEST_LINK := @cmd /c del src\keepass2android-app\AndroidManifest.xml
+ CREATE_MANIFEST_LINK := @cmd /c mklink /h src\keepass2android-app\AndroidManifest.xml src\keepass2android-app\Manifests\$(MANIFEST_FILE)
+ else
+ DELETE_MANIFEST_LINK := rm -f src/keepass2android-app/AndroidManifest.xml
+ CREATE_MANIFEST_LINK := ln -f src/keepass2android-app/Manifests/$(MANIFEST_FILE) src/keepass2android-app/AndroidManifest.xml
+ endif
+
+ endif
else
$(warning Flavor environment variable not set.)
endif
ifneq ($(KeyStore),)
- MSBUILD_PARAM += -p:AndroidKeyStore=True -p:AndroidSigningKeyStore="$(KeyStore)" -p:AndroidSigningStorePass=env:MyAndroidSigningStorePass -p:AndroidSigningKeyPass=env:MyAndroidSigningKeyPass
+ MSBUILD_PARAM += -p:AndroidKeyStore=True -p:AndroidSigningKeyStore="$(KeyStore)" -p:AndroidSigningStorePass=env:MyAndroidSigningStorePass -p:AndroidSigningKeyPass=env:MyAndroidSigningKeyPass -p:AndroidSigningKeyAlias="kp2a"
endif
ifeq ($(detected_OS),Windows)
@@ -281,6 +305,11 @@ endif
$(MSBUILD) src/KeePass.sln -t:restore $(MSBUILD_PARAM) -p:RestorePackagesConfig=true
@echo "" > stamp.nuget_$(Flavor)
+manifestlink:
+ $(info Creating hardlink for manifest of Flavor: $(Flavor))
+ $(DELETE_MANIFEST_LINK)
+ $(CREATE_MANIFEST_LINK)
+
#####
src/Kp2aBusinessLogic/Io/DropboxFileStorageKeys.cs:
ifeq ($(detected_OS),Windows)
@@ -289,11 +318,11 @@ else
$(CP) src/Kp2aBusinessLogic/Io/DropboxFileStorageKeysDummy.cs $@
endif
-msbuild: native java nuget src/Kp2aBusinessLogic/Io/DropboxFileStorageKeys.cs
+msbuild: manifestlink native java nuget src/Kp2aBusinessLogic/Io/DropboxFileStorageKeys.cs
$(MSBUILD) src/KeePass.sln -target:keepass2android-app -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -p:BuildProjectReferences=true $(MSBUILD_PARAM) -p:Platform="Any CPU" -m
-apk: msbuild
- $(MSBUILD) src/keepass2android/keepass2android-app.csproj -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -t:SignAndroidPackage $(MSBUILD_PARAM) -p:Platform=AnyCPU -m
+apk: msbuild
+ $(MSBUILD) src/keepass2android-app/keepass2android-app.csproj -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -t:SignAndroidPackage $(MSBUILD_PARAM) -p:Platform=AnyCPU -m
build_all: msbuild
diff --git a/docs/README.md b/docs/README.md
index f860d392..c952b4ad 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,4 +1,4 @@
-
Keepass2Android
+
Keepass2Android
# What is Keepass2Android?
diff --git a/graphics/add_key.svg b/graphics/add_key.svg
new file mode 100644
index 00000000..4a78d492
--- /dev/null
+++ b/graphics/add_key.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/graphics/donate_beer.svg b/graphics/donate_beer.svg
new file mode 100644
index 00000000..129bfccd
--- /dev/null
+++ b/graphics/donate_beer.svg
@@ -0,0 +1,41 @@
+
+
diff --git a/graphics/donate_beer1.svg b/graphics/donate_beer1.svg
new file mode 100644
index 00000000..c2cdb9da
--- /dev/null
+++ b/graphics/donate_beer1.svg
@@ -0,0 +1,40 @@
+
+
diff --git a/src/AndroidFileChooserBinding/Additions/AboutAdditions.txt b/src/AndroidFileChooserBinding/Additions/AboutAdditions.txt
deleted file mode 100644
index 08caee33..00000000
--- a/src/AndroidFileChooserBinding/Additions/AboutAdditions.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-Additions allow you to add arbitrary C# to the generated classes
-before they are compiled. This can be helpful for providing convenience
-methods or adding pure C# classes.
-
-== Adding Methods to Generated Classes ==
-
-Let's say the library being bound has a Rectangle class with a constructor
-that takes an x and y position, and a width and length size. It will look like
-this:
-
-public partial class Rectangle
-{
- public Rectangle (int x, int y, int width, int height)
- {
- // JNI bindings
- }
-}
-
-Imagine we want to add a constructor to this class that takes a Point and
-Size structure instead of 4 ints. We can add a new file called Rectangle.cs
-with a partial class containing our new method:
-
-public partial class Rectangle
-{
- public Rectangle (Point location, Size size) :
- this (location.X, location.Y, size.Width, size.Height)
- {
- }
-}
-
-At compile time, the additions class will be added to the generated class
-and the final assembly will a Rectangle class with both constructors.
-
-
-== Adding C# Classes ==
-
-Another thing that can be done is adding fully C# managed classes to the
-generated library. In the above example, let's assume that there isn't a
-Point class available in Java or our library. The one we create doesn't need
-to interact with Java, so we'll create it like a normal class in C#.
-
-By adding a Point.cs file with this class, it will end up in the binding library:
-
-public class Point
-{
- public int X { get; set; }
- public int Y { get; set; }
-}
\ No newline at end of file
diff --git a/src/AndroidFileChooserBinding/AndroidFileChooserBinding.csproj b/src/AndroidFileChooserBinding/AndroidFileChooserBinding.csproj
index 6c4f56fc..c7147177 100644
--- a/src/AndroidFileChooserBinding/AndroidFileChooserBinding.csproj
+++ b/src/AndroidFileChooserBinding/AndroidFileChooserBinding.csproj
@@ -1,83 +1,16 @@
-
-
+
- Debug
- AnyCPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}
- {10368E6C-D01B-4462-8E8B-01FC667A7035};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Properties
- AndroidFileChooserBinding
- AndroidFileChooserBinding
- 512
- v8.0
- false
- XAJavaInterop1
- class-parse
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- None
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- false
-
-
- bin\ReleaseNoNet\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
- false
- 4
+ net8.0-android
+ 21
+ enable
+ enable
-
-
-
+
+
+
-
+
-
-
- Jars\android-filechooser-release.aar
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 20.0.0.4
- False
-
-
-
+
\ No newline at end of file
diff --git a/src/AndroidFileChooserBinding/Jars/AboutJars.txt b/src/AndroidFileChooserBinding/Jars/AboutJars.txt
deleted file mode 100644
index c359b62f..00000000
--- a/src/AndroidFileChooserBinding/Jars/AboutJars.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-This directory is for Android .jars.
-
-There are 2 types of jars that are supported:
-
-== Input Jar ==
-
-This is the jar that bindings should be generated for.
-
-For example, if you were binding the Google Maps library, this would
-be Google's "maps.jar".
-
-Set the build action for these jars in the properties page to "InputJar".
-
-
-== Reference Jars ==
-
-These are jars that are referenced by the input jar. C# bindings will
-not be created for these jars. These jars will be used to resolve
-types used by the input jar.
-
-NOTE: Do not add "android.jar" as a reference jar. It will be added automatically
-based on the Target Framework selected.
-
-Set the build action for these jars in the properties page to "ReferenceJar".
\ No newline at end of file
diff --git a/src/AndroidFileChooserBinding/Jars/android-support-v4.jar b/src/AndroidFileChooserBinding/Jars/android-support-v4.jar
deleted file mode 100644
index 187bdf48..00000000
Binary files a/src/AndroidFileChooserBinding/Jars/android-support-v4.jar and /dev/null differ
diff --git a/src/AndroidFileChooserBinding/Properties/AssemblyInfo.cs b/src/AndroidFileChooserBinding/Properties/AssemblyInfo.cs
deleted file mode 100644
index b469b65d..00000000
--- a/src/AndroidFileChooserBinding/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Android.App;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("AndroidFileChooserBinding")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("AndroidFileChooserBinding")]
-[assembly: AssemblyCopyright("Copyright © 2013")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/AndroidFileChooserBinding/Transforms/EnumFields.xml b/src/AndroidFileChooserBinding/Transforms/EnumFields.xml
index 22959957..4dddf452 100644
--- a/src/AndroidFileChooserBinding/Transforms/EnumFields.xml
+++ b/src/AndroidFileChooserBinding/Transforms/EnumFields.xml
@@ -1,14 +1,3 @@
-
+
\ No newline at end of file
diff --git a/src/AndroidFileChooserBinding/Transforms/EnumMethods.xml b/src/AndroidFileChooserBinding/Transforms/EnumMethods.xml
index 49216c61..85202262 100644
--- a/src/AndroidFileChooserBinding/Transforms/EnumMethods.xml
+++ b/src/AndroidFileChooserBinding/Transforms/EnumMethods.xml
@@ -1,13 +1,3 @@
-
+
\ No newline at end of file
diff --git a/src/AndroidFileChooserBinding/Transforms/Metadata.xml b/src/AndroidFileChooserBinding/Transforms/Metadata.xml
index ea974e92..e40a4beb 100644
--- a/src/AndroidFileChooserBinding/Transforms/Metadata.xml
+++ b/src/AndroidFileChooserBinding/Transforms/Metadata.xml
@@ -4,19 +4,4 @@
-
diff --git a/src/AndroidFileChooserBinding/packages.config b/src/AndroidFileChooserBinding/packages.config
deleted file mode 100644
index 1508affa..00000000
--- a/src/AndroidFileChooserBinding/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/src/AppCompatV7Binding/Additions/AboutAdditions.txt b/src/AppCompatV7Binding/Additions/AboutAdditions.txt
deleted file mode 100644
index 08caee33..00000000
--- a/src/AppCompatV7Binding/Additions/AboutAdditions.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-Additions allow you to add arbitrary C# to the generated classes
-before they are compiled. This can be helpful for providing convenience
-methods or adding pure C# classes.
-
-== Adding Methods to Generated Classes ==
-
-Let's say the library being bound has a Rectangle class with a constructor
-that takes an x and y position, and a width and length size. It will look like
-this:
-
-public partial class Rectangle
-{
- public Rectangle (int x, int y, int width, int height)
- {
- // JNI bindings
- }
-}
-
-Imagine we want to add a constructor to this class that takes a Point and
-Size structure instead of 4 ints. We can add a new file called Rectangle.cs
-with a partial class containing our new method:
-
-public partial class Rectangle
-{
- public Rectangle (Point location, Size size) :
- this (location.X, location.Y, size.Width, size.Height)
- {
- }
-}
-
-At compile time, the additions class will be added to the generated class
-and the final assembly will a Rectangle class with both constructors.
-
-
-== Adding C# Classes ==
-
-Another thing that can be done is adding fully C# managed classes to the
-generated library. In the above example, let's assume that there isn't a
-Point class available in Java or our library. The one we create doesn't need
-to interact with Java, so we'll create it like a normal class in C#.
-
-By adding a Point.cs file with this class, it will end up in the binding library:
-
-public class Point
-{
- public int X { get; set; }
- public int Y { get; set; }
-}
\ No newline at end of file
diff --git a/src/AppCompatV7Binding/AppCompatV7Binding.csproj b/src/AppCompatV7Binding/AppCompatV7Binding.csproj
deleted file mode 100644
index cea4c5ce..00000000
--- a/src/AppCompatV7Binding/AppCompatV7Binding.csproj
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {23233A28-D74F-4BF8-B4D8-834060840BD7}
- {10368E6C-D01B-4462-8E8B-01FC667A7035};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Properties
- AppCompatV7Binding
- AppCompatV7Binding
- 512
- v2.2
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
- bin\ReleaseNoNet\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/AppCompatV7Binding/Jars/AboutJars.txt b/src/AppCompatV7Binding/Jars/AboutJars.txt
deleted file mode 100644
index c359b62f..00000000
--- a/src/AppCompatV7Binding/Jars/AboutJars.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-This directory is for Android .jars.
-
-There are 2 types of jars that are supported:
-
-== Input Jar ==
-
-This is the jar that bindings should be generated for.
-
-For example, if you were binding the Google Maps library, this would
-be Google's "maps.jar".
-
-Set the build action for these jars in the properties page to "InputJar".
-
-
-== Reference Jars ==
-
-These are jars that are referenced by the input jar. C# bindings will
-not be created for these jars. These jars will be used to resolve
-types used by the input jar.
-
-NOTE: Do not add "android.jar" as a reference jar. It will be added automatically
-based on the Target Framework selected.
-
-Set the build action for these jars in the properties page to "ReferenceJar".
\ No newline at end of file
diff --git a/src/AppCompatV7Binding/Properties/AssemblyInfo.cs b/src/AppCompatV7Binding/Properties/AssemblyInfo.cs
deleted file mode 100644
index 1795c801..00000000
--- a/src/AppCompatV7Binding/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Android.App;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("AppCompatV7Binding")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("AppCompatV7Binding")]
-[assembly: AssemblyCopyright("Copyright © 2013")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/AppCompatV7Binding/Transforms/EnumFields.xml b/src/AppCompatV7Binding/Transforms/EnumFields.xml
deleted file mode 100644
index 22959957..00000000
--- a/src/AppCompatV7Binding/Transforms/EnumFields.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/src/AppCompatV7Binding/Transforms/EnumMethods.xml b/src/AppCompatV7Binding/Transforms/EnumMethods.xml
deleted file mode 100644
index 49216c61..00000000
--- a/src/AppCompatV7Binding/Transforms/EnumMethods.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/src/AppCompatV7Binding/Transforms/Metadata.xml b/src/AppCompatV7Binding/Transforms/Metadata.xml
deleted file mode 100644
index 2587ddc4..00000000
--- a/src/AppCompatV7Binding/Transforms/Metadata.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/src/AppCompatV7Binding/project_appcompatv7.zip b/src/AppCompatV7Binding/project_appcompatv7.zip
deleted file mode 100644
index b18689cc..00000000
Binary files a/src/AppCompatV7Binding/project_appcompatv7.zip and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Additions/AboutAdditions.txt b/src/JavaFileStorageBindings/Additions/AboutAdditions.txt
index 08caee33..2775bd36 100644
--- a/src/JavaFileStorageBindings/Additions/AboutAdditions.txt
+++ b/src/JavaFileStorageBindings/Additions/AboutAdditions.txt
@@ -1,4 +1,4 @@
-Additions allow you to add arbitrary C# to the generated classes
+Additions allow you to add arbitrary C# to the generated classes
before they are compiled. This can be helpful for providing convenience
methods or adding pure C# classes.
@@ -11,9 +11,9 @@ this:
public partial class Rectangle
{
public Rectangle (int x, int y, int width, int height)
- {
- // JNI bindings
- }
+ {
+ // JNI bindings
+ }
}
Imagine we want to add a constructor to this class that takes a Point and
@@ -23,9 +23,9 @@ with a partial class containing our new method:
public partial class Rectangle
{
public Rectangle (Point location, Size size) :
- this (location.X, location.Y, size.Width, size.Height)
- {
- }
+ this (location.X, location.Y, size.Width, size.Height)
+ {
+ }
}
At compile time, the additions class will be added to the generated class
@@ -44,5 +44,5 @@ By adding a Point.cs file with this class, it will end up in the binding library
public class Point
{
public int X { get; set; }
- public int Y { get; set; }
+ public int Y { get; set; }
}
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/GooglePlayServicesFroyoLib.dll b/src/JavaFileStorageBindings/GooglePlayServicesFroyoLib.dll
deleted file mode 100644
index dd9ed4ac..00000000
Binary files a/src/JavaFileStorageBindings/GooglePlayServicesFroyoLib.dll and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/AboutJars.txt b/src/JavaFileStorageBindings/Jars/AboutJars.txt
deleted file mode 100644
index c359b62f..00000000
--- a/src/JavaFileStorageBindings/Jars/AboutJars.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-This directory is for Android .jars.
-
-There are 2 types of jars that are supported:
-
-== Input Jar ==
-
-This is the jar that bindings should be generated for.
-
-For example, if you were binding the Google Maps library, this would
-be Google's "maps.jar".
-
-Set the build action for these jars in the properties page to "InputJar".
-
-
-== Reference Jars ==
-
-These are jars that are referenced by the input jar. C# bindings will
-not be created for these jars. These jars will be used to resolve
-types used by the input jar.
-
-NOTE: Do not add "android.jar" as a reference jar. It will be added automatically
-based on the Target Framework selected.
-
-Set the build action for these jars in the properties page to "ReferenceJar".
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/AndroidManifest.xml b/src/JavaFileStorageBindings/Jars/adal-1.1.19/AndroidManifest.xml
deleted file mode 100644
index 903dfc4d..00000000
--- a/src/JavaFileStorageBindings/Jars/adal-1.1.19/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/R.txt b/src/JavaFileStorageBindings/Jars/adal-1.1.19/R.txt
deleted file mode 100644
index 7578dbb0..00000000
--- a/src/JavaFileStorageBindings/Jars/adal-1.1.19/R.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-int dimen activity_horizontal_margin 0x7f030000
-int dimen activity_vertical_margin 0x7f030001
-int id LinearLayout1 0x7f060004
-int id com_microsoft_aad_adal_editDummyText 0x7f060002
-int id com_microsoft_aad_adal_progressBar 0x7f060003
-int id com_microsoft_aad_adal_webView1 0x7f060001
-int id editPassword 0x7f060006
-int id editUserName 0x7f060005
-int id webView1 0x7f060000
-int layout activity_authentication 0x7f020000
-int layout dialog_authentication 0x7f020001
-int layout http_auth_dialog 0x7f020002
-int string app_loading 0x7f040000
-int string broker_processing 0x7f040001
-int string http_auth_dialog_cancel 0x7f040006
-int string http_auth_dialog_login 0x7f040005
-int string http_auth_dialog_password 0x7f040003
-int string http_auth_dialog_title 0x7f040004
-int string http_auth_dialog_username 0x7f040002
-int style AppBaseTheme 0x7f050000
-int style AppTheme 0x7f050001
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/classes-adal.jar b/src/JavaFileStorageBindings/Jars/adal-1.1.19/classes-adal.jar
deleted file mode 100644
index 40260d29..00000000
Binary files a/src/JavaFileStorageBindings/Jars/adal-1.1.19/classes-adal.jar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/layout/activity_authentication.xml b/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/layout/activity_authentication.xml
deleted file mode 100644
index 76856e6d..00000000
--- a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/layout/activity_authentication.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/layout/dialog_authentication.xml b/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/layout/dialog_authentication.xml
deleted file mode 100644
index 52fe6909..00000000
--- a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/layout/dialog_authentication.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/layout/http_auth_dialog.xml b/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/layout/http_auth_dialog.xml
deleted file mode 100644
index 3b0c713b..00000000
--- a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/layout/http_auth_dialog.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values-sw600dp/dimens.xml b/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values-sw600dp/dimens.xml
deleted file mode 100644
index 44f01db7..00000000
--- a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values-sw600dp/dimens.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values-sw720dp-land/dimens.xml b/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values-sw720dp-land/dimens.xml
deleted file mode 100644
index 61e3fa8f..00000000
--- a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values-sw720dp-land/dimens.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- 128dp
-
-
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values-v11/styles.xml b/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values-v11/styles.xml
deleted file mode 100644
index 3c02242a..00000000
--- a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values-v11/styles.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values-v14/styles.xml b/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values-v14/styles.xml
deleted file mode 100644
index a91fd037..00000000
--- a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values-v14/styles.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values/dimens.xml b/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values/dimens.xml
deleted file mode 100644
index 55c1e590..00000000
--- a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values/dimens.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
- 16dp
- 16dp
-
-
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values/strings.xml b/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values/strings.xml
deleted file mode 100644
index 9e984b19..00000000
--- a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
- Loading…
- Broker is processing
- Username
- Password
- Enter your credentials
- Login
- Cancel
-
-
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values/styles.xml b/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values/styles.xml
deleted file mode 100644
index 6ce89c7b..00000000
--- a/src/JavaFileStorageBindings/Jars/adal-1.1.19/res/values/styles.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/src/JavaFileStorageBindings/Jars/google-1.17/google-api-client-android-1.17.0-rc-sources.jar b/src/JavaFileStorageBindings/Jars/google-1.17/google-api-client-android-1.17.0-rc-sources.jar
deleted file mode 100644
index 932a07a3..00000000
Binary files a/src/JavaFileStorageBindings/Jars/google-1.17/google-api-client-android-1.17.0-rc-sources.jar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/google-1.17/google-api-client-xml-1.17.0-rc.jar b/src/JavaFileStorageBindings/Jars/google-1.17/google-api-client-xml-1.17.0-rc.jar
deleted file mode 100644
index b5610258..00000000
Binary files a/src/JavaFileStorageBindings/Jars/google-1.17/google-api-client-xml-1.17.0-rc.jar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/google-1.17/google-api-services-drive-v1-rev105-1.17.0-rc.jar b/src/JavaFileStorageBindings/Jars/google-1.17/google-api-services-drive-v1-rev105-1.17.0-rc.jar
deleted file mode 100644
index 86ce0244..00000000
Binary files a/src/JavaFileStorageBindings/Jars/google-1.17/google-api-services-drive-v1-rev105-1.17.0-rc.jar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/google-1.17/google-http-client-gson-1.17.0-rc-sources.jar b/src/JavaFileStorageBindings/Jars/google-1.17/google-http-client-gson-1.17.0-rc-sources.jar
deleted file mode 100644
index 81aedb60..00000000
Binary files a/src/JavaFileStorageBindings/Jars/google-1.17/google-http-client-gson-1.17.0-rc-sources.jar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/jackson-core-2.7.4.jar b/src/JavaFileStorageBindings/Jars/jackson-core-2.7.4.jar
deleted file mode 100644
index 2e70b2ed..00000000
Binary files a/src/JavaFileStorageBindings/Jars/jackson-core-2.7.4.jar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6.aar b/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6.aar
deleted file mode 100644
index c15fe3e7..00000000
Binary files a/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6.aar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/AndroidManifest.xml b/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/AndroidManifest.xml
deleted file mode 100644
index 4eea788d..00000000
--- a/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/AndroidManifest.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/R.txt b/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/R.txt
deleted file mode 100644
index a80644ba..00000000
--- a/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/R.txt
+++ /dev/null
@@ -1 +0,0 @@
-int string app_name 0x7f020000
diff --git a/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/aapt/AndroidManifest.xml b/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/aapt/AndroidManifest.xml
deleted file mode 100644
index 4eea788d..00000000
--- a/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/aapt/AndroidManifest.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/classes-msa-auth.jar b/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/classes-msa-auth.jar
deleted file mode 100644
index e8e60837..00000000
Binary files a/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/classes-msa-auth.jar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/res/values/values.xml b/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/res/values/values.xml
deleted file mode 100644
index a80d8fc5..00000000
--- a/src/JavaFileStorageBindings/Jars/msa-auth-0.8.6/res/values/values.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
- msa-auth
-
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Jars/okhttp-4.10.0-RC1.jar b/src/JavaFileStorageBindings/Jars/okhttp-4.10.0-RC1.jar
deleted file mode 100644
index 48ef9da8..00000000
Binary files a/src/JavaFileStorageBindings/Jars/okhttp-4.10.0-RC1.jar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/okhttp-digest-2.5.jar b/src/JavaFileStorageBindings/Jars/okhttp-digest-2.5.jar
deleted file mode 100644
index ba18ed81..00000000
Binary files a/src/JavaFileStorageBindings/Jars/okhttp-digest-2.5.jar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/okio-2.9.0.jar b/src/JavaFileStorageBindings/Jars/okio-2.9.0.jar
deleted file mode 100644
index fe3b0403..00000000
Binary files a/src/JavaFileStorageBindings/Jars/okio-2.9.0.jar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2.aar b/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2.aar
deleted file mode 100644
index db0ac519..00000000
Binary files a/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2.aar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2/AndroidManifest.xml b/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2/AndroidManifest.xml
deleted file mode 100644
index b26377f9..00000000
--- a/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2/AndroidManifest.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2/R.txt b/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2/R.txt
deleted file mode 100644
index 8fe0dccb..00000000
--- a/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2/R.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-int dimen activity_horizontal_margin 0x7f030000
-int dimen activity_vertical_margin 0x7f030001
-int id LinearLayout1 0x7f060004
-int id com_microsoft_aad_adal_editDummyText 0x7f060002
-int id com_microsoft_aad_adal_progressBar 0x7f060003
-int id com_microsoft_aad_adal_webView1 0x7f060001
-int id editPassword 0x7f060006
-int id editUserName 0x7f060005
-int id webView1 0x7f060000
-int layout activity_authentication 0x7f020000
-int layout dialog_authentication 0x7f020001
-int layout http_auth_dialog 0x7f020002
-int string app_loading 0x7f050000
-int string app_name 0x7f050001
-int string broker_processing 0x7f050002
-int string http_auth_dialog_cancel 0x7f050003
-int string http_auth_dialog_login 0x7f050004
-int string http_auth_dialog_password 0x7f050005
-int string http_auth_dialog_title 0x7f050006
-int string http_auth_dialog_username 0x7f050007
-int style AppBaseTheme 0x7f040000
-int style AppTheme 0x7f040001
diff --git a/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2/aapt/AndroidManifest.xml b/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2/aapt/AndroidManifest.xml
deleted file mode 100644
index b26377f9..00000000
--- a/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2/aapt/AndroidManifest.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2/classes-onedrive-sdk.jar b/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2/classes-onedrive-sdk.jar
deleted file mode 100644
index b806c879..00000000
Binary files a/src/JavaFileStorageBindings/Jars/onedrive-sdk-android-1.2.2/classes-onedrive-sdk.jar and /dev/null differ
diff --git a/src/JavaFileStorageBindings/JavaFileStorageBindings.csproj b/src/JavaFileStorageBindings/JavaFileStorageBindings.csproj
index e3ca901c..e29888f6 100644
--- a/src/JavaFileStorageBindings/JavaFileStorageBindings.csproj
+++ b/src/JavaFileStorageBindings/JavaFileStorageBindings.csproj
@@ -1,382 +1,38 @@
-
-
-
-
+
- Debug
- AnyCPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}
- {10368E6C-D01B-4462-8E8B-01FC667A7035};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Properties
- JavaFileStorageBindings
- JavaFileStorageBindings
- 512
- false
- v13.0
- class-parse
- XAJavaInterop1
-
-
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 0
- None
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- false
-
-
- bin\ReleaseNoNet\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
- false
- 4
+ net8.0-android
+ 21
+ enable
+ enable
-
-
-
-
-
-
-
-
-
- ..\packages\Xamarin.AndroidX.Activity.1.6.0\lib\monoandroid12.0\Xamarin.AndroidX.Activity.dll
-
-
- ..\packages\Xamarin.AndroidX.Annotation.1.5.0\lib\monoandroid12.0\Xamarin.AndroidX.Annotation.dll
-
-
- ..\packages\Xamarin.AndroidX.Annotation.Experimental.1.3.0\lib\monoandroid12.0\Xamarin.AndroidX.Annotation.Experimental.dll
-
-
- ..\packages\Xamarin.AndroidX.Arch.Core.Common.2.1.0.15\lib\monoandroid12.0\Xamarin.AndroidX.Arch.Core.Common.dll
-
-
- ..\packages\Xamarin.AndroidX.Arch.Core.Runtime.2.1.0.15\lib\monoandroid12.0\Xamarin.AndroidX.Arch.Core.Runtime.dll
-
-
- ..\packages\Xamarin.AndroidX.Collection.1.2.0.4\lib\monoandroid12.0\Xamarin.AndroidX.Collection.dll
-
-
- ..\packages\Xamarin.AndroidX.Concurrent.Futures.1.1.0.9\lib\monoandroid12.0\Xamarin.AndroidX.Concurrent.Futures.dll
-
-
- ..\packages\Xamarin.AndroidX.Core.1.9.0\lib\monoandroid12.0\Xamarin.AndroidX.Core.dll
-
-
- ..\packages\Xamarin.AndroidX.Core.Core.Ktx.1.9.0\lib\monoandroid12.0\Xamarin.AndroidX.Core.Core.Ktx.dll
-
-
- ..\packages\Xamarin.AndroidX.CustomView.1.1.0.13\lib\monoandroid12.0\Xamarin.AndroidX.CustomView.dll
-
-
- ..\packages\Xamarin.AndroidX.Fragment.1.5.3\lib\monoandroid12.0\Xamarin.AndroidX.Fragment.dll
-
-
- ..\packages\Xamarin.AndroidX.Lifecycle.Common.2.5.1\lib\monoandroid12.0\Xamarin.AndroidX.Lifecycle.Common.dll
-
-
- ..\packages\Xamarin.AndroidX.Lifecycle.LiveData.Core.2.5.1\lib\monoandroid12.0\Xamarin.AndroidX.Lifecycle.LiveData.Core.dll
-
-
- ..\packages\Xamarin.AndroidX.Lifecycle.Runtime.2.5.1\lib\monoandroid12.0\Xamarin.AndroidX.Lifecycle.Runtime.dll
-
-
- ..\packages\Xamarin.AndroidX.Lifecycle.ViewModel.2.5.1\lib\monoandroid12.0\Xamarin.AndroidX.Lifecycle.ViewModel.dll
-
-
- ..\packages\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.2.5.1\lib\monoandroid12.0\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.dll
-
-
- ..\packages\Xamarin.AndroidX.Loader.1.1.0.14\lib\monoandroid12.0\Xamarin.AndroidX.Loader.dll
-
-
- ..\packages\Xamarin.AndroidX.MultiDex.2.0.1.13\lib\monoandroid12.0\Xamarin.AndroidX.MultiDex.dll
-
-
- ..\packages\Xamarin.AndroidX.SavedState.1.2.0\lib\monoandroid12.0\Xamarin.AndroidX.SavedState.dll
-
-
- ..\packages\Xamarin.AndroidX.Tracing.Tracing.1.1.0.1\lib\monoandroid12.0\Xamarin.AndroidX.Tracing.Tracing.dll
-
-
- ..\packages\Xamarin.AndroidX.VersionedParcelable.1.1.1.14\lib\monoandroid12.0\Xamarin.AndroidX.VersionedParcelable.dll
-
-
- ..\packages\Xamarin.AndroidX.ViewPager.1.0.0.14\lib\monoandroid12.0\Xamarin.AndroidX.ViewPager.dll
-
-
- ..\packages\Xamarin.Google.Guava.28.2.0.1\lib\monoandroid90\Xamarin.Google.Guava.dll
-
-
- ..\packages\Xamarin.Google.Guava.FailureAccess.1.0.1.3\lib\monoandroid90\Xamarin.Google.Guava.FailureAccess.dll
-
-
- ..\packages\Xamarin.Google.Guava.ListenableFuture.1.0.0.9\lib\monoandroid12.0\Xamarin.Google.Guava.ListenableFuture.dll
-
-
- ..\packages\Xamarin.GooglePlayServices.Auth.120.4.0\lib\monoandroid12.0\Xamarin.GooglePlayServices.Auth.dll
-
-
- ..\packages\Xamarin.GooglePlayServices.Auth.Api.Phone.118.0.1.2\lib\monoandroid12.0\Xamarin.GooglePlayServices.Auth.Api.Phone.dll
-
-
- ..\packages\Xamarin.GooglePlayServices.Auth.Base.118.0.6\lib\monoandroid12.0\Xamarin.GooglePlayServices.Auth.Base.dll
-
-
- ..\packages\Xamarin.GooglePlayServices.Base.118.1.0\lib\monoandroid12.0\Xamarin.GooglePlayServices.Base.dll
-
-
- ..\packages\Xamarin.GooglePlayServices.Basement.118.1.0.1\lib\monoandroid12.0\Xamarin.GooglePlayServices.Basement.dll
-
-
- ..\packages\Xamarin.GooglePlayServices.Fido.119.0.0\lib\monoandroid12.0\Xamarin.GooglePlayServices.Fido.dll
-
-
- ..\packages\Xamarin.GooglePlayServices.Tasks.118.0.2\lib\monoandroid12.0\Xamarin.GooglePlayServices.Tasks.dll
-
-
- ..\packages\Xamarin.Jetbrains.Annotations.23.0.0.4\lib\monoandroid12.0\Xamarin.Jetbrains.Annotations.dll
-
-
- ..\packages\Xamarin.Kotlin.StdLib.1.7.10\lib\monoandroid12.0\Xamarin.Kotlin.StdLib.dll
-
-
- ..\packages\Xamarin.Kotlin.StdLib.Common.1.7.10\lib\monoandroid12.0\Xamarin.Kotlin.StdLib.Common.dll
-
-
- ..\packages\Xamarin.Kotlin.StdLib.Jdk7.1.7.10\lib\monoandroid12.0\Xamarin.Kotlin.StdLib.Jdk7.dll
-
-
- ..\packages\Xamarin.Kotlin.StdLib.Jdk8.1.7.10\lib\monoandroid12.0\Xamarin.Kotlin.StdLib.Jdk8.dll
-
-
- ..\packages\Xamarin.KotlinX.Coroutines.Android.1.6.4\lib\monoandroid12.0\Xamarin.KotlinX.Coroutines.Android.dll
-
-
- ..\packages\Xamarin.KotlinX.Coroutines.Core.Jvm.1.6.4\lib\monoandroid12.0\Xamarin.KotlinX.Coroutines.Core.Jvm.dll
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- Jars\JavaFileStorage-debug.aar
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 19.0.0
- False
-
-
-
-
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}
- PCloudBindings
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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/JavaFileStorageBindings/Properties/AssemblyInfo.cs b/src/JavaFileStorageBindings/Properties/AssemblyInfo.cs
deleted file mode 100644
index 7f2865c5..00000000
--- a/src/JavaFileStorageBindings/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Android.App;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("JavaFileStorageBindings")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("JavaFileStorageBindings")]
-[assembly: AssemblyCopyright("Copyright © 2013")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Transforms/EnumFields.xml b/src/JavaFileStorageBindings/Transforms/EnumFields.xml
index 22959957..4dddf452 100644
--- a/src/JavaFileStorageBindings/Transforms/EnumFields.xml
+++ b/src/JavaFileStorageBindings/Transforms/EnumFields.xml
@@ -1,14 +1,3 @@
-
+
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Transforms/EnumMethods.xml b/src/JavaFileStorageBindings/Transforms/EnumMethods.xml
index 49216c61..1918b0cf 100644
--- a/src/JavaFileStorageBindings/Transforms/EnumMethods.xml
+++ b/src/JavaFileStorageBindings/Transforms/EnumMethods.xml
@@ -1,13 +1,3 @@
-
+
\ No newline at end of file
diff --git a/src/JavaFileStorageBindings/Transforms/Metadata.xml b/src/JavaFileStorageBindings/Transforms/Metadata.xml
index 196e6766..b10d2858 100644
--- a/src/JavaFileStorageBindings/Transforms/Metadata.xml
+++ b/src/JavaFileStorageBindings/Transforms/Metadata.xml
@@ -1,17 +1,16 @@
-
+
+
+
+
+
+
diff --git a/src/JavaFileStorageBindings/Jars/dropbox-core-sdk-4.0.0.jar b/src/JavaFileStorageBindings/dropbox-core-sdk-5.4.6.jar
similarity index 50%
rename from src/JavaFileStorageBindings/Jars/dropbox-core-sdk-4.0.0.jar
rename to src/JavaFileStorageBindings/dropbox-core-sdk-5.4.6.jar
index e8376c42..9004a26d 100644
Binary files a/src/JavaFileStorageBindings/Jars/dropbox-core-sdk-4.0.0.jar and b/src/JavaFileStorageBindings/dropbox-core-sdk-5.4.6.jar differ
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/commons-logging-1.1.1.jar b/src/JavaFileStorageBindings/gdrive/commons-logging-1.1.1.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/commons-logging-1.1.1.jar
rename to src/JavaFileStorageBindings/gdrive/commons-logging-1.1.1.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/google-api-client-1.30.5.jar b/src/JavaFileStorageBindings/gdrive/google-api-client-1.30.5.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/google-api-client-1.30.5.jar
rename to src/JavaFileStorageBindings/gdrive/google-api-client-1.30.5.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/google-api-client-android-1.30.5.jar b/src/JavaFileStorageBindings/gdrive/google-api-client-android-1.30.5.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/google-api-client-android-1.30.5.jar
rename to src/JavaFileStorageBindings/gdrive/google-api-client-android-1.30.5.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/google-api-services-drive-v2-rev102-1.16.0-rc.jar b/src/JavaFileStorageBindings/gdrive/google-api-services-drive-v2-rev102-1.16.0-rc.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/google-api-services-drive-v2-rev102-1.16.0-rc.jar
rename to src/JavaFileStorageBindings/gdrive/google-api-services-drive-v2-rev102-1.16.0-rc.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/google-http-client-1.32.1.jar b/src/JavaFileStorageBindings/gdrive/google-http-client-1.32.1.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/google-http-client-1.32.1.jar
rename to src/JavaFileStorageBindings/gdrive/google-http-client-1.32.1.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/google-http-client-android-1.32.1.jar b/src/JavaFileStorageBindings/gdrive/google-http-client-android-1.32.1.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/google-http-client-android-1.32.1.jar
rename to src/JavaFileStorageBindings/gdrive/google-http-client-android-1.32.1.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/google-http-client-gson-1.16.0-rc.jar b/src/JavaFileStorageBindings/gdrive/google-http-client-gson-1.16.0-rc.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/google-http-client-gson-1.16.0-rc.jar
rename to src/JavaFileStorageBindings/gdrive/google-http-client-gson-1.16.0-rc.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/google-http-client-jackson-1.16.0-rc.jar b/src/JavaFileStorageBindings/gdrive/google-http-client-jackson-1.16.0-rc.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/google-http-client-jackson-1.16.0-rc.jar
rename to src/JavaFileStorageBindings/gdrive/google-http-client-jackson-1.16.0-rc.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/google-http-client-jackson2-1.32.1.jar b/src/JavaFileStorageBindings/gdrive/google-http-client-jackson2-1.32.1.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/google-http-client-jackson2-1.32.1.jar
rename to src/JavaFileStorageBindings/gdrive/google-http-client-jackson2-1.32.1.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/google-oauth-client-1.30.4.jar b/src/JavaFileStorageBindings/gdrive/google-oauth-client-1.30.4.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/google-oauth-client-1.30.4.jar
rename to src/JavaFileStorageBindings/gdrive/google-oauth-client-1.30.4.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/grpc-context-1.22.1.jar b/src/JavaFileStorageBindings/gdrive/grpc-context-1.22.1.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/grpc-context-1.22.1.jar
rename to src/JavaFileStorageBindings/gdrive/grpc-context-1.22.1.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/httpclient-4.0.3.jar b/src/JavaFileStorageBindings/gdrive/httpclient-4.0.3.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/httpclient-4.0.3.jar
rename to src/JavaFileStorageBindings/gdrive/httpclient-4.0.3.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/httpcore-4.0.1.jar b/src/JavaFileStorageBindings/gdrive/httpcore-4.0.1.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/httpcore-4.0.1.jar
rename to src/JavaFileStorageBindings/gdrive/httpcore-4.0.1.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/httpmime-4.0.3.jar b/src/JavaFileStorageBindings/gdrive/httpmime-4.0.3.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/httpmime-4.0.3.jar
rename to src/JavaFileStorageBindings/gdrive/httpmime-4.0.3.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/json_simple-1.1.jar b/src/JavaFileStorageBindings/gdrive/json_simple-1.1.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/json_simple-1.1.jar
rename to src/JavaFileStorageBindings/gdrive/json_simple-1.1.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/jsr305-3.0.2.jar b/src/JavaFileStorageBindings/gdrive/jsr305-3.0.2.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/jsr305-3.0.2.jar
rename to src/JavaFileStorageBindings/gdrive/jsr305-3.0.2.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/opencensus-api-0.24.0.jar b/src/JavaFileStorageBindings/gdrive/opencensus-api-0.24.0.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/opencensus-api-0.24.0.jar
rename to src/JavaFileStorageBindings/gdrive/opencensus-api-0.24.0.jar
diff --git a/src/JavaFileStorageBindings/Jars/gdrive/opencensus-contrib-http-util-0.24.0.jar b/src/JavaFileStorageBindings/gdrive/opencensus-contrib-http-util-0.24.0.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gdrive/opencensus-contrib-http-util-0.24.0.jar
rename to src/JavaFileStorageBindings/gdrive/opencensus-contrib-http-util-0.24.0.jar
diff --git a/src/JavaFileStorageBindings/Jars/gson-2.8.6.jar b/src/JavaFileStorageBindings/gson-2.8.6.jar
similarity index 100%
rename from src/JavaFileStorageBindings/Jars/gson-2.8.6.jar
rename to src/JavaFileStorageBindings/gson-2.8.6.jar
diff --git a/src/JavaFileStorageBindings/jackson-core-2.13.5.jar b/src/JavaFileStorageBindings/jackson-core-2.13.5.jar
new file mode 100644
index 00000000..401dee31
Binary files /dev/null and b/src/JavaFileStorageBindings/jackson-core-2.13.5.jar differ
diff --git a/src/JavaFileStorageBindings/okhttp-4.12.0.jar b/src/JavaFileStorageBindings/okhttp-4.12.0.jar
new file mode 100644
index 00000000..faf3fa86
Binary files /dev/null and b/src/JavaFileStorageBindings/okhttp-4.12.0.jar differ
diff --git a/src/JavaFileStorageBindings/okhttp-digest-3.1.0.jar b/src/JavaFileStorageBindings/okhttp-digest-3.1.0.jar
new file mode 100644
index 00000000..af2c08ae
Binary files /dev/null and b/src/JavaFileStorageBindings/okhttp-digest-3.1.0.jar differ
diff --git a/src/JavaFileStorageBindings/okio-3.6.0.jar b/src/JavaFileStorageBindings/okio-3.6.0.jar
new file mode 100644
index 00000000..f3137562
Binary files /dev/null and b/src/JavaFileStorageBindings/okio-3.6.0.jar differ
diff --git a/src/JavaFileStorageBindings/okio-jvm-3.6.0.jar b/src/JavaFileStorageBindings/okio-jvm-3.6.0.jar
new file mode 100644
index 00000000..ec8ad90f
Binary files /dev/null and b/src/JavaFileStorageBindings/okio-jvm-3.6.0.jar differ
diff --git a/src/JavaFileStorageBindings/packages.config b/src/JavaFileStorageBindings/packages.config
deleted file mode 100644
index 7c3dfc28..00000000
--- a/src/JavaFileStorageBindings/packages.config
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/KP2AKdbLibraryBinding/Additions/AboutAdditions.txt b/src/KP2AKdbLibraryBinding/Additions/AboutAdditions.txt
deleted file mode 100644
index 08caee33..00000000
--- a/src/KP2AKdbLibraryBinding/Additions/AboutAdditions.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-Additions allow you to add arbitrary C# to the generated classes
-before they are compiled. This can be helpful for providing convenience
-methods or adding pure C# classes.
-
-== Adding Methods to Generated Classes ==
-
-Let's say the library being bound has a Rectangle class with a constructor
-that takes an x and y position, and a width and length size. It will look like
-this:
-
-public partial class Rectangle
-{
- public Rectangle (int x, int y, int width, int height)
- {
- // JNI bindings
- }
-}
-
-Imagine we want to add a constructor to this class that takes a Point and
-Size structure instead of 4 ints. We can add a new file called Rectangle.cs
-with a partial class containing our new method:
-
-public partial class Rectangle
-{
- public Rectangle (Point location, Size size) :
- this (location.X, location.Y, size.Width, size.Height)
- {
- }
-}
-
-At compile time, the additions class will be added to the generated class
-and the final assembly will a Rectangle class with both constructors.
-
-
-== Adding C# Classes ==
-
-Another thing that can be done is adding fully C# managed classes to the
-generated library. In the above example, let's assume that there isn't a
-Point class available in Java or our library. The one we create doesn't need
-to interact with Java, so we'll create it like a normal class in C#.
-
-By adding a Point.cs file with this class, it will end up in the binding library:
-
-public class Point
-{
- public int X { get; set; }
- public int Y { get; set; }
-}
\ No newline at end of file
diff --git a/src/KP2AKdbLibraryBinding/Jars/AboutJars.txt b/src/KP2AKdbLibraryBinding/Jars/AboutJars.txt
deleted file mode 100644
index c359b62f..00000000
--- a/src/KP2AKdbLibraryBinding/Jars/AboutJars.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-This directory is for Android .jars.
-
-There are 2 types of jars that are supported:
-
-== Input Jar ==
-
-This is the jar that bindings should be generated for.
-
-For example, if you were binding the Google Maps library, this would
-be Google's "maps.jar".
-
-Set the build action for these jars in the properties page to "InputJar".
-
-
-== Reference Jars ==
-
-These are jars that are referenced by the input jar. C# bindings will
-not be created for these jars. These jars will be used to resolve
-types used by the input jar.
-
-NOTE: Do not add "android.jar" as a reference jar. It will be added automatically
-based on the Target Framework selected.
-
-Set the build action for these jars in the properties page to "ReferenceJar".
\ No newline at end of file
diff --git a/src/KP2AKdbLibraryBinding/KP2AKdbLibraryBinding.csproj b/src/KP2AKdbLibraryBinding/KP2AKdbLibraryBinding.csproj
index 404c3eb5..d39c9b67 100644
--- a/src/KP2AKdbLibraryBinding/KP2AKdbLibraryBinding.csproj
+++ b/src/KP2AKdbLibraryBinding/KP2AKdbLibraryBinding.csproj
@@ -1,81 +1,21 @@
-
-
+
- Debug
- AnyCPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}
- {10368E6C-D01B-4462-8E8B-01FC667A7035};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Properties
- KP2AKdbLibraryBinding
- KP2AKdbLibraryBinding
- 512
- v8.0
- false
- XAJavaInterop1
- class-parse
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- None
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- false
-
-
- bin\ReleaseNoNet\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
- false
- 4
+ net8.0-android
+ 21
+ enable
+ enable
-
-
-
+
+
+
-
+
-
- Jars\app-debug.aar
-
-
-
-
-
-
+
Designer
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/KP2AKdbLibraryBinding/Properties/AssemblyInfo.cs b/src/KP2AKdbLibraryBinding/Properties/AssemblyInfo.cs
deleted file mode 100644
index fba6323a..00000000
--- a/src/KP2AKdbLibraryBinding/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Android.App;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("KP2AKdbLibraryBinding")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("KP2AKdbLibraryBinding")]
-[assembly: AssemblyCopyright("Copyright © 2014")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
-
diff --git a/src/KP2AKdbLibraryBinding/Transforms/EnumFields.xml b/src/KP2AKdbLibraryBinding/Transforms/EnumFields.xml
index 22959957..8ee086d7 100644
--- a/src/KP2AKdbLibraryBinding/Transforms/EnumFields.xml
+++ b/src/KP2AKdbLibraryBinding/Transforms/EnumFields.xml
@@ -1,14 +1,3 @@
-
+
\ No newline at end of file
diff --git a/src/KP2AKdbLibraryBinding/Transforms/EnumMethods.xml b/src/KP2AKdbLibraryBinding/Transforms/EnumMethods.xml
index 49216c61..85202262 100644
--- a/src/KP2AKdbLibraryBinding/Transforms/EnumMethods.xml
+++ b/src/KP2AKdbLibraryBinding/Transforms/EnumMethods.xml
@@ -1,13 +1,3 @@
-
+
\ No newline at end of file
diff --git a/src/KP2AKdbLibraryBinding/Transforms/Metadata.xml b/src/KP2AKdbLibraryBinding/Transforms/Metadata.xml
index 0dd04e93..6bd74e5f 100644
--- a/src/KP2AKdbLibraryBinding/Transforms/Metadata.xml
+++ b/src/KP2AKdbLibraryBinding/Transforms/Metadata.xml
@@ -1,12 +1,5 @@
-
+
diff --git a/src/KeePass.sln b/src/KeePass.sln
index bcd542c4..2a9b9700 100644
--- a/src/KeePass.sln
+++ b/src/KeePass.sln
@@ -3,31 +3,31 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33205.214
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZlibAndroid", "ZlibAndroid\ZlibAndroid.csproj", "{1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aKeyboardBinding", "Kp2aKeyboardBinding\Kp2aKeyboardBinding.csproj", "{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TwofishCipher", "TwofishCipher\TwofishCipher.csproj", "{69D491AA-3A31-4467-8216-3641A4F157BE}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aBusinessLogic", "Kp2aBusinessLogic\Kp2aBusinessLogic.csproj", "{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwofishCipher", "TwofishCipher\TwofishCipher.csproj", "{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KP2AKdbLibraryBinding", "KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj", "{BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JavaFileStorageBindings", "JavaFileStorageBindings\JavaFileStorageBindings.csproj", "{48574278-4779-4B3A-A9E4-9CF1BC285D0B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AndroidFileChooserBinding", "AndroidFileChooserBinding\AndroidFileChooserBinding.csproj", "{C3A88E81-0809-49A4-A4EC-DF71A6200F41}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AndroidFileChooserBinding", "AndroidFileChooserBinding\AndroidFileChooserBinding.csproj", "{3C0F7FE5-639F-4422-A087-8B26CF862D1B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JavaFileStorageBindings", "JavaFileStorageBindings\JavaFileStorageBindings.csproj", "{4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KP2AKdbLibraryBinding", "KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj", "{70D3844A-D9FA-4A64-B205-A84C6A822196}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kp2aBusinessLogic", "Kp2aBusinessLogic\Kp2aBusinessLogic.csproj", "{862D7A27-4211-4258-A4B0-741B4C0A73CF}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginSdkBinding", "PluginSdkBinding\PluginSdkBinding.csproj", "{3DA3911E-36DE-465E-8F15-F1991B6437E5}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kp2aAutofillParser", "Kp2aAutofillParser\Kp2aAutofillParser.csproj", "{2D5E3AEF-6EB2-4737-9ACB-921A22928682}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZlibAndroid", "ZlibAndroid\ZlibAndroid.csproj", "{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "keepass2android-app", "keepass2android-app\keepass2android-app.csproj", "{0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PCloudBindings", "PCloudBindings\PCloudBindings.csproj", "{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginSdkBinding", "PluginSdkBinding\PluginSdkBinding.csproj", "{C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "keepass2android-app", "keepass2android\keepass2android-app.csproj", "{D4C32E0A-0193-4496-9DB4-02CC126FD9F3}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kp2aKeyboardBinding", "Kp2aKeyboardBinding\Kp2aKeyboardBinding.csproj", "{B8CFEA61-5165-477A-BBED-6C711107522E}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kp2aAutofillParser", "Kp2aAutofillParser\Kp2aAutofillParser.csproj", "{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PCloudBindings", "PCloudBindings\PCloudBindings.csproj", "{D5F03D6D-B233-4716-93B5-18C2D965B5EC}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aAutofillParserTest", "Kp2aAutofillParserTest\Kp2aAutofillParserTest.csproj", "{3D1560FF-86BB-4CB4-8367-80BA13B81C38}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kp2aAutofillParser.Tests", "Kp2aAutofillParser.Tests\Kp2aAutofillParser.Tests.csproj", "{F5A2A8F9-C084-498F-9603-9D927BA5C626}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -45,296 +45,330 @@ Global
ReleaseNoNet|x64 = ReleaseNoNet|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Win32.Build.0 = Debug|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|x64.ActiveCfg = Debug|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|x64.Build.0 = Debug|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Any CPU.Build.0 = Release|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Win32.ActiveCfg = Release|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|Win32.Build.0 = Release|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|x64.ActiveCfg = Release|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|x64.Build.0 = Release|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Win32.Build.0 = Debug|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|x64.ActiveCfg = Debug|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|x64.Build.0 = Debug|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|Any CPU.Build.0 = Release|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|Win32.ActiveCfg = Release|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|Win32.Build.0 = Release|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|x64.ActiveCfg = Release|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|x64.Build.0 = Release|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.ActiveCfg = Debug|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.Build.0 = Debug|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|x64.ActiveCfg = Debug|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Any CPU.Build.0 = Release|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Win32.ActiveCfg = Release|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|x64.ActiveCfg = Release|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Debug|x64.ActiveCfg = Debug|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Release|Any CPU.Build.0 = Release|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Release|Win32.ActiveCfg = Release|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Release|x64.ActiveCfg = Release|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Win32.Build.0 = Debug|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|x64.ActiveCfg = Debug|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|x64.Build.0 = Debug|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Any CPU.Build.0 = Release|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Win32.ActiveCfg = Release|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Win32.Build.0 = Release|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|x64.ActiveCfg = Release|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|x64.Build.0 = Release|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Win32.Build.0 = ReleaseNoNet|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
- {48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|x64.Build.0 = ReleaseNoNet|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|x64.ActiveCfg = Debug|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|Any CPU.Build.0 = Release|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|Win32.ActiveCfg = Release|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|x64.ActiveCfg = Release|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
- {3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.Debug|x64.ActiveCfg = Debug|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|Any CPU.Build.0 = Release|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|Win32.ActiveCfg = Release|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|x64.ActiveCfg = Release|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
- {70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.Debug|x64.ActiveCfg = Debug|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|Any CPU.Build.0 = Release|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|Win32.ActiveCfg = Release|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|x64.ActiveCfg = Release|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Win32.Build.0 = Debug|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|x64.ActiveCfg = Debug|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|x64.Build.0 = Debug|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|Any CPU.Build.0 = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|Win32.ActiveCfg = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|Win32.Build.0 = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|x64.ActiveCfg = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|x64.Build.0 = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Win32.Build.0 = Debug|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|x64.ActiveCfg = Debug|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|x64.Build.0 = Debug|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Any CPU.Build.0 = Release|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Win32.ActiveCfg = Release|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Win32.Build.0 = Release|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|x64.ActiveCfg = Release|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|x64.Build.0 = Release|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Win32.Build.0 = ReleaseNoNet|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|x64.Build.0 = ReleaseNoNet|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Debug|Win32.Build.0 = Debug|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Debug|Win32.Deploy.0 = Debug|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Debug|x64.ActiveCfg = Debug|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Debug|x64.Build.0 = Debug|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Debug|x64.Deploy.0 = Debug|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Release|Any CPU.Build.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Release|Any CPU.Deploy.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Release|Win32.ActiveCfg = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Release|Win32.Build.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Release|Win32.Deploy.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Release|x64.ActiveCfg = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Release|x64.Build.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.Release|x64.Deploy.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|Win32.Deploy.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|x64.Deploy.0 = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|Win32.Build.0 = Debug|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|x64.ActiveCfg = Debug|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|x64.Build.0 = Debug|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|Any CPU.Build.0 = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|Win32.ActiveCfg = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|Win32.Build.0 = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|x64.ActiveCfg = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|x64.Build.0 = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
- {39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|Win32.Build.0 = Debug|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|x64.ActiveCfg = Debug|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|x64.Build.0 = Debug|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|Any CPU.Build.0 = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|Win32.ActiveCfg = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|Win32.Build.0 = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|x64.ActiveCfg = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|x64.Build.0 = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
- {3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Debug|Win32.Build.0 = Debug|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Debug|x64.Build.0 = Debug|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Release|Win32.ActiveCfg = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Release|Win32.Build.0 = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Release|x64.ActiveCfg = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.Release|x64.Build.0 = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {1DF9DA08-D2FE-4227-BD53-761CD3F6CA42}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Debug|Win32.Build.0 = Debug|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Debug|x64.Build.0 = Debug|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Release|Win32.ActiveCfg = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Release|Win32.Build.0 = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Release|x64.ActiveCfg = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.Release|x64.Build.0 = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {69D491AA-3A31-4467-8216-3641A4F157BE}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Debug|Win32.Build.0 = Debug|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Debug|x64.Build.0 = Debug|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Release|Win32.ActiveCfg = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Release|Win32.Build.0 = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Release|x64.ActiveCfg = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.Release|x64.Build.0 = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {6E1DCFE1-D86D-480F-BE02-BBE8FD4601F0}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Debug|Win32.Build.0 = Debug|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Debug|x64.Build.0 = Debug|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Release|Win32.ActiveCfg = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Release|Win32.Build.0 = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Release|x64.ActiveCfg = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.Release|x64.Build.0 = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {BF542E42-E7A9-4C71-AA3B-DAC0F959F0D5}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Debug|Win32.Build.0 = Debug|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Debug|x64.Build.0 = Debug|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Release|Win32.ActiveCfg = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Release|Win32.Build.0 = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Release|x64.ActiveCfg = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.Release|x64.Build.0 = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {C3A88E81-0809-49A4-A4EC-DF71A6200F41}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Debug|Win32.Build.0 = Debug|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Debug|x64.Build.0 = Debug|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Release|Win32.ActiveCfg = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Release|Win32.Build.0 = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Release|x64.ActiveCfg = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.Release|x64.Build.0 = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {4F2E6B45-2C9F-4DF6-A9DC-9F81DC8681BC}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Debug|Win32.Build.0 = Debug|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Debug|x64.Build.0 = Debug|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Release|Win32.ActiveCfg = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Release|Win32.Build.0 = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Release|x64.ActiveCfg = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.Release|x64.Build.0 = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {862D7A27-4211-4258-A4B0-741B4C0A73CF}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Debug|Win32.Build.0 = Debug|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Debug|x64.Build.0 = Debug|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Release|Win32.ActiveCfg = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Release|Win32.Build.0 = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Release|x64.ActiveCfg = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.Release|x64.Build.0 = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {2D5E3AEF-6EB2-4737-9ACB-921A22928682}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Debug|Win32.Build.0 = Debug|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Debug|Win32.Deploy.0 = Debug|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Debug|x64.Build.0 = Debug|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Debug|x64.Deploy.0 = Debug|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Release|Win32.ActiveCfg = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Release|Win32.Build.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Release|Win32.Deploy.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Release|x64.ActiveCfg = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Release|x64.Build.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.Release|x64.Deploy.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.ReleaseNoNet|Win32.Deploy.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {0CCDA3EB-8A24-4A42-BC91-A4DD254504E7}.ReleaseNoNet|x64.Deploy.0 = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Debug|Win32.Build.0 = Debug|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Debug|x64.Build.0 = Debug|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Release|Win32.ActiveCfg = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Release|Win32.Build.0 = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Release|x64.ActiveCfg = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.Release|x64.Build.0 = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {C80CA4D0-C2A1-44FF-94DD-4097BDC58AF1}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Debug|Win32.Build.0 = Debug|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Debug|x64.Build.0 = Debug|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Release|Win32.ActiveCfg = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Release|Win32.Build.0 = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Release|x64.ActiveCfg = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.Release|x64.Build.0 = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {B8CFEA61-5165-477A-BBED-6C711107522E}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Debug|Win32.Build.0 = Debug|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Debug|x64.Build.0 = Debug|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Release|Win32.ActiveCfg = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Release|Win32.Build.0 = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Release|x64.ActiveCfg = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.Release|x64.Build.0 = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {D5F03D6D-B233-4716-93B5-18C2D965B5EC}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Debug|Win32.Build.0 = Debug|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Debug|x64.Build.0 = Debug|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Release|Win32.ActiveCfg = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Release|Win32.Build.0 = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Release|x64.ActiveCfg = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.Release|x64.Build.0 = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
+ {F5A2A8F9-C084-498F-9603-9D927BA5C626}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/KeePassLib2Android/.gitignore b/src/KeePassLib2Android/.gitignore
deleted file mode 100644
index 2416a678..00000000
--- a/src/KeePassLib2Android/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-obj/
diff --git a/src/KeePassLib2Android/Cryptography/KeyDerivation/Argon2Kdf.cs b/src/KeePassLib2Android/Cryptography/KeyDerivation/Argon2Kdf.cs
index 7b0d1183..a00bef12 100644
--- a/src/KeePassLib2Android/Cryptography/KeyDerivation/Argon2Kdf.cs
+++ b/src/KeePassLib2Android/Cryptography/KeyDerivation/Argon2Kdf.cs
@@ -17,6 +17,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+using Java.Lang;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -179,6 +180,7 @@ namespace KeePassLib.Cryptography.KeyDerivation
Marshal.Copy(pbSalt, 0, saltPtr, pbSalt.Length);
const UInt32 Argon2_d = 0;
+ JavaSystem.LoadLibrary("argon2");
int ret = argon2_hash(
(UInt32)uIt, (UInt32)(uMem / 1024), uPar,
@@ -189,7 +191,7 @@ namespace KeePassLib.Cryptography.KeyDerivation
if (ret != 0)
{
- throw new Exception("argon2_hash failed with " + ret);
+ throw new System.Exception("argon2_hash failed with " + ret);
}
pbRet = new byte[32];
@@ -214,8 +216,9 @@ namespace KeePassLib.Cryptography.KeyDerivation
return p;
}
- [DllImport("argon2")]
- static extern int argon2_hash(
+ [LibraryImport("argon2")]
+ [return: MarshalAs(UnmanagedType.I4)]
+ public static partial int argon2_hash(
UInt32 t_cost, UInt32 m_cost, UInt32 parallelism,
IntPtr pwd, IntPtr pwdlen,
IntPtr salt, IntPtr saltlen,
diff --git a/src/KeePassLib2Android/KeePassLib2Android.csproj b/src/KeePassLib2Android/KeePassLib2Android.csproj
index 849a5cf5..17b69210 100644
--- a/src/KeePassLib2Android/KeePassLib2Android.csproj
+++ b/src/KeePassLib2Android/KeePassLib2Android.csproj
@@ -1,183 +1,29 @@
-
-
+
- Debug
- AnyCPU
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- KeePassLib2Android
- Resources
- Assets
- Resources\Resource.designer.cs
- Resource
- KeePassLib2Android
- v8.0
- false
- 8482b288
-
-
- True
- full
- False
- bin\Debug
- DEBUG;EXCLUDE_TWOFISH;_EXCLUDE_KEYBOARD;_EXCLUDE_FILECHOOSER;_EXCLUDE_JAVAFILESTORAGE;INCLUDE_KEYTRANSFORM
- prompt
- 4
- False
- None
-
-
- none
- True
- bin\Release
- prompt
- 4
- False
- False
-
-
- none
- True
- bin\ReleaseNoNet
- prompt
- 4
- False
- False
+ net8.0-android
+ 21
+ enable
+ enable
+ True
-
- ..\ProtoBuf\protobuf-net.dll
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ Designer
+ MSBuild:UpdateGeneratedFiles
+
+
+
+
Component
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {70D3844A-D9FA-4A64-B205-A84C6A822196}
- KP2AKdbLibraryBinding
-
-
-
\ No newline at end of file
diff --git a/src/KeePassLib2Android/Kp2aLog.cs b/src/KeePassLib2Android/Kp2aLog.cs
index 2226ee87..93106e13 100644
--- a/src/KeePassLib2Android/Kp2aLog.cs
+++ b/src/KeePassLib2Android/Kp2aLog.cs
@@ -108,8 +108,12 @@ namespace keepass2android
public static void SendLog(Context ctx)
{
- if (!File.Exists(LogFilename))
- return;
+ if (!File.Exists(LogFilename))
+ {
+ Toast.MakeText(ctx, "Debug log is empty.", ToastLength.Long).Show();
+ return;
+ }
+
Intent sendIntent = new Intent();
sendIntent.SetAction(Intent.ActionSend);
sendIntent.PutExtra(Intent.ExtraText, File.ReadAllText(LogFilename));
diff --git a/src/KeePassLib2Android/Native/NativeMethods.Unix.cs b/src/KeePassLib2Android/Native/NativeMethods.Unix.cs
deleted file mode 100644
index 3e0ef0c0..00000000
--- a/src/KeePassLib2Android/Native/NativeMethods.Unix.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- KeePass Password Safe - The Open-Source Password Manager
- Copyright (C) 2003-2017 Dominik Reichl
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Text;
-
-#if !KeePassUAP
-using System.Windows.Forms;
-#endif
-
-namespace KeePassLib.Native
-{
- internal static partial class NativeMethods
- {
-#if (!KeePassLibSD && !KeePassUAP)
- [StructLayout(LayoutKind.Sequential)]
- private struct XClassHint
- {
- public IntPtr res_name;
- public IntPtr res_class;
- }
-
- [DllImport("libX11")]
- private static extern int XSetClassHint(IntPtr display, IntPtr window, IntPtr class_hints);
-
- private static Type m_tXplatUIX11 = null;
- private static Type GetXplatUIX11Type(bool bThrowOnError)
- {
- if(m_tXplatUIX11 == null)
- {
- // CheckState is in System.Windows.Forms
- string strTypeCS = typeof(CheckState).AssemblyQualifiedName;
- string strTypeX11 = strTypeCS.Replace("CheckState", "XplatUIX11");
- m_tXplatUIX11 = Type.GetType(strTypeX11, bThrowOnError, true);
- }
-
- return m_tXplatUIX11;
- }
-
- private static Type m_tHwnd = null;
- private static Type GetHwndType(bool bThrowOnError)
- {
- if(m_tHwnd == null)
- {
- // CheckState is in System.Windows.Forms
- string strTypeCS = typeof(CheckState).AssemblyQualifiedName;
- string strTypeHwnd = strTypeCS.Replace("CheckState", "Hwnd");
- m_tHwnd = Type.GetType(strTypeHwnd, bThrowOnError, true);
- }
-
- return m_tHwnd;
- }
-
- internal static void SetWmClass(Form f, string strName, string strClass)
- {
- if(f == null) { Debug.Assert(false); return; }
-
- // The following crashes under Mac OS X (SIGSEGV in native code,
- // not just an exception), thus skip it when we're on Mac OS X;
- // https://sourceforge.net/projects/keepass/forums/forum/329221/topic/5860588
- if(NativeLib.GetPlatformID() == PlatformID.MacOSX) return;
-
- try
- {
- Type tXplatUIX11 = GetXplatUIX11Type(true);
- FieldInfo fiDisplayHandle = tXplatUIX11.GetField("DisplayHandle",
- BindingFlags.NonPublic | BindingFlags.Static);
- IntPtr hDisplay = (IntPtr)fiDisplayHandle.GetValue(null);
-
- Type tHwnd = GetHwndType(true);
- MethodInfo miObjectFromHandle = tHwnd.GetMethod("ObjectFromHandle",
- BindingFlags.Public | BindingFlags.Static);
- object oHwnd = miObjectFromHandle.Invoke(null, new object[] { f.Handle });
-
- FieldInfo fiWholeWindow = tHwnd.GetField("whole_window",
- BindingFlags.NonPublic | BindingFlags.Instance);
- IntPtr hWindow = (IntPtr)fiWholeWindow.GetValue(oHwnd);
-
- XClassHint xch = new XClassHint();
- xch.res_name = Marshal.StringToCoTaskMemAnsi(strName ?? string.Empty);
- xch.res_class = Marshal.StringToCoTaskMemAnsi(strClass ?? string.Empty);
- IntPtr pXch = Marshal.AllocCoTaskMem(Marshal.SizeOf(xch));
- Marshal.StructureToPtr(xch, pXch, false);
-
- XSetClassHint(hDisplay, hWindow, pXch);
-
- Marshal.FreeCoTaskMem(pXch);
- Marshal.FreeCoTaskMem(xch.res_name);
- Marshal.FreeCoTaskMem(xch.res_class);
- }
- catch(Exception) { Debug.Assert(false); }
- }
-#endif
- }
-}
diff --git a/src/KeePassLib2Android/Properties/AssemblyInfo.cs b/src/KeePassLib2Android/Properties/AssemblyInfo.cs
deleted file mode 100644
index 6b1bdc1d..00000000
--- a/src/KeePassLib2Android/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- KeePass Password Safe - The Open-Source Password Manager
- Copyright (C) 2003-2017 Dominik Reichl
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General assembly properties
-[assembly: AssemblyTitle("KeePassLib")]
-[assembly: AssemblyDescription("KeePass Password Management Library")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Dominik Reichl")]
-[assembly: AssemblyProduct("KeePassLib")]
-[assembly: AssemblyCopyright("Copyright © 2003-2017 Dominik Reichl")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// COM settings
-[assembly: ComVisible(false)]
-
-// Assembly GUID
-[assembly: Guid("395f6eec-a1e0-4438-aa82-b75099348134")]
-
-// Assembly version information
-[assembly: AssemblyVersion("2.35.0.*")]
-[assembly: AssemblyFileVersion("2.35.0.0")]
diff --git a/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs b/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs
index b2fe6df2..930b3eaf 100644
--- a/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs
+++ b/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs
@@ -107,7 +107,7 @@ namespace KeePassLib.Serialization
try
{
Stream sXml;
- if (fmt == KdbxFormat.Default || fmt == KdbxFormat.ProtocolBuffers)
+ if (fmt == KdbxFormat.Default)
{
BinaryReaderEx br = new BinaryReaderEx(sHashing,
encNoBom, KLRes.FileCorrupted);
@@ -229,10 +229,7 @@ namespace KeePassLib.Serialization
if (fmt == KdbxFormat.ProtocolBuffers)
{
- KdbpFile.ReadDocument(m_pwDatabase, sXml, m_pbInnerRandomStreamKey, m_pbHashOfHeader);
-
- Kp2aLog.Log(String.Format("KdbpFile.ReadDocument: {0}ms", stopWatch.ElapsedMilliseconds));
-
+ throw new Exception("kdbp is deprecated and was removed to simplify the build process.");
}
else
{
diff --git a/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs b/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs
index 232b06e0..077831fd 100644
--- a/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs
+++ b/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs
@@ -210,35 +210,29 @@ namespace KeePassLib.Serialization
var stopWatch = Stopwatch.StartNew();
- if (m_format == KdbxFormat.ProtocolBuffers)
- {
- KdbpFile.WriteDocument(m_pwDatabase, sXml, m_pbInnerRandomStreamKey, m_pbHashOfHeader);
- }
- else
- {
#if KeePassUAP
- XmlWriterSettings xws = new XmlWriterSettings();
- xws.Encoding = encNoBom;
- xws.Indent = true;
- xws.IndentChars = "\t";
- xws.NewLineOnAttributes = false;
+ XmlWriterSettings xws = new XmlWriterSettings();
+ xws.Encoding = encNoBom;
+ xws.Indent = true;
+ xws.IndentChars = "\t";
+ xws.NewLineOnAttributes = false;
- XmlWriter xw = XmlWriter.Create(sXml, xws);
+ XmlWriter xw = XmlWriter.Create(sXml, xws);
#else
- XmlTextWriter xw = new XmlTextWriter(sXml, encNoBom);
+ XmlTextWriter xw = new XmlTextWriter(sXml, encNoBom);
- xw.Formatting = Formatting.Indented;
- xw.IndentChar = '\t';
- xw.Indentation = 1;
+ xw.Formatting = Formatting.Indented;
+ xw.IndentChar = '\t';
+ xw.Indentation = 1;
#endif
- m_xmlWriter = xw;
+ m_xmlWriter = xw;
WriteDocument(pgRoot);
- m_xmlWriter.Flush();
- m_xmlWriter.Close();
- }
+ m_xmlWriter.Flush();
+ m_xmlWriter.Close();
+
Kp2aLog.Log(String.Format("{1}: {0}ms", stopWatch.ElapsedMilliseconds, m_format == KdbxFormat.ProtocolBuffers ? "KdbpFile.WriteDocument" : "Xml WriteDocument"));
}
diff --git a/src/KeePassLib2Android/Serialization/KdbxFile.cs b/src/KeePassLib2Android/Serialization/KdbxFile.cs
index 2fff60c5..ab762af8 100644
--- a/src/KeePassLib2Android/Serialization/KdbxFile.cs
+++ b/src/KeePassLib2Android/Serialization/KdbxFile.cs
@@ -59,6 +59,8 @@ namespace KeePassLib.Serialization
/// Use this flag when exporting data to a plain-text XML file.
///
PlainXml,
+
+ //Deprecated
ProtocolBuffers
}
diff --git a/src/KeePassLib2Android/Serialization/ProtoBuf/KdbpFile.cs b/src/KeePassLib2Android/Serialization/ProtoBuf/KdbpFile.cs
deleted file mode 100644
index c5b5f669..00000000
--- a/src/KeePassLib2Android/Serialization/ProtoBuf/KdbpFile.cs
+++ /dev/null
@@ -1,1444 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.IO;
-using KeePassLib.Collections;
-using KeePassLib.Cryptography;
-using KeePassLib.Security;
-using KeePassLib.Utility;
-using ProtoBuf;
-using ProtoBuf.Meta;
-
-namespace KeePassLib.Serialization
-{
- public class KdbpFile
- {
- public const string FileNameExtension = "kdbp";
-
- ///
- /// Precompiles the serializer classes for faster first-run execution
- ///
- public static void PrepareSerializer()
- {
- RuntimeTypeModel.Default[typeof(PwDatabaseBuffer)].CompileInPlace();
- }
-
- ///
- /// Determines whether the database pointed to by the specified ioc should be (de)serialised in default (xml) or protocol buffers format.
- ///
- public static KdbxFormat GetFormatToUse(string fileExt)
- {
- return fileExt.Equals(KdbpFile.FileNameExtension, StringComparison.OrdinalIgnoreCase) ? KdbxFormat.ProtocolBuffers :
- (fileExt.Equals("xml", StringComparison.OrdinalIgnoreCase) ? KdbxFormat.PlainXml : KdbxFormat.Default);
- }
-
- public static void WriteDocument(PwDatabase database, Stream stream, byte[] protectedStreamKey, byte[] hashOfHeader)
- {
- var context = new SerializationContext
- {
- Context = new BufferContext(database,
- new CryptoRandomStream(CrsAlgorithm.Salsa20, protectedStreamKey), hashOfHeader)
- };
-
- RuntimeTypeModel.Default.Serialize(stream, new PwDatabaseBuffer(database), context);
- }
-
- public static void ReadDocument(PwDatabase database, Stream stream, byte[] protectedStreamKey, byte[] expectedHashOfHeader)
- {
-
- var context = new BufferContext(database, new CryptoRandomStream(CrsAlgorithm.Salsa20, protectedStreamKey));
-
- // Deserialisation will occur into the database already in context.
- RuntimeTypeModel.Default.Deserialize(stream, null, typeof(PwDatabaseBuffer), new SerializationContext { Context = context });
-
- if (expectedHashOfHeader.Length > 0 &&
- !KeePassLib.Utility.MemUtil.ArraysEqual(context.HeaderHash, expectedHashOfHeader))
- {
- throw new IOException(KeePassLib.Resources.KLRes.FileCorrupted);
- }
- }
-
- private class BufferContext
- {
- // ProtectedBinary objects may be referred to multipe times by entry histories, so reference them only once by ensuring a 1:1 mapping to the buffer wrapping them.
- public readonly Dictionary BinaryPool = new Dictionary();
-
- public readonly PwDatabase Database;
- public readonly CryptoRandomStream RandomStream;
- public byte[] HeaderHash;
-
- public BufferContext(PwDatabase database, CryptoRandomStream randomStream, byte[] pbHashOfHeader = null)
- {
- Database = database;
- RandomStream = randomStream;
- HeaderHash = pbHashOfHeader;
- }
- }
-
- [ProtoContract]
- private class PwDatabaseBuffer
- {
- #region Serialization
-
- private PwDatabase mDatabase;
- private PwDeletedObjectListBuffer mDeletedObjects;
- private PwCustomIconListBuffer mCustomIcons;
-
- public PwDatabaseBuffer(PwDatabase database)
- {
- mDatabase = database;
- mDeletedObjects = new PwDeletedObjectListBuffer(mDatabase.DeletedObjects);
- mCustomIcons = new PwCustomIconListBuffer(mDatabase.CustomIcons);
- }
-
- [ProtoBeforeSerialization]
- private void BeforeSerialization(SerializationContext context)
- {
- var bufferContext = (BufferContext)context.Context;
-
- System.Diagnostics.Debug.Assert(mDatabase == bufferContext.Database);
-
- HeaderHash = bufferContext.HeaderHash;
- }
- #endregion
-
- #region Deserialization
- public PwDatabaseBuffer()
- {
- }
-
- [ProtoBeforeDeserialization]
- private void BeforeDeserialization(SerializationContext context)
- {
- var bufferContext = (BufferContext)context.Context;
-
- mDatabase = bufferContext.Database;
- mDeletedObjects = new PwDeletedObjectListBuffer(mDatabase.DeletedObjects);
- mCustomIcons = new PwCustomIconListBuffer(mDatabase.CustomIcons);
- }
-
- [ProtoAfterDeserialization]
- private void AfterDeserialization(SerializationContext context)
- {
- var bufferContext = (BufferContext)context.Context;
-
- bufferContext.HeaderHash = HeaderHash;
- }
- #endregion
-
- [ProtoMember(1)]
- public string Generator
- {
- get { return PwDatabase.LocalizedAppName; }
- set { /* Ignore */ }
- }
-
- [ProtoMember(2, OverwriteList = true)]
- public byte[] HeaderHash;
-
- [ProtoMember(3)]
- public string Name
- {
- get { return mDatabase.Name; }
- set { mDatabase.Name = value; }
- }
-
- [ProtoMember(4)]
- public DateTime NameChanged
- {
- get { return mDatabase.NameChanged.ToUniversalTime(); }
- set { mDatabase.NameChanged = value.ToLocalTime(); }
- }
-
- [ProtoMember(5)]
- public string Description
- {
- get { return mDatabase.Description; }
- set { mDatabase.Description = value; }
- }
-
- [ProtoMember(6)]
- public DateTime DescriptionChanged
- {
- get { return mDatabase.DescriptionChanged.ToUniversalTime(); }
- set { mDatabase.DescriptionChanged = value.ToLocalTime(); }
- }
-
- [ProtoMember(7)]
- public string DefaultUserName
- {
- get { return mDatabase.DefaultUserName; }
- set { mDatabase.DefaultUserName = value; }
- }
-
- [ProtoMember(8)]
- public DateTime DefaultUserNameChanged
- {
- get { return mDatabase.DefaultUserNameChanged.ToUniversalTime(); }
- set { mDatabase.DefaultUserNameChanged = value.ToLocalTime(); }
- }
-
- [ProtoMember(9)]
- public uint MaintenanceHistoryDays
- {
- get { return mDatabase.MaintenanceHistoryDays; }
- set { mDatabase.MaintenanceHistoryDays = value; }
- }
-
- [ProtoMember(10)]
- public int Color
- {
- get { return mDatabase.Color.ToArgb(); }
- set { mDatabase.Color = System.Drawing.Color.FromArgb(value); }
- }
-
- [ProtoMember(11)]
- public DateTime MasterKeyChanged
- {
- get { return mDatabase.MasterKeyChanged.ToUniversalTime(); }
- set { mDatabase.MasterKeyChanged = value.ToLocalTime(); }
- }
-
- [ProtoMember(12)]
- public long MasterKeyChangeRec
- {
- get { return mDatabase.MasterKeyChangeRec; }
- set { mDatabase.MasterKeyChangeRec = value; }
- }
-
- [ProtoMember(13)]
- public long MasterKeyChangeForce
- {
- get { return mDatabase.MasterKeyChangeForce; }
- set { mDatabase.MasterKeyChangeForce = value; }
- }
-
- [ProtoMember(14)]
- public MemoryProtectionConfigBuffer MemoryProtection
- {
- get { return new MemoryProtectionConfigBuffer(mDatabase.MemoryProtection); }
- set { mDatabase.MemoryProtection = value.MemoryProtectionConfig; }
- }
-
- [ProtoMember(15)]
- public PwCustomIconListBuffer CustomIcons
- {
- get { return mCustomIcons; }
- }
-
- [ProtoMember(16)]
- public bool RecycleBinEnabled
- {
- get { return mDatabase.RecycleBinEnabled; }
- set { mDatabase.RecycleBinEnabled = value; }
- }
-
- [ProtoMember(17, OverwriteList = true)]
- public byte[] RecycleBinUuid
- {
- get { return mDatabase.RecycleBinUuid.UuidBytes; }
- set { mDatabase.RecycleBinUuid = new PwUuid(value); }
- }
-
- [ProtoMember(18)]
- public DateTime RecycleBinChanged
- {
- get { return mDatabase.RecycleBinChanged.ToUniversalTime(); }
- set { mDatabase.RecycleBinChanged = value.ToLocalTime(); }
- }
-
- [ProtoMember(19, OverwriteList = true)]
- public byte[] EntryTemplatesGroup
- {
- get { return mDatabase.EntryTemplatesGroup.UuidBytes; }
- set { mDatabase.EntryTemplatesGroup = new PwUuid(value); }
- }
-
- [ProtoMember(20)]
- public DateTime EntryTemplatesGroupChanged
- {
- get { return mDatabase.EntryTemplatesGroupChanged.ToUniversalTime(); }
- set { mDatabase.EntryTemplatesGroupChanged = value.ToLocalTime(); }
- }
-
- [ProtoMember(21)]
- public int HistoryMaxItems
- {
- get { return mDatabase.HistoryMaxItems; }
- set { mDatabase.HistoryMaxItems = value; }
- }
-
- [ProtoMember(22)]
- public long HistoryMaxSize
- {
- get { return mDatabase.HistoryMaxSize; }
- set { mDatabase.HistoryMaxSize = value; }
- }
-
- [ProtoMember(23, OverwriteList = true)]
- public byte[] LastSelectedGroup
- {
- get { return mDatabase.LastSelectedGroup.UuidBytes; }
- set { mDatabase.LastSelectedGroup = new PwUuid(value); }
- }
-
- [ProtoMember(24, OverwriteList = true)]
- public byte[] LastTopVisibleGroup
- {
- get { return mDatabase.LastTopVisibleGroup.UuidBytes; }
- set { mDatabase.LastTopVisibleGroup = new PwUuid(value); }
- }
-
- [ProtoMember(25)]
- public StringDictionaryExBuffer CustomData
- {
- get { return new StringDictionaryExBuffer(mDatabase.CustomData); }
- set { mDatabase.CustomData = value.StringDictionaryEx; }
- }
-
- [ProtoMember(27)]
- public PwGroupBuffer RootGroup
- {
- get { return new PwGroupBuffer(mDatabase.RootGroup); }
- set { mDatabase.RootGroup = value.Group; }
- }
-
- [ProtoMember(28)]
- public PwDeletedObjectListBuffer DeletedObjects
- {
- get { return mDeletedObjects; }
- }
- }
-
- [ProtoContract]
- private class StringDictionaryExBuffer : IEnumerable>
- {
- #region Serialization
- private StringDictionaryEx mStringDictionaryEx;
-
- public StringDictionaryExBuffer(StringDictionaryEx stringDictionaryEx)
- {
- mStringDictionaryEx = stringDictionaryEx;
- }
- #endregion
-
- #region Deserialization
- public StringDictionaryExBuffer()
- {
- mStringDictionaryEx = new StringDictionaryEx();
- }
-
- public StringDictionaryEx StringDictionaryEx { get { return mStringDictionaryEx; } }
-
- public void Add(KeyValuePair kvp)
- {
- mStringDictionaryEx.Set(kvp.Key, kvp.Value);
- }
- #endregion
-
- public IEnumerator> GetEnumerator()
- {
- return mStringDictionaryEx.GetEnumerator();
- }
-
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- }
-
- [ProtoContract]
- private class PwCustomIconListBuffer : IEnumerable
- {
- private List mCustomIcons;
- #region Serialization
- public PwCustomIconListBuffer(List customIcons)
- {
- mCustomIcons = customIcons;
- }
- #endregion
-
- #region Deserialization
- public void Add(PwCustomIconBuffer item)
- {
- mCustomIcons.Add(item.CustomIcon);
- }
- #endregion
-
- public IEnumerator GetEnumerator()
- {
- foreach (var customIcon in mCustomIcons)
- {
- yield return new PwCustomIconBuffer(customIcon);
- }
- }
-
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- }
-
- [ProtoContract]
- private class PwCustomIconBuffer
- {
- #region Serialization
- private PwCustomIcon mCustomIcon;
- public PwCustomIconBuffer(PwCustomIcon CustomIcon)
- {
- mCustomIcon = CustomIcon;
- Uuid = mCustomIcon.Uuid.UuidBytes;
- ImageData = mCustomIcon.ImageDataPng;
- }
- #endregion
-
- #region Deserialization
- public PwCustomIconBuffer()
- {
- }
-
- [ProtoAfterDeserialization]
- private void AfterDeserialization(SerializationContext context)
- {
- mCustomIcon = new PwCustomIcon(new PwUuid(Uuid), ImageData);
- }
-
- public PwCustomIcon CustomIcon { get { return mCustomIcon; } }
- #endregion
-
- [ProtoMember(1, OverwriteList = true)]
- public byte[] Uuid;
-
- [ProtoMember(2, OverwriteList = true)]
- public byte[] ImageData;
- }
-
- [ProtoContract]
- private class MemoryProtectionConfigBuffer
- {
- #region Serialization
- private readonly MemoryProtectionConfig mMemoryProtectionConfig;
-
- public MemoryProtectionConfigBuffer(MemoryProtectionConfig memoryProtectionConfig)
- {
- mMemoryProtectionConfig = memoryProtectionConfig;
- }
- #endregion
-
- #region Deserialization
- public MemoryProtectionConfigBuffer()
- {
- mMemoryProtectionConfig = new MemoryProtectionConfig();
- }
-
- public MemoryProtectionConfig MemoryProtectionConfig { get { return mMemoryProtectionConfig; } }
- #endregion
-
- [ProtoMember(1)]
- public bool ProtectTitle
- {
- get { return mMemoryProtectionConfig.ProtectTitle; }
- set { mMemoryProtectionConfig.ProtectTitle = value; }
- }
-
- [ProtoMember(2)]
- public bool ProtectUserName
- {
- get { return mMemoryProtectionConfig.ProtectUserName; }
- set { mMemoryProtectionConfig.ProtectUserName = value; }
- }
-
- [ProtoMember(3)]
- public bool ProtectPassword
- {
- get { return mMemoryProtectionConfig.ProtectPassword; }
- set { mMemoryProtectionConfig.ProtectPassword = value; }
- }
-
- [ProtoMember(4)]
- public bool ProtectUrl
- {
- get { return mMemoryProtectionConfig.ProtectUrl; }
- set { mMemoryProtectionConfig.ProtectUrl = value; }
- }
-
- [ProtoMember(5)]
- public bool ProtectNotes
- {
- get { return mMemoryProtectionConfig.ProtectNotes; }
- set { mMemoryProtectionConfig.ProtectNotes = value; }
- }
- }
-
- [ProtoContract]
- private class PwDeletedObjectListBuffer : PwObjectListBufferBase
- {
- #region Serialization
- public PwDeletedObjectListBuffer(PwObjectList objectList)
- : base(objectList)
- {
- }
-
- protected override PwDeletedObjectBuffer CreateBuffer(PwDeletedObject item)
- {
- return new PwDeletedObjectBuffer(item);
- }
- #endregion
-
- #region Deserialization
- public PwDeletedObjectListBuffer()
- : base()
- {
- }
-
- public override void Add(PwDeletedObjectBuffer item)
- {
- ObjectList.Add(item.DeletedObject);
- }
- #endregion
- }
-
- [ProtoContract]
- private class PwDeletedObjectBuffer
- {
- #region Serialization
- private readonly PwDeletedObject mDeletedObject;
-
- public PwDeletedObjectBuffer(PwDeletedObject deletedObject)
- {
- mDeletedObject = deletedObject;
- }
- #endregion
-
- #region Deserialization
- public PwDeletedObjectBuffer()
- {
- mDeletedObject = new PwDeletedObject();
- }
-
- public PwDeletedObject DeletedObject { get { return mDeletedObject; } }
- #endregion
-
- [ProtoMember(1, OverwriteList = true)]
- public byte[] Uuid
- {
- get { return mDeletedObject.Uuid.UuidBytes; }
- set { mDeletedObject.Uuid = new PwUuid(value); }
- }
-
- [ProtoMember(2)]
- public DateTime DeletionTime
- {
- get { return mDeletedObject.DeletionTime.ToUniversalTime(); }
- set { mDeletedObject.DeletionTime = value.ToLocalTime(); }
- }
- }
-
- [ProtoContract]
- private class PwGroupBuffer
- {
- #region Serialization
- private readonly PwGroup mGroup;
- private readonly PwGroupEntryListBuffer mEntries;
- private readonly PwGroupGroupListBuffer mGroups;
-
- public PwGroupBuffer(PwGroup group)
- {
- mGroup = group;
- mEntries = new PwGroupEntryListBuffer(mGroup);
- mGroups = new PwGroupGroupListBuffer(mGroup);
- }
- #endregion
-
- #region Deserialization
- public PwGroupBuffer()
- {
- mGroup = new PwGroup(false, false);
- mEntries = new PwGroupEntryListBuffer(mGroup);
- mGroups = new PwGroupGroupListBuffer(mGroup);
- }
-
- public PwGroup Group { get { return mGroup; } }
- #endregion
-
- [ProtoMember(1, OverwriteList = true)]
- public byte[] Uuid
- {
- get { return mGroup.Uuid.UuidBytes; }
- set { mGroup.Uuid = new PwUuid(value); }
- }
-
- [ProtoMember(2)]
- public string Name
- {
- get { return mGroup.Name; }
- set { mGroup.Name = value; }
- }
-
- [ProtoMember(3)]
- public string Notes
- {
- get { return mGroup.Notes; }
- set { mGroup.Notes = value; }
- }
-
- [ProtoMember(4)]
- public PwIcon IconId
- {
- get { return mGroup.IconId; }
- set { mGroup.IconId = value; }
- }
-
- [ProtoMember(5, OverwriteList = true)]
- public byte[] CustomIconUuid
- {
- get { return mGroup.CustomIconUuid.Equals(PwUuid.Zero) ? null : mGroup.CustomIconUuid.UuidBytes; ; }
- set { mGroup.CustomIconUuid = value == null ? PwUuid.Zero : new PwUuid(value); }
- }
-
- [ProtoMember(6)]
- public bool IsExpanded
- {
- get { return mGroup.IsExpanded; }
- set { mGroup.IsExpanded = value; }
- }
-
- [ProtoMember(7)]
- public string DefaultAutoTypeSequence
- {
- get { return mGroup.DefaultAutoTypeSequence; }
- set { mGroup.DefaultAutoTypeSequence = value; }
- }
-
- [ProtoMember(8)]
- public DateTime LastModificationTime
- {
- get { return mGroup.LastModificationTime.ToUniversalTime(); }
- set { mGroup.LastModificationTime = value.ToLocalTime(); }
- }
-
- [ProtoMember(9)]
- public DateTime CreationTime
- {
- get { return mGroup.CreationTime.ToUniversalTime(); }
- set { mGroup.CreationTime = value.ToLocalTime(); }
- }
-
- [ProtoMember(10)]
- public DateTime LastAccessTime
- {
- get { return mGroup.LastAccessTime.ToUniversalTime(); }
- set { mGroup.LastAccessTime = value.ToLocalTime(); }
- }
-
- [ProtoMember(11)]
- public DateTime ExpiryTime
- {
- get { return mGroup.ExpiryTime.ToUniversalTime(); }
- set { mGroup.ExpiryTime = value.ToLocalTime(); }
- }
-
- [ProtoMember(12)]
- public bool Expires
- {
- get { return mGroup.Expires; }
- set { mGroup.Expires = value; }
- }
-
- [ProtoMember(13)]
- public ulong UsageCount
- {
- get { return mGroup.UsageCount; }
- set { mGroup.UsageCount = value; }
- }
-
- [ProtoMember(14)]
- public DateTime LocationChanged
- {
- get { return mGroup.LocationChanged.ToUniversalTime(); }
- set { mGroup.LocationChanged = value.ToLocalTime(); }
- }
-
- [ProtoMember(15)]
- public bool? EnableAutoType
- {
- get { return mGroup.EnableAutoType; }
- set { mGroup.EnableAutoType = value; }
- }
-
- [ProtoMember(16)]
- public bool? EnableSearching
- {
- get { return mGroup.EnableSearching; }
- set { mGroup.EnableSearching = value; }
- }
-
- [ProtoMember(17, OverwriteList = true)]
- public byte[] LastTopVisibleEntry
- {
- get { return mGroup.LastTopVisibleEntry.UuidBytes; }
- set { mGroup.LastTopVisibleEntry = new PwUuid(value); }
- }
-
- [ProtoMember(18)]
- public PwGroupGroupListBuffer Groups
- {
- get { return mGroups; }
- }
-
- [ProtoMember(19)]
- public PwGroupEntryListBuffer Entries
- {
- get { return mEntries; }
- }
- }
-
- private abstract class PwObjectListBufferBase : IEnumerable
- where TData : class, KeePassLib.Interfaces.IDeepCloneable
- {
- #region Serialization
- private PwObjectList mObjectList;
-
- protected PwObjectListBufferBase(PwObjectList objectList)
- {
- mObjectList = objectList;
- }
-
- protected abstract TDataBuffer CreateBuffer(TData item);
- #endregion
-
- #region Deserialization
- protected PwObjectListBufferBase()
- {
- mObjectList = new PwObjectList();
- }
-
- public PwObjectList ObjectList { get { return mObjectList; } }
-
- public abstract void Add(TDataBuffer item);
- #endregion
-
- public IEnumerator GetEnumerator()
- {
- foreach (var item in mObjectList)
- {
- yield return CreateBuffer(item);
- }
- }
-
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- }
-
- [ProtoContract]
- private class PwGroupGroupListBuffer : PwObjectListBufferBase
- {
- #region Serialization
- private PwGroup mGroup;
- public PwGroupGroupListBuffer(PwGroup group)
- : base(group.Groups)
- {
- mGroup = group;
- }
-
- protected override PwGroupBuffer CreateBuffer(PwGroup item)
- {
- return new PwGroupBuffer(item);
- }
- #endregion
-
- #region Deserialization
- public override void Add(PwGroupBuffer item)
- {
- mGroup.AddGroup(item.Group, true);
- }
- #endregion
- }
-
- [ProtoContract]
- private class PwGroupEntryListBuffer : PwObjectListBufferBase
- {
- #region Serialization
- private PwGroup mGroup;
- public PwGroupEntryListBuffer(PwGroup group)
- : base(group.Entries)
- {
- mGroup = group;
- }
-
- protected override PwEntryBuffer CreateBuffer(PwEntry item)
- {
- return new PwEntryBuffer(item);
- }
- #endregion
-
- #region Deserialization
- public override void Add(PwEntryBuffer item)
- {
- mGroup.AddEntry(item.Entry, true);
- }
- #endregion
- }
-
- [ProtoContract]
- private class PwEntryListBuffer : PwObjectListBufferBase
- {
- #region Serialization
- public PwEntryListBuffer(PwObjectList entryList)
- : base(entryList)
- {
- }
-
- protected override PwEntryBuffer CreateBuffer(PwEntry item)
- {
- return new PwEntryBuffer(item);
- }
- #endregion
-
- #region Deserialization
- public PwEntryListBuffer()
- : base()
- {
- }
-
- public override void Add(PwEntryBuffer item)
- {
- ObjectList.Add(item.Entry);
- }
- #endregion
- }
-
- [ProtoContract]
- private class PwEntryBuffer
- {
- #region Serialization
- private readonly PwEntry mEntry;
- private ProtectedStandardFieldDictionaryBuffer mEntryStandardStrings;
- private ProtectedCustomFieldDictionaryBuffer mEntryCustomStrings;
- private NamedProtectedBinaryListBuffer mEntryBinaries;
-
- public PwEntryBuffer(PwEntry entry)
- {
- mEntry = entry;
- }
-
- [ProtoBeforeSerialization]
- private void BeforeSerialization(SerializationContext context)
- {
- var bufferContext = (BufferContext)context.Context;
-
- // ProtectedStringDictionaryBuffer nver gets its own ProtoBeforeSerialization called as it's a list of objects rather than an object itself
- List> customFields;
- mEntryStandardStrings = new ProtectedStandardFieldDictionaryBuffer(mEntry.Strings, (int)mEntry.Strings.UCount, bufferContext, out customFields);
- mEntryCustomStrings = new ProtectedCustomFieldDictionaryBuffer(customFields);
- mEntryBinaries = new NamedProtectedBinaryListBuffer(mEntry.Binaries, (int)mEntry.Binaries.UCount, bufferContext);
- }
- #endregion
-
- #region Deserialization
- public PwEntryBuffer()
- {
- mEntry = new PwEntry(false, false);
- mEntryStandardStrings = new ProtectedStandardFieldDictionaryBuffer(mEntry.Strings);
- mEntryCustomStrings = new ProtectedCustomFieldDictionaryBuffer(mEntry.Strings);
- mEntryBinaries = new NamedProtectedBinaryListBuffer(mEntry.Binaries);
- }
-
- public PwEntry Entry { get { return mEntry; } }
- #endregion
-
- [ProtoMember(1, OverwriteList = true)]
- public byte[] Uuid
- {
- get { return mEntry.Uuid.UuidBytes; }
- set { mEntry.SetUuid(new PwUuid(value), false); }
- }
-
- [ProtoMember(2)]
- public PwIcon IconId
- {
- get { return mEntry.IconId; }
- set { mEntry.IconId = value; }
- }
-
- [ProtoMember(3, OverwriteList = true)]
- public byte[] CustomIconUuid
- {
- get { return mEntry.CustomIconUuid.Equals(PwUuid.Zero) ? null : mEntry.CustomIconUuid.UuidBytes; }
- set { mEntry.CustomIconUuid = value == null ? PwUuid.Zero : new PwUuid(value); }
- }
-
- [ProtoMember(4)]
- public int ForegroundColor
- {
- get { return mEntry.ForegroundColor.ToArgb(); }
- set { mEntry.ForegroundColor = Color.FromArgb(value); }
- }
-
- [ProtoMember(5)]
- public int BackgroundColor
- {
- get { return mEntry.BackgroundColor.ToArgb(); }
- set { mEntry.BackgroundColor = Color.FromArgb(value); }
- }
-
- [ProtoMember(6)]
- public string OverrideUrl
- {
- get { return mEntry.OverrideUrl; }
- set { mEntry.OverrideUrl = value; }
- }
-
- [ProtoMember(7)]
- public IList Tags
- {
- get { return mEntry.Tags; }
- }
-
- [ProtoMember(8)]
- public DateTime LastModificationTime
- {
- get { return mEntry.LastModificationTime.ToUniversalTime(); }
- set { mEntry.LastModificationTime = value.ToLocalTime(); }
- }
-
- [ProtoMember(9)]
- public DateTime CreationTime
- {
- get { return mEntry.CreationTime.ToUniversalTime(); }
- set { mEntry.CreationTime = value.ToLocalTime(); }
- }
-
- [ProtoMember(10)]
- public DateTime LastAccessTime
- {
- get { return mEntry.LastAccessTime.ToUniversalTime(); }
- set { mEntry.LastAccessTime = value.ToLocalTime(); }
- }
-
- [ProtoMember(11)]
- public DateTime ExpiryTime
- {
- get { return mEntry.ExpiryTime.ToUniversalTime(); }
- set { mEntry.ExpiryTime = value.ToLocalTime(); }
- }
-
- [ProtoMember(12)]
- public bool Expires
- {
- get { return mEntry.Expires; }
- set { mEntry.Expires = value; }
- }
-
- [ProtoMember(13)]
- public ulong UsageCount
- {
- get { return mEntry.UsageCount; }
- set { mEntry.UsageCount = value; }
- }
-
- [ProtoMember(14)]
- public DateTime LocationChanged
- {
- get { return mEntry.LocationChanged.ToUniversalTime(); }
- set { mEntry.LocationChanged = value.ToLocalTime(); }
- }
-
- [ProtoMember(15)]
- public ProtectedStandardFieldDictionaryBuffer StandardStrings
- {
- get { return mEntryStandardStrings; }
- }
-
- [ProtoMember(16)]
- public ProtectedCustomFieldDictionaryBuffer CustomStrings
- {
- get { return mEntryCustomStrings; }
- }
-
- [ProtoMember(17, AsReference = true)]
- public NamedProtectedBinaryListBuffer Binaries
- {
- get { return mEntryBinaries; }
- }
-
- [ProtoMember(18)]
- public AutoTypeConfigBuffer AutoType
- {
- get { return new AutoTypeConfigBuffer(mEntry.AutoType); }
- set { mEntry.AutoType = value.AutoTypeConfig; }
- }
-
- [ProtoMember(19)]
- public PwEntryListBuffer History
- {
- get { return new PwEntryListBuffer(mEntry.History); }
- set { mEntry.History = value.ObjectList; }
- }
-
- }
-
- private abstract class ProtectedStringDictionaryBuffer : IEnumerable>
- {
- #region Serialization
- private List> mProtectedStringBuffers;
-
- ///
- /// Serialisation constructor. Reads strings from dictionary, does not write to it
- ///
- protected ProtectedStringDictionaryBuffer(int capacity)
- {
- mProtectedStringBuffers = new List>(capacity);
- }
-
- protected void AddStringField(TKey key, ProtectedString value, bool? overrideProtect)
- {
- mProtectedStringBuffers.Add(new KeyValuePair(key, new ProtectedStringBuffer(value, overrideProtect)));
- }
-
- public IEnumerator> GetEnumerator()
- {
- return mProtectedStringBuffers.GetEnumerator();
- }
-
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- #endregion
-
- #region Deserialization
- private readonly ProtectedStringDictionary mDictionary;
-
- ///
- /// Deerialisation constructor. Writes strings to dictionary, does read from it
- ///
- protected ProtectedStringDictionaryBuffer(ProtectedStringDictionary dictionary)
- {
- mDictionary = dictionary;
- }
-
- public void Add(KeyValuePair item)
- {
- mDictionary.Set(GetFieldName(item.Key), item.Value.ProtectedString);
- }
-
- protected abstract string GetFieldName(TKey key);
-
- #endregion
- }
-
- [ProtoContract]
- private class ProtectedCustomFieldDictionaryBuffer : ProtectedStringDictionaryBuffer
- {
- public ProtectedCustomFieldDictionaryBuffer(List> entryStrings)
- : base(entryStrings.Count)
- {
- foreach (var kvp in entryStrings)
- {
- System.Diagnostics.Debug.Assert(!PwDefs.IsStandardField(kvp.Key));
- AddStringField(kvp.Key, kvp.Value, null);
- }
- }
-
- public ProtectedCustomFieldDictionaryBuffer(ProtectedStringDictionary dictionary)
- : base(dictionary)
- { }
-
- protected override string GetFieldName(string key)
- {
- return key;
- }
- }
-
- [ProtoContract]
- private class ProtectedStandardFieldDictionaryBuffer : ProtectedStringDictionaryBuffer
- {
- public enum StandardField
- {
- Title,
- UserName,
- Password,
- Url,
- Notes
- }
-
- public ProtectedStandardFieldDictionaryBuffer(IEnumerable> entryStrings, int entryStringCount, BufferContext context,
- out List> customFields) // Perf optimisation - return the custom fields so we don't have to determine them again
- : base(entryStringCount)
- {
- customFields = new List>(entryStringCount);
-
- var database = context.Database;
-
- foreach (var kvp in entryStrings)
- {
- var field = GetField(kvp.Key);
-
- if (field.HasValue)
- {
- // Logic from KdbxFile.Write
-
- bool? overrideProtect = null;
- // Adjust memory protection setting (which might be different
- // from the database default, e.g. due to an import which
- // didn't specify the correct setting)
- switch (field.Value)
- {
- case StandardField.Title:
- overrideProtect = database.MemoryProtection.ProtectTitle;
- break;
- case StandardField.UserName:
- overrideProtect = database.MemoryProtection.ProtectUserName;
- break;
- case StandardField.Password:
- overrideProtect = database.MemoryProtection.ProtectPassword;
- break;
- case StandardField.Url:
- overrideProtect = database.MemoryProtection.ProtectUrl;
- break;
- case StandardField.Notes:
- overrideProtect = database.MemoryProtection.ProtectNotes;
- break;
- }
-
- AddStringField(field.Value, kvp.Value, overrideProtect);
- }
- else
- {
- customFields.Add(kvp);
- }
- }
- }
-
- private static StandardField? GetField(string fieldName)
- {
- switch (fieldName)
- {
- case PwDefs.TitleField:
- return StandardField.Title;
- case PwDefs.UserNameField:
- return StandardField.UserName;
- case PwDefs.PasswordField:
- return StandardField.Password;
- case PwDefs.UrlField:
- return StandardField.Url;
- case PwDefs.NotesField:
- return StandardField.Notes;
-
- default:
- System.Diagnostics.Debug.Assert(!PwDefs.IsStandardField(fieldName));
- return null;
- }
- }
-
- public ProtectedStandardFieldDictionaryBuffer(ProtectedStringDictionary dictionary)
- : base(dictionary)
- { }
-
- protected override string GetFieldName(StandardField key)
- {
- switch (key)
- {
- case StandardField.Title:
- return PwDefs.TitleField;
- case StandardField.UserName:
- return PwDefs.UserNameField;
- case StandardField.Password:
- return PwDefs.PasswordField;
- case StandardField.Url:
- return PwDefs.UrlField;
- case StandardField.Notes:
- return PwDefs.NotesField;
- default:
- throw new ArgumentOutOfRangeException();
- }
- }
- }
-
- [ProtoContract]
- private class ProtectedStringBuffer
- {
- #region Serialisation
- private ProtectedString mProtectedString;
-
- public ProtectedStringBuffer(ProtectedString protectedString, bool? overrideProtect)
- {
- mProtectedString = protectedString;
- IsProtected = overrideProtect.GetValueOrDefault(mProtectedString.IsProtected);
- }
-
- [ProtoBeforeSerialization]
- private void BeforeSerialization(SerializationContext context)
- {
- if (IsProtected)
- {
- Value = mProtectedString.ReadXorredString(((BufferContext)context.Context).RandomStream);
- }
- else
- {
- Value = mProtectedString.ReadUtf8();
- }
- }
- #endregion
-
- #region Deserialisation
- public ProtectedStringBuffer()
- {
- }
-
- [ProtoAfterDeserialization]
- private void AfterDeserialization(SerializationContext context)
- {
- if (IsProtected)
- {
- byte[] pbPad = ((BufferContext)context.Context).RandomStream.GetRandomBytes((uint)Value.Length);
- mProtectedString = new ProtectedString(IsProtected, new XorredBuffer(Value, pbPad));
- }
- else
- {
- mProtectedString = new ProtectedString(IsProtected, Value);
- }
- }
-
- public ProtectedString ProtectedString { get { return mProtectedString; } }
-
- #endregion
-
- [ProtoMember(1)]
- public bool IsProtected;
-
- [ProtoMember(2, OverwriteList = true)]
- public byte[] Value;
- }
-
- [ProtoContract]
- private class NamedProtectedBinaryListBuffer : IEnumerable
- {
- #region Serialisation
- private readonly List mNamedBinaries;
-
- public NamedProtectedBinaryListBuffer(IEnumerable> binaries, int binariesCount, BufferContext context)
- {
- mNamedBinaries = new List(binariesCount);
- foreach (var kvp in binaries)
- {
- NamedProtectedBinaryBuffer namedProtectedBinaryBuffer;
- if (!context.BinaryPool.TryGetValue(kvp.Value, out namedProtectedBinaryBuffer))
- {
- // Hasn't been put in the pool yet, so create it
- namedProtectedBinaryBuffer = new NamedProtectedBinaryBuffer(kvp);
- context.BinaryPool.Add(kvp.Value, namedProtectedBinaryBuffer);
- }
- mNamedBinaries.Add(namedProtectedBinaryBuffer);
- }
- }
-
- public IEnumerator GetEnumerator()
- {
- return mNamedBinaries.GetEnumerator();
- }
-
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- #endregion
-
- #region Deserialization
- private readonly ProtectedBinaryDictionary mBinaryDictionary;
-
- public NamedProtectedBinaryListBuffer(ProtectedBinaryDictionary binaryDictionary)
- {
- mBinaryDictionary = binaryDictionary;
- }
-
- public void Add(NamedProtectedBinaryBuffer item)
- {
- mBinaryDictionary.Set(item.Name, item.ProtectedBinary);
- }
- #endregion
- }
-
- [ProtoContract]
- private class NamedProtectedBinaryBuffer
- {
- #region Serialization
- private ProtectedBinary mProtectedBinary;
- public NamedProtectedBinaryBuffer(KeyValuePair namedBinary)
- {
- Name = namedBinary.Key;
- mProtectedBinary = namedBinary.Value;
- IsProtected = mProtectedBinary.IsProtected;
- }
-
- [ProtoBeforeSerialization]
- private void BeforeSerialization(SerializationContext context)
- {
- if (IsProtected)
- {
- Value = mProtectedBinary.ReadXorredData(((BufferContext)context.Context).RandomStream);
- }
- else
- {
- Value = mProtectedBinary.ReadData();
- }
- }
- #endregion
-
- #region Deserialisation
- public NamedProtectedBinaryBuffer()
- {
- }
-
- [ProtoAfterDeserialization]
- private void AfterDeserialization(SerializationContext context)
- {
- if (IsProtected)
- {
- byte[] pbPad = ((BufferContext)context.Context).RandomStream.GetRandomBytes((uint)Value.Length);
- mProtectedBinary = new ProtectedBinary(IsProtected, new XorredBuffer(Value, pbPad));
- }
- else
- {
- mProtectedBinary = new ProtectedBinary(IsProtected, Value);
- }
- }
-
- public ProtectedBinary ProtectedBinary { get { return mProtectedBinary; } }
-
- #endregion
-
- [ProtoMember(1)]
- public string Name;
-
- [ProtoMember(2)]
- public bool IsProtected;
-
- [ProtoMember(3, OverwriteList = true)]
- public byte[] Value;
- }
-
- [ProtoContract]
- private class AutoTypeConfigBuffer
- {
- private readonly AutoTypeAssociationsBuffer mAutoTypeAssociationsBuffer;
- #region Serialization
- private AutoTypeConfig mAutoTypeConfig;
- public AutoTypeConfigBuffer(AutoTypeConfig autoTypeConfig)
- {
- mAutoTypeConfig = autoTypeConfig;
- mAutoTypeAssociationsBuffer = new AutoTypeAssociationsBuffer(mAutoTypeConfig);
- }
- #endregion
-
- #region Deserialization
- public AutoTypeConfigBuffer()
- {
- mAutoTypeConfig = new AutoTypeConfig();
- mAutoTypeAssociationsBuffer = new AutoTypeAssociationsBuffer(mAutoTypeConfig);
- }
-
- public AutoTypeConfig AutoTypeConfig { get { return mAutoTypeConfig; } }
- #endregion
-
- [ProtoMember(1)]
- public bool Enabled
- {
- get { return mAutoTypeConfig.Enabled; }
- set { mAutoTypeConfig.Enabled = value; }
- }
-
- [ProtoMember(2)]
- public AutoTypeObfuscationOptions ObfuscationOptions
- {
- get { return mAutoTypeConfig.ObfuscationOptions; }
- set { mAutoTypeConfig.ObfuscationOptions = value; }
- }
-
- [ProtoMember(3)]
- public string DefaultSequence
- {
- get { return mAutoTypeConfig.DefaultSequence; }
- set { mAutoTypeConfig.DefaultSequence = value; }
- }
-
- [ProtoMember(4)]
- public AutoTypeAssociationsBuffer Associations
- {
- get { return mAutoTypeAssociationsBuffer; }
- }
- }
-
- [ProtoContract]
- private class AutoTypeAssociationsBuffer : IEnumerable
- {
- #region Serialization
- private AutoTypeConfig mAutoTypeConfig;
-
- public AutoTypeAssociationsBuffer(AutoTypeConfig autoTypeConfig)
- {
- mAutoTypeConfig = autoTypeConfig;
- }
-
- public IEnumerator GetEnumerator()
- {
- foreach (var autoTypeAssociation in mAutoTypeConfig.Associations)
- {
- yield return new AutoTypeAssociationBuffer(autoTypeAssociation);
- }
- }
-
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- #endregion
-
- #region Deserialization
- public void Add(AutoTypeAssociationBuffer value)
- {
- mAutoTypeConfig.Add(value.AutoTypeAssociation);
- }
- #endregion
- }
-
- [ProtoContract]
- private class AutoTypeAssociationBuffer
- {
- #region Serialization
- private AutoTypeAssociation mAutoTypeAssociation;
-
- public AutoTypeAssociationBuffer(AutoTypeAssociation autoTypeAssociation)
- {
- mAutoTypeAssociation = autoTypeAssociation;
- }
- #endregion
-
- #region Deserialization
- public AutoTypeAssociationBuffer()
- {
- mAutoTypeAssociation = new AutoTypeAssociation();
- }
-
- public AutoTypeAssociation AutoTypeAssociation { get { return mAutoTypeAssociation; } }
- #endregion
-
- [ProtoMember(1)]
- public string WindowName
- {
- get { return mAutoTypeAssociation.WindowName; }
- set { mAutoTypeAssociation.WindowName = value; }
- }
-
- [ProtoMember(2)]
- public string Sequence
- {
- get { return mAutoTypeAssociation.Sequence; }
- set { mAutoTypeAssociation.Sequence = value; }
- }
- }
- }
-}
diff --git a/src/KeePassLib2Android/Translation/KPFormCustomization.cs b/src/KeePassLib2Android/Translation/KPFormCustomization.cs
deleted file mode 100644
index f3ca86f7..00000000
--- a/src/KeePassLib2Android/Translation/KPFormCustomization.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- KeePass Password Safe - The Open-Source Password Manager
- Copyright (C) 2003-2017 Dominik Reichl
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Text;
-using System.Xml.Serialization;
-
-#if !KeePassUAP
-using System.Windows.Forms;
-#endif
-
-namespace KeePassLib.Translation
-{
- public sealed class KPFormCustomization
- {
- private string m_strFQName = string.Empty;
- ///
- /// The fully qualified name of the form.
- ///
- [XmlAttribute]
- public string FullName
- {
- get { return m_strFQName; }
- set
- {
- if(value == null) throw new ArgumentNullException("value");
- m_strFQName = value;
- }
- }
-
- private KPControlCustomization m_ccWindow = new KPControlCustomization();
- public KPControlCustomization Window
- {
- get { return m_ccWindow; }
- set { m_ccWindow = value; }
- }
-
- private List m_vControls =
- new List();
- [XmlArray("ChildControls")]
- [XmlArrayItem("Control")]
- public List Controls
- {
- get { return m_vControls; }
- set
- {
- if(value == null) throw new ArgumentNullException("value");
-
- m_vControls = value;
- }
- }
-
-#if (!KeePassLibSD && !KeePassUAP)
- private Form m_formEnglish = null;
- [XmlIgnore]
- public Form FormEnglish
- {
- get { return m_formEnglish; }
- set { m_formEnglish = value; }
- }
-
- public void ApplyTo(Form form)
- {
- Debug.Assert(form != null); if(form == null) throw new ArgumentNullException("form");
-
- // Not supported by TrlUtil (preview form):
- // Debug.Assert(form.GetType().FullName == m_strFQName);
-
- m_ccWindow.ApplyTo(form);
-
- if(m_vControls.Count == 0) return;
- foreach(Control c in form.Controls) ApplyToControl(c);
- }
-
- private void ApplyToControl(Control c)
- {
- foreach(KPControlCustomization cc in m_vControls)
- {
- if(c.Name == cc.Name)
- {
- cc.ApplyTo(c);
- break;
- }
- }
-
- foreach(Control cSub in c.Controls) ApplyToControl(cSub);
- }
-#endif
- }
-}
diff --git a/src/Kp2aAutofillParserTest/AutofillTest.cs b/src/Kp2aAutofillParser.Tests/AutofillTest.cs
similarity index 86%
rename from src/Kp2aAutofillParserTest/AutofillTest.cs
rename to src/Kp2aAutofillParser.Tests/AutofillTest.cs
index 2c9c2a7e..eeefc2f1 100644
--- a/src/Kp2aAutofillParserTest/AutofillTest.cs
+++ b/src/Kp2aAutofillParser.Tests/AutofillTest.cs
@@ -26,65 +26,64 @@ namespace Kp2aAutofillParserTest
[Fact]
public void TestNotFocusedPasswordAutoIsNotFilled()
{
- var resourceName = "Kp2aAutofillParserTest.com-servicenet-mobile-no-focus.json";
+ var resourceName = "com-servicenet-mobile-no-focus.json";
RunTestFromAutofillInput(resourceName, "com.servicenet.mobile");
}
[Fact]
public void TestCrashRegressionEmptySequence()
{
- var resourceName = "Kp2aAutofillParserTest.imdb.json";
+ var resourceName = "imdb.json";
RunTestFromAutofillInput(resourceName, "com.vivaldi.browser", "m.imdb.com");
}
[Fact]
public void TestFocusedPasswordAutoIsFilled()
{
- var resourceName = "Kp2aAutofillParserTest.com-servicenet-mobile-focused.json";
+ var resourceName = "com-servicenet-mobile-focused.json";
RunTestFromAutofillInput(resourceName, "com.servicenet.mobile");
}
[Fact]
public void TestMulitpleUnfocusedLoginsIsFilled()
{
- var resourceName = "Kp2aAutofillParserTest.firefox-amazon-it.json";
+ var resourceName = "firefox-amazon-it.json";
RunTestFromAutofillInput(resourceName, "org.mozilla.firefox", "www.amazon.it");
}
[Fact]
public void CanDetectFieldsWithoutAutofillHints()
{
- var resourceName = "Kp2aAutofillParserTest.chrome-android10-amazon-it.json";
+ var resourceName = "chrome-android10-amazon-it.json";
RunTestFromAutofillInput(resourceName, "com.android.chrome", "www.amazon.it");
}
[Fact]
public void DetectsUsernameFieldDespitePasswordAutoHint()
{
- var resourceName = "Kp2aAutofillParserTest.com-ifs-banking-fiid3364-android13.json";
+ var resourceName = "com-ifs-banking-fiid3364-android13.json";
RunTestFromAutofillInput(resourceName, "com.ifs.banking.fiid3364", null);
}
[Fact]
public void DetectsEmailAutofillHint()
{
- var resourceName = "Kp2aAutofillParserTest.com-expressvpn-vpn-android13.json";
+ var resourceName = "com-expressvpn-vpn-android13.json";
RunTestFromAutofillInput(resourceName, "com.expressvpn.vpn", null);
}
[Fact]
public void TestIgnoresAndroidSettings()
{
- var resourceName = "Kp2aAutofillParserTest.android14-settings.json";
+ var resourceName = "android14-settings.json";
RunTestFromAutofillInput(resourceName, "com.android.settings", null);
}
private void RunTestFromAutofillInput(string resourceName, string expectedPackageName = null, string expectedWebDomain = null)
{
var assembly = Assembly.GetExecutingAssembly();
-
string input;
- using (Stream stream = assembly.GetManifestResourceStream(resourceName))
+ using (Stream stream = assembly.GetManifestResourceStream(assembly.GetName().Name + "." + resourceName))
using (StreamReader reader = new StreamReader(stream))
{
input = reader.ReadToEnd();
diff --git a/src/Kp2aAutofillParserTest/Kp2aAutofillParserTest.csproj b/src/Kp2aAutofillParser.Tests/Kp2aAutofillParser.Tests.csproj
similarity index 80%
rename from src/Kp2aAutofillParserTest/Kp2aAutofillParserTest.csproj
rename to src/Kp2aAutofillParser.Tests/Kp2aAutofillParser.Tests.csproj
index d68279ff..4b0bdfe3 100644
--- a/src/Kp2aAutofillParserTest/Kp2aAutofillParserTest.csproj
+++ b/src/Kp2aAutofillParser.Tests/Kp2aAutofillParser.Tests.csproj
@@ -1,16 +1,18 @@
- net6.0
+ net8.0
enable
enable
false
+ true
+
@@ -20,16 +22,10 @@
-
-
-
- runtime; build; native; contentfiles; analyzers; buildtransitive
- all
-
-
- runtime; build; native; contentfiles; analyzers; buildtransitive
- all
-
+
+
+
+
@@ -37,25 +33,28 @@
+
+ PreserveNewest
+
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
PreserveNewest
-
+
PreserveNewest
@@ -63,4 +62,8 @@
+
+
+
+
diff --git a/src/Kp2aAutofillParserTest/Usings.cs b/src/Kp2aAutofillParser.Tests/Usings.cs
similarity index 100%
rename from src/Kp2aAutofillParserTest/Usings.cs
rename to src/Kp2aAutofillParser.Tests/Usings.cs
diff --git a/src/Kp2aAutofillParserTest/android14-settings.json b/src/Kp2aAutofillParser.Tests/android14-settings.json
similarity index 100%
rename from src/Kp2aAutofillParserTest/android14-settings.json
rename to src/Kp2aAutofillParser.Tests/android14-settings.json
diff --git a/src/Kp2aAutofillParserTest/chrome-android10-amazon-it.json b/src/Kp2aAutofillParser.Tests/chrome-android10-amazon-it.json
similarity index 100%
rename from src/Kp2aAutofillParserTest/chrome-android10-amazon-it.json
rename to src/Kp2aAutofillParser.Tests/chrome-android10-amazon-it.json
diff --git a/src/Kp2aAutofillParser.Tests/citibank.json b/src/Kp2aAutofillParser.Tests/citibank.json
new file mode 100644
index 00000000..7bfc2db4
--- /dev/null
+++ b/src/Kp2aAutofillParser.Tests/citibank.json
@@ -0,0 +1,1110 @@
+{
+ "InputFields": [
+ {
+ "IdEntry": null,
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "action_bar_root",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "action_mode_bar_stub",
+ "Hint": null,
+ "ClassName": "android.view.View",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "container_fl",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "ll",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": null,
+ "Hint": null,
+ "ClassName": "android.webkit.WebView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "rootLayout",
+ "Hint": null,
+ "ClassName": "android.widget.RelativeLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyssey_bg_layout",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "scrollViewOuter",
+ "Hint": null,
+ "ClassName": "android.widget.ScrollView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "outerLayout",
+ "Hint": null,
+ "ClassName": "android.view.ViewGroup",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "bgGradientOverlay",
+ "Hint": null,
+ "ClassName": "android.view.View",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "loadingLayout",
+ "Hint": null,
+ "ClassName": "android.widget.RelativeLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "network_notify",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "scrollViewInner",
+ "Hint": null,
+ "ClassName": "android.widget.ScrollView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "innerLayout",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "ody_login_linearlayout",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyssey_constraint_layout",
+ "Hint": null,
+ "ClassName": "android.view.ViewGroup",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyFooterButtons",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "lnrCULogin",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyssey_multiple_container",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "openABankAccount_link",
+ "Hint": null,
+ "ClassName": "android.widget.Button",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "login_button",
+ "Hint": null,
+ "ClassName": "android.widget.Button",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "register_link",
+ "Hint": null,
+ "ClassName": "android.widget.Button",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "tellus",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "tellus_rel",
+ "Hint": null,
+ "ClassName": "android.widget.RelativeLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "tellusBtn",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "tell_us_LL",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "tell_us_text",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "tellusSingleLine",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "footerLayout",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "footerLayoutTop",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "footerButtons",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "footerSeparator",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "footerLabels",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "cdic_logo",
+ "Hint": null,
+ "ClassName": "android.widget.RelativeLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "language_link",
+ "Hint": null,
+ "ClassName": "android.widget.RelativeLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "txtLanguageLink",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "copyright_message",
+ "Hint": null,
+ "ClassName": "android.widget.RelativeLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "txtCopyrightMessage",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "support_link",
+ "Hint": null,
+ "ClassName": "android.widget.RelativeLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "txtSupportLink",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "footerLayoutBottom",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "txtDisclaim",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "authlogin_button",
+ "Hint": null,
+ "ClassName": "android.widget.RelativeLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "parentRL",
+ "Hint": null,
+ "ClassName": "android.widget.RelativeLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "component_progress_button_text_view",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "component_progress_button_loading",
+ "Hint": null,
+ "ClassName": "android.widget.ProgressBar",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "default_logo_greet_layout",
+ "Hint": null,
+ "ClassName": "android.view.ViewGroup",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "tvGreetText",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "tvReBranding",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "tell_us_LL",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "headerView",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "seperator_view",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "headerView",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "headerLeftActionIconLL",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "titleViewRo",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "tablelyt",
+ "Hint": null,
+ "ClassName": "android.widget.TableLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "titleView",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "headerTitleTextView",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "headerSubTitleTextView",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "headerRightActionIconLL",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "separator",
+ "Hint": null,
+ "ClassName": "android.view.View",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "announcement_notify",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "notificationParentLL",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "notifyTitle",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "notifySubTitle",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "topErrorLayout",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "introductionLayout",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "mfa_container_fl",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "notify",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "loader",
+ "Hint": null,
+ "ClassName": "android.widget.RelativeLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "loading",
+ "Hint": null,
+ "ClassName": "android.widget.ProgressBar",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "status_txt",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": null,
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "popuplayout",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": null,
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "action_bar_root",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "container",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "coordinator",
+ "Hint": null,
+ "ClassName": "android.view.ViewGroup",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "touch_outside",
+ "Hint": null,
+ "ClassName": "android.view.View",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "design_bottom_sheet",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "root",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "loadingLayout",
+ "Hint": null,
+ "ClassName": "android.widget.RelativeLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "container",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "titleTextView",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "userIDTv",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "txtUserID",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "parentRL",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "frmRoot",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyTextLayout",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyEditText",
+ "Hint": null,
+ "ClassName": "android.widget.EditText",
+ "AutofillHints": [
+ "passwordAuto"
+ ],
+ "IsFocused": true,
+ "InputType": 524433,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "rightActionText",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "lblErrorMsg",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "txtUserError",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "lblUsername",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "middleLayout",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "txtPassword",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "parentRL",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "frmRoot",
+ "Hint": null,
+ "ClassName": "android.widget.FrameLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyTextLayout",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyEditText",
+ "Hint": null,
+ "ClassName": "android.widget.EditText",
+ "AutofillHints": [
+ "passwordAuto"
+ ],
+ "IsFocused": false,
+ "InputType": 129,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "rightActionText",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "lblErrorMsg",
+ "Hint": null,
+ "ClassName": "android.widget.TextView",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyssey_login_text_input_sipedittxt",
+ "Hint": null,
+ "ClassName": "android.view.View",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "llErrorMsg",
+ "Hint": null,
+ "ClassName": "android.widget.LinearLayout",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyssey_login_button",
+ "Hint": null,
+ "ClassName": "android.widget.Button",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyssey_send_sms",
+ "Hint": null,
+ "ClassName": "android.widget.Button",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyssey_use_finger_button",
+ "Hint": null,
+ "ClassName": "android.widget.Button",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "odyssey_reset_button",
+ "Hint": null,
+ "ClassName": "android.widget.Button",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ },
+ {
+ "IdEntry": "action_mode_bar_stub",
+ "Hint": null,
+ "ClassName": "android.view.View",
+ "AutofillHints": null,
+ "IsFocused": false,
+ "InputType": 0,
+ "HtmlInfoTag": null,
+ "HtmlInfoTypeAttribute": null
+ }
+ ],
+ "PackageId": "com.konylabs.cbplpat",
+ "WebDomain": null
+}
\ No newline at end of file
diff --git a/src/Kp2aAutofillParserTest/com-expressvpn-vpn-android13.json b/src/Kp2aAutofillParser.Tests/com-expressvpn-vpn-android13.json
similarity index 100%
rename from src/Kp2aAutofillParserTest/com-expressvpn-vpn-android13.json
rename to src/Kp2aAutofillParser.Tests/com-expressvpn-vpn-android13.json
diff --git a/src/Kp2aAutofillParserTest/com-ifs-banking-fiid3364-android13.json b/src/Kp2aAutofillParser.Tests/com-ifs-banking-fiid3364-android13.json
similarity index 100%
rename from src/Kp2aAutofillParserTest/com-ifs-banking-fiid3364-android13.json
rename to src/Kp2aAutofillParser.Tests/com-ifs-banking-fiid3364-android13.json
diff --git a/src/Kp2aAutofillParserTest/com-servicenet-mobile-focused.json b/src/Kp2aAutofillParser.Tests/com-servicenet-mobile-focused.json
similarity index 100%
rename from src/Kp2aAutofillParserTest/com-servicenet-mobile-focused.json
rename to src/Kp2aAutofillParser.Tests/com-servicenet-mobile-focused.json
diff --git a/src/Kp2aAutofillParserTest/com-servicenet-mobile-no-focus.json b/src/Kp2aAutofillParser.Tests/com-servicenet-mobile-no-focus.json
similarity index 100%
rename from src/Kp2aAutofillParserTest/com-servicenet-mobile-no-focus.json
rename to src/Kp2aAutofillParser.Tests/com-servicenet-mobile-no-focus.json
diff --git a/src/Kp2aAutofillParserTest/firefox-amazon-it.json b/src/Kp2aAutofillParser.Tests/firefox-amazon-it.json
similarity index 100%
rename from src/Kp2aAutofillParserTest/firefox-amazon-it.json
rename to src/Kp2aAutofillParser.Tests/firefox-amazon-it.json
diff --git a/src/Kp2aAutofillParserTest/imdb.json b/src/Kp2aAutofillParser.Tests/imdb.json
similarity index 100%
rename from src/Kp2aAutofillParserTest/imdb.json
rename to src/Kp2aAutofillParser.Tests/imdb.json
diff --git a/src/Kp2aAutofillParser/Kp2aAutofillParser.csproj b/src/Kp2aAutofillParser/Kp2aAutofillParser.csproj
index 375762cd..036e5526 100644
--- a/src/Kp2aAutofillParser/Kp2aAutofillParser.csproj
+++ b/src/Kp2aAutofillParser/Kp2aAutofillParser.csproj
@@ -1,12 +1,10 @@
-
-
+
- netstandard2.1
+ net8.0
enable
+ enable
-
-
+
-
-
+
\ No newline at end of file
diff --git a/src/Kp2aBusinessLogic/Io/BuiltInFileStorage.cs b/src/Kp2aBusinessLogic/Io/BuiltInFileStorage.cs
index aa8f428f..f47b777e 100644
--- a/src/Kp2aBusinessLogic/Io/BuiltInFileStorage.cs
+++ b/src/Kp2aBusinessLogic/Io/BuiltInFileStorage.cs
@@ -13,7 +13,7 @@ using Android.Content.PM;
using Android.OS;
using Android.Preferences;
using Java.IO;
-using Android.Support.V4;
+
using KeePassLib.Serialization;
using KeePassLib.Utility;
using File = System.IO.File;
@@ -291,7 +291,7 @@ namespace keepass2android.Io
public void OnCreate(IFileStorageSetupActivity fileStorageSetupActivity, Bundle savedInstanceState)
{
- Android.Support.V4.App.ActivityCompat.RequestPermissions(((Activity)fileStorageSetupActivity), new[] { Manifest.Permission.WriteExternalStorage, Manifest.Permission.ReadExternalStorage }, 0);
+ AndroidX.Core.App.ActivityCompat.RequestPermissions(((Activity)fileStorageSetupActivity), new[] { Manifest.Permission.WriteExternalStorage, Manifest.Permission.ReadExternalStorage }, 0);
}
public void OnResume(IFileStorageSetupActivity activity)
diff --git a/src/Kp2aBusinessLogic/Io/IoUtil.cs b/src/Kp2aBusinessLogic/Io/IoUtil.cs
index 6956635e..054b2a87 100644
--- a/src/Kp2aBusinessLogic/Io/IoUtil.cs
+++ b/src/Kp2aBusinessLogic/Io/IoUtil.cs
@@ -34,14 +34,14 @@ namespace keepass2android.Io
}
return false;
}
- public static bool DeleteDir(File dir, bool contentsOnly=false)
+ public static bool DeleteDir(Java.IO.File dir, bool contentsOnly=false)
{
if (dir != null && dir.IsDirectory)
{
String[] children = dir.List();
for (int i = 0; i < children.Length; i++)
{
- bool success = DeleteDir(new File(dir, children[i]));
+ bool success = DeleteDir(new Java.IO.File(dir, children[i]));
if (!success)
{
return false;
@@ -77,12 +77,12 @@ namespace keepass2android.Io
{
try
{
- File filesDir = context.FilesDir.CanonicalFile;
- File noBackupDir = GetInternalDirectory(context).CanonicalFile;
- File ourFile = new File(path).CanonicalFile;
- //http://www.java2s.com/Tutorial/Java/0180__File/Checkswhetherthechilddirectoryisasubdirectoryofthebasedirectory.htm
+ Java.IO.File filesDir = context.FilesDir.CanonicalFile;
+ Java.IO.File noBackupDir = GetInternalDirectory(context).CanonicalFile;
+ Java.IO.File ourFile = new Java.IO.File(path).CanonicalFile;
+ //http://www.java2s.com/Tutorial/Java/0180__File/Checkswhetherthechilddirectoryisasubdirectoryofthebasedirectory.htm
- File parentFile = ourFile;
+ Java.IO.File parentFile = ourFile;
while (parentFile != null)
{
if ((filesDir.Equals(parentFile) || noBackupDir.Equals(parentFile)))
@@ -137,7 +137,7 @@ namespace keepass2android.Io
targetPath = targetPath.Trim("|\\?*<\":>+[]/'".ToCharArray());
if (targetPath == "")
targetPath = "internal";
- if (new File(internalDirectory, targetPath).Exists())
+ if (new Java.IO.File(internalDirectory, targetPath).Exists())
{
int c = 1;
var ext = UrlUtil.GetExtension(targetPath);
@@ -148,9 +148,9 @@ namespace keepass2android.Io
targetPath = filenameWithoutExt + c;
if (!String.IsNullOrEmpty(ext))
targetPath += "." + ext;
- } while (new File(internalDirectory, targetPath).Exists());
+ } while (new Java.IO.File(internalDirectory, targetPath).Exists());
}
- return IOConnectionInfo.FromPath(new File(internalDirectory, targetPath).CanonicalPath);
+ return IOConnectionInfo.FromPath(new Java.IO.File(internalDirectory, targetPath).CanonicalPath);
}
public static IOConnectionInfo ImportFileToInternalDirectory(IOConnectionInfo sourceIoc, Context ctx, IKp2aApp app)
diff --git a/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs b/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs
index f2016654..f0429e11 100644
--- a/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs
+++ b/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs
@@ -207,7 +207,7 @@ namespace keepass2android.Io
{
try
{
- IList entries = Jfs.ListFiles(IocToPath(ioc));
+ IList entries = Jfs.ListFiles(IocToPath(ioc));
return entries.Select(ConvertToFileDescription);
@@ -222,7 +222,7 @@ namespace keepass2android.Io
}
}
- private FileDescription ConvertToFileDescription(JavaFileStorageFileEntry e)
+ private FileDescription ConvertToFileDescription(IJavaFileStorage.FileEntry e)
{
return new FileDescription
{
@@ -260,14 +260,14 @@ namespace keepass2android.Io
public virtual void StartSelectFile(IFileStorageSetupInitiatorActivity activity, bool isForSave, int requestCode, string protocolId)
{
Kp2aLog.Log("StartSelectFile " + protocolId);
- _jfs.StartSelectFile((IJavaFileStorageFileStorageSetupInitiatorActivity) activity, isForSave, requestCode);
+ _jfs.StartSelectFile((IJavaFileStorage.IFileStorageSetupInitiatorActivity) activity, isForSave, requestCode);
}
public void PrepareFileUsage(IFileStorageSetupInitiatorActivity activity, IOConnectionInfo ioc, int requestCode, Boolean alwaysReturnSuccess)
{
try
{
- _jfs.PrepareFileUsage((IJavaFileStorageFileStorageSetupInitiatorActivity) activity, IocToPath(ioc), requestCode,
+ _jfs.PrepareFileUsage((IJavaFileStorage.IFileStorageSetupInitiatorActivity) activity, IocToPath(ioc), requestCode,
alwaysReturnSuccess);
}
catch (Exception e)
@@ -301,25 +301,25 @@ namespace keepass2android.Io
public void OnCreate(IFileStorageSetupActivity activity, Bundle savedInstanceState)
{
- _jfs.OnCreate(((IJavaFileStorageFileStorageSetupActivity)activity), savedInstanceState);
+ _jfs.OnCreate(((IJavaFileStorage.IFileStorageSetupActivity)activity), savedInstanceState);
}
public void OnResume(IFileStorageSetupActivity activity)
{
#if DEBUG
- Kp2aLog.Log("JFS/OnResume Ioc.Path=" +activity.Ioc.Path+". Path="+((IJavaFileStorageFileStorageSetupActivity)activity).Path);
+ Kp2aLog.Log("JFS/OnResume Ioc.Path=" +activity.Ioc.Path+". Path="+((IJavaFileStorage.IFileStorageSetupActivity)activity).Path);
#endif
- _jfs.OnResume(((IJavaFileStorageFileStorageSetupActivity) activity));
+ _jfs.OnResume(((IJavaFileStorage.IFileStorageSetupActivity) activity));
}
public void OnStart(IFileStorageSetupActivity activity)
{
- _jfs.OnStart(((IJavaFileStorageFileStorageSetupActivity) activity));
+ _jfs.OnStart(((IJavaFileStorage.IFileStorageSetupActivity) activity));
}
public void OnActivityResult(IFileStorageSetupActivity activity, int requestCode, int resultCode, Intent data)
{
- _jfs.OnActivityResult(((IJavaFileStorageFileStorageSetupActivity) activity), requestCode, resultCode, data);
+ _jfs.OnActivityResult(((IJavaFileStorage.IFileStorageSetupActivity) activity), requestCode, resultCode, data);
}
public string GetDisplayName(IOConnectionInfo ioc)
@@ -367,7 +367,7 @@ namespace keepass2android.Io
public void OnRequestPermissionsResult(IFileStorageSetupActivity fileStorageSetupActivity, int requestCode,
string[] permissions, Permission[] grantResults)
{
- _jfs.OnRequestPermissionsResult(((IJavaFileStorageFileStorageSetupActivity) fileStorageSetupActivity), requestCode,
+ _jfs.OnRequestPermissionsResult(((IJavaFileStorage.IFileStorageSetupActivity) fileStorageSetupActivity), requestCode,
permissions, grantResults.Select(p => (int)p).ToArray());
}
}
diff --git a/src/Kp2aBusinessLogic/Io/OneDrive2FileStorage.cs b/src/Kp2aBusinessLogic/Io/OneDrive2FileStorage.cs
index b57a62e7..37d97296 100644
--- a/src/Kp2aBusinessLogic/Io/OneDrive2FileStorage.cs
+++ b/src/Kp2aBusinessLogic/Io/OneDrive2FileStorage.cs
@@ -1,30 +1,26 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Net.Http.Headers;
+using System.Net;
+using System.Reflection;
using System.Text;
-using System.Threading.Tasks;
-using Android.App;
using Android.Content;
-using Android.OS;
using Android.Util;
-using Java.Net;
using keepass2android.Io.ItemLocation;
using KeePassLib.Serialization;
using KeePassLib.Utility;
using Microsoft.Graph;
-using Microsoft.Graph.Auth;
+using Microsoft.Graph.Drives.Item.Items.Item.CreateUploadSession;
+using Microsoft.Graph.Models;
using Microsoft.Identity.Client;
-using Newtonsoft.Json;
+using Microsoft.Kiota.Abstractions;
+using Microsoft.Kiota.Abstractions.Authentication;
+using DriveItemRequestBuilder = Microsoft.Graph.Drives.Item.Items.Item.DriveItemItemRequestBuilder;
+
+
using Exception = System.Exception;
-using File = Microsoft.Graph.File;
using String = System.String;
namespace keepass2android.Io
{
- namespace ItemLocation
+ namespace ItemLocation
{
public class User
{
@@ -45,9 +41,9 @@ namespace keepass2android.Io
}
- public class OneDrive2ItemLocation where OneDrive2PrefixContainerType: OneDrive2PrefixContainer, new()
+ public class OneDrive2ItemLocation where OneDrive2PrefixContainerType : OneDrive2PrefixContainer, new()
{
-
+
public User User { get; set; } = new User();
public Share Share { get; set; } = new Share();
public string DriveId { get; set; }
@@ -59,7 +55,7 @@ namespace keepass2android.Io
{
get
{
- OneDrive2ItemLocation< OneDrive2PrefixContainerType> copy = OneDrive2ItemLocation< OneDrive2PrefixContainerType>.FromString(this.ToString());
+ OneDrive2ItemLocation copy = OneDrive2ItemLocation.FromString(this.ToString());
if (copy.LocalPath.Any())
{
//pop last:
@@ -177,16 +173,16 @@ namespace keepass2android.Io
}
}
-
- public abstract class OneDrive2FileStorage : IFileStorage where OneDrive2PrefixContainerType: OneDrive2PrefixContainer, new()
+
+ public abstract class OneDrive2FileStorage : IFileStorage where OneDrive2PrefixContainerType : OneDrive2PrefixContainer, new()
{
public static IPublicClientApplication _publicClientApp = null;
private string ClientID = "8374f801-0f55-407d-80cc-9a04fe86d9b2";
-
-
+
+
public abstract IEnumerable Scopes
{
get;
@@ -201,21 +197,114 @@ namespace keepass2android.Io
class PathItemBuilder
{
- private readonly string _specialFolder;
- public IGraphServiceClient client;
+ private readonly string? _specialFolder;
+ public GraphServiceClient client;
public OneDrive2ItemLocation itemLocation;
public bool verbose;
- public PathItemBuilder(string specialFolder)
+ public PathItemBuilder(string? specialFolder)
{
_specialFolder = specialFolder;
}
-
- public IDriveItemRequestBuilder getPathItem()
+ ///
+ /// Wraps the different DriveItemRequestBuilder classes and allows accessing the different types easily
+ ///
+ /// NOTE: even though CustomDriveItemItemRequestBuilder derives from Kp2aDriveItemRequestBuilder, we cannot use polymorphism here because the methods are declared with "new".
+ /// If you cast assign an CustomDriveItemItemRequestBuilder object to a variable declared as Kp2aDriveItemRequestBuilder and then call a method on it, it will fail.
+ public class DriveItemRequestBuilderWrapper
{
- Kp2aLog.Log("getPathItem for " + itemLocation.ToString());
- IDriveItemRequestBuilder pathItem;
+
+ public class DriveItemRequestBuilderResult
+ {
+ private readonly DriveItemRequestBuilderWrapper _req;
+
+ public DriveItemRequestBuilderResult(DriveItemRequestBuilderWrapper req)
+ {
+ _req = req;
+ }
+
+ public Task Result { get; set; }
+
+
+ public DriveItemRequestBuilderResult ForDriveItemRequestBuilder(Func> action)
+ {
+ if (_req.DriveItemRequestBuilder != null)
+ {
+ Result = action(_req.DriveItemRequestBuilder);
+ }
+ return this;
+ }
+
+ public DriveItemRequestBuilderResult ForCustomDriveItemRequestBuilder(Func> action)
+ {
+ if (_req.CustomDriveItemRequestBuilder != null)
+ {
+ Result = action(_req.CustomDriveItemRequestBuilder);
+ }
+ return this;
+ }
+
+
+
+ }
+
+ public class DriveItemRequestBuilderAsyncTask
+ {
+ private readonly DriveItemRequestBuilderWrapper _req;
+
+ public DriveItemRequestBuilderAsyncTask(DriveItemRequestBuilderWrapper req)
+ {
+ _req = req;
+ Task = Task.CompletedTask;
+ }
+
+ public Task Task { get; private set; }
+
+ public DriveItemRequestBuilderAsyncTask ForDriveItemRequestBuilder(Func action)
+ {
+ if (_req.DriveItemRequestBuilder != null)
+ {
+ Task = action(_req.DriveItemRequestBuilder);
+ }
+ return this;
+ }
+
+ public DriveItemRequestBuilderAsyncTask ForCustomDriveItemRequestBuilder(Func action)
+ {
+ if (_req.CustomDriveItemRequestBuilder != null)
+ {
+ Task = action(_req.CustomDriveItemRequestBuilder);
+ }
+ return this;
+ }
+ }
+
+
+ public DriveItemRequestBuilder? DriveItemRequestBuilder { get; set; }
+
+ public CustomDriveItemItemRequestBuilder? CustomDriveItemRequestBuilder { get; set; }
+
+
+ public DriveItemRequestBuilderResult ToAsyncResult()
+ {
+ return new DriveItemRequestBuilderResult(this);
+ }
+
+ public DriveItemRequestBuilderAsyncTask ToAsyncTask()
+ {
+ return new DriveItemRequestBuilderAsyncTask(this);
+ }
+
+
+ };
+
+
+ public async Task BuildPathItemAsync()
+ {
+ Kp2aLog.Log("buildPathItem for " + itemLocation.ToString());
+ DriveItemRequestBuilderWrapper result = new DriveItemRequestBuilderWrapper();
+
if (!hasShare())
{
throw new Exception("Cannot get path item without share");
@@ -223,61 +312,58 @@ namespace keepass2android.Io
if ("me".Equals(itemLocation.Share.Id))
{
if (verbose) Kp2aLog.Log("Path share is me");
-
+
if (_specialFolder == null)
{
if (verbose) Kp2aLog.Log("No special folder. Use drive root.");
- pathItem = client.Me.Drive.Root;
+
+ if (itemLocation.LocalPath.Any())
+ {
+ if (verbose) Kp2aLog.Log("LocalPath = " + itemLocation.LocalPathString);
+ result.CustomDriveItemRequestBuilder = client.Drives[itemLocation.DriveId].Root
+ .ItemWithPath(itemLocation.LocalPathString);
+ }
+ else
+ {
+
+ result.DriveItemRequestBuilder = client.Drives[itemLocation.DriveId].Items["root"];
+
+ }
+
+
}
else
{
if (verbose) Kp2aLog.Log("Special folder = " + _specialFolder);
- pathItem = client.Me.Drive.Special[_specialFolder];
+
+ DriveItemRequestBuilder specialRoot = client.Drives[itemLocation.DriveId].Items[_specialFolder];
+
+
+ if (itemLocation.LocalPath.Any())
+ {
+ result.CustomDriveItemRequestBuilder = specialRoot.ItemWithPath(itemLocation.LocalPathString);
+ }
+ else
+ {
+ result.DriveItemRequestBuilder = specialRoot;
+ }
}
- if (itemLocation.LocalPath.Any())
- {
- if (verbose) Kp2aLog.Log("LocalPath = " + itemLocation.LocalPathString);
- pathItem = pathItem.ItemWithPath(itemLocation.LocalPathString);
- }
}
else
{
if (verbose) Kp2aLog.Log("Path share is not me");
if (!itemLocation.LocalPath.Any())
{
- String webUrl = itemLocation.Share.WebUrl;
- if (verbose) Kp2aLog.Log("Share WebUrl = " + webUrl);
- var encodedShareId = CalculateEncodedShareId(webUrl);
- return client.Shares[encodedShareId].Root;
+ result.DriveItemRequestBuilder = client.Drives[itemLocation.DriveId].Items[itemLocation.Share.Id];
+ return result;
}
- /*String webUrl = itemLocation.Share.WebUrl;
- if ("".Equals(itemLocation.LocalPath) == false)
- {
- if (!webUrl.EndsWith("/")) webUrl += "/";
- webUrl += itemLocation.LocalPath;
- }
- Android.Util.Log.Debug("KP2A","webUrl = " + Encoding.UTF8.GetBytes(webUrl));
- //calculate shareid according to https://docs.microsoft.com/en-us/graph/api/shares-get?view=graph-rest-1.0&tabs=java
- var encodedShareId = CalculateEncodedShareId(webUrl);
- Android.Util.Log.Debug("KP2A", "encodedShareId = " + encodedShareId);
- pathItem = client.Shares[encodedShareId].Root;
- */
if (verbose) Kp2aLog.Log("Using driveId=" + itemLocation.DriveId + " and item id=" + itemLocation.LocalPath.Last().Id);
- return client.Drives[itemLocation.DriveId].Items[itemLocation.LocalPath.Last().Id];
+ result.DriveItemRequestBuilder = client.Drives[itemLocation.DriveId].Items[itemLocation.LocalPath.Last().Id];
}
-
- return pathItem;
- }
-
- private static string CalculateEncodedShareId(string webUrl)
- {
- String encodedShareId = "u!" + Base64.EncodeToString(Encoding.UTF8.GetBytes(webUrl),
- Base64Flags.NoPadding).Replace('/', '_').Replace('+', '_')
- .Replace("\n", ""); //encodeToString adds a newline character add the end - remove
- return encodedShareId;
+ return result;
}
public bool hasShare()
@@ -289,6 +375,7 @@ namespace keepass2android.Io
{
return itemLocation.LocalPath.Any();
}
+
}
private string protocolId;
@@ -310,26 +397,23 @@ namespace keepass2android.Io
get { yield return ProtocolId; }
}
- class GraphServiceClientWithState
+ protected class GraphServiceClientWithState
{
- public IGraphServiceClient Client { get; set; }
+ public GraphServiceClient Client { get; set; }
public DateTime TokenExpiryDate { get; set; }
public bool RequiresUserInteraction { get; set; }
}
- readonly Dictionary mClientByUser =
- new Dictionary();
+ protected readonly Dictionary _mClientByUser = new();
- private async Task TryGetMsGraphClient(String path, bool tryConnect)
+ private async Task TryGetMsGraphClient(String path, bool tryConnect)
{
-
- String userId = OneDrive2ItemLocation.FromString(path).User.Id;
+ string userId = OneDrive2ItemLocation.FromString(path).User.Id;
logDebug("TryGetMsGraphClient for " + userId);
- if (mClientByUser.ContainsKey(userId))
+ if (_mClientByUser.TryGetValue(userId, out var clientWithState))
{
logDebug("TryGetMsGraphClient found user " + userId);
- GraphServiceClientWithState clientWithState = mClientByUser[userId];
if (!(clientWithState.RequiresUserInteraction || (clientWithState.TokenExpiryDate < DateTime.Now) ||
(clientWithState.Client == null)))
{
@@ -348,7 +432,7 @@ namespace keepass2android.Io
if (await TryLoginSilent(path) != null)
{
logDebug("trying to connect ok");
- return mClientByUser[userId].Client;
+ return _mClientByUser.GetValueOrDefault(userId, null).Client;
}
logDebug("trying to connect failed");
}
@@ -356,73 +440,85 @@ namespace keepass2android.Io
return null;
}
+ public class TokenFromAuthResultProvider : IAccessTokenProvider
+ {
+ public AuthenticationResult AuthenticationResult
+ {
+ get;
+ set;
+ }
+ public async Task GetAuthorizationTokenAsync(Uri uri, Dictionary? additionalAuthenticationContext = null,
+ CancellationToken cancellationToken = new CancellationToken())
+ {
+ return AuthenticationResult.AccessToken;
+ }
- private IGraphServiceClient BuildClient(AuthenticationResult authenticationResult)
+ public AllowedHostsValidator AllowedHostsValidator { get; }
+ }
+
+ private GraphServiceClient BuildClient(AuthenticationResult authenticationResult)
{
logDebug("buildClient...");
- //DeviceCodeProvider authenticationProvider = new DeviceCodeProvider(_publicClientApp, Scopes);
- var authenticationProvider = new DelegateAuthenticationProvider(
- (requestMessage) =>
- {
- var access_token = authenticationResult.AccessToken;
- requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", access_token);
- return Task.FromResult(0);
- });
+ var authenticationProvider = new BaseBearerTokenAuthenticationProvider(new TokenFromAuthResultProvider() { AuthenticationResult = authenticationResult });
GraphServiceClientWithState clientWithState = new GraphServiceClientWithState()
{
- Client = new GraphServiceClient(authenticationProvider),
+ Client = new GraphServiceClient(new HttpClient(), authenticationProvider),
RequiresUserInteraction = false,
TokenExpiryDate = authenticationResult.ExpiresOn.LocalDateTime
};
-
+
if (authenticationResult.Account == null)
throw new Exception("authenticationResult.Account == null!");
- mClientByUser[authenticationResult.Account.HomeAccountId.Identifier] = clientWithState;
+ _mClientByUser[authenticationResult.Account.HomeAccountId.Identifier] = clientWithState;
logDebug("buildClient ok.");
return clientWithState.Client;
}
-
private void logDebug(string str)
{
#if DEBUG
Log.Debug("KP2A", "OneDrive2: " + str);
#endif
}
-
- protected abstract string SpecialFolder { get; }
+
+ protected abstract Task GetSpecialFolder(
+ OneDrive2ItemLocation itemLocation, GraphServiceClient client);
private async Task GetPathItemBuilder(String path)
{
- PathItemBuilder result = new PathItemBuilder(SpecialFolder);
-
+ var itemLocation = OneDrive2ItemLocation.FromString(path);
+ var client = await TryGetMsGraphClient(path, true);
- result.itemLocation = OneDrive2ItemLocation.FromString(path);
+
+ PathItemBuilder result = new PathItemBuilder(await GetSpecialFolder(itemLocation, client));
+
+
+ result.itemLocation = itemLocation;
if (string.IsNullOrEmpty(result.itemLocation.User?.Name))
{
throw new Exception("path does not contain user");
}
-
- result.client = await TryGetMsGraphClient(path, true);
+ result.client = client;
+
if (result.client == null)
throw new Exception("Failed to connect or authenticate to OneDrive!");
-
-
+
+
return result;
}
- private Exception convertException(ClientException e)
+ private Exception convertException(ServiceException e)
{
if (e.IsMatch(GraphErrorCode.ItemNotFound.ToString()))
@@ -436,8 +532,8 @@ namespace keepass2android.Io
private Exception convertException(Exception e)
{
- if (e is ClientException)
- return convertException((ClientException)e);
+ if (e is ServiceException)
+ return convertException((ServiceException)e);
if (e is AggregateException aggregateException)
{
foreach (var inner in aggregateException.InnerExceptions)
@@ -449,8 +545,6 @@ namespace keepass2android.Io
return e;
}
-
-
public bool UserShouldBackup
{
get { return false; }
@@ -460,13 +554,15 @@ namespace keepass2android.Io
{
try
{
-
+
Task.Run(async () =>
{
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(ioc.Path);
- await pathItemBuilder.getPathItem()
- .Request()
- .DeleteAsync();
+ PathItemBuilder.DriveItemRequestBuilderWrapper pathItem = await pathItemBuilder.BuildPathItemAsync();
+ await pathItem.ToAsyncTask()
+ .ForDriveItemRequestBuilder(builder => builder.DeleteAsync())
+ .ForCustomDriveItemRequestBuilder(b => b.DeleteAsync())
+ .Task;
}).Wait();
}
catch (Exception e)
@@ -490,17 +586,23 @@ namespace keepass2android.Io
try
{
string path = ioc.Path;
-
+
logDebug("openFileForRead. Path=" + path);
- Stream result = Task.Run(async () =>
+
+ Stream? result = Task.Run(async () =>
{
- PathItemBuilder clientAndpath = await GetPathItemBuilder(path);
- return await clientAndpath
- .getPathItem()
- .Content
- .Request()
- .GetAsync();
+ logDebug("openFileForRead. Path=" + path);
+
+ PathItemBuilder clientAndPath = await GetPathItemBuilder(path);
+ return await (await clientAndPath.BuildPathItemAsync())
+ .ToAsyncResult()
+ .ForDriveItemRequestBuilder((b) => b.Content.GetAsync())
+ .ForCustomDriveItemRequestBuilder(b => b.Content.GetAsync())
+ .Result;
+
}).Result;
+ if (result == null)
+ throw new Exception("failed to open stream");
logDebug("ok");
return result;
@@ -551,34 +653,37 @@ namespace keepass2android.Io
{
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(path);
//for small files <2MB use the direct upload:
- if (stream.Length < 2* 1024 * 1024)
+ if (stream.Length < 2 * 1024 * 1024)
{
- return await
- pathItemBuilder
- .getPathItem()
- .Content
- .Request()
- .PutAsync(stream);
+ await
+ (await pathItemBuilder
+ .BuildPathItemAsync())
+ .ToAsyncTask()
+ .ForDriveItemRequestBuilder((b) => b.Content.PutAsync(stream))
+ .ForCustomDriveItemRequestBuilder(b => b.Content.PutAsync(stream))
+ .Task;
+ return;
}
//for larger files use an upload session. This is required for 4MB and beyond, but as the docs are not very clear about this
//limit, let's use it a bit more often to be safe.
- var uploadProps = new DriveItemUploadableProperties
+ var uploadProps = new CreateUploadSessionPostRequestBody
{
- ODataType = null,
AdditionalData = new Dictionary
{
{ "@microsoft.graph.conflictBehavior", "replace" }
}
};
-
- var uploadSession = await pathItemBuilder
- .getPathItem()
- .CreateUploadSession(uploadProps)
- .Request()
- .PostAsync();
+
+ var uploadSession = await (await pathItemBuilder
+ .BuildPathItemAsync())
+ .ToAsyncResult()
+ .ForDriveItemRequestBuilder(b => b.CreateUploadSession.PostAsync(uploadProps))
+ .ForCustomDriveItemRequestBuilder(b => b.CreateUploadSession.PostAsync(uploadProps))
+
+ .Result;
// Max slice size must be a multiple of 320 KiB
int maxSliceSize = 320 * 1024;
@@ -590,21 +695,12 @@ namespace keepass2android.Io
throw new Exception("Failed to upload data!");
}
- return uploadResult.ItemResponse;
-
-
}).Wait();
}
catch (Exception e)
{
- Task.Run(async () =>
- {
- PathItemBuilder pathItemBuilder = await GetPathItemBuilder(path);
- pathItemBuilder.verbose = true;
- pathItemBuilder.getPathItem();
- }).Wait();
throw convertException(e);
}
}
@@ -627,7 +723,7 @@ namespace keepass2android.Io
private string GetFilename(string path)
{
- string localPath = "/"+OneDrive2ItemLocation.FromString(path).LocalPathString;
+ string localPath = "/" + OneDrive2ItemLocation.FromString(path).LocalPathString;
return localPath.Substring(localPath.LastIndexOf("/", StringComparison.Ordinal) + 1);
}
@@ -648,11 +744,12 @@ namespace keepass2android.Io
{
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(parentIoc.Path);
-
- return await pathItemBuilder.getPathItem()
- .Children
- .Request()
- .AddAsync(driveItem);
+
+ return await (await pathItemBuilder.BuildPathItemAsync())
+ .ToAsyncResult()
+ .ForDriveItemRequestBuilder(b => b.Children.PostAsync(driveItem))
+ .ForCustomDriveItemRequestBuilder(b => b.Children.PostAsync(driveItem))
+ .Result;
}).Result;
@@ -681,6 +778,8 @@ namespace keepass2android.Io
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(ioc.Path);
logDebug("listing files for " + ioc.Path);
+ OneDrive2ItemLocation itemLocation = OneDrive2ItemLocation.FromString(ioc.Path);
+ var client = await TryGetMsGraphClient(ioc.Path, true);
if (!pathItemBuilder.hasShare() && !pathItemBuilder.hasOneDrivePath())
{
logDebug("listing shares.");
@@ -689,35 +788,34 @@ namespace keepass2android.Io
logDebug("listing regular children.");
List result = new List();
- /*logDebug("parent before:" + parentPath);
- parentPath = parentPath.substring(getProtocolPrefix().length());
- logDebug("parent after: " + parentPath);*/
- IDriveItemChildrenCollectionPage itemsPage = await pathItemBuilder.getPathItem()
- .Children
- .Request()
- .GetAsync();
- while (true)
- {
- IList items = itemsPage.CurrentPage;
- if (!items.Any())
- return result;
+ var driveItems = await GetDriveItems(pathItemBuilder);
- foreach (DriveItem i in items)
+ if (driveItems != null)
+ foreach (DriveItem? i in driveItems)
{
- var e = GetFileDescription(pathItemBuilder.itemLocation.BuildLocalChildLocation(i.Name, i.Id, i.ParentReference?.DriveId), i);
+ var e = GetFileDescription(itemLocation.BuildLocalChildLocation(i.Name, i.Id, i.ParentReference?.DriveId), i);
result.Add(e);
}
- var nextPageReqBuilder = itemsPage.NextPageRequest;
- if (nextPageReqBuilder == null)
- return result;
- itemsPage = Task.Run(async () => await nextPageReqBuilder.GetAsync()).Result;
- }
+ return result;
+
+ }
+
+ private async Task> GetDriveItems(
+ PathItemBuilder pathItemBuilder)
+ {
+ var pathItem = await pathItemBuilder.BuildPathItemAsync();
+ var response = await pathItem
+ .ToAsyncResult()
+ .ForDriveItemRequestBuilder(b => b.Children.GetAsync())
+ .ForCustomDriveItemRequestBuilder(b => b.Children.GetAsync())
+ .Result;
+ return response.Value;
}
- private FileDescription GetFileDescription(OneDrive2ItemLocation path, DriveItem i)
+ private FileDescription GetFileDescription(OneDrive2ItemLocation path, DriveItem? i)
{
FileDescription e = new FileDescription();
if (i.Size != null)
@@ -740,7 +838,7 @@ namespace keepass2android.Io
{
try
{
- return Task.Run(async() => await GetFileDescriptionAsync(ioc)).Result;
+ return Task.Run(async () => await GetFileDescriptionAsync(ioc)).Result;
}
catch (Exception e)
{
@@ -764,9 +862,11 @@ namespace keepass2android.Io
return rootEntry;
}
- IDriveItemRequestBuilder pathItem = pathItemBuilder.getPathItem();
-
- DriveItem item = await pathItem.Request().GetAsync();
+ var driveReq = await pathItemBuilder.BuildPathItemAsync();
+ DriveItem? item = await driveReq.ToAsyncResult()
+ .ForDriveItemRequestBuilder(b => b.GetAsync())
+ .ForCustomDriveItemRequestBuilder(b => b.GetAsync())
+ .Result;
return GetFileDescription(pathItemBuilder.itemLocation, item);
}
@@ -783,7 +883,7 @@ namespace keepass2android.Io
public void StartSelectFile(IFileStorageSetupInitiatorActivity activity, bool isForSave, int requestCode,
string protocolId)
{
- String path = ProtocolId+ "://";
+ String path = ProtocolId + "://";
activity.StartSelectFileProcess(IOConnectionInfo.FromPath(path), isForSave, requestCode);
}
@@ -827,7 +927,7 @@ namespace keepass2android.Io
public void PrepareFileUsage(Context ctx, IOConnectionInfo ioc)
{
- if (!Task.Run(async() => await IsConnectedAsync(ioc.Path, true)).Result)
+ if (!Task.Run(async () => await IsConnectedAsync(ioc.Path, true)).Result)
{
throw new Exception("MsGraph login required");
}
@@ -846,7 +946,6 @@ namespace keepass2android.Io
protected void FinishActivityWithSuccess(
IFileStorageSetupActivity setupActivity)
{
- //Log.d("KP2AJ", "Success with authenticating!");
Activity activity = (Activity)setupActivity;
if (setupActivity.ProcessName
@@ -919,7 +1018,7 @@ namespace keepass2android.Io
IAccount account = null;
try
{
-
+
if (IsConnected(iocPath))
{
logDebug("Login Silent ok, connected");
@@ -948,8 +1047,6 @@ namespace keepass2android.Io
logDebug("AcquireTokenSilent ok.");
BuildClient(authResult);
- /*User me = await graphClient.Me.Request().WithForceRefresh(true).GetAsync();
- logDebug("received name " + me.DisplayName);*/
var rootFolder = BuildRootPathForUser(authResult);
logDebug("Found RootPath for user");
@@ -966,7 +1063,7 @@ namespace keepass2android.Io
};
- mClientByUser[account.HomeAccountId.Identifier] = clientWithState;
+ _mClientByUser[account.HomeAccountId.Identifier] = clientWithState;
logDebug("ui required");
return null;
}
@@ -984,7 +1081,7 @@ namespace keepass2android.Io
return OneDrive2ItemLocation.RootForUser(res.Account.Username, res.Account.HomeAccountId.Identifier).ToString();
}
-
+
private void FinishActivityWithSuccess(IFileStorageSetupActivity activity, string rootPathForUser)
{
activity.State.PutString(FileStorageSetupDefs.ExtraPath, rootPathForUser);
@@ -1002,7 +1099,7 @@ namespace keepass2android.Io
try
{
var itemLocation = OneDrive2ItemLocation.FromString(ioc.Path);
- string result = ProtocolId+ "://";
+ string result = ProtocolId + "://";
if (!string.IsNullOrEmpty(itemLocation.User?.Id))
{
result += itemLocation.User?.Name;
@@ -1025,75 +1122,82 @@ namespace keepass2android.Io
". Note that SprEnging expressions like {DB_PATH} are not supported with OneDrive!");
return ProtocolId + "://(invalid)";
}
-
+
}
- private async Task> ListShares(OneDrive2ItemLocation parentPath, IGraphServiceClient client)
+ private async Task> ListShares(OneDrive2ItemLocation parentPath, GraphServiceClient client)
{
- List result = new List();
+ List result = [];
+ var drives = (await client.Me.Drives.GetAsync()).Value;
+ if (drives != null)
+ {
+ drives.ForEach(drive =>
+ {
+ var e = new FileDescription()
+ {
+ DisplayName = GetDriveDisplayName(drive),
+ IsDirectory = true,
+ CanRead = true,
+ CanWrite = true,
+ Path = parentPath.BuildShare("me","me","me", drive.Id).ToString()
+ };
+ result.Add(e);
+ });
+ }
+
+ string? driveId = parentPath.DriveId;
+ if ((string.IsNullOrEmpty(driveId)) && (drives?.Any() == true))
+ {
+ driveId = drives.First().Id;
+ }
+
- DriveItem root = await client.Me.Drive.Root.Request().GetAsync();
- FileDescription myEntry = GetFileDescription(parentPath.BuildShare("me","me","me", root.ParentReference?.DriveId), root);
- myEntry.DisplayName = MyOneDriveDisplayName;
-
- result.Add(myEntry);
-
if (!CanListShares)
return result;
+
+ var sharedWithMeResponse = await client.Drives[driveId].SharedWithMe.GetAsSharedWithMeGetResponseAsync();
-
-
- IDriveSharedWithMeCollectionPage sharedWithMeCollectionPage = await client.Me.Drive.SharedWithMe().Request().GetAsync();
-
- while (true)
+ foreach (DriveItem i in sharedWithMeResponse?.Value ?? [])
{
- IList sharedWithMeItems = sharedWithMeCollectionPage.CurrentPage;
- if (!sharedWithMeItems.Any())
- break;
-
- foreach (DriveItem i in sharedWithMeItems)
+ var oneDrive2ItemLocation = parentPath.BuildShare(i.RemoteItem.Id, i.RemoteItem.Name, i.RemoteItem.WebUrl, i.RemoteItem.ParentReference.DriveId);
+ FileDescription sharedFileEntry = new FileDescription()
{
- FileDescription sharedFileEntry = GetFileDescription(parentPath.BuildShare(i.Id, i.Name, i.WebUrl, i.ParentReference?.DriveId), i);
- result.Add(sharedFileEntry);
+ CanWrite = true, CanRead = true, DisplayName = i.Name,
+ IsDirectory = true,
+ Path = oneDrive2ItemLocation.ToString()
+ };
+ result.Add(sharedFileEntry);
- }
- var b = sharedWithMeCollectionPage.NextPageRequest;
- if (b == null) break;
- sharedWithMeCollectionPage = await b.GetAsync();
}
+
return result;
}
+ protected virtual string GetDriveDisplayName(Drive drive)
+ {
+ return drive.Name ?? drive.DriveType ?? "(unnamed drive)";
+ }
+
protected virtual string MyOneDriveDisplayName { get { return "My OneDrive"; } }
- public abstract bool CanListShares { get; }
+ public abstract bool CanListShares { get; }
- DriveItem TryFindFile(PathItemBuilder parent, string filename)
+ async Task TryFindFileAsync(PathItemBuilder parent, string filename)
{
- IDriveItemChildrenCollectionPage itemsPage = Task.Run(async () => await parent.getPathItem()
- .Children
- .Request()
- .GetAsync()).Result;
- while (true)
- {
- IList items = itemsPage.CurrentPage;
- if (!items.Any())
- return null;
- foreach (DriveItem i in items)
+ var driveItems = await GetDriveItems(parent);
+
+ if (driveItems != null)
+ foreach (DriveItem? i in driveItems)
{
if (i.Name == filename)
return i;
}
- var nextPageReqBuilder = itemsPage.NextPageRequest;
- if (nextPageReqBuilder == null)
- return null;
- itemsPage = Task.Run(async () => await nextPageReqBuilder.GetAsync()).Result;
- }
+ return null;
}
@@ -1102,13 +1206,13 @@ namespace keepass2android.Io
{
try
{
- return Task.Run(async() => await CreateFilePathAsync(parent, newFilename)).Result;
+ return Task.Run(async () => await CreateFilePathAsync(parent, newFilename)).Result;
}
catch (Exception e)
{
throw convertException(e);
}
-
+
}
private async Task CreateFilePathAsync(string parent, string newFilename)
@@ -1116,7 +1220,7 @@ namespace keepass2android.Io
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(parent);
//see if such a file exists already:
- var item = TryFindFile(pathItemBuilder, newFilename);
+ var item = await TryFindFileAsync(pathItemBuilder, newFilename);
if (item != null)
{
return pathItemBuilder.itemLocation.BuildLocalChildLocation(item.Name, item.Id, item.ParentReference?.DriveId)
@@ -1124,13 +1228,18 @@ namespace keepass2android.Io
}
//doesn't exist. Create:
logDebug("building request for " + pathItemBuilder.itemLocation);
+
+
+ PathItemBuilder targetPathItemBuilder = await GetPathItemBuilder(pathItemBuilder.itemLocation.BuildLocalChildLocation(newFilename, "", pathItemBuilder.itemLocation.DriveId ?? "").ToString());
- DriveItem res = await pathItemBuilder.getPathItem()
- .ItemWithPath(newFilename)
- .Content
- .Request()
- .PutAsync(new MemoryStream());
+ var emptyStream = new MemoryStream();
+ var driveItemReq = await targetPathItemBuilder.BuildPathItemAsync();
+ DriveItem? res = await driveItemReq
+ .ToAsyncResult()
+ .ForDriveItemRequestBuilder(b => b.Content.PutAsync(emptyStream))
+ .ForCustomDriveItemRequestBuilder(b => b.Content.PutAsync(emptyStream))
+ .Result;
return pathItemBuilder.itemLocation.BuildLocalChildLocation(res.Name, res.Id, res.ParentReference?.DriveId)
.ToString();
@@ -1157,7 +1266,7 @@ namespace keepass2android.Io
}
}
- public class OneDrive2FullFileStorage: OneDrive2FileStorage
+ public class OneDrive2FullFileStorage : OneDrive2FileStorage
{
public override IEnumerable Scopes
{
@@ -1168,12 +1277,17 @@ namespace keepass2android.Io
"https://graph.microsoft.com/Files.ReadWrite",
"https://graph.microsoft.com/Files.ReadWrite.All"
};
-
+
}
}
+ protected override async Task GetSpecialFolder(
+ OneDrive2ItemLocation itemLocation, GraphServiceClient client)
+ {
+ return null;
+ }
+
public override bool CanListShares { get { return true; } }
- protected override string SpecialFolder { get { return null; } }
}
@@ -1190,8 +1304,14 @@ namespace keepass2android.Io
}
}
+
+ protected override async Task GetSpecialFolder(
+ OneDrive2ItemLocation itemLocation, GraphServiceClient client)
+ {
+ return null;
+ }
+
public override bool CanListShares { get { return false; } }
- protected override string SpecialFolder { get { return null; } }
}
@@ -1209,8 +1329,41 @@ namespace keepass2android.Io
}
}
- protected override string SpecialFolder { get { return "approot"; } }
+ protected override async Task GetSpecialFolder(
+ OneDrive2ItemLocation itemLocation, GraphServiceClient client)
+ {
+ if (string.IsNullOrEmpty(itemLocation.DriveId))
+ return null; //can happen if we are accessing the root
+ if (!_specialFolderIdByDriveId.ContainsKey(itemLocation.DriveId))
+ {
+ try
+ {
+ var specialFolder = await client.Drives[itemLocation.DriveId].Special[SpecialFolderName].GetAsync();
+ _specialFolderIdByDriveId[itemLocation.DriveId] = specialFolder.Id;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+
+
+ }
+ return _specialFolderIdByDriveId[itemLocation.DriveId];
+ }
+
+
+ protected string SpecialFolderName { get { return "approot"; } }
+
+ private readonly Dictionary _specialFolderIdByDriveId = new Dictionary();
+
+ protected override string GetDriveDisplayName(Drive drive)
+ {
+ return drive.Name ?? MyOneDriveDisplayName;
+ }
+
+
public override bool CanListShares { get { return false; } }
- protected override string MyOneDriveDisplayName { get { return "Keepass2Android App Folder"; } }
+ protected override string MyOneDriveDisplayName => "Keepass2Android App Folder";
}
}
\ No newline at end of file
diff --git a/src/Kp2aBusinessLogic/Io/OneDriveFileStorage.cs b/src/Kp2aBusinessLogic/Io/OneDriveFileStorage.cs
index 25ff4d9b..a6da1c7d 100644
--- a/src/Kp2aBusinessLogic/Io/OneDriveFileStorage.cs
+++ b/src/Kp2aBusinessLogic/Io/OneDriveFileStorage.cs
@@ -1,31 +1,23 @@
-using System;
using System.Collections.Generic;
using System.IO;
-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 KeePassLib.Serialization;
-#if !EXCLUDE_JAVAFILESTORAGE
-using Keepass2android.Javafilestorage;
+using Exception = Java.Lang.Exception;
namespace keepass2android.Io
{
- public class OneDriveFileStorage: JavaFileStorage
+ ///
+ /// This IFileStorage implementation becomes picked if a user is using a skydrive:// or onedrive:// file.
+ /// These refer to an old (Java) implementation which was replaced starting in 2019. The successor uses onedrive2:// (see OneDrive2FileStorage)
+ /// The Java implementation was removed in 2024 when the jar files became unavailable. We are keeping this file to notify any user who haven't updated their
+ /// file storage within 5 years.
+ /// This file should be removed around mid 2025.
+ ///
+ public class OneDriveFileStorage: IFileStorage
{
- private const string ClientId = "000000004010C234";
-
- public OneDriveFileStorage(Context ctx, IKp2aApp app) :
- base(new Keepass2android.Javafilestorage.OneDriveStorage(ctx, ClientId), app)
- {
- }
-
- public override IEnumerable SupportedProtocols
+
+ public IEnumerable SupportedProtocols
{
get
{
@@ -34,10 +26,146 @@ namespace keepass2android.Io
}
}
- public override bool UserShouldBackup
+ private Exception GetDeprecatedMessage()
+ {
+ return new Exception(
+ "You have opened your file through a deprecated Microsoft API. Please select Change database, Open Database and then select One Drive again.");
+ }
+
+ public bool UserShouldBackup
{
get { return false; }
}
- }
+
+ public void Delete(IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public bool CheckForFileChangeFast(IOConnectionInfo ioc, string previousFileVersion)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public string GetCurrentFileVersionFast(IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public Stream OpenFileForRead(IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public string GetFileExtension(IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public bool RequiresCredentials(IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public void CreateDirectory(IOConnectionInfo ioc, string newDirName)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public IEnumerable ListContents(IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public FileDescription GetFileDescription(IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public bool RequiresSetup(IOConnectionInfo ioConnection)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public string IocToPath(IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public void StartSelectFile(IFileStorageSetupInitiatorActivity activity, bool isForSave, int requestCode, string protocolId)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public void PrepareFileUsage(IFileStorageSetupInitiatorActivity activity, IOConnectionInfo ioc, int requestCode,
+ bool alwaysReturnSuccess)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public void PrepareFileUsage(Context ctx, IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public void OnCreate(IFileStorageSetupActivity activity, Bundle savedInstanceState)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public void OnResume(IFileStorageSetupActivity activity)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public void OnStart(IFileStorageSetupActivity activity)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public void OnActivityResult(IFileStorageSetupActivity activity, int requestCode, int resultCode, Intent data)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public string GetDisplayName(IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public string CreateFilePath(string parent, string newFilename)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public IOConnectionInfo GetParentPath(IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public bool IsPermanentLocation(IOConnectionInfo ioc)
+ {
+ throw GetDeprecatedMessage();
+ }
+
+ public bool IsReadOnly(IOConnectionInfo ioc, OptionalOut reason = null)
+ {
+ throw GetDeprecatedMessage();
+ }
+ }
}
-#endif
\ No newline at end of file
diff --git a/src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj b/src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj
index 8964001d..86fa1711 100644
--- a/src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj
+++ b/src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj
@@ -1,315 +1,34 @@
-
-
-
-
-
-
+
- Debug
- AnyCPU
- {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Properties
- keepass2android
- Kp2aBusinessLogic
- 512
- Resources\Resource.designer.cs
- Off
- v13.0
- false
- $(Flavor)
-
-
+ net8.0-android
+ 21
+ enable
+ enable
-
- true
- full
- false
- bin\Debug\
- DEBUG;_EXCLUDE_TWOFISH;_EXCLUDE_KEYBOARD;_EXCLUDE_FILECHOOSER;_EXCLUDE_JAVAFILESTORAGE;INCLUDE_KEYTRANSFORM
- prompt
- 4
- None
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- 4G
- false
-
-
-
-
- $(DefineConstants);NoNet;EXCLUDE_JAVAFILESTORAGE
-
-
-
-
- bin\ReleaseNoNet\
- TRACE;NoNet;EXCLUDE_JAVAFILESTORAGE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
- false
- 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {3c0f7fe5-639f-4422-a087-8b26cf862d1b}
- AndroidFileChooserBinding
-
-
- {48574278-4779-4b3a-a9e4-9cf1bc285d0b}
- JavaFileStorageBindings
-
-
- {2db80c77-d46f-4970-b967-e9ffa9b2ac2e}
- PCloudBindings
-
-
-
-
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}
- KeePassLib2Android
-
-
- {70D3844A-D9FA-4A64-B205-A84C6A822196}
- KP2AKdbLibraryBinding
-
-
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}
- TwofishCipher
-
-
-
-
-
-
- 48.0.0
-
-
- 1.10.3
-
-
- 1.21.0
-
-
- 1.0.0-preview.7
-
-
- 4.49.1
-
+
+
+
+
+
+
+
+
-
- 1.1.1.3
-
-
- 1.1.1.3
-
-
- 1.1.1.3
-
-
- 1.1.1.3
-
-
- 1.1.1.3
-
-
- 1.1.1.3
-
-
- 1.1.1.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 1.2.0.3
-
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Kp2aBusinessLogic/ProgressTask.cs b/src/Kp2aBusinessLogic/ProgressTask.cs
index f56a78b0..62d4b6ce 100644
--- a/src/Kp2aBusinessLogic/ProgressTask.cs
+++ b/src/Kp2aBusinessLogic/ProgressTask.cs
@@ -75,7 +75,7 @@ namespace keepass2android
private readonly RunnableOnFinish _task;
private IProgressDialog _progressDialog;
private readonly IKp2aApp _app;
- private Thread _thread;
+ private Java.Lang.Thread _thread;
private Activity _activeActivity, _previouslyActiveActivity;
private ProgressDialogStatusLogger _progressDialogStatusLogger;
@@ -127,7 +127,7 @@ namespace keepass2android
public void Run(bool allowOverwriteCurrentTask = false)
{
if ((!allowOverwriteCurrentTask) && (_currentTask != null))
- throw new Exception("Cannot start another ProgressTask while ProgressTask is already running! " + _task.GetType().Name + "/" + _currentTask._task.GetType().Name);
+ throw new System.Exception("Cannot start another ProgressTask while ProgressTask is already running! " + _task.GetType().Name + "/" + _currentTask._task.GetType().Name);
_currentTask = this;
// Show process dialog
@@ -135,7 +135,7 @@ namespace keepass2android
// Start Thread to Run task
- _thread = new Thread(_task.Run);
+ _thread = new Java.Lang.Thread(_task.Run);
_thread.Start();
}
diff --git a/src/Kp2aBusinessLogic/Properties/AssemblyInfo.cs b/src/Kp2aBusinessLogic/Properties/AssemblyInfo.cs
deleted file mode 100644
index 3588c03f..00000000
--- a/src/Kp2aBusinessLogic/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Android.App;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Kp2aBusinessLogic")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Kp2aBusinessLogic")]
-[assembly: AssemblyCopyright("Copyright © 2013")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
-
-// Add some common permissions, these can be removed if not needed
-[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
diff --git a/src/Kp2aBusinessLogic/database/KdbxDatabaseFormat.cs b/src/Kp2aBusinessLogic/database/KdbxDatabaseFormat.cs
index 210c9ecf..0d9ac6fc 100644
--- a/src/Kp2aBusinessLogic/database/KdbxDatabaseFormat.cs
+++ b/src/Kp2aBusinessLogic/database/KdbxDatabaseFormat.cs
@@ -10,6 +10,12 @@ namespace keepass2android
{
private readonly KdbxFormat _format;
+ public static KdbxFormat GetFormatToUse(string fileExt)
+ {
+ return fileExt.Equals("kdbp", StringComparison.OrdinalIgnoreCase) ? KdbxFormat.ProtocolBuffers :
+ (fileExt.Equals("xml", StringComparison.OrdinalIgnoreCase) ? KdbxFormat.PlainXml : KdbxFormat.Default);
+ }
+
public KdbxDatabaseFormat(KdbxFormat format)
{
_format = format;
diff --git a/src/Kp2aBusinessLogic/database/edit/AddEntry.cs b/src/Kp2aBusinessLogic/database/edit/AddEntry.cs
index 03dc9daa..cea0fd9e 100644
--- a/src/Kp2aBusinessLogic/database/edit/AddEntry.cs
+++ b/src/Kp2aBusinessLogic/database/edit/AddEntry.cs
@@ -90,10 +90,15 @@ namespace keepass2android
// Mark parent group dirty
_app.DirtyGroups.Add(parent);
-
+ // even mark the parent of the parent dirty to update the views showing the number of child entries
+ if (parent?.ParentGroup != null)
+ {
+ _app.DirtyGroups.Add(parent.ParentGroup);
+ }
- } else
+
+ } else
{
StatusLogger.UpdateMessage(UiStringKey.UndoingChanges);
//TODO test fail
diff --git a/src/Kp2aBusinessLogic/database/edit/LoadDB.cs b/src/Kp2aBusinessLogic/database/edit/LoadDB.cs
index 03cbaad2..3c476abd 100644
--- a/src/Kp2aBusinessLogic/database/edit/LoadDB.cs
+++ b/src/Kp2aBusinessLogic/database/edit/LoadDB.cs
@@ -82,7 +82,7 @@ namespace keepass2android
}
//ok, try to load the database. Let's start with Kdbx format and retry later if that is the wrong guess:
- _format = new KdbxDatabaseFormat(KdbpFile.GetFormatToUse(_app.GetFileStorage(_ioc).GetFileExtension(_ioc)));
+ _format = new KdbxDatabaseFormat(KdbxDatabaseFormat.GetFormatToUse(_app.GetFileStorage(_ioc).GetFileExtension(_ioc)));
TryLoad(databaseStream);
diff --git a/src/Kp2aBusinessLogic/database/edit/OnFinish.cs b/src/Kp2aBusinessLogic/database/edit/OnFinish.cs
index 383f402c..455e3a53 100644
--- a/src/Kp2aBusinessLogic/database/edit/OnFinish.cs
+++ b/src/Kp2aBusinessLogic/database/edit/OnFinish.cs
@@ -21,6 +21,7 @@ using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
+using Google.Android.Material.Dialog;
namespace keepass2android
{
@@ -132,7 +133,7 @@ namespace keepass2android
{
try
{
- AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(ctx);
builder.SetMessage(message)
.SetPositiveButton(Android.Resource.String.Ok, (sender, args) => ((Dialog)sender).Dismiss())
diff --git a/src/Kp2aBusinessLogic/database/edit/SaveDB.cs b/src/Kp2aBusinessLogic/database/edit/SaveDB.cs
index 454dcfc3..c432d416 100644
--- a/src/Kp2aBusinessLogic/database/edit/SaveDB.cs
+++ b/src/Kp2aBusinessLogic/database/edit/SaveDB.cs
@@ -43,7 +43,7 @@ namespace keepass2android
///
private readonly Stream _streamForOrigFile;
private readonly Context _ctx;
- private Thread _workerThread;
+ private Java.Lang.Thread _workerThread;
public SaveDb(Activity ctx, IKp2aApp app, Database db, OnFinish finish, bool dontSave)
: base(ctx, finish)
@@ -213,7 +213,7 @@ namespace keepass2android
{
try
{
- _workerThread = new Thread(() =>
+ _workerThread = new Java.Lang.Thread(() =>
{
try
{
diff --git a/src/Kp2aKeyboardBinding/Additions/AboutAdditions.txt b/src/Kp2aKeyboardBinding/Additions/AboutAdditions.txt
index 9141ebd7..2775bd36 100644
--- a/src/Kp2aKeyboardBinding/Additions/AboutAdditions.txt
+++ b/src/Kp2aKeyboardBinding/Additions/AboutAdditions.txt
@@ -1,48 +1,48 @@
-Additions allow you to add arbitrary C# to the generated classes
-before they are compiled. This can be helpful for providing convenience
-methods or adding pure C# classes.
-
-== Adding Methods to Generated Classes ==
-
-Let's say the library being bound has a Rectangle class with a constructor
-that takes an x and y position, and a width and length size. It will look like
-this:
-
-public partial class Rectangle
-{
- public Rectangle (int x, int y, int width, int height)
- {
- // JNI bindings
- }
-}
-
-Imagine we want to add a constructor to this class that takes a Point and
-Size structure instead of 4 ints. We can add a new file called Rectangle.cs
-with a partial class containing our new method:
-
-public partial class Rectangle
-{
- public Rectangle (Point location, Size size) :
- this (location.X, location.Y, size.Width, size.Height)
- {
- }
-}
-
-At compile time, the additions class will be added to the generated class
-and the final assembly will a Rectangle class with both constructors.
-
-
-== Adding C# Classes ==
-
-Another thing that can be done is adding fully C# managed classes to the
-generated library. In the above example, let's assume that there isn't a
-Point class available in Java or our library. The one we create doesn't need
-to interact with Java, so we'll create it like a normal class in C#.
-
-By adding a Point.cs file with this class, it will end up in the binding library:
-
-public class Point
-{
- public int X { get; set; }
- public int Y { get; set; }
-}
+Additions allow you to add arbitrary C# to the generated classes
+before they are compiled. This can be helpful for providing convenience
+methods or adding pure C# classes.
+
+== Adding Methods to Generated Classes ==
+
+Let's say the library being bound has a Rectangle class with a constructor
+that takes an x and y position, and a width and length size. It will look like
+this:
+
+public partial class Rectangle
+{
+ public Rectangle (int x, int y, int width, int height)
+ {
+ // JNI bindings
+ }
+}
+
+Imagine we want to add a constructor to this class that takes a Point and
+Size structure instead of 4 ints. We can add a new file called Rectangle.cs
+with a partial class containing our new method:
+
+public partial class Rectangle
+{
+ public Rectangle (Point location, Size size) :
+ this (location.X, location.Y, size.Width, size.Height)
+ {
+ }
+}
+
+At compile time, the additions class will be added to the generated class
+and the final assembly will a Rectangle class with both constructors.
+
+
+== Adding C# Classes ==
+
+Another thing that can be done is adding fully C# managed classes to the
+generated library. In the above example, let's assume that there isn't a
+Point class available in Java or our library. The one we create doesn't need
+to interact with Java, so we'll create it like a normal class in C#.
+
+By adding a Point.cs file with this class, it will end up in the binding library:
+
+public class Point
+{
+ public int X { get; set; }
+ public int Y { get; set; }
+}
\ No newline at end of file
diff --git a/src/Kp2aKeyboardBinding/Kp2aKeyboardBinding.csproj b/src/Kp2aKeyboardBinding/Kp2aKeyboardBinding.csproj
index 869dcc35..696dc506 100644
--- a/src/Kp2aKeyboardBinding/Kp2aKeyboardBinding.csproj
+++ b/src/Kp2aKeyboardBinding/Kp2aKeyboardBinding.csproj
@@ -1,72 +1,11 @@
-
-
+
- Debug
- AnyCPU
- {A8779D4D-7C49-4C2F-82BD-2CDC448391DA}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{10368E6C-D01B-4462-8E8B-01FC667A7035};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Kp2aKeyboardBinding
- Assets
- Resources
- Kp2aKeyboardBinding
- false
- v10.0
- XAJavaInterop1
- class-parse
-
-
- True
- full
- False
- bin\Debug
- DEBUG;
- prompt
- 4
- False
- None
-
-
- none
- True
- bin\Release
- prompt
- 4
- False
- False
-
-
- bin\ReleaseNoNet\
- true
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
- false
- 4
+ net8.0-android
+ 21
+ enable
+ enable
-
-
-
-
+
-
-
-
-
-
- Jars\app-debug.aar
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/Kp2aKeyboardBinding/Properties/AssemblyInfo.cs b/src/Kp2aKeyboardBinding/Properties/AssemblyInfo.cs
deleted file mode 100644
index a8aed884..00000000
--- a/src/Kp2aKeyboardBinding/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using Android.App;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle("Kp2aKeyboardBinding")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("Philipp")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion("1.0.0")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/src/Kp2aKeyboardBinding/Transforms/EnumFields.xml b/src/Kp2aKeyboardBinding/Transforms/EnumFields.xml
index b3aca487..4dddf452 100644
--- a/src/Kp2aKeyboardBinding/Transforms/EnumFields.xml
+++ b/src/Kp2aKeyboardBinding/Transforms/EnumFields.xml
@@ -1,14 +1,3 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/src/Kp2aKeyboardBinding/Transforms/EnumMethods.xml b/src/Kp2aKeyboardBinding/Transforms/EnumMethods.xml
index 0ffc15ca..1918b0cf 100644
--- a/src/Kp2aKeyboardBinding/Transforms/EnumMethods.xml
+++ b/src/Kp2aKeyboardBinding/Transforms/EnumMethods.xml
@@ -1,11 +1,3 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/src/Kp2aKeyboardBinding/Transforms/Metadata.xml b/src/Kp2aKeyboardBinding/Transforms/Metadata.xml
index 3601ad1c..ccb9c065 100644
--- a/src/Kp2aKeyboardBinding/Transforms/Metadata.xml
+++ b/src/Kp2aKeyboardBinding/Transforms/Metadata.xml
@@ -1,11 +1,4 @@
-
-
-
-
-
+
+
+
+
diff --git a/src/PCloudBindings/Additions/AboutAdditions.txt b/src/PCloudBindings/Additions/AboutAdditions.txt
index 08caee33..2775bd36 100644
--- a/src/PCloudBindings/Additions/AboutAdditions.txt
+++ b/src/PCloudBindings/Additions/AboutAdditions.txt
@@ -1,4 +1,4 @@
-Additions allow you to add arbitrary C# to the generated classes
+Additions allow you to add arbitrary C# to the generated classes
before they are compiled. This can be helpful for providing convenience
methods or adding pure C# classes.
@@ -11,9 +11,9 @@ this:
public partial class Rectangle
{
public Rectangle (int x, int y, int width, int height)
- {
- // JNI bindings
- }
+ {
+ // JNI bindings
+ }
}
Imagine we want to add a constructor to this class that takes a Point and
@@ -23,9 +23,9 @@ with a partial class containing our new method:
public partial class Rectangle
{
public Rectangle (Point location, Size size) :
- this (location.X, location.Y, size.Width, size.Height)
- {
- }
+ this (location.X, location.Y, size.Width, size.Height)
+ {
+ }
}
At compile time, the additions class will be added to the generated class
@@ -44,5 +44,5 @@ By adding a Point.cs file with this class, it will end up in the binding library
public class Point
{
public int X { get; set; }
- public int Y { get; set; }
+ public int Y { get; set; }
}
\ No newline at end of file
diff --git a/src/PCloudBindings/Jars/AboutJars.txt b/src/PCloudBindings/Jars/AboutJars.txt
deleted file mode 100644
index c359b62f..00000000
--- a/src/PCloudBindings/Jars/AboutJars.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-This directory is for Android .jars.
-
-There are 2 types of jars that are supported:
-
-== Input Jar ==
-
-This is the jar that bindings should be generated for.
-
-For example, if you were binding the Google Maps library, this would
-be Google's "maps.jar".
-
-Set the build action for these jars in the properties page to "InputJar".
-
-
-== Reference Jars ==
-
-These are jars that are referenced by the input jar. C# bindings will
-not be created for these jars. These jars will be used to resolve
-types used by the input jar.
-
-NOTE: Do not add "android.jar" as a reference jar. It will be added automatically
-based on the Target Framework selected.
-
-Set the build action for these jars in the properties page to "ReferenceJar".
\ No newline at end of file
diff --git a/src/PCloudBindings/PCloudBindings.csproj b/src/PCloudBindings/PCloudBindings.csproj
index 3b99dd22..495b27a6 100644
--- a/src/PCloudBindings/PCloudBindings.csproj
+++ b/src/PCloudBindings/PCloudBindings.csproj
@@ -1,77 +1,12 @@
-
-
+
- Debug
- AnyCPU
- {2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{10368E6C-D01B-4462-8E8B-01FC667A7035};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Properties
- PCloudBindings
- PCouldBindings
- 512
- false
- v8.0
- XAJavaInterop1
- class-parse
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 0
- None
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- false
-
-
- bin\ReleaseNoNet\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
- false
- 4
+ net8.0-android
+ 21
+ enable
+ enable
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/PCloudBindings/Properties/AssemblyInfo.cs b/src/PCloudBindings/Properties/AssemblyInfo.cs
deleted file mode 100644
index 8e086067..00000000
--- a/src/PCloudBindings/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Android.App;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("PCloudBindings")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("PCloudBindings")]
-[assembly: AssemblyCopyright("Copyright © 2013")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.1.0.0")]
-[assembly: AssemblyFileVersion("1.1.0.0")]
diff --git a/src/PCloudBindings/Transforms/EnumFields.xml b/src/PCloudBindings/Transforms/EnumFields.xml
index 22959957..8ee086d7 100644
--- a/src/PCloudBindings/Transforms/EnumFields.xml
+++ b/src/PCloudBindings/Transforms/EnumFields.xml
@@ -1,14 +1,3 @@
-
+
\ No newline at end of file
diff --git a/src/PCloudBindings/Transforms/EnumMethods.xml b/src/PCloudBindings/Transforms/EnumMethods.xml
index 49216c61..1918b0cf 100644
--- a/src/PCloudBindings/Transforms/EnumMethods.xml
+++ b/src/PCloudBindings/Transforms/EnumMethods.xml
@@ -1,13 +1,3 @@
-
+
\ No newline at end of file
diff --git a/src/PCloudBindings/Transforms/Metadata.xml b/src/PCloudBindings/Transforms/Metadata.xml
index e1ee3276..6b36b978 100644
--- a/src/PCloudBindings/Transforms/Metadata.xml
+++ b/src/PCloudBindings/Transforms/Metadata.xml
@@ -1,10 +1,4 @@
-
-
+
+
diff --git a/src/PCloudBindings/Jars/pcloud-sdk-android-1.9.1.aar b/src/PCloudBindings/pcloud-sdk-android-1.9.1.aar
similarity index 100%
rename from src/PCloudBindings/Jars/pcloud-sdk-android-1.9.1.aar
rename to src/PCloudBindings/pcloud-sdk-android-1.9.1.aar
diff --git a/src/PCloudBindings/Jars/pcloud-sdk-java-core-1.9.1.jar b/src/PCloudBindings/pcloud-sdk-java-core-1.9.1.jar
similarity index 100%
rename from src/PCloudBindings/Jars/pcloud-sdk-java-core-1.9.1.jar
rename to src/PCloudBindings/pcloud-sdk-java-core-1.9.1.jar
diff --git a/src/PluginSdkBinding/Additions/AboutAdditions.txt b/src/PluginSdkBinding/Additions/AboutAdditions.txt
index 08caee33..2775bd36 100644
--- a/src/PluginSdkBinding/Additions/AboutAdditions.txt
+++ b/src/PluginSdkBinding/Additions/AboutAdditions.txt
@@ -1,4 +1,4 @@
-Additions allow you to add arbitrary C# to the generated classes
+Additions allow you to add arbitrary C# to the generated classes
before they are compiled. This can be helpful for providing convenience
methods or adding pure C# classes.
@@ -11,9 +11,9 @@ this:
public partial class Rectangle
{
public Rectangle (int x, int y, int width, int height)
- {
- // JNI bindings
- }
+ {
+ // JNI bindings
+ }
}
Imagine we want to add a constructor to this class that takes a Point and
@@ -23,9 +23,9 @@ with a partial class containing our new method:
public partial class Rectangle
{
public Rectangle (Point location, Size size) :
- this (location.X, location.Y, size.Width, size.Height)
- {
- }
+ this (location.X, location.Y, size.Width, size.Height)
+ {
+ }
}
At compile time, the additions class will be added to the generated class
@@ -44,5 +44,5 @@ By adding a Point.cs file with this class, it will end up in the binding library
public class Point
{
public int X { get; set; }
- public int Y { get; set; }
+ public int Y { get; set; }
}
\ No newline at end of file
diff --git a/src/PluginSdkBinding/PluginSdkBinding.csproj b/src/PluginSdkBinding/PluginSdkBinding.csproj
index 11a089fb..16be7749 100644
--- a/src/PluginSdkBinding/PluginSdkBinding.csproj
+++ b/src/PluginSdkBinding/PluginSdkBinding.csproj
@@ -1,77 +1,11 @@
-
-
+
- Debug
- AnyCPU
- {3DA3911E-36DE-465E-8F15-F1991B6437E5}
- {10368E6C-D01B-4462-8E8B-01FC667A7035};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Properties
- PluginSdkBinding
- PluginSdkBinding
- 512
- false
- v8.0
- XAJavaInterop1
- class-parse
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- None
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- false
-
-
- bin\ReleaseNoNet\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
- false
- 4
+ net8.0-android
+ 21
+ enable
+ enable
-
-
-
-
+
-
-
-
-
-
- Jars\Keepass2AndroidPluginSDK2-release.aar
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/PluginSdkBinding/Properties/AssemblyInfo.cs b/src/PluginSdkBinding/Properties/AssemblyInfo.cs
deleted file mode 100644
index 136f4089..00000000
--- a/src/PluginSdkBinding/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Android.App;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("PluginSdkBinding")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("PluginSdkBinding")]
-[assembly: AssemblyCopyright("Copyright © 2014")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/PluginSdkBinding/Transforms/EnumFields.xml b/src/PluginSdkBinding/Transforms/EnumFields.xml
index 22959957..4dddf452 100644
--- a/src/PluginSdkBinding/Transforms/EnumFields.xml
+++ b/src/PluginSdkBinding/Transforms/EnumFields.xml
@@ -1,14 +1,3 @@
-
+
\ No newline at end of file
diff --git a/src/PluginSdkBinding/Transforms/EnumMethods.xml b/src/PluginSdkBinding/Transforms/EnumMethods.xml
index 49216c61..85202262 100644
--- a/src/PluginSdkBinding/Transforms/EnumMethods.xml
+++ b/src/PluginSdkBinding/Transforms/EnumMethods.xml
@@ -1,13 +1,3 @@
-
+
\ No newline at end of file
diff --git a/src/PluginSdkBinding/Transforms/Metadata.xml b/src/PluginSdkBinding/Transforms/Metadata.xml
index 2587ddc4..8c503795 100644
--- a/src/PluginSdkBinding/Transforms/Metadata.xml
+++ b/src/PluginSdkBinding/Transforms/Metadata.xml
@@ -1,9 +1,3 @@
-
-
+
+
diff --git a/src/ProtoBuf/Licence.txt b/src/ProtoBuf/Licence.txt
deleted file mode 100644
index 692cf3ba..00000000
--- a/src/ProtoBuf/Licence.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-The core Protocol Buffers technology is provided courtesy of Google.
-At the time of writing, this is released under the BSD license.
-Full details can be found here:
-
-http://code.google.com/p/protobuf/
-
-
-This .NET implementation is Copyright 2008 Marc Gravell
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/src/ProtoBuf/Readme.txt b/src/ProtoBuf/Readme.txt
deleted file mode 100644
index 51b18fd5..00000000
--- a/src/ProtoBuf/Readme.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-The contents of this folder were generated by compiling the protobuf-net_MonoDroid project
-from the http://code.google.com/p/protobuf-net source code
\ No newline at end of file
diff --git a/src/ProtoBuf/protobuf-net.dll b/src/ProtoBuf/protobuf-net.dll
deleted file mode 100644
index dc79fd0a..00000000
Binary files a/src/ProtoBuf/protobuf-net.dll and /dev/null differ
diff --git a/src/ProtoBuf/protobuf-net.pdb b/src/ProtoBuf/protobuf-net.pdb
deleted file mode 100644
index 6c841feb..00000000
Binary files a/src/ProtoBuf/protobuf-net.pdb and /dev/null differ
diff --git a/src/TwofishCipher/Crypto/Twofish.cs b/src/TwofishCipher/Crypto/Twofish.cs
deleted file mode 100644
index db054e47..00000000
--- a/src/TwofishCipher/Crypto/Twofish.cs
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- A C# implementation of the Twofish cipher
- By Shaun Wilde
-
- An article on integrating a C# implementation of the Twofish cipher into the
- .NET framework.
-
- http://www.codeproject.com/KB/recipes/twofish_csharp.aspx
-
- The Code Project Open License (CPOL) 1.02
- http://www.codeproject.com/info/cpol10.aspx
-
- Download a copy of the CPOL.
- http://www.codeproject.com/info/CPOL.zip
-*/
-
-using System;
-using System.Diagnostics;
-using System.Security.Cryptography;
-
-namespace TwofishCipher.Crypto
-{
- ///
- /// Summary description for Twofish encryption algorithm of which more information can be found at http://www.counterpane.com/twofish.html.
- /// This is based on the MS cryptographic framework and can therefore be used in place of the RijndaelManaged classes
- /// provided by MS in System.Security.Cryptography and the other related classes
- ///
- public sealed class Twofish : SymmetricAlgorithm
- {
- ///
- /// This is the Twofish constructor.
- ///
- public Twofish()
- {
- this.LegalKeySizesValue = new KeySizes[]{new KeySizes(128,256,64)}; // this allows us to have 128,192,256 key sizes
-
- this.LegalBlockSizesValue = new KeySizes[]{new KeySizes(128,128,0)}; // this is in bits - typical of MS - always 16 bytes
-
- this.BlockSize = 128; // set this to 16 bytes we cannot have any other value
- this.KeySize = 128; // in bits - this can be changed to 128,192,256
-
- this.Padding = PaddingMode.Zeros;
-
- this.Mode = CipherMode.ECB;
-
- }
-
- ///
- /// Creates an object that supports ICryptoTransform that can be used to encrypt data using the Twofish encryption algorithm.
- ///
- /// A byte array that contains a key. The length of this key should be equal to the KeySize property
- /// A byte array that contains an initialization vector. The length of this IV should be equal to the BlockSize property
- public override ICryptoTransform CreateEncryptor(byte[] key, byte[] iv)
- {
- Key = key; // this appears to make a new copy
-
- if (Mode == CipherMode.CBC)
- IV = iv;
-
- return new TwofishEncryption(KeySize, ref KeyValue, ref IVValue, ModeValue, TwofishBase.EncryptionDirection.Encrypting);
- }
-
- ///
- /// Creates an object that supports ICryptoTransform that can be used to decrypt data using the Twofish encryption algorithm.
- ///
- /// A byte array that contains a key. The length of this key should be equal to the KeySize property
- /// A byte array that contains an initialization vector. The length of this IV should be equal to the BlockSize property
- public override ICryptoTransform CreateDecryptor(byte[] key, byte[] iv)
- {
- Key = key;
-
- if (Mode == CipherMode.CBC)
- IV = iv;
-
- return new TwofishEncryption(KeySize, ref KeyValue, ref IVValue, ModeValue, TwofishBase.EncryptionDirection.Decrypting);
- }
-
- ///
- /// Generates a random initialization Vector (IV).
- ///
- public override void GenerateIV()
- {
- IV = new byte[16]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
- }
-
- ///
- /// Generates a random Key. This is only really useful in testing scenarios.
- ///
- public override void GenerateKey()
- {
- Key = new byte[KeySize/8];
-
- // set the array to all 0 - implement a random key generation mechanism later probably based on PRNG
- for (int i=Key.GetLowerBound(0);i
- /// Override the Set method on this property so that we only support CBC and EBC
- ///
- public override CipherMode Mode
- {
- set
- {
- switch (value)
- {
- case CipherMode.CBC:
- break;
- case CipherMode.ECB:
- break;
- default:
- throw (new CryptographicException("Specified CipherMode is not supported."));
- }
- this.ModeValue = value;
- }
- }
-
- }
-}
diff --git a/src/TwofishCipher/Crypto/TwofishBase.cs b/src/TwofishCipher/Crypto/TwofishBase.cs
deleted file mode 100644
index a29a9148..00000000
--- a/src/TwofishCipher/Crypto/TwofishBase.cs
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- A C# implementation of the Twofish cipher
- By Shaun Wilde
-
- An article on integrating a C# implementation of the Twofish cipher into the
- .NET framework.
-
- http://www.codeproject.com/KB/recipes/twofish_csharp.aspx
-
- The Code Project Open License (CPOL) 1.02
- http://www.codeproject.com/info/cpol10.aspx
-
- Download a copy of the CPOL.
- http://www.codeproject.com/info/CPOL.zip
-*/
-
-//#define FEISTEL
-
-using System;
-using System.Diagnostics;
-using System.Security.Cryptography;
-
-namespace TwofishCipher.Crypto
-{
-
- ///
- /// Summary description for TwofishBase.
- ///
- internal class TwofishBase
- {
- public enum EncryptionDirection
- {
- Encrypting,
- Decrypting
- }
-
- public TwofishBase()
- {
- }
-
- protected int inputBlockSize = BLOCK_SIZE/8;
- protected int outputBlockSize = BLOCK_SIZE/8;
-
- /*
- +*****************************************************************************
- *
- * Function Name: f32
- *
- * Function: Run four bytes through keyed S-boxes and apply MDS matrix
- *
- * Arguments: x = input to f function
- * k32 = pointer to key dwords
- * keyLen = total key length (k32 --> keyLey/2 bits)
- *
- * Return: The output of the keyed permutation applied to x.
- *
- * Notes:
- * This function is a keyed 32-bit permutation. It is the major building
- * block for the Twofish round function, including the four keyed 8x8
- * permutations and the 4x4 MDS matrix multiply. This function is used
- * both for generating round subkeys and within the round function on the
- * block being encrypted.
- *
- * This version is fairly slow and pedagogical, although a smartcard would
- * probably perform the operation exactly this way in firmware. For
- * ultimate performance, the entire operation can be completed with four
- * lookups into four 256x32-bit tables, with three dword xors.
- *
- * The MDS matrix is defined in TABLE.H. To multiply by Mij, just use the
- * macro Mij(x).
- *
- -****************************************************************************/
- private static uint f32(uint x,ref uint[] k32,int keyLen)
- {
- byte[] b = {b0(x),b1(x),b2(x),b3(x)};
-
- /* Run each byte thru 8x8 S-boxes, xoring with key byte at each stage. */
- /* Note that each byte goes through a different combination of S-boxes.*/
-
- //*((DWORD *)b) = Bswap(x); /* make b[0] = LSB, b[3] = MSB */
- switch (((keyLen + 63)/64) & 3)
- {
- case 0: /* 256 bits of key */
- b[0] = (byte)(P8x8[P_04,b[0]] ^ b0(k32[3]));
- b[1] = (byte)(P8x8[P_14,b[1]] ^ b1(k32[3]));
- b[2] = (byte)(P8x8[P_24,b[2]] ^ b2(k32[3]));
- b[3] = (byte)(P8x8[P_34,b[3]] ^ b3(k32[3]));
- /* fall thru, having pre-processed b[0]..b[3] with k32[3] */
- goto case 3;
- case 3: /* 192 bits of key */
- b[0] = (byte)(P8x8[P_03,b[0]] ^ b0(k32[2]));
- b[1] = (byte)(P8x8[P_13,b[1]] ^ b1(k32[2]));
- b[2] = (byte)(P8x8[P_23,b[2]] ^ b2(k32[2]));
- b[3] = (byte)(P8x8[P_33,b[3]] ^ b3(k32[2]));
- /* fall thru, having pre-processed b[0]..b[3] with k32[2] */
- goto case 2;
- case 2: /* 128 bits of key */
- b[0] = P8x8[P_00, P8x8[P_01, P8x8[P_02, b[0]] ^ b0(k32[1])] ^ b0(k32[0])];
- b[1] = P8x8[P_10, P8x8[P_11, P8x8[P_12, b[1]] ^ b1(k32[1])] ^ b1(k32[0])];
- b[2] = P8x8[P_20, P8x8[P_21, P8x8[P_22, b[2]] ^ b2(k32[1])] ^ b2(k32[0])];
- b[3] = P8x8[P_30, P8x8[P_31, P8x8[P_32, b[3]] ^ b3(k32[1])] ^ b3(k32[0])];
- break;
- }
-
-
- /* Now perform the MDS matrix multiply inline. */
- return (uint)((M00(b[0]) ^ M01(b[1]) ^ M02(b[2]) ^ M03(b[3]))) ^
- (uint)((M10(b[0]) ^ M11(b[1]) ^ M12(b[2]) ^ M13(b[3])) << 8) ^
- (uint)((M20(b[0]) ^ M21(b[1]) ^ M22(b[2]) ^ M23(b[3])) << 16) ^
- (uint)((M30(b[0]) ^ M31(b[1]) ^ M32(b[2]) ^ M33(b[3])) << 24) ;
- }
-
- /*
- +*****************************************************************************
- *
- * Function Name: reKey
- *
- * Function: Initialize the Twofish key schedule from key32
- *
- * Arguments: key = ptr to keyInstance to be initialized
- *
- * Return: TRUE on success
- *
- * Notes:
- * Here we precompute all the round subkeys, although that is not actually
- * required. For example, on a smartcard, the round subkeys can
- * be generated on-the-fly using f32()
- *
- -****************************************************************************/
- protected bool reKey(int keyLen, ref uint[] key32)
- {
- int i,k64Cnt;
- keyLength = keyLen;
- rounds = numRounds[(keyLen-1)/64];
- int subkeyCnt = ROUND_SUBKEYS + 2*rounds;
- uint A,B;
- uint[] k32e = new uint[MAX_KEY_BITS/64];
- uint[] k32o = new uint[MAX_KEY_BITS/64]; /* even/odd key dwords */
-
- k64Cnt=(keyLen+63)/64; /* round up to next multiple of 64 bits */
- for (i=0;i=0;r--) /* main Twofish decryption loop */
- {
- t0 = f32( x[0] ,ref sboxKeys,keyLength);
- t1 = f32(ROL(x[1],8),ref sboxKeys,keyLength);
-
- x[2] = ROL(x[2],1);
- x[2]^= t0 + t1 + subKeys[ROUND_SUBKEYS+2*r ]; /* PHT, round keys */
- x[3]^= t0 + 2*t1 + subKeys[ROUND_SUBKEYS+2*r+1];
- x[3] = ROR(x[3],1);
-
- if (r>0) /* unswap, except for last round */
- {
- t0 = x[0]; x[0]= x[2]; x[2] = t0;
- t1 = x[1]; x[1]= x[3]; x[3] = t1;
- }
- }
-
- for (int i=0;i0) ? k0 : k1; /* merge in 32 more key bits */
- for (j=0;j<4;j++) /* shift one byte at a time */
- RS_rem(ref r);
- }
- return r;
- }
-
- protected uint[] sboxKeys = new uint[MAX_KEY_BITS/64]; /* key bits used for S-boxes */
- protected uint[] subKeys = new uint[TOTAL_SUBKEYS]; /* round subkeys, input/output whitening bits */
- protected uint[] Key = {0,0,0,0,0,0,0,0}; //new int[MAX_KEY_BITS/32];
- protected uint[] IV = {0,0,0,0}; // this should be one block size
- private int keyLength;
- private int rounds;
- protected CipherMode cipherMode = CipherMode.ECB;
-
-
- #region These are all the definitions that were found in AES.H
- static private readonly int BLOCK_SIZE = 128; /* number of bits per block */
- static private readonly int MAX_ROUNDS = 16; /* max # rounds (for allocating subkey array) */
- static private readonly int ROUNDS_128 = 16; /* default number of rounds for 128-bit keys*/
- static private readonly int ROUNDS_192 = 16; /* default number of rounds for 192-bit keys*/
- static private readonly int ROUNDS_256 = 16; /* default number of rounds for 256-bit keys*/
- static private readonly int MAX_KEY_BITS = 256; /* max number of bits of key */
-// static private readonly int MIN_KEY_BITS = 128; /* min number of bits of key (zero pad) */
-
-//#define VALID_SIG 0x48534946 /* initialization signature ('FISH') */
-//#define MCT_OUTER 400 /* MCT outer loop */
-//#define MCT_INNER 10000 /* MCT inner loop */
-//#define REENTRANT 1 /* nonzero forces reentrant code (slightly slower) */
-
- static private readonly int INPUT_WHITEN = 0; /* subkey array indices */
- static private readonly int OUTPUT_WHITEN = (INPUT_WHITEN + BLOCK_SIZE/32);
- static private readonly int ROUND_SUBKEYS = (OUTPUT_WHITEN + BLOCK_SIZE/32); /* use 2 * (# rounds) */
- static private readonly int TOTAL_SUBKEYS = (ROUND_SUBKEYS + 2*MAX_ROUNDS);
-
-
- #endregion
-
- #region These are all the definitions that were found in TABLE.H that we need
- /* for computing subkeys */
- static private readonly uint SK_STEP = 0x02020202u;
- static private readonly uint SK_BUMP = 0x01010101u;
- static private readonly int SK_ROTL = 9;
-
- /* Reed-Solomon code parameters: (12,8) reversible code
- g(x) = x**4 + (a + 1/a) x**3 + a x**2 + (a + 1/a) x + 1
- where a = primitive root of field generator 0x14D */
- static private readonly uint RS_GF_FDBK = 0x14D; /* field generator */
- static private void RS_rem(ref uint x)
- {
- byte b = (byte) (x >> 24);
- // TODO: maybe change g2 and g3 to bytes
- uint g2 = (uint)(((b << 1) ^ (((b & 0x80)==0x80) ? RS_GF_FDBK : 0 )) & 0xFF);
- uint g3 = (uint)(((b >> 1) & 0x7F) ^ (((b & 1)==1) ? RS_GF_FDBK >> 1 : 0 ) ^ g2) ;
- x = (x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b;
- }
-
- /* Macros for the MDS matrix
- * The MDS matrix is (using primitive polynomial 169):
- * 01 EF 5B 5B
- * 5B EF EF 01
- * EF 5B 01 EF
- * EF 01 EF 5B
- *----------------------------------------------------------------
- * More statistical properties of this matrix (from MDS.EXE output):
- *
- * Min Hamming weight (one byte difference) = 8. Max=26. Total = 1020.
- * Prob[8]: 7 23 42 20 52 95 88 94 121 128 91
- * 102 76 41 24 8 4 1 3 0 0 0
- * Runs[8]: 2 4 5 6 7 8 9 11
- * MSBs[8]: 1 4 15 8 18 38 40 43
- * HW= 8: 05040705 0A080E0A 14101C14 28203828 50407050 01499101 A080E0A0
- * HW= 9: 04050707 080A0E0E 10141C1C 20283838 40507070 80A0E0E0 C6432020 07070504
- * 0E0E0A08 1C1C1410 38382820 70705040 E0E0A080 202043C6 05070407 0A0E080E
- * 141C101C 28382038 50704070 A0E080E0 4320C620 02924B02 089A4508
- * Min Hamming weight (two byte difference) = 3. Max=28. Total = 390150.
- * Prob[3]: 7 18 55 149 270 914 2185 5761 11363 20719 32079
- * 43492 51612 53851 52098 42015 31117 20854 11538 6223 2492 1033
- * MDS OK, ROR: 6+ 7+ 8+ 9+ 10+ 11+ 12+ 13+ 14+ 15+ 16+
- * 17+ 18+ 19+ 20+ 21+ 22+ 23+ 24+ 25+ 26+
- */
- static private readonly int MDS_GF_FDBK = 0x169; /* primitive polynomial for GF(256)*/
- static private int LFSR1(int x)
- {
- return ( ((x) >> 1) ^ ((((x) & 0x01)==0x01) ? MDS_GF_FDBK/2 : 0));
- }
-
- static private int LFSR2(int x)
- {
- return ( ((x) >> 2) ^ ((((x) & 0x02)==0x02) ? MDS_GF_FDBK/2 : 0) ^
- ((((x) & 0x01)==0x01) ? MDS_GF_FDBK/4 : 0));
- }
-
- // TODO: not the most efficient use of code but it allows us to update the code a lot quicker we can possibly optimize this code once we have got it all working
- static private int Mx_1(int x)
- {
- return x; /* force result to int so << will work */
- }
-
- static private int Mx_X(int x)
- {
- return x ^ LFSR2(x); /* 5B */
- }
-
- static private int Mx_Y(int x)
- {
- return x ^ LFSR1(x) ^ LFSR2(x); /* EF */
- }
-
- static private int M00(int x)
- {
- return Mul_1(x);
- }
- static private int M01(int x)
- {
- return Mul_Y(x);
- }
- static private int M02(int x)
- {
- return Mul_X(x);
- }
- static private int M03(int x)
- {
- return Mul_X(x);
- }
-
- static private int M10(int x)
- {
- return Mul_X(x);
- }
- static private int M11(int x)
- {
- return Mul_Y(x);
- }
- static private int M12(int x)
- {
- return Mul_Y(x);
- }
- static private int M13(int x)
- {
- return Mul_1(x);
- }
-
- static private int M20(int x)
- {
- return Mul_Y(x);
- }
- static private int M21(int x)
- {
- return Mul_X(x);
- }
- static private int M22(int x)
- {
- return Mul_1(x);
- }
- static private int M23(int x)
- {
- return Mul_Y(x);
- }
-
- static private int M30(int x)
- {
- return Mul_Y(x);
- }
- static private int M31(int x)
- {
- return Mul_1(x);
- }
- static private int M32(int x)
- {
- return Mul_Y(x);
- }
- static private int M33(int x)
- {
- return Mul_X(x);
- }
-
- static private int Mul_1(int x)
- {
- return Mx_1(x);
- }
- static private int Mul_X(int x)
- {
- return Mx_X(x);
- }
- static private int Mul_Y(int x)
- {
- return Mx_Y(x);
- }
- /* Define the fixed p0/p1 permutations used in keyed S-box lookup.
- By changing the following constant definitions for P_ij, the S-boxes will
- automatically get changed in all the Twofish source code. Note that P_i0 is
- the "outermost" 8x8 permutation applied. See the f32() function to see
- how these constants are to be used.
- */
- static private readonly int P_00 = 1; /* "outermost" permutation */
- static private readonly int P_01 = 0;
- static private readonly int P_02 = 0;
- static private readonly int P_03 = (P_01^1); /* "extend" to larger key sizes */
- static private readonly int P_04 = 1;
-
- static private readonly int P_10 = 0;
- static private readonly int P_11 = 0;
- static private readonly int P_12 = 1;
- static private readonly int P_13 = (P_11^1);
- static private readonly int P_14 = 0;
-
- static private readonly int P_20 = 1;
- static private readonly int P_21 = 1;
- static private readonly int P_22 = 0;
- static private readonly int P_23 = (P_21^1);
- static private readonly int P_24 = 0;
-
- static private readonly int P_30 = 0;
- static private readonly int P_31 = 1;
- static private readonly int P_32 = 1;
- static private readonly int P_33 = (P_31^1);
- static private readonly int P_34 = 1;
-
- /* fixed 8x8 permutation S-boxes */
-
- /***********************************************************************
- * 07:07:14 05/30/98 [4x4] TestCnt=256. keySize=128. CRC=4BD14D9E.
- * maxKeyed: dpMax = 18. lpMax =100. fixPt = 8. skXor = 0. skDup = 6.
- * log2(dpMax[ 6..18])= --- 15.42 1.33 0.89 4.05 7.98 12.05
- * log2(lpMax[ 7..12])= 9.32 1.01 1.16 4.23 8.02 12.45
- * log2(fixPt[ 0.. 8])= 1.44 1.44 2.44 4.06 6.01 8.21 11.07 14.09 17.00
- * log2(skXor[ 0.. 0])
- * log2(skDup[ 0.. 6])= --- 2.37 0.44 3.94 8.36 13.04 17.99
- ***********************************************************************/
- static private byte[,] P8x8 =
- {
- /* p0: */
- /* dpMax = 10. lpMax = 64. cycleCnt= 1 1 1 0. */
- /* 817D6F320B59ECA4.ECB81235F4A6709D.BA5E6D90C8F32471.D7F4126E9B3085CA. */
- /* Karnaugh maps:
- * 0111 0001 0011 1010. 0001 1001 1100 1111. 1001 1110 0011 1110. 1101 0101 1111 1001.
- * 0101 1111 1100 0100. 1011 0101 0010 0000. 0101 1000 1100 0101. 1000 0111 0011 0010.
- * 0000 1001 1110 1101. 1011 1000 1010 0011. 0011 1001 0101 0000. 0100 0010 0101 1011.
- * 0111 0100 0001 0110. 1000 1011 1110 1001. 0011 0011 1001 1101. 1101 0101 0000 1100.
- */
- {
- 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
- 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
- 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
- 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
- 0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23,
- 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
- 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C,
- 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
- 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
- 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
- 0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66,
- 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
- 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA,
- 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
- 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
- 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
- 0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2,
- 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
- 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB,
- 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
- 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
- 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
- 0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A,
- 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
- 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02,
- 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
- 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
- 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
- 0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8,
- 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
- 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00,
- 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
- },
- /* p1: */
- /* dpMax = 10. lpMax = 64. cycleCnt= 2 0 0 1. */
- /* 28BDF76E31940AC5.1E2B4C376DA5F908.4C75169A0ED82B3F.B951C3DE647F208A. */
- /* Karnaugh maps:
- * 0011 1001 0010 0111. 1010 0111 0100 0110. 0011 0001 1111 0100. 1111 1000 0001 1100.
- * 1100 1111 1111 1010. 0011 0011 1110 0100. 1001 0110 0100 0011. 0101 0110 1011 1011.
- * 0010 0100 0011 0101. 1100 1000 1000 1110. 0111 1111 0010 0110. 0000 1010 0000 0011.
- * 1101 1000 0010 0001. 0110 1001 1110 0101. 0001 0100 0101 0111. 0011 1011 1111 0010.
- */
- {
- 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
- 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
- 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
- 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
- 0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D,
- 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
- 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3,
- 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
- 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
- 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
- 0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70,
- 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
- 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC,
- 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
- 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
- 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
- 0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3,
- 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
- 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49,
- 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
- 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
- 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
- 0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19,
- 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
- 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5,
- 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
- 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
- 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
- 0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB,
- 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
- 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2,
- 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
- }
- };
- #endregion
-
- #region These are all the definitions that were found in PLATFORM.H that we need
- // left rotation
- private static uint ROL(uint x, int n)
- {
- return ( ((x) << ((n) & 0x1F)) | (x) >> (32-((n) & 0x1F)) );
- }
-
- // right rotation
- private static uint ROR(uint x,int n)
- {
- return (((x) >> ((n) & 0x1F)) | ((x) << (32-((n) & 0x1F))));
- }
-
- // first byte
- protected static byte b0(uint x)
- {
- return (byte)(x );//& 0xFF);
- }
- // second byte
- protected static byte b1(uint x)
- {
- return (byte)((x >> 8));// & (0xFF));
- }
- // third byte
- protected static byte b2(uint x)
- {
- return (byte)((x >> 16));// & (0xFF));
- }
- // fourth byte
- protected static byte b3(uint x)
- {
- return (byte)((x >> 24));// & (0xFF));
- }
-
- #endregion
- }
-}
diff --git a/src/TwofishCipher/Crypto/TwofishEncryption.cs b/src/TwofishCipher/Crypto/TwofishEncryption.cs
deleted file mode 100644
index 4f2a2307..00000000
--- a/src/TwofishCipher/Crypto/TwofishEncryption.cs
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- A C# implementation of the Twofish cipher
- By Shaun Wilde
-
- An article on integrating a C# implementation of the Twofish cipher into the
- .NET framework.
-
- http://www.codeproject.com/KB/recipes/twofish_csharp.aspx
-
- The Code Project Open License (CPOL) 1.02
- http://www.codeproject.com/info/cpol10.aspx
-
- Download a copy of the CPOL.
- http://www.codeproject.com/info/CPOL.zip
-*/
-
-using System;
-using System.Diagnostics;
-using System.Security.Cryptography;
-
-namespace TwofishCipher.Crypto
-{
- ///
- /// Summary description for TwofishEncryption.
- ///
- internal class TwofishEncryption : TwofishBase, ICryptoTransform
- {
- public TwofishEncryption(int keyLen, ref byte[] key, ref byte[] iv, CipherMode cMode, EncryptionDirection direction)
- {
- // convert our key into an array of ints
- for (int i=0;i
- /// Transform a block depending on whether we are encrypting or decrypting
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public int TransformBlock(
- byte[] inputBuffer,
- int inputOffset,
- int inputCount,
- byte[] outputBuffer,
- int outputOffset
- )
- {
- uint[] x=new uint[4];
-
- // load it up
- for (int i=0;i<4;i++)
- {
- x[i]= (uint)(inputBuffer[i*4+3+inputOffset]<<24) | (uint)(inputBuffer[i*4+2+inputOffset] << 16) |
- (uint)(inputBuffer[i*4+1+inputOffset] << 8) | (uint)(inputBuffer[i*4+0+inputOffset]);
-
- }
-
- if (encryptionDirection == EncryptionDirection.Encrypting)
- {
- blockEncrypt(ref x);
- }
- else
- {
- blockDecrypt(ref x);
- }
-
-
- // load it up
- for (int i=0;i<4;i++)
- {
- outputBuffer[i*4+0+outputOffset] = b0(x[i]);
- outputBuffer[i*4+1+outputOffset] = b1(x[i]);
- outputBuffer[i*4+2+outputOffset] = b2(x[i]);
- outputBuffer[i*4+3+outputOffset] = b3(x[i]);
- }
-
-
- return inputCount;
- }
-
- public byte[] TransformFinalBlock(
- byte[] inputBuffer,
- int inputOffset,
- int inputCount
- )
- {
- byte[] outputBuffer;// = new byte[0];
-
- if (inputCount>0)
- {
- outputBuffer = new byte[16]; // blocksize
- uint[] x=new uint[4];
-
- // load it up
- for (int i=0;i<4;i++) // should be okay as we have already said to pad with zeros
- {
- x[i]= (uint)(inputBuffer[i*4+3+inputOffset]<<24) | (uint)(inputBuffer[i*4+2+inputOffset] << 16) |
- (uint)(inputBuffer[i*4+1+inputOffset] << 8) | (uint)(inputBuffer[i*4+0+inputOffset]);
-
- }
-
- if (encryptionDirection == EncryptionDirection.Encrypting)
- {
- blockEncrypt(ref x);
- }
- else
- {
- blockDecrypt(ref x);
- }
-
- // load it up
- for (int i=0;i<4;i++)
- {
- outputBuffer[i*4+0] = b0(x[i]);
- outputBuffer[i*4+1] = b1(x[i]);
- outputBuffer[i*4+2] = b2(x[i]);
- outputBuffer[i*4+3] = b3(x[i]);
- }
- }
- else
- {
- outputBuffer = new byte[0]; // the .NET framework doesn't like it if you return null - this calms it down
- }
-
- return outputBuffer;
- }
-
- // not worked out this property yet - placing break points here just don't get caught.
- private bool canReuseTransform = true;
- public bool CanReuseTransform
- {
- get
- {
- return canReuseTransform;
- }
- }
-
- // I normally set this to false when block encrypting so that I can work on one block at a time
- // but for compression and stream type ciphers this can be set to true so that you get all the data
- private bool canTransformMultipleBlocks = false;
- public bool CanTransformMultipleBlocks
- {
- get
- {
- return canTransformMultipleBlocks;
- }
- }
-
- public int InputBlockSize
- {
- get
- {
- return inputBlockSize;
- }
- }
-
- public int OutputBlockSize
- {
- get
- {
- return outputBlockSize;
- }
- }
-
- private EncryptionDirection encryptionDirection;
- }
-}
diff --git a/src/TwofishCipher/License.txt b/src/TwofishCipher/License.txt
deleted file mode 100644
index 94a9ed02..00000000
--- a/src/TwofishCipher/License.txt
+++ /dev/null
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- Copyright (C)
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-.
diff --git a/src/TwofishCipher/Properties/AssemblyInfo.cs b/src/TwofishCipher/Properties/AssemblyInfo.cs
deleted file mode 100644
index cb31f738..00000000
--- a/src/TwofishCipher/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Android.App;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("TwofishCipher")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("TwofishCipher")]
-[assembly: AssemblyCopyright("Copyright © 2013")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
-
-[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
diff --git a/src/TwofishCipher/Readme.txt b/src/TwofishCipher/Readme.txt
deleted file mode 100644
index 84ff0657..00000000
--- a/src/TwofishCipher/Readme.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Twofish Cipher for KeePass Password Safe
-Copyright (C) 2009-2010 SEG Tech
-
-PREFACE
-
-Enables KeePass to encrypt databases using the Twofish algorithm.
-
-REQUIREMENTS
-
-This plugin requires KeePass 2.0x.
-
-INSTALLATION
-
-Just copy TwofishCipher.dll to the same directory where KeePass.exe is located
-and KeePass should automatically recognize and load the plugin.
-
-CREDITS
-
-Many thanks to Dominik Reichl for creating KeePass Password Safe, without which,
-this plugin would not exist. Thanks also goes to Shaun Wilde for C#
-implementation of the Twofish cipher as posted on The Code Project.
diff --git a/src/TwofishCipher/Resources/AboutResources.txt b/src/TwofishCipher/Resources/AboutResources.txt
deleted file mode 100644
index 194ae28a..00000000
--- a/src/TwofishCipher/Resources/AboutResources.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-Images, layout descriptions, binary blobs and string dictionaries can be included
-in your application as resource files. Various Android APIs are designed to
-operate on the resource IDs instead of dealing with images, strings or binary blobs
-directly.
-
-For example, a sample Android app that contains a user interface layout (main.xml),
-an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
-would keep its resources in the "Resources" directory of the application:
-
-Resources/
- drawable-hdpi/
- icon.png
-
- drawable-ldpi/
- icon.png
-
- drawable-mdpi/
- icon.png
-
- layout/
- main.xml
-
- values/
- strings.xml
-
-In order to get the build system to recognize Android resources, set the build action to
-"AndroidResource". The native Android APIs do not operate directly with filenames, but
-instead operate on resource IDs. When you compile an Android application that uses resources,
-the build system will package the resources for distribution and generate a class called
-"Resource" that contains the tokens for each one of the resources included. For example,
-for the above Resources layout, this is what the Resource class would expose:
-
-public class Resource {
- public class drawable {
- public const int icon = 0x123;
- }
-
- public class layout {
- public const int main = 0x456;
- }
-
- public class strings {
- public const int first_string = 0xabc;
- public const int second_string = 0xbcd;
- }
-}
-
-You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
-to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
-string in the dictionary file values/strings.xml.
\ No newline at end of file
diff --git a/src/TwofishCipher/Resources/Values/Strings.xml b/src/TwofishCipher/Resources/Values/Strings.xml
deleted file mode 100644
index b0217a55..00000000
--- a/src/TwofishCipher/Resources/Values/Strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- $projectname$
-
diff --git a/src/TwofishCipher/TwofishCipher.csproj b/src/TwofishCipher/TwofishCipher.csproj
index 9bfaafbb..6ae180c2 100644
--- a/src/TwofishCipher/TwofishCipher.csproj
+++ b/src/TwofishCipher/TwofishCipher.csproj
@@ -1,84 +1,11 @@
-
-
+
- Debug
- AnyCPU
- {5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Properties
- TwofishCipher
- TwofishCipher
- 512
- Resources\Resource.designer.cs
- Off
- false
- v8.0
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- None
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- false
-
-
- bin\ReleaseNoNet\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
- false
- 4
+ net8.0-android
+ 21
+ enable
+ enable
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {545B4A6B-8BBA-4FBE-92FC-4AC060122A54}
- KeePassLib2Android
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/ZlibAndroid/Resources/AboutResources.txt b/src/ZlibAndroid/Resources/AboutResources.txt
deleted file mode 100644
index 54c2267a..00000000
--- a/src/ZlibAndroid/Resources/AboutResources.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-Images, layout descriptions, binary blobs and string dictionaries can be included
-in your application as resource files. Various Android APIs are designed to
-operate on the resource IDs instead of dealing with images, strings or binary blobs
-directly.
-
-For example, a sample Android app that contains a user interface layout (main.axml),
-an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
-would keep its resources in the "Resources" directory of the application:
-
-Resources/
- drawable/
- icon.png
-
- layout/
- main.axml
-
- values/
- strings.xml
-
-In order to get the build system to recognize Android resources, set the build action to
-"AndroidResource". The native Android APIs do not operate directly with filenames, but
-instead operate on resource IDs. When you compile an Android application that uses resources,
-the build system will package the resources for distribution and generate a class called "R"
-(this is an Android convention) that contains the tokens for each one of the resources
-included. For example, for the above Resources layout, this is what the R class would expose:
-
-public class R {
- public class drawable {
- public const int icon = 0x123;
- }
-
- public class layout {
- public const int main = 0x456;
- }
-
- public class strings {
- public const int first_string = 0xabc;
- public const int second_string = 0xbcd;
- }
-}
-
-You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main
-to reference the layout/main.axml file, or R.strings.first_string to reference the first
-string in the dictionary file values/strings.xml.
diff --git a/src/ZlibAndroid/Resources/values/Strings.xml b/src/ZlibAndroid/Resources/values/Strings.xml
deleted file mode 100644
index 8d16a887..00000000
--- a/src/ZlibAndroid/Resources/values/Strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- ZlibAndroid
-
diff --git a/src/ZlibAndroid/ZlibAndroid.csproj b/src/ZlibAndroid/ZlibAndroid.csproj
index 35524aa5..5b3ea69e 100644
--- a/src/ZlibAndroid/ZlibAndroid.csproj
+++ b/src/ZlibAndroid/ZlibAndroid.csproj
@@ -1,75 +1,8 @@
-
-
+
- Debug
- AnyCPU
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- {6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}
- Library
- ZlibAndroid
- Resources\Resource.designer.cs
- Resource
- Resources
- Assets
- false
- ZlibAndroid
- v8.0
+ net8.0-android
+ 21
+ enable
+ enable
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- false
- None
-
-
- full
- true
- bin\Release
- prompt
- 4
- false
- false
-
-
- bin\ReleaseNoNet\
- true
- full
- AnyCPU
- Off
- prompt
- MinimumRecommendedRules.ruleset
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/java/JavaFileStorage/app/build.gradle b/src/java/JavaFileStorage/app/build.gradle
index fe29146e..939b6edd 100644
--- a/src/java/JavaFileStorage/app/build.gradle
+++ b/src/java/JavaFileStorage/app/build.gradle
@@ -4,11 +4,10 @@ android {
namespace 'keepass2android.javafilestorage'
- compileSdkVersion 33
-
defaultConfig {
- minSdkVersion 15
+ minSdkVersion 21
targetSdkVersion 33
+ compileSdk 34
}
buildTypes {
release {
@@ -22,6 +21,10 @@ android {
sourceCompatibility 11
targetCompatibility 11
}
+
+ packagingOptions {
+ exclude 'META-INF/DEPENDENCIES'
+ }
}
/*
@@ -30,27 +33,21 @@ NOTE: If you change dependencies here, don't forget to update the jar files in J
dependencies {
- implementation 'com.squareup.okhttp3:okhttp:4.10.0-RC1'
- implementation 'com.burgstaller:okhttp-digest:2.5'
+ implementation 'com.squareup.okhttp3:okhttp:4.12.0'
+ implementation 'io.github.rburgst:okhttp-digest:3.1.0'
implementation 'com.google.http-client:google-http-client-gson:1.20.0'
implementation('com.google.api-client:google-api-client-android:1.30.5') {
exclude group: 'com.google.android.google-play-services'
}
implementation 'com.google.apis:google-api-services-drive:v2-rev102-1.16.0-rc'
- implementation 'com.dropbox.core:dropbox-core-sdk:4.0.0'
+ implementation 'com.dropbox.core:dropbox-core-sdk:5.4.6'
implementation 'com.google.api-client:google-api-client:1.30.5'
implementation 'com.google.api-client:google-api-client-android:1.30.5'
implementation 'com.google.android.gms:play-services-auth:20.4.0'
- //onedrive:
- implementation('com.onedrive.sdk:onedrive-sdk-android:1.2.0') {
- transitive = false
- }
implementation 'com.pcloud.sdk:java-core:1.9.1'
implementation 'com.pcloud.sdk:android:1.9.1'
implementation 'com.google.code.gson:gson:2.8.6'
- implementation 'com.microsoft.services.msa:msa-auth:0.8.6'
- implementation 'com.microsoft.aad:adal:1.14.0'
}
diff --git a/src/java/JavaFileStorage/app/src/main/java/keepass2android/javafilestorage/OneDriveStorage.java b/src/java/JavaFileStorage/app/src/main/java/keepass2android/javafilestorage/OneDriveStorage.java
deleted file mode 100644
index c9255efc..00000000
--- a/src/java/JavaFileStorage/app/src/main/java/keepass2android/javafilestorage/OneDriveStorage.java
+++ /dev/null
@@ -1,436 +0,0 @@
-package keepass2android.javafilestorage;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import androidx.annotation.NonNull;
-import android.util.Log;
-
-import com.onedrive.sdk.core.DefaultClientConfig;
-import com.onedrive.sdk.core.IClientConfig;
-import com.onedrive.sdk.core.OneDriveErrorCodes;
-import com.onedrive.sdk.extensions.IItemCollectionPage;
-import com.onedrive.sdk.extensions.IItemCollectionRequestBuilder;
-import com.onedrive.sdk.extensions.IOneDriveClient;
-import com.onedrive.sdk.extensions.Item;
-import com.onedrive.sdk.extensions.OneDriveClient;
-import com.onedrive.sdk.http.OneDriveServiceException;
-
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Created by Philipp on 20.11.2016.
- */
-public class OneDriveStorage extends JavaFileStorageBase
-{
- final IClientConfig oneDriveConfig;
- final keepass2android.javafilestorage.onedrive.MyMSAAuthenticator msaAuthenticator;
-
- IOneDriveClient oneDriveClient;
-
- public OneDriveStorage(final Context context, final String clientId) {
- msaAuthenticator = new keepass2android.javafilestorage.onedrive.MyMSAAuthenticator(context) {
- @Override
- public String getClientId() {
- return clientId;
- }
-
- @Override
- public String[] getScopes() {
- return new String[] { "offline_access", "onedrive.readwrite" };
- }
- };
- oneDriveConfig = DefaultClientConfig.createWithAuthenticator(msaAuthenticator);
- initAuthenticator(null);
-
-
- }
-
-
- @Override
- public boolean requiresSetup(String path) {
- return !isConnected(null);
- }
-
- @Override
- public void startSelectFile(FileStorageSetupInitiatorActivity activity, boolean isForSave, int requestCode) {
-
- initAuthenticator((Activity)activity.getActivity());
-
- String path = getProtocolId()+":///";
- Log.d("KP2AJ", "startSelectFile "+path+", connected: "+path);
- if (isConnected(null))
- {
- Intent intent = new Intent();
- intent.putExtra(EXTRA_IS_FOR_SAVE, isForSave);
- intent.putExtra(EXTRA_PATH, path);
- activity.onImmediateResult(requestCode, RESULT_FILECHOOSER_PREPARED, intent);
- }
- else
- {
- activity.startSelectFileProcess(path, isForSave, requestCode);
- }
- }
-
- private boolean isConnected(Activity activity) {
- if (oneDriveClient == null)
- {
- try
- {
- Log.d("KP2AJ", "trying silent login");
- if (msaAuthenticator.loginSilent() != null)
- {
- Log.d("KP2AJ", "ok: silent login");
-
- oneDriveClient = buildClient(activity);
-
-
- }
- else Log.d("KP2AJ", "trying silent login failed.");
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- return oneDriveClient != null;
- }
-
- private void initAuthenticator(Activity activity) {
- msaAuthenticator.init(
- oneDriveConfig.getExecutors(),
- oneDriveConfig.getHttpProvider(),
- activity,
- oneDriveConfig.getLogger());
- }
-
-
- @Override
- public void prepareFileUsage(FileStorageSetupInitiatorActivity activity, String path, int requestCode, boolean alwaysReturnSuccess) {
- initAuthenticator((Activity)activity.getActivity());
- if (isConnected((Activity)activity.getActivity()))
- {
- Intent intent = new Intent();
- intent.putExtra(EXTRA_PATH, path);
- activity.onImmediateResult(requestCode, RESULT_FILEUSAGE_PREPARED, intent);
- }
- else
- {
- activity.startFileUsageProcess(path, requestCode, alwaysReturnSuccess);
- }
-
- }
-
- @Override
- public String getProtocolId() {
- return "onedrive";
- }
-
- @Override
- public void prepareFileUsage(Context appContext, String path) throws UserInteractionRequiredException {
- if (!isConnected(null))
- {
- throw new UserInteractionRequiredException();
- }
-
- }
-
- @Override
- public void onCreate(FileStorageSetupActivity activity, Bundle savedInstanceState) {
-
- Log.d("KP2AJ", "OnCreate");
-
- }
-
- @Override
- public void onResume(final FileStorageSetupActivity activity) {
-
-
-
-
- }
-
- private IOneDriveClient buildClient(Activity activity) {
-
- return new OneDriveClient.Builder()
- .fromConfig(oneDriveConfig)
- .loginAndBuildClient(activity);
-
- }
-
- String getPathFromSkydrivePath(String skydrivePath)
- {
- String path = "";
- if (skydrivePath.equals(""))
- return "";
-
- String[] parts = skydrivePath.split("/");
-
- for (int i = 0; i < parts.length; i++) {
- String part = parts[i];
- logDebug("parsing part " + part);
- int indexOfSeparator = part.lastIndexOf(NAME_ID_SEP);
- if (indexOfSeparator < 0) {
- // seems invalid, but we're very generous here
- path += "/" + part;
- continue;
- }
- String name = part.substring(0, indexOfSeparator);
- try {
- name = decode(name);
- } catch (UnsupportedEncodingException e) {
- // ignore
- }
- path += "/" + name;
- }
- logDebug("return " +path + ". original was " + skydrivePath);
- return path;
-
- }
-
- String removeProtocol(String path) throws Exception {
- if (path == null)
- return null;
- if (path.startsWith("skydrive"))
- return getPathFromSkydrivePath(path.substring("skydrive://".length()));
- return path.substring(getProtocolId().length()+3);
- }
-
- @Override
- public String getDisplayName(String path) {
-
- if (path == null)
- return null;
- if (path.startsWith("skydrive"))
- return getProtocolId()+"://"+getPathFromSkydrivePath(path.substring("skydrive://".length()));
-
- return path;
- }
-
- @Override
- public String getFilename(String path) throws Exception {
- return path.substring(path.lastIndexOf("/")+1);
- }
-
- @Override
- public boolean checkForFileChangeFast(String path, String previousFileVersion) throws Exception {
- return false;
- }
-
- @Override
- public String getCurrentFileVersionFast(String path) {
- return null;
- }
-
- @Override
- public InputStream openFileForRead(String path) throws Exception {
- try {
- path = removeProtocol(path);
- logDebug("openFileForRead. Path="+path);
- InputStream result = oneDriveClient.getDrive()
- .getRoot()
- .getItemWithPath(path)
- .getContent()
- .buildRequest()
- .get();
- logDebug("ok");
- return result;
-
- }
- catch (OneDriveServiceException e)
- {
- throw convertException(e);
- }
- }
-
- private Exception convertException(OneDriveServiceException e) {
- if (e.isError(OneDriveErrorCodes.ItemNotFound))
- return new FileNotFoundException(e.getMessage());
- return e;
- }
-
- @Override
- public void uploadFile(String path, byte[] data, boolean writeTransactional) throws Exception {
- try {
- path = removeProtocol(path);
- oneDriveClient.getDrive()
- .getRoot()
- .getItemWithPath(path)
- .getContent()
- .buildRequest()
- .put(data);
- } catch (OneDriveServiceException e) {
- throw convertException(e);
- }
- }
-
- @Override
- public String createFolder(String parentPath, String newDirName) throws Exception {
- throw new Exception("not implemented.");
- }
-
- @Override
- public String createFilePath(String parentPath, String newFileName) throws Exception {
- String path = parentPath;
- if (!path.endsWith("/"))
- path = path + "/";
- path = path + newFileName;
-
- return path;
- }
-
- @Override
- public List listFiles(String parentPath) throws Exception {
- try {
- ArrayList result = new ArrayList();
- parentPath = removeProtocol(parentPath);
- IItemCollectionPage itemsPage = oneDriveClient.getDrive()
- .getRoot()
- .getItemWithPath(parentPath)
- .getChildren()
- .buildRequest()
- .get();
- if (parentPath.endsWith("/"))
- parentPath = parentPath.substring(0,parentPath.length()-1);
- while (true)
- {
- List- items = itemsPage.getCurrentPage();
- if (items.isEmpty())
- return result;
-
- for (Item i: items)
- {
- FileEntry e = getFileEntry(parentPath + "/" + i.name, i);
- Log.d("KP2AJ", e.path);
- result.add(e);
- }
- IItemCollectionRequestBuilder nextPageReqBuilder = itemsPage.getNextPage();
- if (nextPageReqBuilder == null)
- return result;
- itemsPage = nextPageReqBuilder.buildRequest().get();
-
- }
- } catch (OneDriveServiceException e) {
- throw convertException(e);
- }
- }
-
- @NonNull
- private FileEntry getFileEntry(String path, Item i) {
- FileEntry e = new FileEntry();
- if (i.size != null)
- e.sizeInBytes = i.size;
- else if ((i.remoteItem != null) && (i.remoteItem.size != null))
- e.sizeInBytes = i.remoteItem.size;
-
- e.displayName = i.name;
- e.canRead = e.canWrite = true;
- e.path = getProtocolId() +"://"+path;
- if (i.lastModifiedDateTime != null)
- e.lastModifiedTime = i.lastModifiedDateTime.getTimeInMillis();
- else if ((i.remoteItem != null)&&(i.remoteItem.lastModifiedDateTime != null))
- e.lastModifiedTime = i.remoteItem.lastModifiedDateTime.getTimeInMillis();
- e.isDirectory = (i.folder != null) || ((i.remoteItem != null) && (i.remoteItem.folder != null));
- return e;
- }
-
- @Override
- public FileEntry getFileEntry(String filename) throws Exception {
- try {
- filename = removeProtocol(filename);
- Item item = oneDriveClient.getDrive()
- .getRoot()
- .getItemWithPath(filename)
- .buildRequest()
- .get();
- return getFileEntry(filename, item);
- } catch (OneDriveServiceException e) {
- throw convertException(e);
- }
- }
-
- @Override
- public void delete(String path) throws Exception {
- try {
- path = removeProtocol(path);
- oneDriveClient.getDrive()
- .getRoot()
- .getItemWithPath(path)
- .buildRequest()
- .delete();
- } catch (OneDriveServiceException e) {
- throw convertException(e);
- }
- }
-
- @Override
- public void onStart(final FileStorageSetupActivity activity) {
- Log.d("KP2AJ", "onStart");
- if (activity.getProcessName().equals(PROCESS_NAME_SELECTFILE))
- activity.getState().putString(EXTRA_PATH, activity.getPath());
-
- JavaFileStorage.FileStorageSetupActivity storageSetupAct = activity;
-
- if (oneDriveClient != null) {
- Log.d("KP2AJ", "auth successful");
- try {
-
- finishActivityWithSuccess(activity);
- return;
-
- } catch (Exception e) {
- Log.d("KP2AJ", "finish with error: " + e.toString());
- finishWithError(activity, e);
- return;
- }
- }
-
-
- {
- Log.d("KP2AJ", "Starting auth");
- new AsyncTask
+ - wrap_content
+ - 1
+ -->
+
-
-
+
-
-
+
-
+
-
-
-
+
-
-
+ />
-
+
-
-
-
+
-
-
-
+
+ android:src="@drawable/baseline_more_horiz_24" />
@@ -199,7 +177,7 @@
style="@style/EntryEditSingleLine_container">
+ android:src="@drawable/baseline_attachment_24" />
-
-
-
+
-
-
-
+
+ android:src="@drawable/baseline_explicit_24" />
-
-
+
+
+>
diff --git a/src/keepass2android/Resources/layout/entry_list_entry.xml b/src/keepass2android/Resources/layout/entry_list_entry.xml
index 07d1d558..3cb157cc 100644
--- a/src/keepass2android/Resources/layout/entry_list_entry.xml
+++ b/src/keepass2android/Resources/layout/entry_list_entry.xml
@@ -29,7 +29,7 @@
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="5dp"
- android:src="@drawable/checkmark"/>
+ android:src="@drawable/baseline_check_24"/>
+ android:src="@drawable/baseline_keyboard_arrow_right_24"/>
diff --git a/src/keepass2android/Resources/layout/entry_view.xml b/src/keepass2android/Resources/layout/entry_view.xml
index ed734684..4b5d4477 100644
--- a/src/keepass2android/Resources/layout/entry_view.xml
+++ b/src/keepass2android/Resources/layout/entry_view.xml
@@ -1,5 +1,5 @@
-
-
-
\ No newline at end of file
+ android:src="@drawable/baseline_edit_24" />
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/layout/entry_view_contents.xml b/src/keepass2android/Resources/layout/entry_view_contents.xml
index 99444cee..c41b5619 100644
--- a/src/keepass2android/Resources/layout/entry_view_contents.xml
+++ b/src/keepass2android/Resources/layout/entry_view_contents.xml
@@ -1,5 +1,6 @@
+ android:src="@drawable/baseline_folder_open_24" />
+
+ android:id="@+id/group_name_vdots"
+ android:layout_width="wrap_content"
+ android:layout_height="20dp"
+ android:paddingRight="12dp"
+ android:tint="@color/md_theme_primary"
+ android:src="@drawable/baseline_more_vert_24"
+ android:gravity="right|bottom"
+ android:layout_alignParentRight="true" />
+
+ android:src="@drawable/baseline_account_circle_24" />
+ android:src="@drawable/baseline_link_24" />
+ android:src="@drawable/baseline_password_24" />
+ android:src="@drawable/baseline_access_time_24" />
+ android:src="@drawable/baseline_comment_24" />
+ android:src="@drawable/baseline_more_horiz_24" />
+ android:src="@drawable/baseline_attachment_24" />
+ android:src="@drawable/baseline_label_24" />
+ android:src="@drawable/baseline_link_24" />
+ android:src="@drawable/baseline_date_range_24" />
+ android:src="@drawable/baseline_explicit_24" />
+ android:src="@drawable/baseline_edit_calendar_24" />
@@ -476,7 +493,9 @@
@@ -488,7 +507,7 @@
style="@style/EntryEditSingleLine_container">
+ android:src="@drawable/baseline_history_24" />
- .
-->
-
-
-
-
+
+
+
+
diff --git a/src/keepass2android/Resources/layout/file_selection.xml b/src/keepass2android/Resources/layout/file_selection.xml
index 229b23db..a0bef729 100644
--- a/src/keepass2android/Resources/layout/file_selection.xml
+++ b/src/keepass2android/Resources/layout/file_selection.xml
@@ -1,58 +1,116 @@
-
-
+
+
+
+
-
-
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
\ No newline at end of file
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/layout/file_selection_filename.xml b/src/keepass2android/Resources/layout/file_selection_filename.xml
index bf53169b..e5799595 100644
--- a/src/keepass2android/Resources/layout/file_selection_filename.xml
+++ b/src/keepass2android/Resources/layout/file_selection_filename.xml
@@ -17,7 +17,7 @@
android:id="@+id/browse_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:src="@drawable/ic_launcher_folder_small"
+ android:src="@drawable/baseline_folder_24"
android:layout_alignParentRight="true"
android:layout_below="@id/label_open_by_filename" />
-
+
+ />
+ />
+ android:src="@drawable/baseline_fingerprint_24" />
+ android:textColor="@color/md_theme_primary" />
diff --git a/src/keepass2android/Resources/layout/icon_picker.xml b/src/keepass2android/Resources/layout/icon_picker.xml
index 6f2e3129..940c3d43 100644
--- a/src/keepass2android/Resources/layout/icon_picker.xml
+++ b/src/keepass2android/Resources/layout/icon_picker.xml
@@ -22,7 +22,7 @@
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:verticalSpacing="5dp"
- android:background="?activityBackgroundColor"
+ android:background="@color/md_theme_surface"
android:horizontalSpacing="5dp"
android:columnWidth="60dp"
android:numColumns="auto_fit"
diff --git a/src/keepass2android/Resources/layout/no_secure_display_layout.axml b/src/keepass2android/Resources/layout/no_secure_display_layout.axml
index f6e2613e..dbc1271d 100644
--- a/src/keepass2android/Resources/layout/no_secure_display_layout.axml
+++ b/src/keepass2android/Resources/layout/no_secure_display_layout.axml
@@ -9,9 +9,6 @@
android:paddingEnd="24dp"
android:paddingTop="16dp">
+ app:theme="@style/ThemeOverlay.Material3.Dark.ActionBar"
+ app:popupTheme="@style/ThemeOverlay.Material3.Light"
+ android:minHeight="?attr/actionBarSize" />
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -166,7 +149,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
- android:src="@drawable/ic_menu_view"
+ android:src="@drawable/baseline_visibility_24"
android:background="?android:selectableItemBackground" />
@@ -330,11 +313,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/TextAppearance_Help_Dense"
- android:textColor="@color/light_gray"
app:help_text="@string/help_quickunlock"
app:title_text="@string/enable_quickunlock"
- android:text="@string/help_quickunlock"
- android:background="?android:attr/selectableItemBackground"/>
+ android:text="@string/help_quickunlock"
+ />
+ />
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
@@ -413,24 +426,24 @@
-
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/layout/plugin_details.xml b/src/keepass2android/Resources/layout/plugin_details.xml
index d57b5ec9..e65cfb3d 100644
--- a/src/keepass2android/Resources/layout/plugin_details.xml
+++ b/src/keepass2android/Resources/layout/plugin_details.xml
@@ -25,7 +25,7 @@
android:layout_gravity="center"
android:paddingRight="20dp"
android:drawablePadding="8dp"
- android:drawableLeft="@drawable/navigation_accept"
+ android:drawableLeft="@drawable/baseline_check_24"
android:gravity="center_vertical"
android:text="@string/accept" />
@@ -41,7 +41,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingRight="20dp"
- android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel"
+ android:drawableLeft="@drawable/baseline_close_24"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:text="@string/deny" />
diff --git a/src/keepass2android/Resources/layout/preference.axml b/src/keepass2android/Resources/layout/preference.axml
index 1b279768..6d12ab00 100644
--- a/src/keepass2android/Resources/layout/preference.axml
+++ b/src/keepass2android/Resources/layout/preference.axml
@@ -1,16 +1,9 @@
-
-
+
+
-
-
-
\ No newline at end of file
+ android:layout_height="match_parent" />
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/layout/recent_files.xml b/src/keepass2android/Resources/layout/recent_files.xml
index 020a63ec..04fa4c8b 100644
--- a/src/keepass2android/Resources/layout/recent_files.xml
+++ b/src/keepass2android/Resources/layout/recent_files.xml
@@ -3,22 +3,22 @@
android:id="@+id/recent_files"
android:orientation="vertical"
android:layout_width="fill_parent"
- android:layout_height="fill_parent"
+ android:layout_height="wrap_content"
>
-
+
@@ -28,7 +28,6 @@
android:layout_height="wrap_content"
android:text="@string/show_local_backups"
android:checked="false"
- android:textColor="#fff"
android:gravity="left"/>
\ No newline at end of file
diff --git a/src/keepass2android/Resources/layout/search.xml b/src/keepass2android/Resources/layout/search.xml
index b7bdde50..be925067 100644
--- a/src/keepass2android/Resources/layout/search.xml
+++ b/src/keepass2android/Resources/layout/search.xml
@@ -11,7 +11,7 @@
android:id="@+id/search_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:src="@drawable/ic_action_search"
+ android:src="@drawable/baseline_search_24"
android:layout_below="@id/search_label"
android:layout_alignParentRight="true" />
+ android:background="?android:attr/colorBackground">
+ android:background="?android:attr/colorBackground">
diff --git a/src/keepass2android/Resources/layout/toolbar.axml b/src/keepass2android/Resources/layout/toolbar.axml
deleted file mode 100644
index 75825311..00000000
--- a/src/keepass2android/Resources/layout/toolbar.axml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
\ No newline at end of file
diff --git a/src/keepass2android/Resources/menu/entry.xml b/src/keepass2android/Resources/menu/entry.xml
index 06a26ab7..f2f25e0d 100644
--- a/src/keepass2android/Resources/menu/entry.xml
+++ b/src/keepass2android/Resources/menu/entry.xml
@@ -18,22 +18,22 @@
diff --git a/src/keepass2android/Resources/menu/group.xml b/src/keepass2android/Resources/menu/group.xml
index 2c2d5b74..583bdc13 100644
--- a/src/keepass2android/Resources/menu/group.xml
+++ b/src/keepass2android/Resources/menu/group.xml
@@ -18,38 +18,38 @@
Hiermit werden Anmeldeinformationen für die Domäne „%1$s“ in die Anwendung „%2$s“ eingefügt.
Wenn darauf vertraut wird, dass „%2$s“ zu „%1$s“ gehört, oder wenn darauf vertraut wird, dass die App „%2$s“ die Anmeldeinformationen nicht missbraucht (z. B. weil es sich um eine vertrauenswürdige Browser-App handelt), kann fortgefahren werden. Falls nicht, bitte abbrechen.
Für „%1$s“ immer akzeptieren
-
+Keepass2Android-Tastatureinstellungen
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-el/strings.xml b/src/keepass2android/Resources/values-el/strings.xml
index 88c16596..f8b2844c 100644
--- a/src/keepass2android/Resources/values-el/strings.xml
+++ b/src/keepass2android/Resources/values-el/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Σχόλια
Το KP2A είναι ένας διαχειριστής συνθηματικών, που παρέχει την δυνατότητα ανάγνωσης/εγγραφής σε βάσεις δεδομένων του KeePass 2.x στο Android.
@@ -866,4 +865,6 @@
Πρόκειται να εισάγετε διαπιστευτήρια για τον τομέα \"%1$s\" στην εφαρμογή \"%2$s\".
Εάν εμπιστεύεστε ότι το \"%2$s\" ανήκει στο \"%1$s\" ή εμπιστεύεστε ότι η εφαρμογή \"%2$s\" δεν καταχράται τα διαπιστευτήρια (πχ. επειδή είναι μια αξιόπιστη εφαρμογή περιήγησης), είναι εντάξει να συνεχίσετε. Αν όχι, ακυρώστε.
Αποδοχή πάντα στο \"%1$s\"
-
+Ρυθμίσεις πληκτρολογίου Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-en-rGB/strings.xml b/src/keepass2android/Resources/values-en-rGB/strings.xml
new file mode 100644
index 00000000..21088ad2
--- /dev/null
+++ b/src/keepass2android/Resources/values-en-rGB/strings.xml
@@ -0,0 +1,3 @@
+
+"Keepass2Android keyboard settings"
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-es-rUS/strings.xml b/src/keepass2android/Resources/values-es-rUS/strings.xml
new file mode 100644
index 00000000..38cd5f9e
--- /dev/null
+++ b/src/keepass2android/Resources/values-es-rUS/strings.xml
@@ -0,0 +1,3 @@
+
+"Configuración de teclado de Keepass2Android"
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-es/strings.xml b/src/keepass2android/Resources/values-es/strings.xml
index ca915038..9502c33e 100644
--- a/src/keepass2android/Resources/values-es/strings.xml
+++ b/src/keepass2android/Resources/values-es/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Sugerencias
Keepass2Android es una implementación completa para Android del gestor de contraseñas KeePass 2.x.
@@ -1175,4 +1174,6 @@ Consejo: Keepass2Android ha guardado la última versión de la base de datos que
Está a punto de insertar credenciales para el dominio \"%1$s\" en la aplicación \"%2$s\".
Si confía en que \"%2$s\" pertenece a \"%1$s\", o confía en que la aplicación \"%2$s\" no utilizará mal las credenciales (p. e. porque es una aplicación de navegador de confianza), está bien continuar. Si no, por favor cancele.
Aceptar siempre en \"%1$s\"
-
+Ajustes del teclado de Keepass2Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-eu/strings.xml b/src/keepass2android/Resources/values-eu/strings.xml
index 993dcc44..176bd3df 100644
--- a/src/keepass2android/Resources/values-eu/strings.xml
+++ b/src/keepass2android/Resources/values-eu/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Iruzkinak
Keepass2Android pasahitz kudeatzaile bat da, Androiden KeePass 2.x datu-baseetan irakurketa/idazketa ahalbideratzen duena.
@@ -436,4 +435,6 @@
- Ohartarazi balidazioak huts egitean
- Do not accept invalid certificates
-
+Android teklatuaren ezarpenak
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-fa/strings.xml b/src/keepass2android/Resources/values-fa/strings.xml
index d41a0af8..83a32f27 100644
--- a/src/keepass2android/Resources/values-fa/strings.xml
+++ b/src/keepass2android/Resources/values-fa/strings.xml
@@ -1,5 +1,4 @@
-
-
+
ﺑﺎﺯﺧﻮﺭﺩ
برنامهٔ Keepass2Android یک برنامهٔ مدیریت گذرواژه است که دسترسی خواندنی/نوشتنی به پایگاهدادههای KeePass 2.x را در اندروید فراهم میکند.
@@ -789,4 +788,6 @@ mycloud.me.com/webdav/ )
در حال واردکردن اطلاعات شناسایی برای دامنهٔ «%1$s» در برنامهٔ «%2$s» هستید.
اگر اعتماد دارید که «%2$s» به «%1$s» تعلق دارد یا اعتماد دارید که برنامهٔ «%2$s» از اطلاعات شناسایی سوءاستفاده نمیکند (مثلاً مرورگری قابلاعتماد است)، بدون نگرانی ادامه دهید، در غیر این صورت لغو کنید.
در «%1$s» همیشه بپذیر
-
+تنظیمات صفحه کلید Keepass2Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-fi/strings.xml b/src/keepass2android/Resources/values-fi/strings.xml
index dcbefe92..49b2b997 100644
--- a/src/keepass2android/Resources/values-fi/strings.xml
+++ b/src/keepass2android/Resources/values-fi/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Palaute
Keepass2Android on salasanojen hallintaohjelma, jolla voit katsella ja muokata KeePass 2.x tietokantoja Androidilla.
@@ -764,4 +763,6 @@
Nykyistä näyttöä ei ole merkitty turvalliseksi. Tämä tarkoittaa sitä että muut sovellukset voivat tehdä kuvankaappauksen. Keepass2Android on näyttää arkaluontoisia tietoja vain suojatuissa näytöissä. Vaihda suojattuun näyttöön (esimerkiksi irrottamalla HDMI-näyttö) tai muuta sovelluksen asetuksia.
Poista tämä viesti käytöstä
Yritä uudelleen
-
+Keepass2Android-näppäimistön asetukset
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-fr/strings.xml b/src/keepass2android/Resources/values-fr/strings.xml
index 624ab14b..c6bb88a1 100644
--- a/src/keepass2android/Resources/values-fr/strings.xml
+++ b/src/keepass2android/Resources/values-fr/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Commentaires
Keepass2Android est un gestionnaire de mot de passe pour Android permettant de lire et écrire des bases de données KeePass 2.x.
@@ -905,4 +904,6 @@
Vous êtes sur le point d\'insérer des identifiants pour le domaine \"%1$s\" dans l\'application \"%2$s\".
Si vous faites confiance à \"%2$s\" pour appartenir à \"%1$s\" ou que vous faites confiance à l\'application \"%2$s\" pour ne pas abuser des identifiants (ex. parce que c\'est une application de navigateur de confiance), il est possible de continuer. Si ce n\'est pas le cas, veuillez annuler.
Accepter toujours dans \"%1$s\"
-
+Paramètres du clavier Keepass2Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-hr/strings.xml b/src/keepass2android/Resources/values-hr/strings.xml
index dd6a9e8f..af1bb30d 100644
--- a/src/keepass2android/Resources/values-hr/strings.xml
+++ b/src/keepass2android/Resources/values-hr/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Povratna informacija
Keepass2Android je upravitelj lozinki koji pruža pregled i uređivanje KeePass 2.x baza podataka na Android uređajima.
@@ -756,4 +755,6 @@
Pokušaj ponovno
Upozorenje Sigurnosti: Nepoznata domena/veza aplikacije
Prehvati uvijek u \"%1$s\"
-
+Postavke tipkovnice za Keepass2Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-hu/strings.xml b/src/keepass2android/Resources/values-hu/strings.xml
index 5c8099d7..03982ff8 100644
--- a/src/keepass2android/Resources/values-hu/strings.xml
+++ b/src/keepass2android/Resources/values-hu/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Visszajelzés
Keepass2Android egy jelszókezelő alkalmazás, amely KeePass 2.x adatbázisokhoz írás-olvasási hozzáférést biztosít Android eszközökön.
@@ -767,4 +766,6 @@
A(z) \"%1$s\" tartományhoz tartozó azonosítókat készül a(z) \"%2$s\" alkalmazás számára elérhetővé tenni.
Ha megbízik abban, hogy a(z) \"%1$s\" tartomány a(z) \"%2$s\" alkalmazáshoz tartozik, vagy megbízik abban, hogy az alkalmazás nem él vissza a titkos adatokkal (mert például egy megbízható böngészőprogram), folytassa. Ha nem, szakítsa meg a folyamatot.
Mindig fogadja el itt: \"%1$s\"
-
+Keepass2Android billentyűzetbeállítások
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-in/strings.xml b/src/keepass2android/Resources/values-in/strings.xml
index 26ab0843..2911e414 100644
--- a/src/keepass2android/Resources/values-in/strings.xml
+++ b/src/keepass2android/Resources/values-in/strings.xml
@@ -1,6 +1,4 @@
-
-
-
+
Umpan balik
Laman
@@ -837,4 +835,5 @@ Rilis publik awal
Pastikan ini bekerja pada sistem anda dan pertimbangkan jika tidak untuk menggunakan built-in keyboard.
Deskripsi disediakan oleh plugin:
-
+"Setelan Keepass2Android Android"
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-it/strings.xml b/src/keepass2android/Resources/values-it/strings.xml
index 9afc2700..630ae412 100644
--- a/src/keepass2android/Resources/values-it/strings.xml
+++ b/src/keepass2android/Resources/values-it/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Commenti
Keepass2Android è un gestore di password per Android che supporta l\'accesso in lettura/scrittura ai database di KeePass 2.x.
@@ -1010,4 +1009,6 @@
Stai per inserire le credenziali per il dominio \"%1$s\" nell\'app \"%2$s\"
Se ti fidi di \"%2$s\" ad appartenere a \"%1$s\" o se ti fidi dell\'app \"%2$s\" a non abusare delle credenziali (es. perché si tratta di un\'applicazione sicura), è possibile continuare. Altrimenti si prega di annullare.
Accetta sempre in \"%1$s\"
-
+Impostazioni tastiera Keepass2Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-iw/strings.xml b/src/keepass2android/Resources/values-iw/strings.xml
index 7517b0fb..e320b180 100644
--- a/src/keepass2android/Resources/values-iw/strings.xml
+++ b/src/keepass2android/Resources/values-iw/strings.xml
@@ -1,6 +1,4 @@
-
-
-
+
משוב
עמוד הבית
@@ -243,4 +241,5 @@
לא הייתה אפשרות לשמור את הקובץ ב-%1$s.
שמירת טקסט החיפוש?
תרצו לשמור את הטקסט \"%1$s\" ברשומה הנבחרת על מנת למצוא את הרשומה אוטומטית בפעם הבאה?
-
+"הגדרות מקלדת של Keepass2Android"
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-ja/strings.xml b/src/keepass2android/Resources/values-ja/strings.xml
index cc191152..d0d624e7 100644
--- a/src/keepass2android/Resources/values-ja/strings.xml
+++ b/src/keepass2android/Resources/values-ja/strings.xml
@@ -1,5 +1,4 @@
-
-
+
フィードバック
Keepass2Android は Android で KeePass 2.x データベースを読み書きするパスワードマネージャーです。
@@ -1182,4 +1181,6 @@
ドメイン「%1$s」のアカウント情報をアプリ「%2$s」に挿入しようとしています。
「%2$s」が信頼できて「%1$s」に属するか、アプリ「%2$s」を信頼していて、アカウント情報の誤用ではない場合 (信頼できるブラウザアプリなど) であれば続行しても問題ありません。そうでない場合はキャンセルしてください。
常に「%1$s」に同意
-
+Keepass2Android キーボードの設定
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-ko/strings.xml b/src/keepass2android/Resources/values-ko/strings.xml
index 242aad99..aa7815d3 100644
--- a/src/keepass2android/Resources/values-ko/strings.xml
+++ b/src/keepass2android/Resources/values-ko/strings.xml
@@ -1,5 +1,4 @@
-
-
+
의견 보내기
Keepass2Android는 Android에서 KeePass 2.x 데이터베이스에 대한 읽기/쓰기 액세스를 제공하는 암호 관리자입니다.
@@ -746,4 +745,6 @@ Keepass2Android는 오프라인에서도 데이터베이스 파일의 사용이
\"%2$s\" 앱을 통해 \"%1$s\" 도메인에 신용 정보를 입력하려고 합니다
\"%1$s\"를 통해서 \"%2$s\"를 사용 하는 것에 대해 신뢰하시거나 \"%2$s\" 앱이 신용 정보를 남용하지 않을 것이라고 신뢰하신다면 (예: 검증된 브라우저 앱의 경우), 계속 하셔도 괜찮습니다. 그렇지 않다면 취소해 주십시오.
항상 \"%1$s\" 앱을 쓰는 경우를 제외함
-
+Keepass2Android 키보드 설정
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-lt/strings.xml b/src/keepass2android/Resources/values-lt/strings.xml
new file mode 100644
index 00000000..bf5953a0
--- /dev/null
+++ b/src/keepass2android/Resources/values-lt/strings.xml
@@ -0,0 +1,3 @@
+
+"„Keepass2Android“ klaviatūros nustatymai"
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-lv/strings.xml b/src/keepass2android/Resources/values-lv/strings.xml
new file mode 100644
index 00000000..f6984d95
--- /dev/null
+++ b/src/keepass2android/Resources/values-lv/strings.xml
@@ -0,0 +1,3 @@
+
+"Keepass2Android tastatūras iestatījumi"
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-ml/strings.xml b/src/keepass2android/Resources/values-ml/strings.xml
index 8d951cc5..fbc1ce7c 100644
--- a/src/keepass2android/Resources/values-ml/strings.xml
+++ b/src/keepass2android/Resources/values-ml/strings.xml
@@ -1,5 +1,4 @@
-
-
+
അഭിപ്രായം
അംഗീകരിക്കുക
@@ -222,4 +221,5 @@
എനിക്ക് മനസിലായി
വീണ്ടും കാണിക്കരുത്
-
+ആൻഡ്രോയിഡ് കീബോർഡ് ക്രമീകരണങ്ങൾ
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-nb/strings.xml b/src/keepass2android/Resources/values-nb/strings.xml
index 4d54ad99..5fe29367 100644
--- a/src/keepass2android/Resources/values-nb/strings.xml
+++ b/src/keepass2android/Resources/values-nb/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Tilbakemelding
Keepass2Android er en android-utgave av KeePass passordbestyrer.
@@ -590,4 +589,6 @@
For å opprette en sikkerhetskopi nå, gå til %1$s > %2$s > %3$s.
Er du forberedt på nødssituasjoner?
Har du noen gang vurdert hva som skjer dersom du ikke lenger har tilgang til passorddatabasen? Hva om du blir utsatt for en ulykke? Det er god praksis å overlate hovednøkkelen til en person du stoler helt på i tilfelle en nødssituasjon. Ellers vil ingen ha tilgang til dine passord.
-
+Innstillinger for Keepass2Android tastatur
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-night/colors.xml b/src/keepass2android/Resources/values-night/colors.xml
new file mode 100644
index 00000000..c28f154f
--- /dev/null
+++ b/src/keepass2android/Resources/values-night/colors.xml
@@ -0,0 +1,145 @@
+
+ #4B662C
+
+ #ACE668
+ #1E3700
+ #84BB43
+ #132600
+ #99CBFF
+ #003355
+ #006DAE
+ #FFFFFF
+ #4CF0B1
+ #003825
+ #00C48B
+ #002819
+ #FFB4AB
+ #690005
+ #93000A
+ #FFDAD6
+ #11150C
+ #E1E4D6
+ #11150C
+ #E1E4D6
+ #424939
+ #C2C9B4
+ #8C9380
+ #424939
+ #000000
+ #E1E4D6
+ #2E3228
+ #3E6A00
+ #B9F474
+ #0F2000
+ #9ED75B
+ #2E4F00
+ #CFE5FF
+ #001D34
+ #99CBFF
+ #004A78
+ #5DFDBE
+ #002114
+ #36E0A3
+ #005138
+ #11150C
+ #373A31
+ #0C0F08
+ #191D14
+ #1D2118
+ #282B22
+ #32362C
+ #ACE668
+ #122500
+ #84BB43
+ #000000
+ #A2CFFF
+ #00182B
+ #3F96DE
+ #000000
+ #4CF0B1
+ #002618
+ #00C48B
+ #000000
+ #FFBAB1
+ #370001
+ #FF5449
+ #000000
+ #11150C
+ #E1E4D6
+ #11150C
+ #FAFCEE
+ #424939
+ #C7CDB8
+ #9FA592
+ #7F8673
+ #000000
+ #E1E4D6
+ #282B22
+ #2F5100
+ #B9F474
+ #081400
+ #9ED75B
+ #223D00
+ #CFE5FF
+ #001223
+ #99CBFF
+ #00395E
+ #5DFDBE
+ #00150C
+ #36E0A3
+ #003F2A
+ #11150C
+ #373A31
+ #0C0F08
+ #191D14
+ #1D2118
+ #282B22
+ #32362C
+ #F4FFE0
+ #000000
+ #A2DC5F
+ #000000
+ #FAFAFF
+ #000000
+ #A2CFFF
+ #000000
+ #EEFFF3
+ #000000
+ #3CE4A7
+ #000000
+ #FFF9F9
+ #000000
+ #FFBAB1
+ #000000
+ #11150C
+ #E1E4D6
+ #11150C
+ #FFFFFF
+ #424939
+ #F7FEE7
+ #C7CDB8
+ #C7CDB8
+ #000000
+ #E1E4D6
+ #000000
+ #1A3000
+ #BDF978
+ #000000
+ #A2DC5F
+ #0C1A00
+ #D7E9FF
+ #000000
+ #A2CFFF
+ #00182B
+ #79FFC6
+ #000000
+ #3CE4A7
+ #001B10
+ #11150C
+ #373A31
+ #0C0F08
+ #191D14
+ #1D2118
+ #282B22
+ #32362C
+
diff --git a/src/keepass2android/Resources/values-nl/strings.xml b/src/keepass2android/Resources/values-nl/strings.xml
index cbdbe9ea..34d2f12a 100644
--- a/src/keepass2android/Resources/values-nl/strings.xml
+++ b/src/keepass2android/Resources/values-nl/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Terugkoppeling
Keepass2Android is een wachtwoordbeheerder die lees-/schrijftoegang biedt tot KeePass 2.x-databases op Android.
@@ -978,4 +977,6 @@ ChangeLog_1_05
Je staat op het punt, om inloggegevens voor domein \"%1$s\" in te voegen in de app \"%2$s\".
Als je vertrouwt dat \"%2$s\" tot \"%1$s\" behoort, of je vertrouwt dat app \"%2$s\" de inloggegevens niet misbruikt (bijvoorbeeld omdat het een vertrouwde browser-app is), kun je doorgaan. Anders annuleren.
Altijd accepteren in \"%1$s\"
-
+Instellingen voor Keepass2Android-toetsenbord
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-pl/strings.xml b/src/keepass2android/Resources/values-pl/strings.xml
index 6159f24a..58e09674 100644
--- a/src/keepass2android/Resources/values-pl/strings.xml
+++ b/src/keepass2android/Resources/values-pl/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Opinie
Keepass2Android to menedżer haseł umożliwiający odczyt i zapis baz danych programu KeePass 2.x w systemie Android.
@@ -901,4 +900,6 @@
Zamierzasz wstawić poświadczenia dla domeny \"%1$s\" do aplikacji \"%2$s\".
Jeśli ufasz \"%2$s\" należącym do \"%1$s\" lub ufasz aplikacji \"%2$s\", aby nie używać danych logowania (np. ponieważ jest to zaufana aplikacja przeglądarki), jest w porządku, aby kontynuować. Jeśli nie, proszę anulować.
Akceptuj zawsze w \"%1$s\"
-
+Ustawienia klawiatury Keepass2Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-pt-rBR/strings.xml b/src/keepass2android/Resources/values-pt-rBR/strings.xml
index 246588c4..0654900c 100644
--- a/src/keepass2android/Resources/values-pt-rBR/strings.xml
+++ b/src/keepass2android/Resources/values-pt-rBR/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Comentários
Keepass2Android é uma implementação do gerenciador de senhas KeePass.
@@ -1185,4 +1184,6 @@
Você esta prestes a inserir credenciais do domínio \"%1$s\" no app \"%2$s\".
Se você confia em \"%2$s\" para pertencer \"%1$s\" ou se você confia no app \"%2$s\" a não mal-usar as credenciais (ex. por causa de um app de navegador confiável), é ok para continuar. Se não, por favor cancele.
Aceitar sempre em \"%1$s\"
-
+Configurações do teclado Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-pt/strings.xml b/src/keepass2android/Resources/values-pt/strings.xml
index 4f5213aa..fc366012 100644
--- a/src/keepass2android/Resources/values-pt/strings.xml
+++ b/src/keepass2android/Resources/values-pt/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Opinião
Keepass2Android é um gestor de palavras-passe, que fornece acesso de leitura/gravação às bases de dados do KeePass 2.x em Android.
@@ -1173,4 +1172,6 @@ Não há forma de fazer \"reset\" à chave mestra.
Está prestes a inserir credenciais para o domínio \"%1$s\" na aplicação \"%2$s\".
Se confia em \"%2$s\" para pertencer a \"%1$s\" ou confia na aplicação \"%2$s\" para que esta não utilize indevidamente as credenciais (por ex. por ser uma aplicação de navegação confiável), pode continuar. Caso contrário cancele.
Aceitar sempre em \"%1$s\"
-
+Configurações de teclado Keepass2Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-ro/strings.xml b/src/keepass2android/Resources/values-ro/strings.xml
index 70b08f85..88013e86 100644
--- a/src/keepass2android/Resources/values-ro/strings.xml
+++ b/src/keepass2android/Resources/values-ro/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Feedback
Keepass2Android este un manager de parole ce oferă citire/scriere la baze de date KeePass 2.x pe Android.
@@ -650,4 +649,6 @@
Sunteți pe cale de a insera datele de autentificare pentru domeniul \"%1$s\" în aplicația \"%2$s\".
Dacă aveți încredere că \"%2$s\" aparține la \"%1$s\" sau dacă aveți încredere în aplicația \"%2$s\" să nu abuzeze de datele de autentificare (de ex. deoarece este o aplicație de încredere pentru browser), este in regulă să continuați. Dacă nu, vă rugăm să anulați.
Acceptați întotdeauna în \"%1$s\"
-
+Setările tastaturii Keepass2Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-ru/strings.xml b/src/keepass2android/Resources/values-ru/strings.xml
index 0060e3f8..b736c24c 100644
--- a/src/keepass2android/Resources/values-ru/strings.xml
+++ b/src/keepass2android/Resources/values-ru/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Оставить отзыв
Keepass2Android — это менеджер паролей, обеспечивающий полноценную работу с базами KeePass 2.x на Android.
@@ -886,4 +885,6 @@
Вы собираетесь вставить учётные данные для домена \"%1$s\" в приложение \"%2$s\".
Если вы уверены, что \"%2$s\" принадлежит к \"%1$s\" или доверяете приложению \"%2$s\" не злоупотребляйте учётными данными (например, потому что это доверенное приложение браузера), если всё хорошо можно продолжить. Если нет, пожалуйста, отмените.
Всегда принимать в \"%1$s\"
-
+Настройки клавиатуры \"Keepass2Android\"
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-sk/strings.xml b/src/keepass2android/Resources/values-sk/strings.xml
index 36d258ff..c9122127 100644
--- a/src/keepass2android/Resources/values-sk/strings.xml
+++ b/src/keepass2android/Resources/values-sk/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Spätná odozva
Keepass2Android je správca hesiel umožňujúci čítanie/zápis do databáz KeePass 2.x, v systéme Android.
@@ -1185,4 +1184,6 @@
Chcete vložiť prihlas. údaje pre doménu \"%1$s\" do aplikácie \"%2$s\".
Ak dôverujete aplikácii \"%2$s\", že patrí \"%1$s\" alebo ak dôverujete, že aplikácia \"%2$s\" nezneužíva prihlasovacie údaje (ak je to napríklad dôveryhodný prehliadač), môžete pokračovať. Ak nie, prosím zrušte túto akciu.
Vždy súhlasiť v \"%1$s\"
-
+Nastavenia klávesnice Keepass2Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-sl/strings.xml b/src/keepass2android/Resources/values-sl/strings.xml
index 6b6fa0ca..62d0377a 100644
--- a/src/keepass2android/Resources/values-sl/strings.xml
+++ b/src/keepass2android/Resources/values-sl/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Povratna informacija
Keepass2Android je upravitelj gesel, ki omogoča branje/pisanje podatkovnih zbirk KeePass 2.x na Androidu.
@@ -1183,4 +1182,6 @@
V aplikacijo \"%2$s\" vstavite poverilnice za domeno \"%1$s\".
Če zaupate, da \"%2$s\" pripada \"%1$s\" ali da zaupate aplikaciji \"%2$s\" in ne boste zlorabljali poverilnic (npr. ker gre za zaupanja vredno aplikacijo brskalnika), je v redu, če nadaljujete . V nasprotnem primeru prekličite postopek.
Sprejmi vedno v \"%1$s\"
-
+Nastavitve tipkovnice Keepass2Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-sr/strings.xml b/src/keepass2android/Resources/values-sr/strings.xml
index 0f61d53f..b71d3109 100644
--- a/src/keepass2android/Resources/values-sr/strings.xml
+++ b/src/keepass2android/Resources/values-sr/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Повратне информације
Keepass2Android је управљач лозинкама који пружа читање и уписивање у KeePass 2.x базе података на Android-у.
@@ -309,4 +308,6 @@
- KP2A Private/Public key
- Custom Private key
-
+Подешавања Keepass2Android тастатуре
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-sv/strings.xml b/src/keepass2android/Resources/values-sv/strings.xml
index d9b0e85d..9c47a140 100644
--- a/src/keepass2android/Resources/values-sv/strings.xml
+++ b/src/keepass2android/Resources/values-sv/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Feedback
Keepass2Android är en lösenordshanterare som tillhandahåller läs- och skrivåtkomst för KeePass 2.x-databaser på Android.
@@ -811,4 +810,6 @@
Du är på väg att mata in inloggnings-uppgifter för domänen \"%1$s\" i appen \"%2$s\".
Om du litar på \"%2$s\" att tillhöra \"%1$s\" eller du litar på appen \"%2$s\" att inte missbruka autentiseringsuppgifterna (t.ex. om det är en betrodd webbläsarapp) är det okej att fortsätta. Om inte, vänligen avbryt.
Acceptera alltid i \"%1$s\"
-
+Inställningar för Keepass2Androids tangentbord
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-th/strings.xml b/src/keepass2android/Resources/values-th/strings.xml
new file mode 100644
index 00000000..389202f3
--- /dev/null
+++ b/src/keepass2android/Resources/values-th/strings.xml
@@ -0,0 +1,3 @@
+
+"การตั้งค่าแป้นพิมพ์ Keepass2Android"
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-tl/strings.xml b/src/keepass2android/Resources/values-tl/strings.xml
new file mode 100644
index 00000000..b8a984a7
--- /dev/null
+++ b/src/keepass2android/Resources/values-tl/strings.xml
@@ -0,0 +1,3 @@
+
+"Mga setting ng Keepass2Android keyboard"
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-tr/strings.xml b/src/keepass2android/Resources/values-tr/strings.xml
index 51295ca0..cfbd2d6d 100644
--- a/src/keepass2android/Resources/values-tr/strings.xml
+++ b/src/keepass2android/Resources/values-tr/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Geri bildirim
Keepass2Android Android üzerinde KeePass 2.x veritabanları için okuma/yazma erişimi sağlayan bir şifre yöneticisidir.
@@ -812,4 +811,6 @@
\"%1$s\" alanı için kimlik bilgilerini \"%2$s\" uygulamasına eklemek üzeresiniz.
\"%2$s\" öğesinin \"%1$s\" öğesine ait olduğuna veya \"%2$s\" uygulamasının kimlik bilgilerini kötüye kullanmayacağına (örneğin, güvenilir bir tarayıcı uygulaması olduğu için) güveniyorsanız, devam edebilirsiniz. Değilse, lütfen iptal edin.
Her zaman kabul et
-
+Keepass2Android klavye ayarları
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-uk/strings.xml b/src/keepass2android/Resources/values-uk/strings.xml
index d9c027c5..e7137d1c 100644
--- a/src/keepass2android/Resources/values-uk/strings.xml
+++ b/src/keepass2android/Resources/values-uk/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Залишити відгук
Keepass2Android - це менеджер паролів, який забезпечує читання/запис баз даних KeePass 2.x на Android.
@@ -844,4 +843,6 @@
Ви збираєтеся вставити облікові дані для домену \"%1$s\" в програму \"%2$s\".
Якщо ви впевнені, що домен \"%2$s\" належить \"%1$s\", або якщо ви впевнені, що програма \"%2$s\" не скомпрометує облікові дані (наприклад, якщо це довірений веббраузер), тоді немає чого хвилюватися. Якщо ви не впевнені, скасуйте цю дію.
Завжди схвалювати в \"%1$s\"
-
+Налаштування клавіатури Android
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-v21/styles.xml b/src/keepass2android/Resources/values-v21/styles.xml
index 4cd55095..bbb65f55 100644
--- a/src/keepass2android/Resources/values-v21/styles.xml
+++ b/src/keepass2android/Resources/values-v21/styles.xml
@@ -1,44 +1,4 @@
-
-
-
-
-
-
-
diff --git a/src/keepass2android/Resources/values-vi/strings.xml b/src/keepass2android/Resources/values-vi/strings.xml
index b9fd4d72..f784e7c2 100644
--- a/src/keepass2android/Resources/values-vi/strings.xml
+++ b/src/keepass2android/Resources/values-vi/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Thông tin phản hồi
Keepass2Android là một ứng dụng quản lý mật khẩu cung cấp quyền truy cập đọc/ghi vào cơ sở dữ liệu KeePass 2.x trên Android.
@@ -870,7 +869,9 @@
Tắt tính năng Tự động điền cho %1$s
Bật Tự động điền cho %1$s
Không thể liên kết tên miền trang web %1$s với ứng dụng %2$s
- Keepass2Android đã phát hiện phần cứng sinh trắc học. Bạn có muốn bật Mở khóa sinh trắc học cho cơ sở dữ liệu này không?
+Cài đặt bàn phím Keepass2Android
+
+ Keepass2Android đã phát hiện phần cứng sinh trắc học. Bạn có muốn bật Mở khóa sinh trắc học cho cơ sở dữ liệu này không?
Cho phép thông báo
Keepass2Android có thể hiển thị thông báo bằng các nút để sao chép các giá trị như mật khẩu và TOTP vào khay nhớ tạm hoặc để hiển thị bàn phím tích hợp. Điều này rất hữu ích để chuyển các giá trị sang các ứng dụng khác mà không cần chuyển sang Keepass2Android nhiều lần. Bạn có muốn kích hoạt các thông báo như vậy không?
Cho phép thông báo
@@ -894,4 +895,4 @@
Bạn sắp chèn thông tin đăng nhập của miền \"%1$s\" vào ứng dụng \"%2$s\".
Nếu bạn tin tưởng \"%2$s\" thuộc về \"%1$s\" hoặc bạn tin tưởng ứng dụng \"%2$s\" không sử dụng sai thông tin xác thực (ví dụ: vì đây là ứng dụng trình duyệt đáng tin cậy), bạn có thể tiếp tục. Nếu không, xin vui lòng hủy bỏ.
Luôn chấp nhận trong \"%1$s\"
-
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-zh-rTW/strings.xml b/src/keepass2android/Resources/values-zh-rTW/strings.xml
index 37bdaf0f..c5814184 100644
--- a/src/keepass2android/Resources/values-zh-rTW/strings.xml
+++ b/src/keepass2android/Resources/values-zh-rTW/strings.xml
@@ -1,5 +1,4 @@
-
-
+
意見回饋:
Keepass2Android 是 Android 的 KeePass 2.x 密碼資料庫管理軟體。
@@ -820,4 +819,6 @@
你正將「%1$s」網域的憑證輸入到「%2$s」應用程式。
如你相信「%2$s」屬於「%1$s」,或「%2$s」應用程式不會誤用憑證(例如這是可信的瀏覽器)時,請繼續。反之請取消。
一律接受「%1$s」
-
+Keepass2Android 鍵盤設定
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values-zh/strings.xml b/src/keepass2android/Resources/values-zh/strings.xml
index 22c91826..f601d456 100644
--- a/src/keepass2android/Resources/values-zh/strings.xml
+++ b/src/keepass2android/Resources/values-zh/strings.xml
@@ -1,5 +1,4 @@
-
-
+
反馈
Keepass2Android 是一款支持 Keepass 2.x 数据库读写的密码管理应用。
@@ -1157,4 +1156,6 @@ Initial public release
您将要将域名\"%1$s\"的凭据插入应用“%2$s”。
如果你相信“%2$s”属于\"%1$s\",或者你相信应用“%2$s”不会滥用凭据(例如,它是受信任的浏览器应用),所以可以继续。如果不是,请取消。
总是在 \"%1$s 中接受
-
+键盘设置
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values/attrs.xml b/src/keepass2android/Resources/values/attrs.xml
index 6aa3e7aa..24b9925c 100644
--- a/src/keepass2android/Resources/values/attrs.xml
+++ b/src/keepass2android/Resources/values/attrs.xml
@@ -1,24 +1,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/src/keepass2android/Resources/values/colors.xml b/src/keepass2android/Resources/values/colors.xml
deleted file mode 100644
index 1cec8d52..00000000
--- a/src/keepass2android/Resources/values/colors.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
- #fff
- #0000
-
- #8bc34a
- #548a2e
- #0277bd
- #015080
-
- #0000dd
- #333333
- #00555555
- #000000
- #a8a8a8
- #303030
-
- #a8a8a8
-
- #31b6e7
- #4f7a8a
-
- #f4511e
- #42000000
- #009688
-
-
diff --git a/src/keepass2android/Resources/values/colors_kp2a.xml b/src/keepass2android/Resources/values/colors_kp2a.xml
new file mode 100644
index 00000000..136da9ba
--- /dev/null
+++ b/src/keepass2android/Resources/values/colors_kp2a.xml
@@ -0,0 +1,145 @@
+
+ #4B662C
+
+ #4B662C
+ #FFFFFF
+ #CCEDA4
+ #0F2000
+ #31628D
+ #FFFFFF
+ #CFE5FF
+ #001D34
+ #386663
+ #FFFFFF
+ #BBECE8
+ #00201E
+ #BA1A1A
+ #FFFFFF
+ #FFDAD6
+ #410002
+ #F9FAEF
+ #1A1C16
+ #F5FAFB
+ #171D1E
+ #E1E4D5
+ #44483D
+ #75796C
+ #C5C8BA
+ #000000
+ #2B3133
+ #ECF2F3
+ #B1D18A
+ #CCEDA4
+ #0F2000
+ #B1D18A
+ #344E16
+ #CFE5FF
+ #001D34
+ #9DCBFB
+ #124A73
+ #BBECE8
+ #00201E
+ #A0D0CC
+ #1F4E4B
+ #D5DBDC
+ #F5FAFB
+ #FFFFFF
+ #EFF5F6
+ #E9EFF0
+ #E3E9EA
+ #DEE3E5
+ #314A12
+ #FFFFFF
+ #617D40
+ #FFFFFF
+ #0B466F
+ #FFFFFF
+ #4A78A4
+ #FFFFFF
+ #1A4A47
+ #FFFFFF
+ #4F7D79
+ #FFFFFF
+ #8C0009
+ #FFFFFF
+ #DA342E
+ #FFFFFF
+ #F9FAEF
+ #1A1C16
+ #F5FAFB
+ #171D1E
+ #E1E4D5
+ #40443A
+ #5D6155
+ #787C70
+ #000000
+ #2B3133
+ #ECF2F3
+ #B1D18A
+ #617D40
+ #FFFFFF
+ #49642A
+ #FFFFFF
+ #4A78A4
+ #FFFFFF
+ #2F5F8A
+ #FFFFFF
+ #4F7D79
+ #FFFFFF
+ #366461
+ #FFFFFF
+ #D5DBDC
+ #F5FAFB
+ #FFFFFF
+ #EFF5F6
+ #E9EFF0
+ #E3E9EA
+ #DEE3E5
+ #142700
+ #FFFFFF
+ #314A12
+ #FFFFFF
+ #00243E
+ #FFFFFF
+ #0B466F
+ #FFFFFF
+ #002726
+ #FFFFFF
+ #1A4A47
+ #FFFFFF
+ #4E0002
+ #FFFFFF
+ #8C0009
+ #FFFFFF
+ #F9FAEF
+ #1A1C16
+ #F5FAFB
+ #000000
+ #E1E4D5
+ #21251C
+ #40443A
+ #40443A
+ #000000
+ #2B3133
+ #FFFFFF
+ #D6F7AD
+ #314A12
+ #FFFFFF
+ #1B3300
+ #FFFFFF
+ #0B466F
+ #FFFFFF
+ #002F4F
+ #FFFFFF
+ #1A4A47
+ #FFFFFF
+ #003331
+ #FFFFFF
+ #D5DBDC
+ #F5FAFB
+ #FFFFFF
+ #EFF5F6
+ #E9EFF0
+ #E3E9EA
+ #DEE3E5
+
diff --git a/src/keepass2android/Resources/values/dimens.xml b/src/keepass2android/Resources/values/dimens.xml
index becbf1f6..dbc57788 100644
--- a/src/keepass2android/Resources/values/dimens.xml
+++ b/src/keepass2android/Resources/values/dimens.xml
@@ -9,7 +9,7 @@
79dp
104dp
- 16dp
+ 64dp
30dp
diff --git a/src/keepass2android/Resources/values/strings.xml b/src/keepass2android/Resources/values/strings.xml
index 2247ae18..5301473e 100644
--- a/src/keepass2android/Resources/values/strings.xml
+++ b/src/keepass2android/Resources/values/strings.xml
@@ -1,5 +1,4 @@
-
-
+
Feedback
Keepass2Android is a password manager providing read/write access to KeePass 2.x databases on Android.
@@ -678,25 +677,25 @@
Invalid composite key! Please try the following steps to unlock your database:\n
- • Make sure you have entered the correct password. Use the eye icon to reveal the entered password.\n
- • Make sure you have selected the correct password type. Make sure this matches the type used when creating the database.\n
- • Make sure you have selected the correct database file.
+ • Make sure you have entered the correct password. Use the eye icon to reveal the entered password.\n
+ • Make sure you have selected the correct password type. Make sure this matches the type used when creating the database.\n
+ • Make sure you have selected the correct database file.
\n
- • Hint: If you think your database file might be corrupt or you do not remember the master key after modifying it, you can try with the last successfully opened file version by tapping "%1$s" and selecting the local backup.
+ • Hint: If you think your database file might be corrupt or you do not remember the master key after modifying it, you can try with the last successfully opened file version by tapping "%1$s" and selecting the local backup.
\n
- • Hint: Keepass2Android has stored the last successfully opened file version on internal storage. You can open it by tapping "%1$s" and selecting the local backup.
+ • Hint: Keepass2Android has stored the last successfully opened file version on internal storage. You can open it by tapping "%1$s" and selecting the local backup.
File is corrupted. \n
Here are some hints which might help to diagnose the issue:\n
- • If you copied the file over USB (MTP-Mode), please try again using a tool like MyPhoneExplorer. MTP truncates files in certain cases.\n
- • If you cannot open the file from the same location on your PC, it is very likely that the file is actually corrupted. Please use a database backup then. If you assume that Keepass2Android has corrupted the file, please contact the support team.\n
- • If you can still open the file on your PC, please contact the support team. You might try to save it with different settings (e.g. unzipped) on the PC and retry to open in Keepass2Android.
+ • If you copied the file over USB (MTP-Mode), please try again using a tool like MyPhoneExplorer. MTP truncates files in certain cases.\n
+ • If you cannot open the file from the same location on your PC, it is very likely that the file is actually corrupted. Please use a database backup then. If you assume that Keepass2Android has corrupted the file, please contact the support team.\n
+ • If you can still open the file on your PC, please contact the support team. You might try to save it with different settings (e.g. unzipped) on the PC and retry to open in Keepass2Android.
Open another database…
@@ -1230,4 +1229,8 @@
You are about to insert credentials for domain "%1$s" into the app "%2$s".
If you trust "%2$s" to belong to "%1$s" or you trust the app "%2$s" not to misuse the credentials (e.g. because it is a trusted browser app), it is ok to continue. If not, please cancel.
Accept always in "%1$s"
-
+ Switch back when done
+ Switch back when pressing send/go/done
+Android keyboard settings
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values/styles.xml b/src/keepass2android/Resources/values/styles.xml
index 385103c0..1788f087 100644
--- a/src/keepass2android/Resources/values/styles.xml
+++ b/src/keepass2android/Resources/values/styles.xml
@@ -23,7 +23,7 @@
- 0dip
- 12dip
- 4dp
- - ?android:attr/textColorSecondary
+
- 18sp
@@ -55,7 +54,6 @@
@@ -74,7 +72,6 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/values/styles_dark.xml b/src/keepass2android/Resources/values/styles_dark.xml
deleted file mode 100644
index 09b506dc..00000000
--- a/src/keepass2android/Resources/values/styles_dark.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/keepass2android/Resources/values/styles_light.xml b/src/keepass2android/Resources/values/styles_light.xml
deleted file mode 100644
index da89f6a9..00000000
--- a/src/keepass2android/Resources/values/styles_light.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/keepass2android/Resources/values/styles_material.xml b/src/keepass2android/Resources/values/styles_material.xml
deleted file mode 100644
index 9e525bde..00000000
--- a/src/keepass2android/Resources/values/styles_material.xml
+++ /dev/null
@@ -1,247 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/keepass2android/Resources/values/themes.xml b/src/keepass2android/Resources/values/themes.xml
new file mode 100644
index 00000000..9635d989
--- /dev/null
+++ b/src/keepass2android/Resources/values/themes.xml
@@ -0,0 +1,274 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/keepass2android/Resources/xml/autofillservice.xml b/src/keepass2android/Resources/xml/autofillservice.xml
index 4ccf760a..49699d68 100644
--- a/src/keepass2android/Resources/xml/autofillservice.xml
+++ b/src/keepass2android/Resources/xml/autofillservice.xml
@@ -1,106 +1,106 @@
-
+
+>
+ android:name="com.android.chrome"
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="2015836711" />
+ android:maxLongVersionCode="2015849447" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
+ android:maxLongVersionCode="10000000000" />
-
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_app.xml b/src/keepass2android/Resources/xml/pref_app.xml
new file mode 100644
index 00000000..ea5b70c3
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_app.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_app_debug.xml b/src/keepass2android/Resources/xml/pref_app_debug.xml
new file mode 100644
index 00000000..f5aab528
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_app_debug.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_app_display.xml b/src/keepass2android/Resources/xml/pref_app_display.xml
new file mode 100644
index 00000000..01b99365
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_app_display.xml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_app_file_handling.xml b/src/keepass2android/Resources/xml/pref_app_file_handling.xml
new file mode 100644
index 00000000..98b85e90
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_app_file_handling.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_app_password_access.xml b/src/keepass2android/Resources/xml/pref_app_password_access.xml
new file mode 100644
index 00000000..4cc843f9
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_app_password_access.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_app_password_access_autofill.xml b/src/keepass2android/Resources/xml/pref_app_password_access_autofill.xml
new file mode 100644
index 00000000..e0a75584
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_app_password_access_autofill.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_app_password_access_autofill_totp.xml b/src/keepass2android/Resources/xml/pref_app_password_access_autofill_totp.xml
new file mode 100644
index 00000000..34bdde6c
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_app_password_access_autofill_totp.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_app_password_access_keyboard_switch.xml b/src/keepass2android/Resources/xml/pref_app_password_access_keyboard_switch.xml
new file mode 100644
index 00000000..b3c1f615
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_app_password_access_keyboard_switch.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_app_quick_unlock.xml b/src/keepass2android/Resources/xml/pref_app_quick_unlock.xml
new file mode 100644
index 00000000..5c676c5f
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_app_quick_unlock.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_app_security.xml b/src/keepass2android/Resources/xml/pref_app_security.xml
new file mode 100644
index 00000000..10844852
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_app_security.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_app_traytotp.xml b/src/keepass2android/Resources/xml/pref_app_traytotp.xml
new file mode 100644
index 00000000..4d1e2b3d
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_app_traytotp.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_database.xml b/src/keepass2android/Resources/xml/pref_database.xml
new file mode 100644
index 00000000..97a8d1e3
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_database.xml
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/pref_database_key_deriv_func.xml b/src/keepass2android/Resources/xml/pref_database_key_deriv_func.xml
new file mode 100644
index 00000000..f2f49adb
--- /dev/null
+++ b/src/keepass2android/Resources/xml/pref_database_key_deriv_func.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keepass2android/Resources/xml/preferences.xml b/src/keepass2android/Resources/xml/preferences.xml
index 71daf0a2..7747d450 100644
--- a/src/keepass2android/Resources/xml/preferences.xml
+++ b/src/keepass2android/Resources/xml/preferences.xml
@@ -2,7 +2,8 @@
-
-
-
-
-
+ android:title="@string/database"
+ android:summary="@string/menu_db_settings" />
-
-
-
-
-
+
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/keepass2android/SearchProvider.cs b/src/keepass2android/SearchProvider.cs
deleted file mode 100644
index 33610f11..00000000
--- a/src/keepass2android/SearchProvider.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System;
-using Android.App;
-using Android.Content;
-using Android.Database;
-using Uri = Android.Net.Uri;
-
-namespace MaterialTest2
-{
- [ContentProvider(new string[] {"MaterialTest2.SearchProvider"},Exported=false)]
- public class SearchProvider: ContentProvider
- {
- public override int Delete(Uri uri, string selection, string[] selectionArgs)
- {
- return 0;
- }
-
- public override string GetType(Uri uri)
- {
- return null;
- }
-
- public override Uri Insert(Uri uri, ContentValues values)
- {
- return null;
- }
-
- public override bool OnCreate()
- {
- return false;
- }
-
- public override Android.Database.ICursor Query(Android.Net.Uri uri, string[] projection, string selection, string[] selectionArgs, string sortOrder)
- {
- var c = new MatrixCursor(new String[] { "_id", SearchManager.SuggestColumnText1, "lat", "lng" });
-
- c.AddRow(new Java.Lang.Object[] { 123, "description", "lat", "lng" });
- c.AddRow(new Java.Lang.Object[] { 1243, "description 2", "lat", "lng" });
- c.AddRow(new Java.Lang.Object[] { 1235, "description", "lat", "lng" });
- c.AddRow(new Java.Lang.Object[] { 12436, "description 2", "lat", "lng" });
- return c;
- }
-
- public override int Update(Uri uri, ContentValues values, string selection, string[] selectionArgs)
- {
- return 0;
- }
- }
-}
\ No newline at end of file
diff --git a/src/keepass2android/SelectCurrentDbActivity.cs b/src/keepass2android/SelectCurrentDbActivity.cs
index 786672a0..26f270ca 100644
--- a/src/keepass2android/SelectCurrentDbActivity.cs
+++ b/src/keepass2android/SelectCurrentDbActivity.cs
@@ -12,7 +12,6 @@ using Android.Graphics.Drawables;
using Android.OS;
using Android.Preferences;
using Android.Runtime;
-using Android.Support.V7.App;
using Android.Text;
using Android.Util;
using Android.Views;
@@ -21,6 +20,7 @@ using Java.IO;
using Java.Net;
using keepass2android.Io;
using keepass2android.Utils;
+using keepass2android;
using KeePassLib;
using KeePassLib.Keys;
using KeePassLib.Serialization;
@@ -31,7 +31,7 @@ namespace keepass2android
{
[Activity(Label = AppNames.AppName,
MainLauncher = false,
- Theme = "@style/MyTheme_Blue",
+ Theme = "@style/Kp2aTheme_BlueNoActionBar",
Exported = true,
LaunchMode = LaunchMode.SingleInstance)] //caution, see manifest file
public class SelectCurrentDbActivity : LifecycleAwareActivity
@@ -141,7 +141,7 @@ namespace keepass2android
else if (position < _displayedDatabases.Count + _autoExecItems.Count)
{
var item = _autoExecItems[position - _displayedDatabases.Count];
- drawable = App.Kp2a.GetResourceDrawable("ic_nav_changedb");
+ drawable = App.Kp2a.GetResourceDrawable("baseline_file_open_24");
displayName = item.Entry.Strings.ReadSafe(PwDefs.TitleField);
btn.SetBackgroundResource(Resource.Drawable.storagetype_button_bg_dark);
}
@@ -149,7 +149,7 @@ namespace keepass2android
{
btn.SetBackgroundResource(Resource.Drawable.storagetype_button_bg);
displayName = _context.GetString(Resource.String.start_open_file);
- drawable = App.Kp2a.GetResourceDrawable("ic_nav_changedb");
+ drawable = App.Kp2a.GetResourceDrawable("baseline_file_open_24");
}
var str = new SpannableString(displayName);
@@ -343,7 +343,7 @@ namespace keepass2android
IntentFilter filter = new IntentFilter();
filter.AddAction(Intents.DatabaseLocked);
filter.AddAction(Intent.ActionScreenOff);
- RegisterReceiver(_intentReceiver, filter);
+ RegisterReceiver(_intentReceiver, filter, ReceiverFlags.Exported);
}
}
@@ -375,7 +375,7 @@ namespace keepass2android
return false;
}
- File dbFile = new File(ioc.Path);
+ Java.IO.File dbFile = new Java.IO.File(ioc.Path);
if (!dbFile.Exists())
{
// File does not exist
diff --git a/src/keepass2android/SelectStorageLocationActivity.cs b/src/keepass2android/SelectStorageLocationActivity.cs
index 3991962b..c5be5b0e 100644
--- a/src/keepass2android/SelectStorageLocationActivity.cs
+++ b/src/keepass2android/SelectStorageLocationActivity.cs
@@ -3,10 +3,12 @@ using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
+using Google.Android.Material.Dialog;
using KeePassLib.Serialization;
using KeePassLib.Utility;
using keepass2android.Io;
using keepass2android.Utils;
+using keepass2android;
namespace keepass2android
{
@@ -155,7 +157,8 @@ namespace keepass2android
protected override void ShowAlertDialog(string message, EventHandler onOk, EventHandler onCancel)
{
- new AlertDialog.Builder(this)
+ new
+ MaterialAlertDialogBuilder(this)
.SetPositiveButton(Android.Resource.String.Ok, onOk)
.SetMessage(message)
.SetCancelable(false)
diff --git a/src/keepass2android/SetPasswordDialog.cs b/src/keepass2android/SetPasswordDialog.cs
index 8c4dde25..cf581570 100644
--- a/src/keepass2android/SetPasswordDialog.cs
+++ b/src/keepass2android/SetPasswordDialog.cs
@@ -20,6 +20,7 @@ using Android.Content;
using Android.OS;
using Android.Preferences;
using Android.Widget;
+using keepass2android;
namespace keepass2android
{
diff --git a/src/keepass2android/ShareUrlResults.cs b/src/keepass2android/ShareUrlResults.cs
index 184e4f80..0eb4e09b 100644
--- a/src/keepass2android/ShareUrlResults.cs
+++ b/src/keepass2android/ShareUrlResults.cs
@@ -26,12 +26,13 @@ using Android.Views;
using Android.Widget;
using Android.Content.PM;
using Android.Preferences;
+using keepass2android;
using KeePassLib;
using KeePassLib.Utility;
namespace keepass2android
{
- [Activity(Label = "@string/kp2a_findUrl", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden, Theme = "@style/MyTheme_ActionBar", Exported = true)]
+ [Activity(Label = "@string/kp2a_findUrl", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden, Theme = "@style/Kp2aTheme_ActionBar", Exported = true)]
#if NoNet
[MetaData("android.app.searchable", Resource = "@xml/searchable_offline")]
#else
diff --git a/src/keepass2android/SwitchImeActivity.cs b/src/keepass2android/SwitchImeActivity.cs
index 14071775..44aebdb5 100644
--- a/src/keepass2android/SwitchImeActivity.cs
+++ b/src/keepass2android/SwitchImeActivity.cs
@@ -11,6 +11,7 @@ using Android.Util;
using Android.Views;
using Android.Views.InputMethods;
using Android.Widget;
+using keepass2android;
namespace keepass2android
{
diff --git a/src/keepass2android/Totp/TrayTotpPluginAdapter.cs b/src/keepass2android/Totp/TrayTotpPluginAdapter.cs
index 54765c95..4f1a2e36 100644
--- a/src/keepass2android/Totp/TrayTotpPluginAdapter.cs
+++ b/src/keepass2android/Totp/TrayTotpPluginAdapter.cs
@@ -5,6 +5,7 @@ using Android.OS;
using Android.Preferences;
using Android.Widget;
using keepass2android;
+using keepass2android;
namespace PluginTOTP
{
diff --git a/src/keepass2android/Totp/UpdateTotpTimerTask.cs b/src/keepass2android/Totp/UpdateTotpTimerTask.cs
index dc34a81e..636c4b81 100644
--- a/src/keepass2android/Totp/UpdateTotpTimerTask.cs
+++ b/src/keepass2android/Totp/UpdateTotpTimerTask.cs
@@ -44,7 +44,7 @@ namespace PluginTOTP
//update, but that's inexpensive and relatively rare
BroadcastNewTotp(totp);
//restart timer
- new Timer().Schedule(new UpdateTotpTimerTask(_context, _adapter), 1000 * prov.Timer);
+ new Java.Util.Timer().Schedule(new UpdateTotpTimerTask(_context, _adapter), 1000 * prov.Timer);
}
}
catch (Exception e)
diff --git a/src/keepass2android/Utils/ActivityDesign.cs b/src/keepass2android/Utils/ActivityDesign.cs
index 9d345433..b92af97e 100644
--- a/src/keepass2android/Utils/ActivityDesign.cs
+++ b/src/keepass2android/Utils/ActivityDesign.cs
@@ -4,6 +4,8 @@ using Android.App;
using Android.Content.Res;
using Android.OS;
using Android.Preferences;
+using AndroidX.AppCompat.App;
+using keepass2android;
namespace keepass2android
{
@@ -45,67 +47,34 @@ namespace keepass2android
public void ApplyTheme()
{
- if (HasThemes())
- {
- var dark = UseDarkTheme;
- int newTheme = dark ? DarkTheme : LightTheme;
- _activity.SetTheme(newTheme);
- _currentThemeId = newTheme;
- _secureWindow = SecureWindowPref();
- }
+ _currentThemeId = NightModePreference;
+ AppCompatDelegate.DefaultNightMode = _currentThemeId.Value;
+ _secureWindow = SecureWindowPref();
+
_currentIconSet = PreferenceManager.GetDefaultSharedPreferences(_activity)
.GetString("IconSetKey", _activity.PackageName);
}
- public int DarkTheme
- {
- get
- {
- if (string.IsNullOrEmpty(_attributeTheme))
- return Resource.Style.MyTheme_Dark;
- if (_attributeTheme.Contains("MyTheme_Blue"))
- return Resource.Style.MyTheme_Blue_Dark;
- if (_attributeTheme.Contains("MyTheme_ActionBar"))
- return Resource.Style.MyTheme_ActionBar_Dark;
- return Resource.Style.MyTheme_Dark;
- }
-
- }
-
- public int LightTheme
- {
- get
- {
- if (string.IsNullOrEmpty(_attributeTheme))
- return Resource.Style.MyTheme;
- if (_attributeTheme.Contains("MyTheme_Blue"))
- return Resource.Style.MyTheme_Blue;
- if (_attributeTheme.Contains("MyTheme_ActionBar"))
- return Resource.Style.MyTheme_ActionBar;
- return Resource.Style.MyTheme;
- }
-
- }
public void ReapplyTheme()
{
- if (HasThemes())
+
+ int newTheme = NightModePreference;
+ if (newTheme != _currentThemeId)
{
- int newTheme = UseDarkTheme ? DarkTheme : LightTheme;
- if (newTheme != _currentThemeId)
- {
- Kp2aLog.Log("recreating due to theme change.");
- _activity.Recreate();
- return;
- }
- }
+ Kp2aLog.Log("recreating due to theme change.");
+ _activity.Recreate();
+ _activity.Finish(); //withouth this, we'll have two GroupActivities on the backstack afterwards
+ return;
+ }
+
if (PreferenceManager.GetDefaultSharedPreferences(_activity)
.GetString("IconSetKey", _activity.PackageName) != _currentIconSet)
{
Kp2aLog.Log("recreating due to icon set change.");
_activity.Recreate();
- return;
+ return;
}
@@ -113,44 +82,34 @@ namespace keepass2android
{
Kp2aLog.Log("recreating due to secure window change.");
_activity.Recreate();
- return;
+ return;
}
}
- public bool UseDarkTheme
+ public int NightModePreference
{
get
{
var prefs = PreferenceManager.GetDefaultSharedPreferences(_activity);
string design = prefs.GetString(_activity.GetString(Resource.String.design_key), _activity.GetString(Resource.String.design_default));
-
- if ((design == "System") && (int)Build.VERSION.SdkInt>=29 && _activity.Resources.Configuration != null)
+ return design switch
{
- UiMode nightModeFlags = ((UiMode)((int)_activity.Resources.Configuration.UiMode & (int)Android.Content.Res.UiMode.NightMask));
-
- if (nightModeFlags == UiMode.NightYes)
- return true;
- }
-
- bool dark = (design == "Dark");
- return dark;
+ "System" => AppCompatDelegate.ModeNightFollowSystem,
+ "Light" => AppCompatDelegate.ModeNightNo,
+ "Dark" => AppCompatDelegate.ModeNightYes,
+ _ => AppCompatDelegate.ModeNightFollowSystem,
+ };
}
}
public void ApplyDialogTheme()
{
- if (HasThemes())
- {
- bool dark = UseDarkTheme;
- _activity.SetTheme(dark ? Resource.Style.Base_Dialog_Dark : Resource.Style.Base_Dialog);
- }
+
+ _activity.SetTheme(Resource.Style.Kp2aTheme_Dialog);
+
}
- public bool HasThemes()
- {
- return ((int)Android.OS.Build.VERSION.SdkInt >= 14);
- }
}
}
\ No newline at end of file
diff --git a/src/keepass2android/Utils/LoadingDialog.cs b/src/keepass2android/Utils/LoadingDialog.cs
index b832b487..cdc88ba3 100644
--- a/src/keepass2android/Utils/LoadingDialog.cs
+++ b/src/keepass2android/Utils/LoadingDialog.cs
@@ -4,6 +4,7 @@ using Android.Content;
using Android.OS;
using Android.Runtime;
using Java.Lang;
+using keepass2android;
using Exception = System.Exception;
using Object = Java.Lang.Object;
diff --git a/src/keepass2android/Utils/Util.cs b/src/keepass2android/Utils/Util.cs
index b849df3b..67389100 100644
--- a/src/keepass2android/Utils/Util.cs
+++ b/src/keepass2android/Utils/Util.cs
@@ -36,6 +36,8 @@ using Android.Hardware.Display;
using Android.Util;
using Android.Views.InputMethods;
using AndroidX.Core.View.InputMethod;
+using Google.Android.Material.Dialog;
+using keepass2android;
using KeePassLib;
using KeePassLib.Security;
using KeePassLib.Serialization;
@@ -581,7 +583,7 @@ namespace keepass2android
public static void ShowFilenameDialog(Activity activity, Func onOpen, Func onCreate, Action onCancel, bool showBrowseButton, string defaultFilename, string detailsText, int requestCodeBrowse)
{
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity);
builder.SetView(activity.LayoutInflater.Inflate(Resource.Layout.file_selection_filename, null));
if (onCancel != null)
@@ -645,7 +647,7 @@ namespace keepass2android
public static void QueryCredentials(IOConnectionInfo ioc, Action afterQueryCredentials, Activity activity)
{
//Build dialog to query credentials:
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity);
builder.SetTitle(activity.GetString(Resource.String.credentials_dialog_title));
builder.SetPositiveButton(activity.GetString(Android.Resource.String.Ok), (dlgSender, dlgEvt) =>
{
diff --git a/src/keepass2android/app/App.cs b/src/keepass2android/app/App.cs
index f04c045d..510c5d34 100644
--- a/src/keepass2android/app/App.cs
+++ b/src/keepass2android/app/App.cs
@@ -33,8 +33,8 @@ using KeePassLib.Cryptography.Cipher;
using KeePassLib.Keys;
using KeePassLib.Serialization;
using Android.Preferences;
-using Android.Support.V4.App;
-using Android.Support.V4.Content;
+using AndroidX.Core.Content;
+using Google.Android.Material.Dialog;
#if !EXCLUDE_TWOFISH
using TwofishCipher;
#endif
@@ -42,6 +42,7 @@ using Keepass2android.Pluginsdk;
using keepass2android.Io;
using keepass2android.addons.OtpKeyProv;
using keepass2android.database.edit;
+using keepass2android;
using KeePassLib.Interfaces;
using KeePassLib.Utility;
#if !NoNet
@@ -472,7 +473,7 @@ namespace keepass2android
private void AskForReload(Activity activity, Action actionOnResult)
{
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity);
builder.SetTitle(activity.GetString(Resource.String.AskReloadFile_title));
builder.SetMessage(activity.GetString(Resource.String.AskReloadFile));
@@ -592,7 +593,7 @@ namespace keepass2android
Handler handler = new Handler(Looper.MainLooper);
handler.Post(() =>
{
- AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(ctx);
builder.SetTitle(GetResourceString(titleKey));
builder.SetMessage(GetResourceString(messageKey) + (messageSuffix != "" ? " " + messageSuffix : ""));
@@ -632,7 +633,7 @@ namespace keepass2android
cancelHandlerWithShow);
}
- AlertDialog dialog = builder.Create();
+ var dialog = builder.Create();
if (dismissHandler != null)
{
dialog.SetOnDismissListener(new Util.DismissListener(() => {
@@ -828,7 +829,7 @@ namespace keepass2android
new DropboxAppFolderFileStorage(LocaleManager.LocalizedAppContext, this),
GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(LocaleManager.LocalizedAppContext)==ConnectionResult.Success ? new GoogleDriveFileStorage(LocaleManager.LocalizedAppContext, this) : null,
GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(LocaleManager.LocalizedAppContext)==ConnectionResult.Success ? new GoogleDriveAppDataFileStorage(LocaleManager.LocalizedAppContext, this) : null,
- new OneDriveFileStorage(LocaleManager.LocalizedAppContext, this),
+ new OneDriveFileStorage(),
new OneDrive2FullFileStorage(),
new OneDrive2MyFilesFileStorage(),
new OneDrive2AppFolderFileStorage(),
@@ -1341,11 +1342,9 @@ namespace keepass2android
intentFilter.AddAction(Intents.LockDatabase);
intentFilter.AddAction(Intents.LockDatabaseByTimeout);
intentFilter.AddAction(Intents.CloseDatabase);
- Context.RegisterReceiver(broadcastReceiver, intentFilter);
+ Context.RegisterReceiver(broadcastReceiver, intentFilter, ReceiverFlags.Exported);
-
- Xamarin.Essentials.Platform.Init(this);
- ZXing.Net.Mobile.Forms.Android.Platform.Init();
+ //ZXing.Net.Mobile.Forms.Android.Platform.Init();
}
private ApplicationBroadcastReceiver broadcastReceiver = new ApplicationBroadcastReceiver();
diff --git a/src/keepass2android/app/AppTask.cs b/src/keepass2android/app/AppTask.cs
index 385d3766..dd15a1a4 100644
--- a/src/keepass2android/app/AppTask.cs
+++ b/src/keepass2android/app/AppTask.cs
@@ -13,6 +13,8 @@ using KeePassLib.Utility;
using KeeTrayTOTP.Libraries;
using Android.Content.Res;
using Android.Preferences;
+using Google.Android.Material.Dialog;
+using keepass2android;
namespace keepass2android
{
@@ -494,7 +496,7 @@ namespace keepass2android
///
public void AskAddUrlThenCompleteCreate(EntryActivity activity, string url, Thread notifyPluginsOnOpenThread)
{
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity);
builder.SetTitle(activity.GetString(Resource.String.AddUrlToEntryDialog_title));
builder.SetMessage(activity.GetString(Resource.String.AddUrlToEntryDialog_text, new Java.Lang.Object[] { url }));
diff --git a/src/keepass2android/app/OtpAuxCacheSupervisor.cs b/src/keepass2android/app/OtpAuxCacheSupervisor.cs
index 3517aa2f..dda66dc4 100644
--- a/src/keepass2android/app/OtpAuxCacheSupervisor.cs
+++ b/src/keepass2android/app/OtpAuxCacheSupervisor.cs
@@ -2,6 +2,7 @@ using System;
using Android.App;
using KeePassLib.Serialization;
using keepass2android.addons.OtpKeyProv;
+using keepass2android;
namespace keepass2android
{
diff --git a/src/keepass2android/fileselect/FileSelectActivity.cs b/src/keepass2android/fileselect/FileSelectActivity.cs
index 88b003dd..e11a279d 100644
--- a/src/keepass2android/fileselect/FileSelectActivity.cs
+++ b/src/keepass2android/fileselect/FileSelectActivity.cs
@@ -26,13 +26,15 @@ using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Content.PM;
-using Android.Support.V7.App;
using Java.IO;
using KeePassLib.Serialization;
using Keepass2android.Pluginsdk;
using keepass2android.Io;
+using keepass2android;
using Console = System.Console;
using Environment = Android.OS.Environment;
+using Google.Android.Material.AppBar;
+using Android.Util;
namespace keepass2android
{
@@ -44,7 +46,7 @@ namespace keepass2android
[Activity (Label = "@string/app_name",
ConfigurationChanges=ConfigChanges.Orientation|
ConfigChanges.KeyboardHidden,
- Theme = "@style/MyTheme_Blue")]
+ Theme = "@style/Kp2aTheme_BlueNoActionBar")]
public class FileSelectActivity : AndroidX.AppCompat.App.AppCompatActivity
{
private readonly ActivityDesign _design;
@@ -85,9 +87,14 @@ namespace keepass2android
_dbHelper = App.Kp2a.FileDbHelper;
SetContentView(Resource.Layout.file_selection);
-
- if (ShowRecentFiles())
+ var collapsingToolbar = FindViewById(Resource.Id.collapsing_toolbar);
+ collapsingToolbar.Title = "";
+ SetSupportActionBar(FindViewById(Resource.Id.toolbar));
+ SupportActionBar.Title = "";
+
+
+ if (ShowRecentFiles())
{
_recentMode = true;
@@ -247,7 +254,7 @@ namespace keepass2android
AccessManager.PreparePopup(popupMenu);
int remove = 0;
int edit = 1;
- popupMenu.Menu.Add(0, remove, 0, context.GetString(Resource.String.remove_from_filelist)).SetIcon(Resource.Drawable.ic_menu_delete_grey);
+ popupMenu.Menu.Add(0, remove, 0, context.GetString(Resource.String.remove_from_filelist)).SetIcon(Resource.Drawable.baseline_delete_24);
TextView textView = view.FindViewById(Resource.Id.file_filename);
@@ -255,7 +262,7 @@ namespace keepass2android
IOConnectionInfo ioc = new IOConnectionInfo { Path = filename };
if (FileSelectHelper.CanEditIoc(ioc))
{
- popupMenu.Menu.Add(0, edit, 0, context.GetString(Resource.String.edit)).SetIcon(Resource.Drawable.ic_menu_edit_grey);
+ popupMenu.Menu.Add(0, edit, 0, context.GetString(Resource.String.edit)).SetIcon(Resource.Drawable.baseline_edit_24);
}
@@ -267,7 +274,7 @@ namespace keepass2android
{
try
{
- Java.IO.File file = new File(filename);
+ Java.IO.File file = new Java.IO.File(filename);
file.Delete();
}
catch (Exception exception)
@@ -295,6 +302,17 @@ namespace keepass2android
});
};
+ view.FindViewById(Resource.Id.file_filename).Click += (sender, args) =>
+ {
+ TextView textView = view.FindViewById(Resource.Id.file_filename);
+
+ String filename = (string)textView.Tag;
+ IOConnectionInfo ioc = new IOConnectionInfo { Path = filename };
+
+ App.Kp2a.GetFileStorage(ioc)
+ .PrepareFileUsage(new FileStorageSetupInitiatorActivity(_activity, _activity.OnActivityResult, null), ioc, 0, false);
+ };
+
return view;
}
@@ -371,17 +389,6 @@ namespace keepass2android
Finish();
}
- public void OnListItemClick(ListView l, View v, int position, long id)
- {
- ICursor cursor = _dbHelper.FetchFile(id);
- StartManagingCursor(cursor);
-
- IOConnectionInfo ioc = _dbHelper.CursorToIoc(cursor);
-
- App.Kp2a.GetFileStorage(ioc)
- .PrepareFileUsage(new FileStorageSetupInitiatorActivity(this, OnActivityResult, null), ioc, 0, false);
- }
-
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
@@ -519,6 +526,36 @@ namespace keepass2android
}
+
+ public class NonScrollListView : ListView
+ {
+ public NonScrollListView(Context context) : base(context)
+ {
+ }
+
+ public NonScrollListView(Context context, IAttributeSet attrs) : base(context, attrs)
+ {
+ }
+
+ public NonScrollListView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
+ {
+ }
+
+ protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
+ {
+ // Custom height measure spec to make ListView non-scrollable
+ int heightMeasureSpecCustom = MeasureSpec.MakeMeasureSpec(int.MaxValue >> 2, MeasureSpecMode.AtMost);
+ base.OnMeasure(widthMeasureSpec, heightMeasureSpecCustom);
+
+ // Set the height of the ListView to the measured height
+ ViewGroup.LayoutParams layoutParams = LayoutParameters;
+ if (layoutParams != null)
+ {
+ layoutParams.Height = MeasuredHeight;
+ }
+ }
+ }
+
public class RecentFilesFragment : ListFragment
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
@@ -538,10 +575,7 @@ namespace keepass2android
{
base.OnActivityCreated(savedInstanceState);
Android.Util.Log.Debug("KP2A", "OnActCreated");
- ListView.ItemClick += (sender, args) =>
- {
- ((FileSelectActivity) Activity).OnListItemClick((ListView) sender, args.View, args.Position, args.Id);
- };
+
RefreshList();
RegisterForContextMenu(ListView);
diff --git a/src/keepass2android/fileselect/FileStorageSetupActivity.cs b/src/keepass2android/fileselect/FileStorageSetupActivity.cs
index ee180f66..5bb3936a 100644
--- a/src/keepass2android/fileselect/FileStorageSetupActivity.cs
+++ b/src/keepass2android/fileselect/FileStorageSetupActivity.cs
@@ -12,15 +12,16 @@ using Android.Views;
using Android.Widget;
using KeePassLib.Serialization;
using keepass2android.Io;
+using keepass2android;
namespace keepass2android.fileselect
{
- [Activity(Label = "@string/filestorage_setup_title", Theme = "@style/MyTheme_ActionBar", ConfigurationChanges = ConfigChanges.Orientation |
+ [Activity(Label = "@string/filestorage_setup_title", Theme = "@style/Kp2aTheme_ActionBar", ConfigurationChanges = ConfigChanges.Orientation |
ConfigChanges.KeyboardHidden)]
public class FileStorageSetupActivity : Activity, IFileStorageSetupActivity
#if !EXCLUDE_JAVAFILESTORAGE
#if !NoNet
- ,Keepass2android.Javafilestorage.IJavaFileStorageFileStorageSetupActivity
+ ,Keepass2android.Javafilestorage.IJavaFileStorage.IFileStorageSetupActivity
#endif
#endif
{
diff --git a/src/keepass2android/fileselect/FileStorageSetupInitiatorActivity.cs b/src/keepass2android/fileselect/FileStorageSetupInitiatorActivity.cs
index ef08fe73..c2281796 100644
--- a/src/keepass2android/fileselect/FileStorageSetupInitiatorActivity.cs
+++ b/src/keepass2android/fileselect/FileStorageSetupInitiatorActivity.cs
@@ -11,7 +11,7 @@ namespace keepass2android
#if !EXCLUDE_JAVAFILESTORAGE
Java.Lang.Object
#if !NoNet
- ,Keepass2android.Javafilestorage.IJavaFileStorageFileStorageSetupInitiatorActivity
+ ,Keepass2android.Javafilestorage.IJavaFileStorage.IFileStorageSetupInitiatorActivity
#endif
,
#endif
diff --git a/src/keepass2android/icons/DrawableFactory.cs b/src/keepass2android/icons/DrawableFactory.cs
index 15d8471a..9b2ba999 100644
--- a/src/keepass2android/icons/DrawableFactory.cs
+++ b/src/keepass2android/icons/DrawableFactory.cs
@@ -26,6 +26,7 @@ using Android.Content.Res;
using KeePassLib;
using Android.Graphics;
using Android.Preferences;
+using keepass2android;
namespace keepass2android
{
diff --git a/src/keepass2android/keepass2android-app.csproj b/src/keepass2android/keepass2android-app.csproj
index a2293da7..0190d54f 100644
--- a/src/keepass2android/keepass2android-app.csproj
+++ b/src/keepass2android/keepass2android-app.csproj
@@ -1,838 +1,722 @@
-
-
-
-
-
-
-
+
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {D4C32E0A-0193-4496-9DB4-02CC126FD9F3}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- {84dd83c5-0fe3-4294-9419-09e7c8ba324f}
- Library
- Properties
+ net8.0-android
+ 21
keepass2android
- keepass2anrdoid-setup2
- 512
- True
- True
- Resources\Resource.designer.cs
- Resource
- Off
- false
- v13.0
- Properties\AndroidManifest_debug.xml
- Resources
- Assets
- true
- true
- Xamarin.Android.Net.AndroidClientHandler
- $(Flavor)
+ Exe
+ enable
+ enable
+ keepass2android.keepass2android
+ 1
+ 1.0
+ true
-
- True
- portable
- False
- bin\Debug\
- DEBUG;TRACE;INCLUDE_KEYTRANSFORM
- prompt
- 4
- True
- SdkOnly
- true
- false
- false
- false
- false
- false
- true
- d8
-
- 2G
-
-
-
-
- false
- portable
- True
- bin\Release\
- RELEASE
- prompt
- 4
- true
- False
- SdkOnly
- True
- false
- false
- false
- false
-
-
-
-
- Properties\AndroidManifest_net.xml
-
-
-
-
- Properties\AndroidManifest_nonet.xml
- $(DefineConstants);NoNet;EXCLUDE_JAVAFILESTORAGE
-
-
-
-
-
- 13.0.1
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- 1.5.0
-
-
- 1.1.0.9
-
-
- 1.1.1.11
-
-
- 1.2.1.3
-
-
- 0.11.4
-
-
- 3.1.0-beta2
-
-
- 3.1.0-beta2
-
-
-
-
-
-
-
-
- 1.1.0.3-beta01
-
-
-
-
-
- 117.0.0.4
-
-
- 1.3.50.1
-
-
- 1.3.50.1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ..\packages\Xamarin.Kotlin.StdLib.1.3.50.1\lib\monoandroid90\Xamarin.Kotlin.StdLib.dll
-
-
- ..\packages\Xamarin.Kotlin.StdLib.Common.1.3.50.1\lib\monoandroid90\Xamarin.Kotlin.StdLib.Common.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Designer
-
-
-
-
-
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- AndroidResource
-
-
- Designer
-
-
- AndroidResource
-
-
- AndroidResource
-
-
- AndroidResource
-
-
- AndroidResource
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Designer
-
-
-
- Designer
-
-
- Designer
-
-
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
- Designer
-
-
-
-
-
-
- Designer
-
-
-
- Designer
-
-
- Designer
-
-
+
Designer
+ MSBuild:UpdateGeneratedFiles
@@ -843,1170 +727,54 @@
-
- Designer
-
+
-
- Designer
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
-
-
-
- Designer
-
-
-
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
-
-
-
- Designer
-
-
-
-
-
-
-
-
-
-
- Designer
-
-
-
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Designer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Designer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Designer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Designer
-
-
-
-
- Designer
-
-
-
-
-
-
-
+
+ AndroidResource
+
+
+ AndroidResource
+
+
+ AndroidResource
+
+
+ AndroidResource
+
+
AndroidResource
- MSBuild:UpdateGeneratedFiles
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1.1.0.6
-
-
- 1.0.0
-
-
- 119.2.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
- 28.0.0.3
-
-
-
-
-
- {48574278-4779-4b3a-a9e4-9cf1bc285d0b}
- JavaFileStorageBindings
-
-
- {2db80c77-d46f-4970-b967-e9ffa9b2ac2e}
- PCloudBindings
-
-
-
-
- {3c0f7fe5-639f-4422-a087-8b26cf862d1b}
- AndroidFileChooserBinding
-
-
- {545b4a6b-8bba-4fbe-92fc-4ac060122a54}
- KeePassLib2Android
-
-
- {39b12571-bafe-4d3a-aee2-4d74f14dfd96}
- Kp2aAutofillParser
-
-
- {53a9cb7f-6553-4bc0-b56b-9410bb2e59aa}
- Kp2aBusinessLogic
-
-
- {70d3844a-d9fa-4a64-b205-a84c6a822196}
- KP2AKdbLibraryBinding
-
-
- {a8779d4d-7c49-4c2f-82bd-2cdc448391da}
- Kp2aKeyboardBinding
-
-
- {3da3911e-36de-465e-8f15-f1991b6437e5}
- PluginSdkBinding
-
-
- {5cf675a5-9bee-4720-bed9-d5bf14a2ebf9}
- TwofishCipher
-
-
- {6c29a7e7-e016-4fc1-b1a0-dee26ac711bb}
- ZlibAndroid
-
-
-
-
- MSBuild:UpdateGeneratedFiles
- Designer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/keepass2android/password/PasswordGenerator.cs b/src/keepass2android/password/PasswordGenerator.cs
index 126d14da..730aae9b 100644
--- a/src/keepass2android/password/PasswordGenerator.cs
+++ b/src/keepass2android/password/PasswordGenerator.cs
@@ -1,4 +1,4 @@
-/*
+/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
@@ -51,7 +51,7 @@ namespace keepass2android
private const String UnderlineChars = "_";
private const String SpaceChars = " ";
private const String SpecialChars = "!\"#$%&'*+,./:;=?@\\^`";
- private const String ExtendedChars = "";
+ private const String ExtendedChars = "§©®¢°±¹²³¼½×÷«âéïñù¡¿»¦Ø";
private const String BracketChars = "[]{}()<>";
private readonly Context _cxt;
diff --git a/src/keepass2android/pluginhost/PluginArrayAdapter.cs b/src/keepass2android/pluginhost/PluginArrayAdapter.cs
index 091ecdc1..a27bd65a 100644
--- a/src/keepass2android/pluginhost/PluginArrayAdapter.cs
+++ b/src/keepass2android/pluginhost/PluginArrayAdapter.cs
@@ -8,6 +8,7 @@ using Android.Views;
using System.Collections.Generic;
using Android.App;
using Android.Runtime;
+using keepass2android;
namespace keepass2android
{
diff --git a/src/keepass2android/pluginhost/PluginDetailsActivity.cs b/src/keepass2android/pluginhost/PluginDetailsActivity.cs
index 4319c4f0..f5724683 100644
--- a/src/keepass2android/pluginhost/PluginDetailsActivity.cs
+++ b/src/keepass2android/pluginhost/PluginDetailsActivity.cs
@@ -16,6 +16,7 @@ using Android.Widget;
using Java.Util;
using Keepass2android.Pluginsdk;
using keepass2android.views;
+using keepass2android;
namespace keepass2android
{
diff --git a/src/keepass2android/pluginhost/PluginListActivity.cs b/src/keepass2android/pluginhost/PluginListActivity.cs
index a5e6f711..7e55b9f6 100644
--- a/src/keepass2android/pluginhost/PluginListActivity.cs
+++ b/src/keepass2android/pluginhost/PluginListActivity.cs
@@ -6,6 +6,7 @@ using Android.Content.PM;
using Android.OS;
using Android.Widget;
using Keepass2android.Pluginsdk;
+using keepass2android;
namespace keepass2android
{
diff --git a/src/keepass2android/search/SearchActivity.cs b/src/keepass2android/search/SearchActivity.cs
index fa5699f1..0eb66f53 100644
--- a/src/keepass2android/search/SearchActivity.cs
+++ b/src/keepass2android/search/SearchActivity.cs
@@ -23,13 +23,14 @@ using Android.OS;
using Android.Widget;
using KeePassLib;
using keepass2android.search;
+using keepass2android;
namespace keepass2android
{
///
/// Activity to display search options
///
- [Activity(Label = "@string/app_name", Theme = "@style/MyTheme_ActionBar", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden)]
+ [Activity(Label = "@string/app_name", Theme = "@style/Kp2aTheme_ActionBar", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden)]
public class SearchActivity : LockCloseActivity
{
bool GetCheckBoxValue(int resId)
diff --git a/src/keepass2android/search/SearchProvider.cs b/src/keepass2android/search/SearchProvider.cs
index bcb782c2..3142ff29 100644
--- a/src/keepass2android/search/SearchProvider.cs
+++ b/src/keepass2android/search/SearchProvider.cs
@@ -31,6 +31,7 @@ using KeePassLib.Utility;
using System.Threading;
using System.Collections.Generic;
using KeePass.Util.Spr;
+using keepass2android;
namespace keepass2android.search
{
diff --git a/src/keepass2android/search/SearchResults.cs b/src/keepass2android/search/SearchResults.cs
index baacadf6..b465a08d 100644
--- a/src/keepass2android/search/SearchResults.cs
+++ b/src/keepass2android/search/SearchResults.cs
@@ -24,6 +24,7 @@ using Android.Preferences;
using Android.Views;
using Android.Widget;
using keepass2android.view;
+using keepass2android;
using KeePassLib;
namespace keepass2android.search
@@ -31,7 +32,7 @@ namespace keepass2android.search
///
/// Activity to show search results
///
- [Activity(Label = "@string/app_name", Theme = "@style/MyTheme_ActionBar", LaunchMode = Android.Content.PM.LaunchMode.SingleTop, Permission="keepass2android."+AppNames.PackagePart+".permission.KP2aInternalSearch", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden, Exported = true)]
+ [Activity(Label = "@string/app_name", Theme = "@style/Kp2aTheme_ActionBar", LaunchMode = Android.Content.PM.LaunchMode.SingleTop, Permission="keepass2android."+AppNames.PackagePart+".permission.KP2aInternalSearch", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden, Exported = true)]
#if NoNet
[MetaData("android.app.searchable", Resource = "@xml/searchable_offline")]
#else
diff --git a/src/keepass2android/search/SearchTotpResults.cs b/src/keepass2android/search/SearchTotpResults.cs
index 59395782..47609fe9 100644
--- a/src/keepass2android/search/SearchTotpResults.cs
+++ b/src/keepass2android/search/SearchTotpResults.cs
@@ -25,6 +25,7 @@ using Android.Preferences;
using Android.Views;
using Android.Widget;
using keepass2android.view;
+using keepass2android;
using KeePassLib;
namespace keepass2android.search
@@ -32,7 +33,7 @@ namespace keepass2android.search
///
/// Activity to show search results
///
- [Activity(Label = "@string/app_name", Theme = "@style/MyTheme_ActionBar", LaunchMode = Android.Content.PM.LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden)]
+ [Activity(Label = "@string/app_name", Theme = "@style/Kp2aTheme_ActionBar", LaunchMode = Android.Content.PM.LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden)]
public class SearchTotpResults : GroupBaseActivity
{
diff --git a/src/keepass2android/services/AutofillBase/AutofillHelper.cs b/src/keepass2android/services/AutofillBase/AutofillHelper.cs
index 28328862..96dbabf7 100644
--- a/src/keepass2android/services/AutofillBase/AutofillHelper.cs
+++ b/src/keepass2android/services/AutofillBase/AutofillHelper.cs
@@ -12,6 +12,7 @@ using Android.Widget;
using Android.Widget.Inline;
using AndroidX.AutoFill.Inline;
using AndroidX.AutoFill.Inline.V1;
+using keepass2android;
using Kp2aAutofillParser;
namespace keepass2android.services.AutofillBase
diff --git a/src/keepass2android/services/AutofillBase/AutofillServiceBase.cs b/src/keepass2android/services/AutofillBase/AutofillServiceBase.cs
index fd1e9368..e153b293 100644
--- a/src/keepass2android/services/AutofillBase/AutofillServiceBase.cs
+++ b/src/keepass2android/services/AutofillBase/AutofillServiceBase.cs
@@ -20,6 +20,7 @@ using AndroidX.AutoFill.Inline;
using AndroidX.AutoFill.Inline.V1;
using Java.Util.Concurrent.Atomic;
using keepass2android.services.AutofillBase.model;
+using keepass2android;
using KeePassLib;
using Kp2aAutofillParser;
@@ -399,12 +400,12 @@ namespace keepass2android.services.AutofillBase
string text = GetString(isForDisable ? Resource.String.autofill_disable : Resource.String.autofill_enable_for, new Java.Lang.Object[] { GetDisplayNameForQuery(query, this) });
RemoteViews presentation = AutofillHelper.NewRemoteViews(base.PackageName,
- text, Resource.Drawable.ic_menu_close_grey);
+ text, Resource.Drawable.baseline_close_24);
var datasetBuilder = new Dataset.Builder(presentation);
datasetBuilder.SetAuthentication(pendingIntent?.IntentSender);
- AutofillHelper.AddInlinePresentation(this, inlinePresentationSpec, text, datasetBuilder, Resource.Drawable.ic_menu_close_grey, null);
+ AutofillHelper.AddInlinePresentation(this, inlinePresentationSpec, text, datasetBuilder, Resource.Drawable.baseline_close_24, null);
foreach (var autofillId in autofillIds)
{
diff --git a/src/keepass2android/services/AutofillBase/ChooseForAutofillActivityBase.cs b/src/keepass2android/services/AutofillBase/ChooseForAutofillActivityBase.cs
index 133ffaa9..c3a52769 100644
--- a/src/keepass2android/services/AutofillBase/ChooseForAutofillActivityBase.cs
+++ b/src/keepass2android/services/AutofillBase/ChooseForAutofillActivityBase.cs
@@ -4,7 +4,6 @@ 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;
@@ -12,10 +11,9 @@ using Java.Util;
using keepass2android.services.AutofillBase.model;
using System.Linq;
using Android.Content.PM;
+using Google.Android.Material.Dialog;
+using keepass2android;
using Kp2aAutofillParser;
-#if !NoNet
-using Com.Dropbox.Core.V2.Teamlog;
-#endif
using AlertDialog = Android.App.AlertDialog;
namespace keepass2android.services.AutofillBase
@@ -67,7 +65,7 @@ namespace keepass2android.services.AutofillBase
Kp2aLog.Log("ChooseForAutofillActivityBase: ExtraDisplayWarning = " + warning);
if (warning != AutofillServiceBase.DisplayWarning.None)
{
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
builder.SetTitle(this.GetString(Resource.String.AutofillWarning_title));
string appName = Intent.GetStringExtra(ExtraQueryPackageString);
diff --git a/src/keepass2android/services/AutofillBase/Kp2aDigitalAssetLinksDataSource.cs b/src/keepass2android/services/AutofillBase/Kp2aDigitalAssetLinksDataSource.cs
index 14fa2367..48a985b4 100644
--- a/src/keepass2android/services/AutofillBase/Kp2aDigitalAssetLinksDataSource.cs
+++ b/src/keepass2android/services/AutofillBase/Kp2aDigitalAssetLinksDataSource.cs
@@ -2,6 +2,7 @@
using System.Linq;
using Android.Content;
using Android.Preferences;
+using keepass2android;
using Kp2aAutofillParser;
namespace keepass2android.services.AutofillBase
@@ -70,7 +71,7 @@ namespace keepass2android.services.AutofillBase
static readonly HashSet _trustedBrowsers = new HashSet
{
"org.mozilla.firefox","org.mozilla.firefox_beta","org.mozilla.klar","org.mozilla.focus",
- "org.mozilla.fenix","org.mozilla.fenix.nightly","org.mozilla.reference.browser",
+ "org.mozilla.fenix","org.mozilla.reference.browser",
"com.android.browser","com.android.chrome","com.chrome.beta","com.chrome.dev","com.chrome.canary",
"com.google.android.apps.chrome","com.google.android.apps.chrome_dev",
"com.opera.browser","com.opera.browser.beta","com.opera.mini.native","com.opera.mini.native.beta","com.opera.touch",
diff --git a/src/keepass2android/services/AutofillBase/StructureParser.cs b/src/keepass2android/services/AutofillBase/StructureParser.cs
index 5fb6227a..09aa9ac0 100644
--- a/src/keepass2android/services/AutofillBase/StructureParser.cs
+++ b/src/keepass2android/services/AutofillBase/StructureParser.cs
@@ -6,6 +6,7 @@ using Android.Content;
using Android.Preferences;
using Android.Views.Autofill;
using DomainNameParser;
+using keepass2android;
using Kp2aAutofillParser;
using Newtonsoft.Json;
diff --git a/src/keepass2android/services/CopyToClipboardService.cs b/src/keepass2android/services/CopyToClipboardService.cs
index 34d040f2..fff79c56 100644
--- a/src/keepass2android/services/CopyToClipboardService.cs
+++ b/src/keepass2android/services/CopyToClipboardService.cs
@@ -19,7 +19,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Android.AccessibilityServices;
-using Android.Support.V4.App;
+
using Java.Util;
using Android.App;
@@ -34,7 +34,9 @@ using Android.Views.Accessibility;
using KeePassLib;
using KeePassLib.Utility;
using Android.Views.InputMethods;
+using AndroidX.Core.App;
using KeePass.Util.Spr;
+using keepass2android;
using KeePassLib.Serialization;
using PluginTOTP;
@@ -128,15 +130,15 @@ namespace keepass2android
//add action buttons to base notification:
if (_hasUsername)
- notificationBuilder.AddAction(new NotificationCompat.Action(Resource.Drawable.ic_action_username,
+ notificationBuilder.AddAction(new NotificationCompat.Action(Resource.Drawable.baseline_account_circle_24,
_ctx.GetString(Resource.String.menu_copy_user),
GetPendingIntent(Intents.CopyUsername, Resource.String.menu_copy_user)));
if (_hasPassword)
- notificationBuilder.AddAction(new NotificationCompat.Action(Resource.Drawable.ic_action_password,
+ notificationBuilder.AddAction(new NotificationCompat.Action(Resource.Drawable.baseline_vpn_key_24,
_ctx.GetString(Resource.String.menu_copy_pass),
GetPendingIntent(Intents.CopyPassword, Resource.String.menu_copy_pass)));
if (_hasTotp)
- notificationBuilder.AddAction(new NotificationCompat.Action(Resource.Drawable.ic_action_password,
+ notificationBuilder.AddAction(new NotificationCompat.Action(Resource.Drawable.baseline_vpn_key_24,
_ctx.GetString(Resource.String.menu_copy_totp),
GetPendingIntent(Intents.CopyTotp, Resource.String.menu_copy_totp)));
@@ -161,7 +163,7 @@ namespace keepass2android
{
// only show notification if password is available
Notification password = GetNotification(Intents.CopyPassword, Resource.String.copy_password,
- Resource.Drawable.ic_action_password, entryName, entryIcon);
+ Resource.Drawable.baseline_vpn_key_24, entryName, entryIcon);
numNotifications++;
password.DeleteIntent = CreateDeleteIntent(NotifyPassword);
_notificationManager.Notify(NotifyPassword, password);
@@ -170,7 +172,7 @@ namespace keepass2android
{
// only show notification if username is available
Notification username = GetNotification(Intents.CopyUsername, Resource.String.copy_username,
- Resource.Drawable.ic_action_username, entryName, entryIcon);
+ Resource.Drawable.baseline_account_circle_24, entryName, entryIcon);
username.DeleteIntent = CreateDeleteIntent(NotifyUsername);
_notificationManager.Notify(NotifyUsername, username);
numNotifications++;
@@ -179,7 +181,7 @@ namespace keepass2android
{
// only show notification if totp is available
Notification totp = GetNotification(Intents.CopyTotp, Resource.String.copy_totp,
- Resource.Drawable.ic_action_password, entryName, entryIcon);
+ Resource.Drawable.baseline_vpn_key_24, entryName, entryIcon);
totp.DeleteIntent = CreateDeleteIntent(NotifyTotp);
_notificationManager.Notify(NotifyTotp, totp);
numNotifications++;
@@ -320,7 +322,7 @@ namespace keepass2android
_stopOnLockBroadcastReceiver = new StopOnLockBroadcastReceiver(this);
IntentFilter filter = new IntentFilter();
filter.AddAction(Intents.DatabaseLocked);
- RegisterReceiver(_stopOnLockBroadcastReceiver, filter);
+ RegisterReceiver(_stopOnLockBroadcastReceiver, filter, ReceiverFlags.Exported);
}
if ((intent.Action == Intents.ShowNotification) || (intent.Action == Intents.UpdateKeyboard))
@@ -527,7 +529,7 @@ namespace keepass2android
_notificationDeletedBroadcastReceiver = new NotificationDeletedBroadcastReceiver(this);
IntentFilter deletefilter = new IntentFilter();
deletefilter.AddAction(ActionNotificationCancelled);
- RegisterReceiver(_notificationDeletedBroadcastReceiver, deletefilter);
+ RegisterReceiver(_notificationDeletedBroadcastReceiver, deletefilter, ReceiverFlags.Exported);
}
}
@@ -641,7 +643,7 @@ namespace keepass2android
#endif
}
- private readonly Timer _timer = new Timer();
+ private readonly Java.Util.Timer _timer = new Java.Util.Timer();
internal void TimeoutCopyToClipboard(String text, bool isProtected)
{
diff --git a/src/keepass2android/services/Kp2aAutofill/ChooseForAutofillActivity.cs b/src/keepass2android/services/Kp2aAutofill/ChooseForAutofillActivity.cs
index 65cce2c6..5b159136 100644
--- a/src/keepass2android/services/Kp2aAutofill/ChooseForAutofillActivity.cs
+++ b/src/keepass2android/services/Kp2aAutofill/ChooseForAutofillActivity.cs
@@ -15,6 +15,7 @@ using KeePass.Util.Spr;
using keepass2android.services.AutofillBase;
using keepass2android.services.AutofillBase.model;
using Keepass2android.Pluginsdk;
+using keepass2android;
using KeePassLib;
using KeePassLib.Utility;
using Kp2aAutofillParser;
@@ -23,7 +24,7 @@ namespace keepass2android.services.Kp2aAutofill
{
[Activity(Label = "@string/app_name",
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
- Theme = "@style/MyTheme_ActionBar",
+ Theme = "@style/Kp2aTheme_ActionBar",
WindowSoftInputMode = SoftInput.AdjustResize,
Permission = "keepass2android." + AppNames.PackagePart + ".permission.Kp2aChooseAutofill")]
public class ChooseForAutofillActivity : ChooseForAutofillActivityBase
diff --git a/src/keepass2android/services/Kp2aAutofill/Kp2aAutofillService.cs b/src/keepass2android/services/Kp2aAutofill/Kp2aAutofillService.cs
index 05914c20..614f8ebb 100644
--- a/src/keepass2android/services/Kp2aAutofill/Kp2aAutofillService.cs
+++ b/src/keepass2android/services/Kp2aAutofill/Kp2aAutofillService.cs
@@ -50,7 +50,7 @@ namespace keepass2android.services
int numDisableDatasets = 0;
if (!PreferenceManager.GetDefaultSharedPreferences(this)
- .GetBoolean(GetString(Resource.String.NoAutofillDisabling_key), false))
+ .GetBoolean(GetString(keepass2android.Resource.String.NoAutofillDisabling_key), false))
numDisableDatasets = 1;
//it seems like at least with Firefox we can have at most 3 datasets. Reserve space for the disable dataset and the "fill with KP2A" which allows to select another item
diff --git a/src/keepass2android/services/OngoingNotificationsService.cs b/src/keepass2android/services/OngoingNotificationsService.cs
index 02259077..4dbb0e33 100644
--- a/src/keepass2android/services/OngoingNotificationsService.cs
+++ b/src/keepass2android/services/OngoingNotificationsService.cs
@@ -18,10 +18,12 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
using System;
using Android.App;
using Android.Content;
+using Android.Content.PM;
using Android.Graphics;
using Android.OS;
using Android.Preferences;
-using Android.Support.V4.App;
+using AndroidX.Core.App;
+using keepass2android;
using KeePassLib.Utility;
namespace keepass2android
@@ -36,7 +38,9 @@ namespace keepass2android
/// used by the user. This ensures the database is kept in memory (until Android kills it due to low memory).
/// It is important to also have a foreground service also for the "unlocked" state because it's really
/// irritating if the db is closed while switching between apps.
- [Service]
+ [Service(ForegroundServiceType = ForegroundService.TypeSpecialUse )]
+ [MetaData("android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE", Value = " This service is running as foreground service to keep the app alive even when it's not currently used by the user. This ensures the database is kept in memory (until Android kills it due to low memory). It is important to also have a foreground service also for the \"unlocked\" state because it's really irritating if the db is closed while switching between apps.")]
+
public class OngoingNotificationsService : Service
{
protected override void AttachBaseContext(Context baseContext)
@@ -56,7 +60,7 @@ namespace keepass2android
_screenOffReceiver = new ScreenOffReceiver();
IntentFilter filter = new IntentFilter();
filter.AddAction(Intent.ActionScreenOff);
- RegisterReceiver(_screenOffReceiver, filter);
+ RegisterReceiver(_screenOffReceiver, filter, ReceiverFlags.Exported);
}
@@ -172,7 +176,7 @@ namespace keepass2android
// Default action is to show Kp2A
builder.SetContentIntent(GetSwitchToAppPendingIntent());
// Additional action to allow locking the database
- builder.AddAction(Android.Resource.Drawable.IcLockLock, GetString(Resource.String.QuickUnlock_lockButton),
+ builder.AddAction(Resource.Drawable.baseline_lock_24, GetString(Resource.String.QuickUnlock_lockButton),
PendingIntent.GetBroadcast(this, 0, new Intent(this, typeof(ApplicationBroadcastReceiver)).SetAction(Intents.CloseDatabase), Util.AddMutabilityFlag(PendingIntentFlags.UpdateCurrent, PendingIntentFlags.Immutable)));
@@ -216,7 +220,7 @@ namespace keepass2android
// Default action is to show Kp2A
builder.SetContentIntent(GetSwitchToAppPendingIntent());
// Additional action to allow locking the database
- builder.AddAction(Resource.Drawable.ic_action_lock, GetString(Resource.String.menu_lock), PendingIntent.GetBroadcast(this, 0, new Intent(this, typeof(ApplicationBroadcastReceiver)).SetAction(Intents.LockDatabase), Util.AddMutabilityFlag(PendingIntentFlags.UpdateCurrent, PendingIntentFlags.Immutable)));
+ builder.AddAction(Resource.Drawable.baseline_lock_24, GetString(Resource.String.menu_lock), PendingIntent.GetBroadcast(this, 0, new Intent(this, typeof(ApplicationBroadcastReceiver)).SetAction(Intents.LockDatabase), Util.AddMutabilityFlag(PendingIntentFlags.UpdateCurrent, PendingIntentFlags.Immutable)));
return builder.Build();
}
diff --git a/src/keepass2android/settings/AppSettingsActivity.cs b/src/keepass2android/settings/AppSettingsActivity.cs
index dbed5075..d6a790d6 100644
--- a/src/keepass2android/settings/AppSettingsActivity.cs
+++ b/src/keepass2android/settings/AppSettingsActivity.cs
@@ -24,99 +24,1216 @@ using Android.Content.PM;
using Android.Content.Res;
using Android.Graphics.Drawables;
using Android.OS;
-using Android.Preferences;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
+using AndroidX.AppCompat.App;
+using AndroidX.Preference;
+
using keepass2android.Io;
+using keepass2android.settings;
+using keepass2android;
+using KeePassLib.Cryptography.KeyDerivation;
+using KeePassLib.Utility;
+using KeePassLib;
+using static Android.Icu.Text.CaseMap;
using Object = Java.Lang.Object;
-using Toolbar = Android.Support.V7.Widget.Toolbar;
+using Preference = AndroidX.Preference.Preference;
+using PreferenceFragment = AndroidX.Preference.PreferenceFragment;
+using Toolbar = AndroidX.AppCompat.Widget.Toolbar;
+using Android.Views.Autofill;
+using Google.Android.Material.Dialog;
+using AlertDialog = AndroidX.AppCompat.App.AlertDialog;
+using String = System.String;
+using KeePassLib.Cryptography.Cipher;
+using keepass2android.Utils;
+using KeePassLib.Keys;
+using KeePassLib.Serialization;
+using FragmentManager = AndroidX.Fragment.App.FragmentManager;
namespace keepass2android
{
- public class ToolbarPreference : Preference
+ namespace settings
{
- #region constructors
- protected ToolbarPreference(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
+ #region preference fragments
+ public class PreferenceFragmentWithResource : PreferenceFragmentCompat
{
- }
+ private readonly int _resXml;
- public ToolbarPreference(Context context) : base(context)
- {
- }
-
- public ToolbarPreference(Context context, IAttributeSet attrs) : base(context, attrs)
- {
- }
-
- public ToolbarPreference(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
- {
- }
-
- public ToolbarPreference(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
- {
- }
-#endregion
-
- protected override View OnCreateView(ViewGroup parent)
- {
- parent.SetPadding(0, 0, 0, 0);
-
- LayoutInflater inflater = (LayoutInflater) Context.GetSystemService(Context.LayoutInflaterService);
- View layout = inflater.Inflate(Resource.Layout.toolbar, parent, false);
-
- Toolbar toolbar = (Toolbar) layout.FindViewById(Resource.Id.mytoolbar);
- toolbar.SetNavigationIcon(Resource.Drawable.ic_arrow_back_white_24dp);
- toolbar.Title = Title;
- toolbar.NavigationClick += (sender, args) =>
+ public PreferenceFragmentWithResource(int resXml)
{
- PreferenceScreen prefScreen = (PreferenceScreen) PreferenceManager.FindPreference(Key);
- if (prefScreen == null)
- throw new Exception("didn't find preference " + Key);
- prefScreen.Dialog.Dismiss();
- };
+ _resXml = resXml;
+ }
+ public override void OnCreatePreferences(Bundle savedInstanceState, string rootKey)
+ {
+ SetPreferencesFromResource(_resXml, rootKey);
+ }
- return layout;
+ public override void OnResume()
+ {
+ base.OnResume();
+ if (Activity != null && !string.IsNullOrEmpty(PreferenceScreen?.Title))
+ {
+ Activity.Title = PreferenceScreen?.Title;
+ }
+
+ }
+ }
+ public class MainPreferenceFragment : PreferenceFragmentWithResource
+ {
+ public MainPreferenceFragment() : base(Resource.Xml.preferences)
+ {
+ }
+
+ public override void OnCreate(Bundle? savedInstanceState)
+ {
+
+ base.OnCreate(savedInstanceState);
+ FindPreference(GetString(Resource.String.db_key)).Enabled = (App.Kp2a.CurrentDb != null);
+
+ }
+ }
+ public class SettingsFragmentDatabase : PreferenceFragmentWithResource
+ {
+ public SettingsFragmentDatabase() : base(Resource.Xml.pref_database)
+ {
+ }
+ private void PrepareDefaultUsername(Database db)
+ {
+ Preference defaultUser = FindPreference(GetString(Resource.String.default_username_key));
+ if (!db.DatabaseFormat.HasDefaultUsername)
+ {
+ ((PreferenceScreen)FindPreference(GetString(Resource.String.db_key))).RemovePreference(defaultUser);
+ }
+ else
+ {
+ defaultUser.Enabled = db.CanWrite;
+ //TODO test this
+ ((EditTextPreference)defaultUser).Text = db.KpDatabase.DefaultUserName;
+ defaultUser.PreferenceChange += (sender, e) =>
+ {
+ DateTime previousUsernameChanged = db.KpDatabase.DefaultUserNameChanged;
+ var previousUsername = db.KpDatabase.DefaultUserName;
+ db.KpDatabase.DefaultUserName = e.NewValue.ToString();
+
+ SaveDb save = new SaveDb(Activity, App.Kp2a, App.Kp2a.CurrentDb, new ActionOnFinish(Activity, (success, message, activity) =>
+ {
+ if (!success)
+ {
+ db.KpDatabase.DefaultUserName = previousUsername;
+ db.KpDatabase.DefaultUserNameChanged = previousUsernameChanged;
+ Toast.MakeText(activity, message, ToastLength.Long).Show();
+ }
+ }));
+ ProgressTask pt = new ProgressTask(App.Kp2a, Activity, save);
+ pt.Run();
+ };
+ }
+ }
+
+
+ private void PrepareTemplates(Database db)
+ {
+ Preference pref = FindPreference("AddTemplates_pref_key");
+ if ((!db.DatabaseFormat.SupportsTemplates) || (AddTemplateEntries.ContainsAllTemplates(App.Kp2a.CurrentDb)))
+ {
+ pref.Enabled = false;
+ }
+ else
+ {
+ pref.PreferenceClick += (sender, args) =>
+ {
+ ProgressTask pt = new ProgressTask(App.Kp2a, Activity,
+ new AddTemplateEntries(Activity, App.Kp2a, new ActionOnFinish(Activity,
+ delegate
+ {
+ pref.Enabled = false;
+ })));
+ pt.Run();
+ };
+ }
+
+ }
+
+ private void PrepareMasterPassword()
+ {
+ Preference changeMaster = FindPreference(GetString(Resource.String.master_pwd_key));
+ if (App.Kp2a.CurrentDb.CanWrite)
+ {
+ changeMaster.Enabled = true;
+ changeMaster.PreferenceClick += delegate { new SetPasswordDialog(Activity).Show(); };
+ }
+ }
+
+ private void PrepareDatabaseName(Database db)
+ {
+ Preference databaseName = FindPreference(GetString(Resource.String.database_name_key));
+ if (!db.DatabaseFormat.HasDatabaseName)
+ {
+ ((PreferenceScreen)FindPreference(GetString(Resource.String.db_key))).RemovePreference(databaseName);
+ }
+ else
+ {
+ databaseName.Enabled = db.CanWrite;
+ ((EditTextPreference)databaseName).Text = db.KpDatabase.Name;
+ databaseName.PreferenceChange += (sender, e) =>
+ {
+ DateTime previousNameChanged = db.KpDatabase.NameChanged;
+ String previousName = db.KpDatabase.Name;
+ db.KpDatabase.Name = e.NewValue.ToString();
+
+ SaveDb save = new SaveDb(Activity, App.Kp2a, App.Kp2a.CurrentDb, new ActionOnFinish(Activity, (success, message, activity) =>
+ {
+ if (!success)
+ {
+ db.KpDatabase.Name = previousName;
+ db.KpDatabase.NameChanged = previousNameChanged;
+ Toast.MakeText(activity, message, ToastLength.Long).Show();
+ }
+ else
+ {
+ // Name is reflected in notification, so update it
+ App.Kp2a.UpdateOngoingNotification();
+ }
+ }));
+ ProgressTask pt = new ProgressTask(App.Kp2a, Activity, save);
+ pt.Run();
+ };
+ }
+ }
+
+ private void UpdateImportDbPref()
+ {
+ //Import db/key file preferences:
+ Preference importDb = FindPreference("import_db_prefs");
+ bool isLocalOrContent =
+ App.Kp2a.CurrentDb.Ioc.IsLocalFile() || App.Kp2a.CurrentDb.Ioc.Path.StartsWith("content://");
+ if (!isLocalOrContent)
+ {
+ importDb.Summary = GetString(Resource.String.OnlyAvailableForLocalFiles);
+ importDb.Enabled = false;
+ }
+ else
+ {
+ if (IoUtil.IsInInternalDirectory(App.Kp2a.CurrentDb.Ioc.Path, Activity))
+ {
+ importDb.Summary = GetString(Resource.String.FileIsInInternalDirectory);
+ importDb.Enabled = false;
+ }
+ else
+ {
+ importDb.Enabled = true;
+ importDb.PreferenceClick += delegate { MoveDbToInternalFolder(); };
+ }
+ }
+ }
+
+ private void MoveDbToInternalFolder()
+ {
+ Func copyAndReturnPostExecute = () =>
+ {
+ try
+ {
+ var sourceIoc = App.Kp2a.CurrentDb.Ioc;
+ var newIoc = IoUtil.ImportFileToInternalDirectory(sourceIoc, Activity, App.Kp2a);
+ return () =>
+ {
+ var builder = new MaterialAlertDialogBuilder(Activity);
+ builder
+ .SetMessage(Resource.String.DatabaseFileMoved);
+ builder.SetPositiveButton(Android.Resource.String.Ok, (sender, args) =>
+ {
+ var key = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
+ App.Kp2a.CloseDatabase(App.Kp2a.CurrentDb);
+ PasswordActivity.Launch(Activity, newIoc, key, new ActivityLaunchModeSimple(), false);
+
+ });
+ builder.Show();
+
+ };
+
+
+
+
+ }
+ catch (System.Exception e)
+ {
+ return () =>
+ {
+ Toast.MakeText(Activity, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, ToastLength.Long).Show();
+ };
+ }
+
+
+
+ };
+
+ new SimpleLoadingDialog(Activity, GetString(Resource.String.CopyingFile), false,
+ copyAndReturnPostExecute
+ ).Execute();
+
+ }
+
+ private void UpdateImportKeyfilePref()
+ {
+ var prefs = PreferenceManager.GetDefaultSharedPreferences(Activity);
+ var rememberKeyfile = prefs.GetBoolean(GetString(Resource.String.keyfile_key), Resources.GetBoolean(Resource.Boolean.keyfile_default));
+
+ Preference importKeyfile = FindPreference("import_keyfile_prefs");
+ Preference exportKeyfile = FindPreference("export_keyfile_prefs");
+ importKeyfile.Summary = "";
+
+ if (!rememberKeyfile)
+ {
+ importKeyfile.Summary = GetString(Resource.String.KeyfileMoveRequiresRememberKeyfile);
+ importKeyfile.Enabled = false;
+ exportKeyfile.Enabled = false;
+ return;
+ }
+ CompositeKey masterKey = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
+ if (masterKey.ContainsType(typeof(KcpKeyFile)))
+ {
+ IOConnectionInfo iocKeyfile = ((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).Ioc;
+ if (iocKeyfile.IsLocalFile() && IoUtil.IsInInternalDirectory(iocKeyfile.Path, Activity))
+ {
+ importKeyfile.Enabled = false;
+ exportKeyfile.Enabled = true;
+ exportKeyfile.PreferenceClick += (sender, args) => { ExportKeyfileFromInternalFolder(); };
+ importKeyfile.Summary = GetString(Resource.String.FileIsInInternalDirectory);
+ }
+ else
+ {
+ exportKeyfile.Enabled = false;
+ importKeyfile.Enabled = true;
+ importKeyfile.PreferenceClick += (sender, args) => { MoveKeyfileToInternalFolder(); };
+ }
+
+
+ }
+ else
+ {
+ exportKeyfile.Enabled = false;
+ importKeyfile.Enabled = false;
+ }
+ }
+
+
+
+ private void ExportKeyfileFromInternalFolder()
+ {
+ StartActivity(new Intent(Activity.ApplicationContext, typeof(ExportKeyfileActivity)));
+
+ }
+
+ private void MoveKeyfileToInternalFolder()
+ {
+ Func copyAndReturnPostExecute = () =>
+ {
+ try
+ {
+ CompositeKey masterKey = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
+ var sourceIoc = ((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).Ioc;
+ var newIoc = IoUtil.ImportFileToInternalDirectory(sourceIoc, Activity, App.Kp2a);
+ ((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).ResetIoc(newIoc);
+ var keyfileString = IOConnectionInfo.SerializeToString(newIoc);
+ App.Kp2a.StoreOpenedFileAsRecent(App.Kp2a.CurrentDb.Ioc, keyfileString, false);
+ return () =>
+ {
+ UpdateImportKeyfilePref();
+ var builder = new MaterialAlertDialogBuilder(Activity);
+ builder
+ .SetMessage(Resource.String.KeyfileMoved);
+ builder.SetPositiveButton(Android.Resource.String.Ok, (sender, args) => { });
+ builder.Show();
+
+ };
+
+
+
+
+ }
+ catch (System.Exception e)
+ {
+ return () =>
+ {
+ Toast.MakeText(Activity, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, ToastLength.Long).Show();
+ };
+ }
+
+
+
+ };
+
+ new SimpleLoadingDialog(Activity, GetString(Resource.String.CopyingFile), false,
+ copyAndReturnPostExecute
+ ).Execute();
+
+ }
+
+ public override void OnCreate(Bundle? savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+ var db = App.Kp2a.CurrentDb;
+ if (db != null)
+ {
+ PrepareDefaultUsername(App.Kp2a.CurrentDb);
+
+ PrepareDatabaseName(db);
+ PrepareMasterPassword();
+ PrepareTemplates(db);
+
+ PrepareEncryptionAlgorithm(db);
+
+ UpdateImportDbPref();
+ UpdateImportKeyfilePref();
+ }
+
+
+ }
+
+ private void PrepareEncryptionAlgorithm(Database db)
+ {
+ ListPreference algorithmPref = (ListPreference)FindPreference(GetString(Resource.String.algorithm_key));
+ algorithmPref.SetEntries(CipherPool.GlobalPool.Engines.Select(eng => eng.DisplayName).ToArray());
+ string[] algoValues = CipherPool.GlobalPool.Engines.Select(eng => eng.CipherUuid.ToHexString()).ToArray();
+ algorithmPref.SetEntryValues(algoValues);
+ algorithmPref.SetValueIndex(algoValues.Select((v, i) => new { kdf = v, index = i }).First(el => el.kdf == db.KpDatabase.DataCipherUuid.ToHexString()).index);
+ algorithmPref.PreferenceChange += AlgorithmPrefChange;
+ algorithmPref.Summary =
+ CipherPool.GlobalPool.GetCipher(App.Kp2a.CurrentDb.KpDatabase.DataCipherUuid).DisplayName;
+ }
+
+ private void AlgorithmPrefChange(object sender, Preference.PreferenceChangeEventArgs preferenceChangeEventArgs)
+ {
+ var db = App.Kp2a.CurrentDb;
+ var previousCipher = db.KpDatabase.DataCipherUuid;
+ db.KpDatabase.DataCipherUuid = new PwUuid(MemUtil.HexStringToByteArray((string)preferenceChangeEventArgs.NewValue));
+
+ SaveDb save = new SaveDb(Activity, App.Kp2a, App.Kp2a.CurrentDb, new ActionOnFinish(Activity, (success, message, activity) =>
+ {
+ if (!success)
+ {
+ db.KpDatabase.DataCipherUuid = previousCipher;
+ Toast.MakeText(activity, message, ToastLength.Long).Show();
+ return;
+ }
+ preferenceChangeEventArgs.Preference.Summary =
+ CipherPool.GlobalPool.GetCipher(db.KpDatabase.DataCipherUuid).DisplayName;
+ }));
+ ProgressTask pt = new ProgressTask(App.Kp2a, Activity, save);
+ pt.Run();
+ }
+
+
+ }
+ public class SettingsFragmentApp : PreferenceFragmentWithResource
+ {
+ public SettingsFragmentApp() : base(Resource.Xml.pref_app)
+ {
+ }
+ }
+ public class SecurityPreferenceFragment : PreferenceFragmentWithResource
+ {
+ public SecurityPreferenceFragment() : base(Resource.Xml.pref_app_security)
+ {
+ }
+
+ void OnRememberKeyFileHistoryChanged(object sender, Preference.PreferenceChangeEventArgs eventArgs)
+ {
+ if (!(bool)eventArgs.NewValue)
+ {
+ App.Kp2a.FileDbHelper.DeleteAllKeys();
+ }
+ }
+
+ public override void OnCreate(Bundle? savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+ FindPreference(GetString(Resource.String.keyfile_key)).PreferenceChange += OnRememberKeyFileHistoryChanged;
+
+
+ }
+ }
+ public class DisplayPreferenceFragment : PreferenceFragmentWithResource
+ {
+ public DisplayPreferenceFragment() : base(Resource.Xml.pref_app_display)
+ {
+ }
+
+
+
+ void OnShowUnlockedNotificationChanged(object sender, Preference.PreferenceChangeEventArgs eventArgs)
+ {
+ App.Kp2a.UpdateOngoingNotification();
+ }
+
+ private void PrepareNoDonationReminderPreference(Activity ctx, PreferenceScreen screen, Preference preference)
+ {
+ ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
+
+ if (!prefs.GetBoolean("DismissedDonateReminder", false))
+ {
+ screen.RemovePreference(preference);
+ }
+
+
+ }
+
+ public void PrepareNoDonatePreference(Context ctx, Preference preference)
+ {
+ ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
+
+ long usageCount = prefs.GetLong(ctx.GetString(Resource.String.UsageCount_key), 0);
+
+#if DEBUG
+ preference.Enabled = (usageCount > 1);
+#else
+ preference.Enabled = (usageCount > 50);
+#endif
+ preference.PreferenceChange += delegate (object sender, Preference.PreferenceChangeEventArgs args)
+ {
+ if ((bool)args.NewValue)
+ {
+ new MaterialAlertDialogBuilder(ctx)
+ .SetTitle(ctx.GetString(AppNames.AppNameResource))
+ .SetCancelable(false)
+ .SetPositiveButton(Android.Resource.String.Ok, delegate (object o, DialogClickEventArgs eventArgs)
+ {
+ Util.GotoDonateUrl(ctx);
+ ((Dialog)o).Dismiss();
+ })
+ .SetMessage(Resource.String.NoDonateOption_question)
+ .Create().Show();
+
+ }
+ };
+
+ }
+
+ public override void OnCreate(Bundle? savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+
+ var unlockedNotificationPref = FindPreference(GetString(Resource.String.ShowUnlockedNotification_key));
+ unlockedNotificationPref.PreferenceChange += OnShowUnlockedNotificationChanged;
+ if ((int)Build.VERSION.SdkInt >= 26)
+ {
+ //use system notification channels to control notification visibility
+ unlockedNotificationPref.Parent.RemovePreference(unlockedNotificationPref);
+ }
+ unlockedNotificationPref.PreferenceChange += (sender, args) => App.Kp2a.UpdateOngoingNotification();
+
+
+
+ HashSet supportedLocales = new HashSet() { "en", "af", "ar", "az", "be", "bg", "ca", "cs", "da", "de", "el", "es", "eu", "fa", "fi", "fr", "gl", "he", "hr", "hu", "id", "in", "it", "iw", "ja", "ko", "ml", "nb", "nl", "nn", "no", "pl", "pt", "ro", "ru", "si", "sk", "sl", "sr", "sv", "tr", "uk", "vi", "zh" };
+ var languagePref = (ListPreference)FindPreference(GetString(Resource.String.app_language_pref_key));
+ new AppLanguageManager(this, languagePref, supportedLocales);
+
+
+ PrepareNoDonatePreference(Activity, FindPreference(GetString(Resource.String.NoDonateOption_key)));
+ var displayPrefScreen = ((PreferenceScreen)FindPreference(GetString(Resource.String.display_prefs_key)));
+ PrepareNoDonationReminderPreference(Activity, displayPrefScreen, FindPreference(GetString(Resource.String.NoDonationReminder_key)));
+
+ FindPreference(GetString(Resource.String.design_key)).PreferenceChange += (sender, args) =>
+ {
+ //it would be nicer to recreate, but that - for some reason - causes GroupActivity to be twice on the backstack afterwards :-(
+ //So better finish here.
+ Activity.Finish();
+ };
+
+
+ displayPrefScreen.RemovePreference(unlockedNotificationPref);
+
+
+
+ FindPreference("IconSetKey").PreferenceChange += (sender, args) =>
+ {
+ if (App.Kp2a.CurrentDb != null)
+ App.Kp2a.CurrentDb.DrawableFactory.Clear();
+
+ };
+
+
+
+
+ }
+ }
+ public class QuickUnlockPreferenceFragment : PreferenceFragmentWithResource
+ {
+ public QuickUnlockPreferenceFragment() : base(Resource.Xml.pref_app_quick_unlock)
+ {
+ }
+
+ public override void OnCreate(Bundle? savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+ try
+ {
+ //depending on Android version, we offer to use a transparent icon for QuickUnlock or use the notification priority (since API level 16)
+ Preference hideQuickUnlockTranspIconPref = FindPreference(GetString(Resource.String.QuickUnlockIconHidden_key));
+ Preference hideQuickUnlockIconPref = FindPreference(GetString(Resource.String.QuickUnlockIconHidden16_key));
+ var quickUnlockScreen = ((PreferenceScreen)FindPreference(GetString(Resource.String.QuickUnlock_prefs_key)));
+ if ((int)Android.OS.Build.VERSION.SdkInt >= 26)
+ {
+ //use notification channels
+ quickUnlockScreen.RemovePreference(hideQuickUnlockTranspIconPref);
+ quickUnlockScreen.RemovePreference(hideQuickUnlockIconPref);
+ }
+ else if ((int)Android.OS.Build.VERSION.SdkInt >= 16)
+ {
+ quickUnlockScreen.RemovePreference(hideQuickUnlockTranspIconPref);
+
+ hideQuickUnlockIconPref.PreferenceChange += delegate { App.Kp2a.UpdateOngoingNotification(); };
+ }
+ else
+ {
+ //old version: only show transparent quickUnlock and no option to hide unlocked icon:
+ quickUnlockScreen.RemovePreference(hideQuickUnlockIconPref);
+ FindPreference(GetString(Resource.String.QuickUnlockIconHidden_key)).PreferenceChange +=
+ delegate { App.Kp2a.UpdateOngoingNotification(); };
+
+ }
+ }
+ catch (Exception ex)
+ {
+ Kp2aLog.LogUnexpectedError(ex);
+ }
+
+
+
+ }
+ }
+
+ public class FileHandlingPreferenceFragment : PreferenceFragmentWithResource
+ {
+ public FileHandlingPreferenceFragment() : base(Resource.Xml.pref_app_file_handling)
+ {
+ }
+ private void OnUseOfflineCacheChanged(object sender, Preference.PreferenceChangeEventArgs e)
+ {
+ if (!(bool)e.NewValue)
+ {
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(Activity);
+ builder.SetTitle(GetString(Resource.String.ClearOfflineCache_title));
+
+ builder.SetMessage(GetString(Resource.String.ClearOfflineCache_question));
+
+ builder.SetPositiveButton(App.Kp2a.GetResourceString(UiStringKey.yes), (o, args) =>
+ {
+ try
+ {
+ App.Kp2a.ClearOfflineCache();
+ }
+ catch (Exception ex)
+ {
+ Kp2aLog.LogUnexpectedError(ex);
+ Toast.MakeText(LocaleManager.LocalizedAppContext, ex.Message, ToastLength.Long).Show();
+ }
+ }
+ );
+
+ builder.SetNegativeButton(App.Kp2a.GetResourceString(UiStringKey.no), (o, args) =>
+ {
+ ((CheckBoxPreference)e.Preference).Checked = true;
+ }
+ );
+ builder.SetCancelable(false);
+ Dialog dialog = builder.Create();
+ dialog.Show();
+
+
+ }
+ }
+
+
+ public override void OnCreate(Bundle? savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+
+ Preference cachingPreference = FindPreference(GetString(Resource.String.UseOfflineCache_key));
+ cachingPreference.PreferenceChange += OnUseOfflineCacheChanged;
+
+
+
+ }
+ }
+
+ public class TotpPreferenceFragment : PreferenceFragmentWithResource
+ {
+ public TotpPreferenceFragment() : base(Resource.Xml.pref_app_traytotp)
+ {
+ }
+ }
+
+ public class DebugLogPreferenceFragment : PreferenceFragmentWithResource
+ {
+
+ public DebugLogPreferenceFragment() : base(Resource.Xml.pref_app_debug)
+ {
+ }
+
+ private void UpdateDependingPreferences(bool debugLogEnabled)
+ {
+
+ FindPreference(GetString(Resource.String.DebugLog_send_key)).Visible = debugLogEnabled;
+
+#if !EXCLUDE_JAVAFILESTORAGE && !NoNet
+ FindPreference(GetString(Resource.String.FtpDebug_key)).Visible = debugLogEnabled;
+#endif
+ }
+
+
+ private void OnSendDebug(object sender, Preference.PreferenceClickEventArgs e)
+ {
+ Kp2aLog.SendLog(this.Activity);
+ }
+
+ private void OnDebugLogChanged(object sender, Preference.PreferenceChangeEventArgs e)
+ {
+ if ((bool)e.NewValue)
+ Kp2aLog.CreateLogFile();
+ else
+ Kp2aLog.FinishLogFile();
+
+#if !EXCLUDE_JAVAFILESTORAGE && !NoNet
+ SetJSchLogging(PreferenceManager.GetDefaultSharedPreferences(Application.Context)
+ .GetBoolean(Application.Context.GetString(Resource.String.FtpDebug_key), false));
+#endif
+ UpdateDependingPreferences((bool)e.NewValue);
+ }
+
+#if !EXCLUDE_JAVAFILESTORAGE && !NoNet
+ private void OnJSchDebugChanged(object sender, Preference.PreferenceChangeEventArgs e)
+ {
+ bool debugEnabled = (bool)e.NewValue;
+ SetJSchLogging(debugEnabled);
+
+ string prefKey = Application.Context.GetString(Resource.String.FtpDebug_key);
+ PreferenceManager.SharedPreferences.Edit().PutBoolean(prefKey, debugEnabled).Apply();
+ }
+
+ private void SetJSchLogging(bool enabled)
+ {
+ var sftpStorage = new Keepass2android.Javafilestorage.SftpStorage(Context);
+ string? logFilename = null;
+ if (Kp2aLog.LogToFile)
+ {
+ logFilename = Kp2aLog.LogFilename;
+ }
+ sftpStorage.SetJschLogging(enabled, logFilename);
+ }
+
+#endif
+
+ public override void OnCreate(Bundle? savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+
+ FindPreference(GetString(Resource.String.DebugLog_key)).PreferenceChange += OnDebugLogChanged;
+ FindPreference(GetString(Resource.String.DebugLog_send_key)).PreferenceClick += OnSendDebug;
+
+#if !EXCLUDE_JAVAFILESTORAGE && !NoNet
+ FindPreference(GetString(Resource.String.FtpDebug_key)).PreferenceChange += OnJSchDebugChanged;
+#else
+ FindPreference(GetString(Resource.String.FtpDebug_key)).Enabled = false;
+#endif
+ bool debugLogEnabled = (PreferenceManager.GetDefaultSharedPreferences(Application.Context)
+ .GetBoolean(Application.Context.GetString(Resource.String.DebugLog_key), false));
+ UpdateDependingPreferences(debugLogEnabled);
+
+
+ }
+ }
+
+
+ public class KeyboardSwitchPreferenceFragment : PreferenceFragmentWithResource
+ {
+ public class KeyboardSwitchPrefManager
+ {
+ private readonly Activity _act;
+ private readonly CheckBoxPreference _switchPref;
+ private readonly CheckBoxPreference _openKp2aAutoPref;
+ private readonly CheckBoxPreference _openOnlyOnSearchPref;
+ private CheckBoxPreference _switchBackPref;
+ private readonly PreferenceScreen _screen;
+ private readonly PreferenceFragmentCompat _fragment;
+
+ public KeyboardSwitchPrefManager(PreferenceFragmentCompat fragment)
+ {
+ var act = fragment.Activity;
+ this._act = act;
+ this._fragment = fragment;
+ this._screen = (PreferenceScreen)_fragment.FindPreference(act.GetString(Resource.String.keyboardswitch_prefs_key));
+
+ var keyboardSwapPref = _fragment.FindPreference("get_keyboardswap");
+ var pm = act.PackageManager;
+ var intnt = Keepass2android.Kbbridge.ImeSwitcher.GetLaunchIntentForKeyboardSwap(act);
+ if ((intnt != null) && pm.QueryIntentActivities(intnt, 0).Any())
+ {
+ _screen.RemovePreference(keyboardSwapPref);
+ }
+ else
+ {
+ keyboardSwapPref.PreferenceClick += (sender, args) =>
+ {
+ Util.GotoUrl(act, act.GetString(Resource.String.MarketURL) + "keepass2android.plugin.keyboardswap2");
+ };
+ }
+
+ _switchPref = (CheckBoxPreference)_fragment.FindPreference("kp2a_switch_rooted");
+ _openKp2aAutoPref =
+ (CheckBoxPreference)_fragment.FindPreference(act.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key));
+ _openOnlyOnSearchPref =
+ (CheckBoxPreference)
+ _fragment.FindPreference(act.GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key));
+ _switchBackPref =
+ (CheckBoxPreference)_fragment.FindPreference(act.GetString(Resource.String.AutoSwitchBackKeyboard_key));
+
+ EnableSwitchPreferences(_switchPref.Checked);
+
+ _switchPref.PreferenceChange += (sender, args) =>
+ {
+ bool switchOnRooted = (bool)args.NewValue;
+ EnableSwitchPreferences(switchOnRooted);
+ };
+ }
+
+
+ private void EnableSwitchPreferences(bool switchOnRooted)
+ {
+ if (!switchOnRooted)
+ {
+ if (_fragment.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key)) == null)
+ {
+ _screen.AddPreference(_openKp2aAutoPref);
+ }
+ if (_fragment.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key)) != null)
+ {
+ _screen.RemovePreference(_openOnlyOnSearchPref);
+ }
+ }
+ else
+ {
+ {
+ _screen.RemovePreference(_openKp2aAutoPref);
+ }
+ if (_fragment.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key)) == null)
+ {
+ _screen.AddPreference(_openOnlyOnSearchPref);
+ }
+ }
+ /*_openKp2aAutoPref.Enabled = !switchOnRooted;
+
+ _openOnlyOnSearchPref.Enabled = switchOnRooted;
+
+ _switchBackPref.Enabled = switchOnRooted;*/
+ }
+ }
+ KeyboardSwitchPrefManager _manager;
+ public KeyboardSwitchPreferenceFragment() : base(Resource.Xml.pref_app_password_access_keyboard_switch)
+ {
+
+ }
+
+ public override void OnCreate(Bundle? savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+ _manager = new KeyboardSwitchPrefManager(this);
+ }
+ }
+ public class AutofillPreferenceFragment : PreferenceFragmentWithResource
+ {
+ public AutofillPreferenceFragment() : base(Resource.Xml.pref_app_password_access_autofill)
+ {
+ }
+
+ private void UpdateAutofillPref()
+ {
+ var autofillScreen = FindPreference(GetString(Resource.String.AutoFill_prefs_screen_key));
+ var autofillPref = FindPreference(GetString(Resource.String.AutoFill_prefs_key));
+ var autofillDisabledPref = FindPreference(GetString(Resource.String.AutofillDisabledQueriesPreference_key));
+ var autofillSavePref = FindPreference(GetString(Resource.String.OfferSaveCredentials_key));
+ var autofillInlineSuggestions = FindPreference(GetString(Resource.String.InlineSuggestions_key));
+ var noAutofillDisablingPref = FindPreference(GetString(Resource.String.NoAutofillDisabling_key));
+ var autofillNoDalVerification = FindPreference(GetString(Resource.String.NoDalVerification_key));
+ if (autofillPref == null)
+ return;
+ if ((Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.O) ||
+ !((AutofillManager)Activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager))))
+ .IsAutofillSupported)
+ {
+ var passwordAccessScreen =
+ (PreferenceScreen)FindPreference(Activity.GetString(Resource.String.password_access_prefs_key));
+ passwordAccessScreen.RemovePreference(autofillScreen);
+ }
+ else
+ {
+ if (((AutofillManager)Activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager))))
+ .HasEnabledAutofillServices)
+ {
+ autofillDisabledPref.Enabled = true;
+ autofillSavePref.Enabled = true;
+ autofillNoDalVerification.Enabled = true;
+ autofillInlineSuggestions.Enabled = true;
+ noAutofillDisablingPref.Enabled = true;
+ autofillPref.Summary = Activity.GetString(Resource.String.plugin_enabled);
+ autofillPref.Intent = new Intent(Intent.ActionView);
+ autofillPref.Intent.SetData(Android.Net.Uri.Parse("https://philippc.github.io/keepass2android/OreoAutoFill.html"));
+ }
+ else
+ {
+ autofillNoDalVerification.Enabled = false;
+ autofillDisabledPref.Enabled = false;
+ autofillSavePref.Enabled = false;
+ noAutofillDisablingPref.Enabled = false;
+ autofillInlineSuggestions.Enabled = false;
+ autofillPref.Summary = Activity.GetString(Resource.String.not_enabled);
+ }
+ if ((int)Android.OS.Build.VERSION.SdkInt < 30)
+ {
+ autofillInlineSuggestions.Summary = Activity.GetString(Resource.String.requires_android11);
+ CheckBoxPreference cbp = autofillInlineSuggestions as CheckBoxPreference;
+ if (cbp != null)
+ cbp.Checked = false;
+ autofillInlineSuggestions.Enabled = false;
+ }
+ }
+ }
+
+
+ public override void OnResume()
+ {
+ base.OnResume();
+
+ UpdateAutofillPref();
+ }
+
+ public override void OnCreate(Bundle? savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+
+ UpdateAutofillPref();
+
+ var autofillPref = FindPreference(GetString(Resource.String.AutoFill_prefs_key));
+ if (autofillPref != null)
+ {
+ autofillPref.PreferenceClick += (sender, args) =>
+ {
+
+ var intent = new Intent(Android.Provider.Settings.ActionRequestSetAutofillService);
+ if (((AutofillManager)Activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager))))
+ .HasEnabledAutofillServices)
+ {
+ intent.SetData(Android.Net.Uri.Parse("package:" + Context.PackageName + "notexisting")); //if we use our package name, the activity won't launch
+ }
+ else
+ {
+ intent.SetData(Android.Net.Uri.Parse("package:" + Context.PackageName));
+ }
+
+ try
+ {
+ Context.StartActivity(intent);
+ }
+ catch (ActivityNotFoundException e)
+ {
+ //this exception was reported by many Huawei users
+ Kp2aLog.LogUnexpectedError(e);
+ new MaterialAlertDialogBuilder(Context)
+ .SetTitle(Resource.String.autofill_enable)
+ .SetMessage(Resource.String.autofill_enable_failed)
+ .SetPositiveButton(Android.Resource.String.Ok, (o, eventArgs) => { })
+ .Show();
+
+ }
+ catch (System.Exception e)
+ {
+ Kp2aLog.LogUnexpectedError(e);
+ }
+ };
+ }
+
+
+
+
+ }
+ }
+
+ public class AutofillTotpPreferenceFragment : PreferenceFragmentWithResource
+ {
+ public AutofillTotpPreferenceFragment() : base(Resource.Xml.pref_app_password_access_autofill_totp)
+ {
+ }
+ }
+
+ public class PasswordAccessPreferenceFragment : PreferenceFragmentWithResource
+ {
+ public PasswordAccessPreferenceFragment() : base(Resource.Xml.pref_app_password_access)
+ {
+ }
+ }
+
+
+ public class KeyDerivFuncPreferenceFragment : PreferenceFragmentWithResource
+ {
+ private Preference aesRounds, argon2parallelism, argon2rounds, argon2memory;
+ public KeyDerivFuncPreferenceFragment() : base(Resource.Xml.pref_database_key_deriv_func)
+ {
+ }
+
+ public override void OnCreate(Bundle? savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+ aesRounds = FindPreference(GetString(Resource.String.rounds_key));
+ argon2rounds = FindPreference("argon2rounds");
+ argon2memory = FindPreference("argon2memory");
+ argon2parallelism = FindPreference("argon2parallelism");
+
+ aesRounds.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference);
+ argon2rounds.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference);
+ argon2memory.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference);
+ argon2parallelism.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference);
+
+ var db = App.Kp2a.CurrentDb;
+ if (db != null)
+ {
+ ListPreference kdfPref = (ListPreference)FindPreference(GetString(Resource.String.kdf_key));
+ kdfPref.SetEntries(KdfPool.Engines.Select(eng => eng.Name).ToArray());
+ string[] kdfValues = KdfPool.Engines.Select(eng => eng.Uuid.ToHexString()).ToArray();
+ kdfPref.SetEntryValues(kdfValues);
+ kdfPref.SetValueIndex(kdfValues.Select((v, i) => new { kdf = v, index = i }).First(el => el.kdf == db.KpDatabase.KdfParameters.KdfUuid.ToHexString()).index);
+ kdfPref.PreferenceChange += OnKdfChange;
+
+
+
+ UpdateKdfScreen();
+ }
+ }
+
+ public override void OnDisplayPreferenceDialog(Preference preference)
+ {
+ if (preference is KdfNumberDialogPreference dialogPreference)
+ {
+ dialogPreference.ShowDialog(this);
+ }
+ else
+ base.OnDisplayPreferenceDialog(preference);
+ }
+
+ private void UpdateKdfScreen()
+ {
+ var db = App.Kp2a.CurrentDb;
+ var kdf = KdfPool.Get(db.KpDatabase.KdfParameters.KdfUuid);
+
+ var kdfpref = FindPreference(GetString(Resource.String.kdf_key));
+
+
+ kdfpref.Summary = kdf.Name;
+
+ var kdfscreen = ((PreferenceScreen)FindPreference(GetString(Resource.String.kdf_screen_key)));
+ if (kdf is AesKdf)
+ {
+ if (kdfscreen.FindPreference(GetString(Resource.String.rounds_key)) == null)
+ kdfscreen.AddPreference(aesRounds);
+ kdfscreen.RemovePreference(argon2rounds);
+ kdfscreen.RemovePreference(argon2memory);
+ kdfscreen.RemovePreference(argon2parallelism);
+
+ aesRounds.Enabled = db.CanWrite;
+ UpdateKdfSummary(aesRounds);
+ }
+ else
+ {
+ kdfscreen.RemovePreference(aesRounds);
+ if (kdfscreen.FindPreference("argon2rounds") == null)
+ {
+ kdfscreen.AddPreference(argon2rounds);
+ kdfscreen.AddPreference(argon2memory);
+ kdfscreen.AddPreference(argon2parallelism);
+ }
+ UpdateKdfSummary(argon2rounds);
+ UpdateKdfSummary(argon2memory);
+ UpdateKdfSummary(argon2parallelism);
+ }
+
+ }
+
+ private void OnKdfChange(object sender, Preference.PreferenceChangeEventArgs preferenceChangeEventArgs)
+ {
+ var db = App.Kp2a.CurrentDb;
+ var previousKdfParams = db.KpDatabase.KdfParameters;
+ Kp2aLog.Log("previous kdf: " + KdfPool.Get(db.KpDatabase.KdfParameters.KdfUuid) + " " + db.KpDatabase.KdfParameters.KdfUuid.ToHexString());
+ db.KpDatabase.KdfParameters =
+ KdfPool.Get(
+ new PwUuid(MemUtil.HexStringToByteArray((string)preferenceChangeEventArgs.NewValue)))
+ .GetDefaultParameters();
+
+ Kp2aLog.Log("--new kdf: " + KdfPool.Get(db.KpDatabase.KdfParameters.KdfUuid) + " " + db.KpDatabase.KdfParameters.KdfUuid.ToHexString());
+
+ SaveDb save = new SaveDb(Activity, App.Kp2a, App.Kp2a.CurrentDb, new ActionOnFinish(Activity, (success, message, activity) =>
+ {
+ if (!success)
+ {
+ db.KpDatabase.KdfParameters = previousKdfParams;
+ Toast.MakeText(activity, message, ToastLength.Long).Show();
+ return;
+ }
+ UpdateKdfScreen();
+
+ }));
+ ProgressTask pt = new ProgressTask(App.Kp2a, Activity, save);
+ pt.Run();
+
+ }
+
+ private void UpdateKdfSummary(Preference preference)
+ {
+ preference.Summary = ((KdfNumberDialogPreference)preference).ParamValue.ToString();
+ }
+
+ }
+
+ #endregion
+ }
+
+ public class SettingsFragmentManager
+ {
+ private readonly LifecycleAwareActivity _parentActivity;
+ private const string TitleTag = "settingsActivityTitle";
+
+ public SettingsFragmentManager(LifecycleAwareActivity parentActivity)
+ {
+ _parentActivity = parentActivity;
+ _parentActivity.OnCreateListener = OnCreate;
+ _parentActivity.OnSaveInstanceStateListener = OnSaveInstanceState;
+ _parentActivity.OnSupportNavigateUpListener = OnSupportNavigateUp;
+
+
+ }
+
+ protected void OnCreate(Bundle savedInstanceState)
+ {
+
+ _parentActivity.SetContentView(Resource.Layout.preference);
+
+ if (savedInstanceState == null)
+ {
+ _parentActivity.SupportFragmentManager
+ .BeginTransaction()
+ .Replace(Resource.Id.settings, new MainPreferenceFragment())
+ .Commit();
+ }
+ else
+ {
+ _parentActivity.Title = savedInstanceState.GetCharSequence(TitleTag);
+ }
+
+ _parentActivity.SupportActionBar?.SetDisplayHomeAsUpEnabled(true);
+ }
+
+ protected void OnSaveInstanceState(Bundle outState)
+ {
+ // Save the current activity title to restore after configuration changes
+ outState.PutCharSequence(TitleTag, _parentActivity.Title);
+ }
+
+ public bool? OnSupportNavigateUp()
+ {
+ if (_parentActivity.SupportFragmentManager.PopBackStackImmediate())
+ {
+ if (_parentActivity.SupportFragmentManager.BackStackEntryCount == 0)
+ {
+ _parentActivity.SetTitle(Resource.String.app_name);
+ }
+
+ return true;
+ }
+ else
+ {
+ _parentActivity.Finish();
+ return true;
+ }
+ }
+
+
+
+ public bool OnPreferenceStartFragment(PreferenceFragmentCompat caller, AndroidX.Preference.Preference pref)
+ {
+ var t = Type.GetType(pref.Fragment);
+ var javaName = Java.Lang.Class.FromType(t).Name;
+ // Instantiate the new Fragment
+ var args = pref.Extras;
+ var fragment = _parentActivity.SupportFragmentManager.FragmentFactory.Instantiate(
+ _parentActivity.ClassLoader,
+ javaName);
+
+ fragment.Arguments = args;
+ fragment.SetTargetFragment(caller, 0);
+
+ // Replace the existing Fragment with the new Fragment
+ _parentActivity.SupportFragmentManager.BeginTransaction()
+ .Replace(Resource.Id.settings, fragment)
+ .AddToBackStack(null)
+ .Commit();
+
+ _parentActivity.Title = pref.Title;
+ return true;
+ }
+
+ public void OnBackStackChanged()
+ {
}
}
- ///
- /// Activity to configure the application, without database settings. Does not require an unlocked database, or close when the database is locked
- ///
- [Activity(Label = "@string/app_name", Theme = "@style/MyTheme", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden)]
- public class AppSettingsActivity : LockingActivity
- {
- private ActivityDesign _design;
-
- public AppSettingsActivity()
- {
- _design = new ActivityDesign(this);
- }
+ ///
+ /// Activity to configure the application, without database settings. Does not require an unlocked database, or close when the database is locked
+ ///
+ [Activity(Label = "@string/app_name", Theme = "@style/Kp2aTheme_BlueActionBar", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden)]
+ public class AppSettingsActivity : LockingActivity, PreferenceFragmentCompat.IOnPreferenceStartFragmentCallback, FragmentManager.IOnBackStackChangedListener
+ {
+ private ActivityDesign _design;
- public static void Launch(Context ctx)
- {
- ctx.StartActivity(new Intent(ctx, typeof(AppSettingsActivity)));
- }
+ public static bool BeingRecreated = false;
- protected override void OnCreate(Bundle savedInstanceState)
- {
- _design.ApplyTheme();
- base.OnCreate(savedInstanceState);
-
-
- SetContentView(Resource.Layout.preference);
+ public AppSettingsActivity()
+ {
+ _design = new ActivityDesign(this);
+ settingsFragmentManager = new SettingsFragmentManager(this);
+ //TODO adding this makes the app crash on back (https://github.com/dotnet/android-libraries/issues/1055)
+ //We need this in order to update the activity title to the re-activated preference
+ //SupportFragmentManager.AddOnBackStackChangedListener(this);
+ }
- SetSupportActionBar(FindViewById(Resource.Id.mytoolbar));
+ public static void Launch(Context ctx)
+ {
+ ctx.StartActivity(new Intent(ctx, typeof(AppSettingsActivity)));
+ }
- FragmentManager.FindFragmentById(Resource.Id.settings_fragment).FindPreference(GetString(Resource.String.db_key)).Enabled = false;
-
- }
+ protected override void OnCreate(Bundle savedInstanceState)
+ {
+ _design.ApplyTheme();
+ base.OnCreate(savedInstanceState);
- }
+
+ }
+
+ public SettingsFragmentManager settingsFragmentManager;
+
+
+ public bool OnPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref)
+ {
+ return settingsFragmentManager.OnPreferenceStartFragment(caller, pref);
+ }
+
+ public void OnBackStackChanged()
+ {
+ settingsFragmentManager.OnBackStackChanged();
+ }
+ }
}
diff --git a/src/keepass2android/settings/Argon2Preference.cs b/src/keepass2android/settings/Argon2Preference.cs
index 41efd76d..9507a2f4 100644
--- a/src/keepass2android/settings/Argon2Preference.cs
+++ b/src/keepass2android/settings/Argon2Preference.cs
@@ -4,7 +4,7 @@ using KeePassLib.Cryptography.KeyDerivation;
namespace keepass2android.settings
{
- public class Argon2RoundsPreference: KdfNumberParamPreference
+ public class Argon2RoundsPreference: KdfNumberDialogPreference
{
public Argon2RoundsPreference(Context context, IAttributeSet attrs) : base(context, attrs)
{
@@ -34,8 +34,8 @@ namespace keepass2android.settings
}
}
- public class Argon2ParallelismPreference : KdfNumberParamPreference
- {
+ public class Argon2ParallelismPreference : KdfNumberDialogPreference
+ {
public Argon2ParallelismPreference(Context context, IAttributeSet attrs)
: base(context, attrs)
{
@@ -66,8 +66,8 @@ namespace keepass2android.settings
}
}
- public class Argon2MemoryPreference : KdfNumberParamPreference
- {
+ public class Argon2MemoryPreference : KdfNumberDialogPreference
+ {
public Argon2MemoryPreference(Context context, IAttributeSet attrs)
: base(context, attrs)
{
diff --git a/src/keepass2android/settings/AutofillDisabledQueriesPreference.cs b/src/keepass2android/settings/AutofillDisabledQueriesPreference.cs
index b999580f..8f89a74a 100644
--- a/src/keepass2android/settings/AutofillDisabledQueriesPreference.cs
+++ b/src/keepass2android/settings/AutofillDisabledQueriesPreference.cs
@@ -7,13 +7,14 @@ using Android.Content;
using Android.Content.PM;
using Android.Content.Res;
using Android.Graphics;
-using Android.Preferences;
+using AndroidX.Preference;
using Android.Runtime;
-using Android.Support.V4.Content;
using Android.Util;
using Android.Views;
using Android.Widget;
using keepass2android.services.AutofillBase;
+using keepass2android;
+using Google.Android.Material.Dialog;
namespace keepass2android
{
@@ -155,15 +156,16 @@ namespace keepass2android
}
-
- protected override void OnPrepareDialogBuilder(AlertDialog.Builder builder)
+ protected override void OnClick()
{
_populatorTask.Wait();
- base.OnPrepareDialogBuilder(builder);
+
+ var builder = new MaterialAlertDialogBuilder(Context);
+
var adapter = new DisabledQueryPreferenceScreenAdapter(this, Context);
-
+
builder.SetAdapter(adapter, (sender, args) => { });
builder.SetPositiveButton(Android.Resource.String.Ok, (sender, args) =>
{
@@ -172,8 +174,10 @@ namespace keepass2android
prefs.Edit().PutStringSet("AutoFillDisabledQueries", newList).Commit();
});
-
+ var dialog = builder.Create();
+ dialog.Show();
}
+
}
}
\ No newline at end of file
diff --git a/src/keepass2android/settings/DatabaseSettingsActivity.cs b/src/keepass2android/settings/DatabaseSettingsActivity.cs
index 9d7aa071..7ad6f3fe 100644
--- a/src/keepass2android/settings/DatabaseSettingsActivity.cs
+++ b/src/keepass2android/settings/DatabaseSettingsActivity.cs
@@ -25,7 +25,6 @@ using Android.Content;
using Android.Content.PM;
using Android.OS;
using Android.Widget;
-using Android.Preferences;
using Android.Provider;
using Android.Views.Autofill;
using Java.IO;
@@ -40,855 +39,12 @@ using KeePassLib;
using KeePassLib.Cryptography.KeyDerivation;
using KeePassLib.Interfaces;
using System.Collections.Generic;
+using AndroidX.Preference;
+using keepass2android;
namespace keepass2android
{
- //http://stackoverflow.com/a/27422401/292233
-#pragma warning disable CS0618 // Type or member is obsolete
- public class SettingsFragment : PreferenceFragment
- {
-
-
-
-
- public class KeyboardSwitchPrefManager
- {
- private readonly Activity _act;
- private CheckBoxPreference _switchPref;
- private CheckBoxPreference _openKp2aAutoPref;
- private CheckBoxPreference _openOnlyOnSearchPref;
- private CheckBoxPreference _switchBackPref;
- private PreferenceScreen _screen;
- private PreferenceFragment _fragment;
-
- public KeyboardSwitchPrefManager(PreferenceFragment fragment)
- {
- var act = fragment.Activity;
- this._act = act;
- this._fragment = fragment;
- this._screen = (PreferenceScreen)_fragment.FindPreference(act.GetString(Resource.String.keyboardswitch_prefs_key));
-
- var keyboardSwapPref = _fragment.FindPreference("get_keyboardswap");
- var pm = act.PackageManager;
- var intnt = Keepass2android.Kbbridge.ImeSwitcher.GetLaunchIntentForKeyboardSwap(act);
- if ((intnt != null) && pm.QueryIntentActivities(intnt, 0).Any())
- {
- _screen.RemovePreference(keyboardSwapPref);
- }
- else
- {
- keyboardSwapPref.PreferenceClick += (sender, args) =>
- {
- Util.GotoUrl(act, act.GetString(Resource.String.MarketURL) + "keepass2android.plugin.keyboardswap2");
- };
- }
-
- _switchPref = (CheckBoxPreference)_fragment.FindPreference("kp2a_switch_rooted");
- _openKp2aAutoPref =
- (CheckBoxPreference)_fragment.FindPreference(act.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key));
- _openOnlyOnSearchPref =
- (CheckBoxPreference)
- _fragment.FindPreference(act.GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key));
- _switchBackPref =
- (CheckBoxPreference)_fragment.FindPreference(act.GetString(Resource.String.AutoSwitchBackKeyboard_key));
-
- EnableSwitchPreferences(_switchPref.Checked);
-
- _switchPref.PreferenceChange += (sender, args) =>
- {
- bool switchOnRooted = (bool)args.NewValue;
- EnableSwitchPreferences(switchOnRooted);
- };
- }
-
-
- private void EnableSwitchPreferences(bool switchOnRooted)
- {
- if (!switchOnRooted)
- {
- if (_fragment.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key)) == null)
- {
- _screen.AddPreference(_openKp2aAutoPref);
- }
- if (_fragment.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key)) != null)
- {
- _screen.RemovePreference(_openOnlyOnSearchPref);
- }
- }
- else
- {
- {
- _screen.RemovePreference(_openKp2aAutoPref);
- }
- if (_fragment.FindPreference(_act.GetString(Resource.String.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key)) == null)
- {
- _screen.AddPreference(_openOnlyOnSearchPref);
- }
- }
- /*_openKp2aAutoPref.Enabled = !switchOnRooted;
-
- _openOnlyOnSearchPref.Enabled = switchOnRooted;
-
- _switchBackPref.Enabled = switchOnRooted;*/
- }
- }
-
- private KeyboardSwitchPrefManager _switchPrefManager;
- private Preference aesRounds, argon2parallelism, argon2rounds, argon2memory;
-
-
- void OnRememberKeyFileHistoryChanged(object sender, Preference.PreferenceChangeEventArgs eventArgs)
- {
- if (!(bool)eventArgs.NewValue)
- {
- App.Kp2a.FileDbHelper.DeleteAllKeys();
- }
- }
-
- void OnShowUnlockedNotificationChanged(object sender, Preference.PreferenceChangeEventArgs eventArgs)
- {
- App.Kp2a.UpdateOngoingNotification();
- }
-
- public override void OnResume()
- {
- base.OnResume();
-
- UpdateAutofillPref();
- }
-
-
- public override void OnCreate(Bundle savedInstanceState)
- {
- base.OnCreate(savedInstanceState);
- AddPreferencesFromResource(Resource.Xml.preferences);
-
- // Re-use the change handlers for the application settings
- FindPreference(GetString(Resource.String.keyfile_key)).PreferenceChange += OnRememberKeyFileHistoryChanged;
- var unlockedNotificationPref = FindPreference(GetString(Resource.String.ShowUnlockedNotification_key));
- unlockedNotificationPref.PreferenceChange += OnShowUnlockedNotificationChanged;
- if ((int)Build.VERSION.SdkInt >= 26)
- {
- //use system notification channels to control notification visibility
- unlockedNotificationPref.Parent.RemovePreference(unlockedNotificationPref);
- }
-
-
- FindPreference(GetString(Resource.String.DebugLog_key)).PreferenceChange += OnDebugLogChanged;
- FindPreference(GetString(Resource.String.DebugLog_send_key)).PreferenceClick += OnSendDebug;
-
-#if !EXCLUDE_JAVAFILESTORAGE && !NoNet
- FindPreference(GetString(Resource.String.FtpDebug_key)).PreferenceChange += OnJSchDebugChanged;
-#else
- FindPreference(GetString(Resource.String.FtpDebug_key)).Enabled = false;
-#endif
-
- HashSet supportedLocales = new HashSet() { "en", "af", "ar", "az", "be", "bg", "ca", "cs", "da", "de", "el", "es", "eu", "fa", "fi", "fr", "gl", "he", "hr", "hu", "id", "in", "it", "iw", "ja", "ko", "ml", "nb", "nl", "nn", "no", "pl", "pt", "ro", "ru", "si", "sk", "sl", "sr", "sv", "tr", "uk", "vi", "zh" };
- var languagePref = (ListPreference)FindPreference(GetString(Resource.String.app_language_pref_key));
- new AppLanguageManager(this, languagePref, supportedLocales);
-
- UpdateAutofillPref();
-
- var autofillPref = FindPreference(GetString(Resource.String.AutoFill_prefs_key));
- if (autofillPref != null)
- {
- autofillPref.PreferenceClick += (sender, args) =>
- {
-
- var intent = new Intent(Settings.ActionRequestSetAutofillService);
- if (((AutofillManager)Activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager))))
- .HasEnabledAutofillServices)
- {
- intent.SetData(Android.Net.Uri.Parse("package:" + Context.PackageName + "notexisting")); //if we use our package name, the activity won't launch
- }
- else
- {
- intent.SetData(Android.Net.Uri.Parse("package:" + Context.PackageName));
- }
-
- try
- {
- Context.StartActivity(intent);
- }
- catch (ActivityNotFoundException e)
- {
- //this exception was reported by many Huawei users
- Kp2aLog.LogUnexpectedError(e);
- new AlertDialog.Builder(Context)
- .SetTitle(Resource.String.autofill_enable)
- .SetMessage(Resource.String.autofill_enable_failed)
- .SetPositiveButton(Android.Resource.String.Ok, (o, eventArgs) => { })
- .Show();
-
- }
- catch (Exception e)
- {
- Kp2aLog.LogUnexpectedError(e);
- }
- };
- }
-
-
- PrepareNoDonatePreference(Activity, FindPreference(GetString(Resource.String.NoDonateOption_key)));
- PrepareNoDonationReminderPreference(Activity, ((PreferenceScreen)FindPreference(GetString(Resource.String.display_prefs_key))), FindPreference(GetString(Resource.String.NoDonationReminder_key)));
-
- FindPreference(GetString(Resource.String.design_key)).PreferenceChange += (sender, args) => Activity.Recreate();
-
- Database db = App.Kp2a.CurrentDb;
- if (db != null)
- {
- ListPreference kdfPref = (ListPreference)FindPreference(GetString(Resource.String.kdf_key));
- kdfPref.SetEntries(KdfPool.Engines.Select(eng => eng.Name).ToArray());
- string[] kdfValues = KdfPool.Engines.Select(eng => eng.Uuid.ToHexString()).ToArray();
- kdfPref.SetEntryValues(kdfValues);
- kdfPref.SetValueIndex(kdfValues.Select((v, i) => new { kdf = v, index = i }).First(el => el.kdf == db.KpDatabase.KdfParameters.KdfUuid.ToHexString()).index);
- kdfPref.PreferenceChange += OnKdfChange;
-
- aesRounds = FindPreference(GetString(Resource.String.rounds_key));
- argon2rounds = FindPreference("argon2rounds");
- argon2memory = FindPreference("argon2memory");
- argon2parallelism = FindPreference("argon2parallelism");
-
- aesRounds.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference);
- argon2rounds.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference);
- argon2memory.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference);
- argon2parallelism.PreferenceChange += (sender, e) => UpdateKdfSummary(e.Preference);
-
- UpdateKdfScreen();
-
- PrepareDefaultUsername(db);
- PrepareDatabaseName(db);
- PrepareMasterPassword();
- PrepareTemplates(db);
-
- ListPreference algorithmPref = (ListPreference)FindPreference(GetString(Resource.String.algorithm_key));
- algorithmPref.SetEntries(CipherPool.GlobalPool.Engines.Select(eng => eng.DisplayName).ToArray());
- string[] algoValues = CipherPool.GlobalPool.Engines.Select(eng => eng.CipherUuid.ToHexString()).ToArray();
- algorithmPref.SetEntryValues(algoValues);
- algorithmPref.SetValueIndex(algoValues.Select((v, i) => new { kdf = v, index = i }).First(el => el.kdf == db.KpDatabase.DataCipherUuid.ToHexString()).index);
- algorithmPref.PreferenceChange += AlgorithmPrefChange;
- algorithmPref.Summary =
- CipherPool.GlobalPool.GetCipher(App.Kp2a.CurrentDb.KpDatabase.DataCipherUuid).DisplayName;
- UpdateImportDbPref();
- UpdateImportKeyfilePref();
- }
-
- try
- {
- //depending on Android version, we offer to use a transparent icon for QuickUnlock or use the notification priority (since API level 16)
- Preference hideQuickUnlockTranspIconPref = FindPreference(GetString(Resource.String.QuickUnlockIconHidden_key));
- Preference hideQuickUnlockIconPref = FindPreference(GetString(Resource.String.QuickUnlockIconHidden16_key));
- var quickUnlockScreen = ((PreferenceScreen)FindPreference(GetString(Resource.String.QuickUnlock_prefs_key)));
- if ((int)Android.OS.Build.VERSION.SdkInt >= 26)
- {
- //use notification channels
- quickUnlockScreen.RemovePreference(hideQuickUnlockTranspIconPref);
- quickUnlockScreen.RemovePreference(hideQuickUnlockIconPref);
- }
- else if ((int)Android.OS.Build.VERSION.SdkInt >= 16)
- {
- quickUnlockScreen.RemovePreference(hideQuickUnlockTranspIconPref);
- unlockedNotificationPref.PreferenceChange += (sender, args) => App.Kp2a.UpdateOngoingNotification();
- hideQuickUnlockIconPref.PreferenceChange += delegate { App.Kp2a.UpdateOngoingNotification(); };
- }
- else
- {
- //old version: only show transparent quickUnlock and no option to hide unlocked icon:
- quickUnlockScreen.RemovePreference(hideQuickUnlockIconPref);
- FindPreference(GetString(Resource.String.QuickUnlockIconHidden_key)).PreferenceChange +=
- delegate { App.Kp2a.UpdateOngoingNotification(); };
-
- ((PreferenceScreen)FindPreference(GetString(Resource.String.display_prefs_key))).RemovePreference(
- unlockedNotificationPref);
- }
- }
- catch (Exception ex)
- {
- Kp2aLog.LogUnexpectedError(ex);
- }
-
-
-
- //AppSettingsActivity.PrepareKeyboardSwitchingPreferences(this);
- _switchPrefManager = new KeyboardSwitchPrefManager(this);
- PrepareSeparateNotificationsPreference();
-
- FindPreference("IconSetKey").PreferenceChange += (sender, args) =>
- {
- if (App.Kp2a.CurrentDb != null)
- App.Kp2a.CurrentDb.DrawableFactory.Clear();
-
- };
-
- Preference cachingPreference = FindPreference(GetString(Resource.String.UseOfflineCache_key));
- cachingPreference.PreferenceChange += OnUseOfflineCacheChanged;
-
-
- }
-
- private void UpdateAutofillPref()
- {
- var autofillScreen = FindPreference(GetString(Resource.String.AutoFill_prefs_screen_key));
- var autofillPref = FindPreference(GetString(Resource.String.AutoFill_prefs_key));
- var autofillDisabledPref = FindPreference(GetString(Resource.String.AutofillDisabledQueriesPreference_key));
- var autofillSavePref = FindPreference(GetString(Resource.String.OfferSaveCredentials_key));
- var autofillInlineSuggestions = FindPreference(GetString(Resource.String.InlineSuggestions_key));
- var noAutofillDisablingPref = FindPreference(GetString(Resource.String.NoAutofillDisabling_key));
- var autofillNoDalVerification = FindPreference(GetString(Resource.String.NoDalVerification_key));
- if (autofillPref == null)
- return;
- if ((Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.O) ||
- !((AutofillManager) Activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager))))
- .IsAutofillSupported)
- {
- var passwordAccessScreen =
- (PreferenceScreen) FindPreference(Activity.GetString(Resource.String.password_access_prefs_key));
- passwordAccessScreen.RemovePreference(autofillScreen);
- }
- else
- {
- if (((AutofillManager) Activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager))))
- .HasEnabledAutofillServices)
- {
- autofillDisabledPref.Enabled = true;
- autofillSavePref.Enabled = true;
- autofillNoDalVerification.Enabled = true;
- autofillInlineSuggestions.Enabled = true;
- noAutofillDisablingPref.Enabled = true;
- autofillPref.Summary = Activity.GetString(Resource.String.plugin_enabled);
- autofillPref.Intent = new Intent(Intent.ActionView);
- autofillPref.Intent.SetData(Android.Net.Uri.Parse("https://philippc.github.io/keepass2android/OreoAutoFill.html"));
- }
- else
- {
- autofillNoDalVerification.Enabled = false;
- autofillDisabledPref.Enabled = false;
- autofillSavePref.Enabled = false;
- noAutofillDisablingPref.Enabled = false;
- autofillInlineSuggestions.Enabled = false;
- autofillPref.Summary = Activity.GetString(Resource.String.not_enabled);
- }
- if ((int)Android.OS.Build.VERSION.SdkInt < 30)
- {
- autofillInlineSuggestions.Summary = Activity.GetString(Resource.String.requires_android11);
- CheckBoxPreference cbp = autofillInlineSuggestions as CheckBoxPreference;
- if (cbp != null)
- cbp.Checked = false;
- autofillInlineSuggestions.Enabled = false;
- }
- }
- }
-
- private void OnSendDebug(object sender, Preference.PreferenceClickEventArgs e)
- {
- Kp2aLog.SendLog(this.Activity);
- }
-
- private void OnDebugLogChanged(object sender, Preference.PreferenceChangeEventArgs e)
- {
- if ((bool)e.NewValue)
- Kp2aLog.CreateLogFile();
- else
- Kp2aLog.FinishLogFile();
-
-#if !EXCLUDE_JAVAFILESTORAGE && !NoNet
- SetJSchLogging(PreferenceManager.GetDefaultSharedPreferences(Application.Context)
- .GetBoolean(Application.Context.GetString(Resource.String.FtpDebug_key), false));
-#endif
- }
-
-#if !EXCLUDE_JAVAFILESTORAGE && !NoNet
- private void OnJSchDebugChanged(object sender, Preference.PreferenceChangeEventArgs e)
- {
- bool debugEnabled = (bool)e.NewValue;
- SetJSchLogging(debugEnabled);
-
- string prefKey = Application.Context.GetString(Resource.String.FtpDebug_key);
- PreferenceManager.SharedPreferences.Edit().PutBoolean(prefKey, debugEnabled).Apply();
- }
-
- private void SetJSchLogging(bool enabled)
- {
- var sftpStorage = new Keepass2android.Javafilestorage.SftpStorage(Context);
- string? logFilename = null;
- if (Kp2aLog.LogToFile)
- {
- logFilename = Kp2aLog.LogFilename;
- }
- sftpStorage.SetJschLogging(enabled, logFilename);
- }
-
-#endif
-
- private void AlgorithmPrefChange(object sender, Preference.PreferenceChangeEventArgs preferenceChangeEventArgs)
- {
- var db = App.Kp2a.CurrentDb;
- var previousCipher = db.KpDatabase.DataCipherUuid;
- db.KpDatabase.DataCipherUuid = new PwUuid(MemUtil.HexStringToByteArray((string)preferenceChangeEventArgs.NewValue));
-
- SaveDb save = new SaveDb(Activity, App.Kp2a, App.Kp2a.CurrentDb, new ActionOnFinish(Activity, (success, message, activity) =>
- {
- if (!success)
- {
- db.KpDatabase.DataCipherUuid = previousCipher;
- Toast.MakeText(activity, message, ToastLength.Long).Show();
- return;
- }
- preferenceChangeEventArgs.Preference.Summary =
- CipherPool.GlobalPool.GetCipher(db.KpDatabase.DataCipherUuid).DisplayName;
- }));
- ProgressTask pt = new ProgressTask(App.Kp2a, Activity, save);
- pt.Run();
- }
-
- private void UpdateKdfScreen()
- {
- var db = App.Kp2a.CurrentDb;
- var kdf = KdfPool.Get(db.KpDatabase.KdfParameters.KdfUuid);
-
- var kdfpref = FindPreference(GetString(Resource.String.kdf_key));
-
-
- kdfpref.Summary = kdf.Name;
-
- var kdfscreen = ((PreferenceScreen)FindPreference(GetString(Resource.String.kdf_screen_key)));
- if (kdf is AesKdf)
- {
- if (kdfscreen.FindPreference(GetString(Resource.String.rounds_key)) == null)
- kdfscreen.AddPreference(aesRounds);
- kdfscreen.RemovePreference(argon2rounds);
- kdfscreen.RemovePreference(argon2memory);
- kdfscreen.RemovePreference(argon2parallelism);
-
- aesRounds.Enabled = db.CanWrite;
- UpdateKdfSummary(aesRounds);
- }
- else
- {
- kdfscreen.RemovePreference(aesRounds);
- if (kdfscreen.FindPreference("argon2rounds") == null)
- {
- kdfscreen.AddPreference(argon2rounds);
- kdfscreen.AddPreference(argon2memory);
- kdfscreen.AddPreference(argon2parallelism);
- }
- UpdateKdfSummary(argon2rounds);
- UpdateKdfSummary(argon2memory);
- UpdateKdfSummary(argon2parallelism);
- }
-
- }
-
- private void OnKdfChange(object sender, Preference.PreferenceChangeEventArgs preferenceChangeEventArgs)
- {
- var db = App.Kp2a.CurrentDb;
- var previousKdfParams = db.KpDatabase.KdfParameters;
- Kp2aLog.Log("previous kdf: " + KdfPool.Get(db.KpDatabase.KdfParameters.KdfUuid) + " " + db.KpDatabase.KdfParameters.KdfUuid.ToHexString() );
- db.KpDatabase.KdfParameters =
- KdfPool.Get(
- new PwUuid(MemUtil.HexStringToByteArray((string)preferenceChangeEventArgs.NewValue)))
- .GetDefaultParameters();
-
- Kp2aLog.Log("--new kdf: " + KdfPool.Get(db.KpDatabase.KdfParameters.KdfUuid) + " " + db.KpDatabase.KdfParameters.KdfUuid.ToHexString());
-
- SaveDb save = new SaveDb(Activity, App.Kp2a, App.Kp2a.CurrentDb, new ActionOnFinish(Activity, (success, message, activity) =>
- {
- if (!success)
- {
- db.KpDatabase.KdfParameters = previousKdfParams;
- Toast.MakeText(activity, message, ToastLength.Long).Show();
- return;
- }
- UpdateKdfScreen();
-
- }));
- ProgressTask pt = new ProgressTask(App.Kp2a, Activity, save);
- pt.Run();
-
- }
-
- private void UpdateKdfSummary(Preference preference)
- {
- preference.Summary = ((keepass2android.settings.KdfNumberParamPreference)preference).ParamValue.ToString();
- }
-
- private void PrepareNoDonationReminderPreference(Activity ctx, PreferenceScreen screen, Preference preference)
- {
- ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
-
- if (!prefs.GetBoolean("DismissedDonateReminder", false))
- {
- screen.RemovePreference(preference);
- }
-
-
- }
- private void PrepareTemplates(Database db)
- {
- Preference pref = FindPreference("AddTemplates_pref_key");
- if ((!db.DatabaseFormat.SupportsTemplates) || (AddTemplateEntries.ContainsAllTemplates(App.Kp2a.CurrentDb)))
- {
- pref.Enabled = false;
- }
- else
- {
- pref.PreferenceClick += (sender, args) =>
- {
- ProgressTask pt = new ProgressTask(App.Kp2a, Activity,
- new AddTemplateEntries(Activity, App.Kp2a, new ActionOnFinish(Activity,
- delegate
- {
- pref.Enabled = false;
- })));
- pt.Run();
- };
- }
-
- }
-
- private void PrepareMasterPassword()
- {
- Preference changeMaster = FindPreference(GetString(Resource.String.master_pwd_key));
- if (App.Kp2a.CurrentDb.CanWrite)
- {
- changeMaster.Enabled = true;
- changeMaster.PreferenceClick += delegate { new SetPasswordDialog(Activity).Show(); };
- }
- }
-
- private void PrepareDatabaseName(Database db)
- {
- Preference databaseName = FindPreference(GetString(Resource.String.database_name_key));
- if (!db.DatabaseFormat.HasDatabaseName)
- {
- ((PreferenceScreen) FindPreference(GetString(Resource.String.db_key))).RemovePreference(databaseName);
- }
- else
- {
- databaseName.Enabled = db.CanWrite;
- ((EditTextPreference) databaseName).EditText.Text = db.KpDatabase.Name;
- ((EditTextPreference) databaseName).Text = db.KpDatabase.Name;
- databaseName.PreferenceChange += (sender, e) =>
- {
- DateTime previousNameChanged = db.KpDatabase.NameChanged;
- String previousName = db.KpDatabase.Name;
- db.KpDatabase.Name = e.NewValue.ToString();
-
- SaveDb save = new SaveDb(Activity, App.Kp2a, App.Kp2a.CurrentDb, new ActionOnFinish(Activity, (success, message, activity) =>
- {
- if (!success)
- {
- db.KpDatabase.Name = previousName;
- db.KpDatabase.NameChanged = previousNameChanged;
- Toast.MakeText(activity, message, ToastLength.Long).Show();
- }
- else
- {
- // Name is reflected in notification, so update it
- App.Kp2a.UpdateOngoingNotification();
- }
- }));
- ProgressTask pt = new ProgressTask(App.Kp2a, Activity, save);
- pt.Run();
- };
- }
- }
-
- private void PrepareDefaultUsername(Database db)
- {
- Preference defaultUser = FindPreference(GetString(Resource.String.default_username_key));
- if (!db.DatabaseFormat.HasDefaultUsername)
- {
- ((PreferenceScreen) FindPreference(GetString(Resource.String.db_key))).RemovePreference(defaultUser);
- }
- else
- {
- defaultUser.Enabled = db.CanWrite;
- ((EditTextPreference) defaultUser).EditText.Text = db.KpDatabase.DefaultUserName;
- ((EditTextPreference) defaultUser).Text = db.KpDatabase.DefaultUserName;
- defaultUser.PreferenceChange += (sender, e) =>
- {
- DateTime previousUsernameChanged = db.KpDatabase.DefaultUserNameChanged;
- String previousUsername = db.KpDatabase.DefaultUserName;
- db.KpDatabase.DefaultUserName = e.NewValue.ToString();
-
- SaveDb save = new SaveDb(Activity, App.Kp2a, App.Kp2a.CurrentDb, new ActionOnFinish(Activity, (success, message, activity) =>
- {
- if (!success)
- {
- db.KpDatabase.DefaultUserName = previousUsername;
- db.KpDatabase.DefaultUserNameChanged = previousUsernameChanged;
- Toast.MakeText(activity, message, ToastLength.Long).Show();
- }
- }));
- ProgressTask pt = new ProgressTask(App.Kp2a, Activity, save);
- pt.Run();
- };
- }
- }
-
- public void PrepareSeparateNotificationsPreference()
- {
- try
- {
- //depending on Android version, we offer to show a combined notification (with action buttons) (since API level 16)
- Preference separateNotificationsPref = FindPreference(Activity.GetString(Resource.String.ShowSeparateNotifications_key));
- var passwordAccessScreen = ((PreferenceScreen)FindPreference(Activity.GetString(Resource.String.password_access_prefs_key)));
- if ((int)Build.VERSION.SdkInt < 16)
- {
- passwordAccessScreen.RemovePreference(separateNotificationsPref);
- }
- }
- catch (Exception ex)
- {
- Kp2aLog.LogUnexpectedError(ex);
- }
- }
-
- private void OnUseOfflineCacheChanged(object sender, Preference.PreferenceChangeEventArgs e)
- {
- if (!(bool)e.NewValue)
- {
- AlertDialog.Builder builder = new AlertDialog.Builder(Activity);
- builder.SetTitle(GetString(Resource.String.ClearOfflineCache_title));
-
- builder.SetMessage(GetString(Resource.String.ClearOfflineCache_question));
-
- builder.SetPositiveButton(App.Kp2a.GetResourceString(UiStringKey.yes), (o, args) =>
- {
- try
- {
- App.Kp2a.ClearOfflineCache();
- }
- catch (Exception ex)
- {
- Kp2aLog.LogUnexpectedError(ex);
- Toast.MakeText(LocaleManager.LocalizedAppContext, ex.Message, ToastLength.Long).Show();
- }
- }
- );
-
- builder.SetNegativeButton(App.Kp2a.GetResourceString(UiStringKey.no), (o, args) =>
- {
- ((CheckBoxPreference) e.Preference).Checked = true;
- }
- );
- builder.SetCancelable(false);
- Dialog dialog = builder.Create();
- dialog.Show();
-
-
- }
- }
-
- private void UpdateImportKeyfilePref()
- {
- var prefs = PreferenceManager.GetDefaultSharedPreferences(Activity);
- var rememberKeyfile = prefs.GetBoolean(GetString(Resource.String.keyfile_key), Resources.GetBoolean(Resource.Boolean.keyfile_default));
-
- Preference importKeyfile = FindPreference("import_keyfile_prefs");
- Preference exportKeyfile = FindPreference("export_keyfile_prefs");
- importKeyfile.Summary = "";
-
- if (!rememberKeyfile)
- {
- importKeyfile.Summary = GetString(Resource.String.KeyfileMoveRequiresRememberKeyfile);
- importKeyfile.Enabled = false;
- exportKeyfile.Enabled = false;
- return;
- }
- CompositeKey masterKey = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
- if (masterKey.ContainsType(typeof(KcpKeyFile)))
- {
- IOConnectionInfo iocKeyfile = ((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).Ioc;
- if (iocKeyfile.IsLocalFile() && IoUtil.IsInInternalDirectory(iocKeyfile.Path, Activity))
- {
- importKeyfile.Enabled = false;
- exportKeyfile.Enabled = true;
- exportKeyfile.PreferenceClick += (sender, args) => { ExportKeyfileFromInternalFolder(); };
- importKeyfile.Summary = GetString(Resource.String.FileIsInInternalDirectory);
- }
- else
- {
- exportKeyfile.Enabled = false;
- importKeyfile.Enabled = true;
- importKeyfile.PreferenceClick += (sender, args) => { MoveKeyfileToInternalFolder(); };
- }
-
-
- }
- else
- {
- exportKeyfile.Enabled = false;
- importKeyfile.Enabled = false;
- }
- }
-
-
-
- private void ExportKeyfileFromInternalFolder()
- {
- StartActivity(new Intent(Activity.ApplicationContext, typeof(ExportKeyfileActivity)));
-
- }
-
- private void MoveKeyfileToInternalFolder()
- {
- Func copyAndReturnPostExecute = () =>
- {
- try
- {
- CompositeKey masterKey = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
- var sourceIoc = ((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).Ioc;
- var newIoc = IoUtil.ImportFileToInternalDirectory(sourceIoc, Activity, App.Kp2a);
- ((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).ResetIoc(newIoc);
- var keyfileString = IOConnectionInfo.SerializeToString(newIoc);
- App.Kp2a.StoreOpenedFileAsRecent(App.Kp2a.CurrentDb.Ioc, keyfileString, false);
- return () =>
- {
- UpdateImportKeyfilePref();
- var builder = new AlertDialog.Builder(Activity);
- builder
- .SetMessage(Resource.String.KeyfileMoved);
- builder.SetPositiveButton(Android.Resource.String.Ok, (sender, args) => { });
- builder.Show();
-
- };
-
-
-
-
- }
- catch (Exception e)
- {
- return () =>
- {
- Toast.MakeText(Activity, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, ToastLength.Long).Show();
- };
- }
-
-
-
- };
-
- new SimpleLoadingDialog(Activity, GetString(Resource.String.CopyingFile), false,
- copyAndReturnPostExecute
- ).Execute();
-
- }
- private void UpdateImportDbPref()
- {
- //Import db/key file preferences:
- Preference importDb = FindPreference("import_db_prefs");
- bool isLocalOrContent =
- App.Kp2a.CurrentDb.Ioc.IsLocalFile() || App.Kp2a.CurrentDb.Ioc.Path.StartsWith("content://");
- if (!isLocalOrContent)
- {
- importDb.Summary = GetString(Resource.String.OnlyAvailableForLocalFiles);
- importDb.Enabled = false;
- }
- else
- {
- if (IoUtil.IsInInternalDirectory(App.Kp2a.CurrentDb.Ioc.Path, Activity))
- {
- importDb.Summary = GetString(Resource.String.FileIsInInternalDirectory);
- importDb.Enabled = false;
- }
- else
- {
- importDb.Enabled = true;
- importDb.PreferenceClick += delegate { MoveDbToInternalFolder(); };
- }
- }
- }
-
- private void MoveDbToInternalFolder()
- {
- Func copyAndReturnPostExecute = () =>
- {
- try
- {
- var sourceIoc = App.Kp2a.CurrentDb.Ioc;
- var newIoc = IoUtil.ImportFileToInternalDirectory(sourceIoc, Activity, App.Kp2a);
- return () =>
- {
- var builder = new AlertDialog.Builder(Activity);
- builder
- .SetMessage(Resource.String.DatabaseFileMoved);
- builder.SetPositiveButton(Android.Resource.String.Ok, (sender, args) =>
- {
- var key = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
- App.Kp2a.CloseDatabase(App.Kp2a.CurrentDb);
- PasswordActivity.Launch(Activity, newIoc, key, new ActivityLaunchModeSimple(), false);
-
- });
- builder.Show();
-
- };
-
-
-
-
- }
- catch (Exception e)
- {
- return () =>
- {
- Toast.MakeText(Activity, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, ToastLength.Long).Show();
- };
- }
-
-
-
- };
-
- new SimpleLoadingDialog(Activity, GetString(Resource.String.CopyingFile), false,
- copyAndReturnPostExecute
- ).Execute();
-
- }
-
-
-
- private void SetAlgorithm(Database db, Preference algorithm)
- {
- algorithm.Summary = CipherPool.GlobalPool.GetCipher(db.KpDatabase.DataCipherUuid).DisplayName;
- }
-
- public void PrepareNoDonatePreference(Context ctx, Preference preference)
- {
- ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
-
- long usageCount = prefs.GetLong(ctx.GetString(Resource.String.UsageCount_key), 0);
-
-#if DEBUG
- preference.Enabled = (usageCount > 1);
-#else
- preference.Enabled = (usageCount > 50);
-#endif
- preference.PreferenceChange += delegate(object sender, Preference.PreferenceChangeEventArgs args)
- {
- if ((bool)args.NewValue)
- {
- new AlertDialog.Builder(ctx)
- .SetTitle(ctx.GetString(AppNames.AppNameResource))
- .SetCancelable(false)
- .SetPositiveButton(Android.Resource.String.Ok, delegate(object o, DialogClickEventArgs eventArgs)
- {
- Util.GotoDonateUrl(ctx);
- ((Dialog)o).Dismiss();
- })
- .SetMessage(Resource.String.NoDonateOption_question)
- .Create().Show();
-
- }
- };
-
- }
-
-
- }
///
///
@@ -909,11 +65,11 @@ namespace keepass2android
///
internal class AppLanguageManager
{
- private readonly PreferenceFragment _fragment;
- private readonly ListPreference _langPref;
+ private readonly PreferenceFragmentCompat _fragment;
+ private readonly AndroidX.Preference.ListPreference _langPref;
private readonly Dictionary _langEntriesByCodeUnique;
- public AppLanguageManager(PreferenceFragment fragment, ListPreference langPref, HashSet supportedLocales)
+ public AppLanguageManager(PreferenceFragmentCompat fragment, AndroidX.Preference.ListPreference langPref, HashSet supportedLocales)
{
this._fragment = fragment;
this._langPref = langPref;
@@ -922,7 +78,7 @@ namespace keepass2android
ConfigureLanguageList();
}
- private static Dictionary CreateCodeToEntryMapping(PreferenceFragment fragment, HashSet supportedLocales)
+ private static Dictionary CreateCodeToEntryMapping(PreferenceFragmentCompat fragment, HashSet supportedLocales)
{
var localesByCode = new Dictionary>();
foreach (var loc in Java.Util.Locale.GetAvailableLocales())
@@ -972,7 +128,7 @@ namespace keepass2android
return _fragment.GetString(Resource.String.SystemLanguage);
}
- private void AppLanguagePrefChange(object sender, Preference.PreferenceChangeEventArgs args)
+ private void AppLanguagePrefChange(object sender, AndroidX.Preference.Preference.PreferenceChangeEventArgs args)
{
string langCode = LanguageEntry.PrefCodeToLanguage((string)args.NewValue);
LocaleManager.Language = langCode;
@@ -986,29 +142,37 @@ namespace keepass2android
///
/// Activity to configure the application and database settings. The database must be unlocked, and this activity will close if it becomes locked.
///
- [Activity(Label = "@string/app_name", Theme = "@style/MyTheme", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden)]
- public class DatabaseSettingsActivity : LockCloseActivity
- {
-
- public DatabaseSettingsActivity()
- {
-
- }
+ [Activity(Label = "@string/app_name", Theme = "@style/Kp2aTheme_ActionBar", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden)]
+ public class DatabaseSettingsActivity : LockCloseActivity, PreferenceFragmentCompat.IOnPreferenceStartFragmentCallback
+ {
public static void Launch(Activity ctx)
{
ctx.StartActivity(new Intent(ctx, typeof(DatabaseSettingsActivity)));
}
- protected override void OnCreate(Bundle savedInstanceState)
- {
- base.OnCreate(savedInstanceState);
- SetContentView(Resource.Layout.preference);
+ private ActivityDesign _design;
- SetSupportActionBar(FindViewById(Resource.Id.mytoolbar));
+ public DatabaseSettingsActivity()
+ {
+ _design = new ActivityDesign(this);
+ settingsFragmentManager = new SettingsFragmentManager(this);
+ }
- }
+ protected override void OnCreate(Bundle savedInstanceState)
+ {
+ _design.ApplyTheme();
+ base.OnCreate(savedInstanceState);
- }
+
+ }
+
+ public SettingsFragmentManager settingsFragmentManager;
+ public bool OnPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref)
+ {
+ return settingsFragmentManager.OnPreferenceStartFragment(caller, pref);
+ }
+
+ }
}
diff --git a/src/keepass2android/settings/ExportKeyfileActivity.cs b/src/keepass2android/settings/ExportKeyfileActivity.cs
index e185d588..ed5b4a7d 100644
--- a/src/keepass2android/settings/ExportKeyfileActivity.cs
+++ b/src/keepass2android/settings/ExportKeyfileActivity.cs
@@ -3,6 +3,7 @@ using Android.App;
using Android.Content;
using Android.Widget;
using keepass2android.Io;
+using keepass2android;
using KeePassLib.Keys;
using KeePassLib.Serialization;
diff --git a/src/keepass2android/settings/IconSetPreference.cs b/src/keepass2android/settings/IconSetPreference.cs
index b7580e76..fe13fa7b 100644
--- a/src/keepass2android/settings/IconSetPreference.cs
+++ b/src/keepass2android/settings/IconSetPreference.cs
@@ -7,11 +7,13 @@ using Android.Content;
using Android.Content.Res;
using Android.Graphics;
using Android.Graphics.Drawables;
-using Android.Preferences;
+using AndroidX.Preference;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
+using Google.Android.Material.Dialog;
+using keepass2android;
namespace keepass2android
{
@@ -126,6 +128,8 @@ namespace keepass2android
}
}
+ public Dialog Dialog { get; set; }
+
List _iconSets = null;
List IconSets
@@ -182,12 +186,9 @@ namespace keepass2android
}
-
- protected override void OnPrepareDialogBuilder(AlertDialog.Builder builder)
+ protected override void OnClick()
{
_populatorTask.Wait();
- base.OnPrepareDialogBuilder(builder);
-
var iconListPreferenceAdapter = new IconListPreferenceScreenAdapter(this, Context);
@@ -201,13 +202,17 @@ namespace keepass2android
}
}
+ var builder = new MaterialAlertDialogBuilder(Context);
+
builder.SetAdapter(iconListPreferenceAdapter, (sender, args) => { });
builder.SetNeutralButton(Resource.String.IconSet_install, (sender, args) =>
{
Util.GotoUrl(Context, "market://search?q=keepass2android icon set");
});
-
+ Dialog = builder.Create();
+ Dialog.Show();
}
+
}
}
\ No newline at end of file
diff --git a/src/keepass2android/settings/PrefsUtil.cs b/src/keepass2android/settings/PrefsUtil.cs
index 8a3730de..4cc94f78 100644
--- a/src/keepass2android/settings/PrefsUtil.cs
+++ b/src/keepass2android/settings/PrefsUtil.cs
@@ -18,6 +18,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
using System;
using Android.Content;
using Android.Preferences;
+using keepass2android;
namespace keepass2android
{
diff --git a/src/keepass2android/settings/RoundsPreference.cs b/src/keepass2android/settings/RoundsPreference.cs
index 1769e1be..909cc1ff 100644
--- a/src/keepass2android/settings/RoundsPreference.cs
+++ b/src/keepass2android/settings/RoundsPreference.cs
@@ -21,30 +21,106 @@ using Android.Content;
using Android.OS;
using Android.Views;
using Android.Widget;
-using Android.Preferences;
+
using KeePassLib;
using Android.Util;
+using AndroidX.Preference;
+using keepass2android;
using KeePassLib.Cryptography.KeyDerivation;
+using Google.Android.Material.Dialog;
namespace keepass2android.settings
{
- public abstract class KdfNumberParamPreference: DialogPreference {
+ /*
+ *
+ public class KdfNumberDialogPreference : DialogPreference
+ {
+ private readonly Context _context;
+ public KdfNumberDialogPreference(Context context) : base(context)
+ {
+ _context = context;
+ }
+
+ public KdfNumberDialogPreference(Context context, IAttributeSet attrs) : base(context, attrs)
+ {
+ _context = context;
+ }
+
+ public KdfNumberDialogPreference(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
+ {
+ _context = context;
+ }
+
+ public override int DialogLayoutResource => Resource.Layout.activity_main;
+
+ }
+
+
+ */
+ public abstract class KdfNumberDialogPreference : DialogPreference {
- internal TextView edittext;
-
- protected override View OnCreateDialogView() {
- View view = base.OnCreateDialogView();
-
- edittext = (TextView) view.FindViewById(Resource.Id.rounds);
+ public KdfNumberDialogPreference(Context context) : base(context)
+ {
+
+ }
+ public KdfNumberDialogPreference(Context context, IAttributeSet attrs) : base(context, attrs)
+ {
+
+ }
- ulong numRounds = ParamValue;
- edittext.Text = numRounds.ToString(CultureInfo.InvariantCulture);
+ public KdfNumberDialogPreference(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
+ {
+
+ }
- view.FindViewById(Resource.Id.rounds_explaination).Text = ExplanationString;
+ public void ShowDialog(PreferenceFragmentCompat containingFragment)
+ {
+ var activity = containingFragment.Activity;
+ MaterialAlertDialogBuilder db = new MaterialAlertDialogBuilder(activity);
- return view;
- }
+ View dialogView = activity.LayoutInflater.Inflate(Resource.Layout.database_kdf_settings, null);
+ var inputEditText = dialogView.FindViewById(Resource.Id.rounds);
+
+ inputEditText.Text = ParamValue.ToString();
+
+ db.SetView(dialogView);
+ db.SetTitle(Title);
+ db.SetPositiveButton(Android.Resource.String.Ok, (sender, args) =>
+ {
+ //store the old value for restoring in case of failure
+ ulong paramValue;
+
+ String strRounds = inputEditText.Text;
+ if (!(ulong.TryParse(strRounds, out paramValue)))
+ {
+ Toast.MakeText(Context, Resource.String.error_param_not_number, ToastLength.Long).Show();
+ return;
+ }
+
+ if (paramValue < 1)
+ {
+ paramValue = 1;
+ }
+
+ ulong oldValue = ParamValue;
+
+ if (oldValue == paramValue)
+ {
+ return;
+ }
+
+ ParamValue = paramValue;
+
+ Handler handler = new Handler();
+ SaveDb save = new SaveDb((Activity)Context, App.Kp2a, App.Kp2a.CurrentDb, new AfterSave((Activity)Context, handler, oldValue, this));
+ ProgressTask pt = new ProgressTask(App.Kp2a, (Activity)Context, save);
+ pt.Run();
+ });
+ db.SetNegativeButton(Android.Resource.String.Cancel, ((sender, args) => { }));
+
+ db.Create().Show();
+ }
public virtual string ExplanationString
{
@@ -52,61 +128,17 @@ namespace keepass2android.settings
}
public abstract ulong ParamValue { get; set; }
- public KdfNumberParamPreference(Context context, IAttributeSet attrs):base(context, attrs) {
- }
- public KdfNumberParamPreference(Context context, IAttributeSet attrs, int defStyle)
- : base(context, attrs, defStyle)
- {
- }
-
- protected override void OnDialogClosed(bool positiveResult) {
- base.OnDialogClosed(positiveResult);
-
- if ( positiveResult ) {
- ulong paramValue;
-
- String strRounds = edittext.Text;
- if (!(ulong.TryParse(strRounds,out paramValue)))
- {
- Toast.MakeText(Context, Resource.String.error_param_not_number, ToastLength.Long).Show();
- return;
- }
-
- if ( paramValue < 1 ) {
- paramValue = 1;
- }
-
- Database db = App.Kp2a.CurrentDb;
-
- ulong oldValue = ParamValue;
-
- if (oldValue == paramValue)
- {
- return;
- }
-
- ParamValue = paramValue;
-
- Handler handler = new Handler();
- SaveDb save = new SaveDb((Activity)Context, App.Kp2a, App.Kp2a.CurrentDb, new KdfNumberParamPreference.AfterSave((Activity)Context, handler, oldValue, this));
- ProgressTask pt = new ProgressTask(App.Kp2a, (Activity)Context, save);
- pt.Run();
-
- }
-
- }
-
private class AfterSave : OnFinish {
- private readonly ulong _oldRounds;
+ private readonly ulong _oldParamValue;
private readonly Context _ctx;
- private readonly KdfNumberParamPreference _pref;
+ private readonly KdfNumberDialogPreference _pref;
- public AfterSave(Activity ctx, Handler handler, ulong oldRounds, KdfNumberParamPreference pref):base(ctx, handler) {
+ public AfterSave(Activity ctx, Handler handler, ulong oldParamValue, KdfNumberDialogPreference pref):base(ctx, handler) {
_pref = pref;
_ctx = ctx;
- _oldRounds = oldRounds;
+ _oldParamValue = oldParamValue;
}
public override void Run() {
@@ -118,8 +150,8 @@ namespace keepass2android.settings
} else {
DisplayMessage(_ctx);
- App.Kp2a.CurrentDb.KpDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds, _oldRounds);
- }
+ _pref.ParamValue = _oldParamValue;
+ }
base.Run();
}
@@ -131,7 +163,8 @@ namespace keepass2android.settings
///
/// Represents the setting for the number of key transformation rounds. Changing this requires to save the database.
///
- public class RoundsPreference : KdfNumberParamPreference {
+ public class RoundsPreference : KdfNumberDialogPreference
+ {
private readonly Context _context;
diff --git a/src/keepass2android/timeout/TimeoutHelper.cs b/src/keepass2android/timeout/TimeoutHelper.cs
index f3582321..51effeec 100644
--- a/src/keepass2android/timeout/TimeoutHelper.cs
+++ b/src/keepass2android/timeout/TimeoutHelper.cs
@@ -20,6 +20,7 @@ using Android.App;
using Android.Content;
using Android.Preferences;
using Android.Util;
+using keepass2android;
using KeePassLib.Serialization;
namespace keepass2android
diff --git a/src/keepass2android/views/EntryContentsView.cs b/src/keepass2android/views/EntryContentsView.cs
index 8535e34c..9627ae59 100644
--- a/src/keepass2android/views/EntryContentsView.cs
+++ b/src/keepass2android/views/EntryContentsView.cs
@@ -22,6 +22,7 @@ using Android.Widget;
using System;
using Android.Runtime;
+using keepass2android;
namespace keepass2android.view
diff --git a/src/keepass2android/views/EntrySection.cs b/src/keepass2android/views/EntrySection.cs
index aefee5a9..f051e491 100644
--- a/src/keepass2android/views/EntrySection.cs
+++ b/src/keepass2android/views/EntrySection.cs
@@ -21,6 +21,7 @@ using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Util;
+using keepass2android;
namespace keepass2android.view
{
diff --git a/src/keepass2android/views/GroupListItemView.cs b/src/keepass2android/views/GroupListItemView.cs
index 7b55d5a9..7e5b4b0d 100644
--- a/src/keepass2android/views/GroupListItemView.cs
+++ b/src/keepass2android/views/GroupListItemView.cs
@@ -4,6 +4,7 @@ using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
+using keepass2android;
namespace keepass2android.view
{
diff --git a/src/keepass2android/views/Kp2aShortHelpView.cs b/src/keepass2android/views/Kp2aShortHelpView.cs
index 6672a073..438e7e95 100644
--- a/src/keepass2android/views/Kp2aShortHelpView.cs
+++ b/src/keepass2android/views/Kp2aShortHelpView.cs
@@ -16,6 +16,8 @@ using Android.Text.Util;
using Android.Util;
using Android.Views;
using Android.Widget;
+using Google.Android.Material.Dialog;
+using keepass2android;
namespace keepass2android.views
{
@@ -77,7 +79,7 @@ namespace keepass2android.views
string title = Context.GetString(AppNames.AppNameResource);
if (!string.IsNullOrEmpty(TitleText))
title = TitleText;
- new AlertDialog.Builder(Context)
+ new MaterialAlertDialogBuilder(Context)
.SetTitle(title)
.SetMessage(_helpText)
.SetPositiveButton(Android.Resource.String.Ok, (o, eventArgs) => { })
diff --git a/src/keepass2android/views/PwEntryView.cs b/src/keepass2android/views/PwEntryView.cs
index fd5489e6..4a4fcca4 100644
--- a/src/keepass2android/views/PwEntryView.cs
+++ b/src/keepass2android/views/PwEntryView.cs
@@ -30,6 +30,7 @@ using KeeTrayTOTP.Libraries;
using PluginTOTP;
using Android.Content;
using System.ComponentModel;
+using keepass2android;
namespace keepass2android.view
@@ -157,7 +158,7 @@ namespace keepass2android.view
if (_groupActivity.IsBeingMoved(_entry.Uuid))
{
- int elementBeingMoved = Context.Resources.GetColor(Resource.Color.element_being_moved);
+ int elementBeingMoved = Context.Resources.GetColor(Resource.Color.md_theme_inversePrimary);
_textView.SetTextColor(new Color(elementBeingMoved));
}
else
diff --git a/src/keepass2android/views/PwGroupView.cs b/src/keepass2android/views/PwGroupView.cs
index 38cf6456..5a0584c1 100644
--- a/src/keepass2android/views/PwGroupView.cs
+++ b/src/keepass2android/views/PwGroupView.cs
@@ -21,6 +21,7 @@ using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
+using keepass2android;
using KeePassLib;
using Object = Java.Lang.Object;
@@ -98,7 +99,7 @@ namespace keepass2android.view
if (_groupBaseActivity.IsBeingMoved(_pwGroup.Uuid))
{
- int elementBeingMoved = Context.Resources.GetColor(Resource.Color.element_being_moved);
+ int elementBeingMoved = Context.Resources.GetColor(Resource.Color.md_theme_inversePrimary);
_textview.SetTextColor(new Color(elementBeingMoved));
}
else
diff --git a/src/keepass2android/views/TextWithHelp.cs b/src/keepass2android/views/TextWithHelp.cs
index ba1d511d..b4c78e56 100644
--- a/src/keepass2android/views/TextWithHelp.cs
+++ b/src/keepass2android/views/TextWithHelp.cs
@@ -11,6 +11,7 @@ using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
+using keepass2android;
namespace keepass2android.views
{