add Android Studio / gradle version of PluginSDK
This commit is contained in:
		
							
								
								
									
										27
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -152,3 +152,30 @@ Thumbs.db | ||||
| /src/java/PluginInputStick3/keepass2AndroidPluginSDK/build/ | ||||
| /src/java/KP2ASoftkeyboard_AS/.gradle/2.2.1/taskArtifacts/cache.properties | ||||
| /src/java/KP2ASoftkeyboard_AS/.gradle/2.2.1/taskArtifacts/cache.properties.lock | ||||
| /src/java/JavaFileStorageTest-AS/.idea/.name | ||||
| /src/java/JavaFileStorageTest-AS/.idea/compiler.xml | ||||
| /src/java/JavaFileStorageTest-AS/.idea/copyright/profiles_settings.xml | ||||
| /src/java/JavaFileStorageTest-AS/.idea/encodings.xml | ||||
| /src/java/JavaFileStorageTest-AS/.idea/gradle.xml | ||||
| /src/java/JavaFileStorageTest-AS/.idea/misc.xml | ||||
| /src/java/JavaFileStorageTest-AS/.idea/modules.xml | ||||
| /src/java/JavaFileStorageTest-AS/.idea/runConfigurations.xml | ||||
| /src/java/Keepass2AndroidPluginSDK2/.gradle/2.2.1/taskArtifacts/cache.properties | ||||
| /src/java/Keepass2AndroidPluginSDK2/.gradle/2.2.1/taskArtifacts/cache.properties.lock | ||||
| /src/java/Keepass2AndroidPluginSDK2/.gradle/2.2.1/taskArtifacts/fileHashes.bin | ||||
| /src/java/Keepass2AndroidPluginSDK2/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin | ||||
| /src/java/Keepass2AndroidPluginSDK2/.gradle/2.2.1/taskArtifacts/outputFileStates.bin | ||||
| /src/java/Keepass2AndroidPluginSDK2/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/.name | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/compiler.xml | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/copyright/profiles_settings.xml | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/encodings.xml | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/gradle.xml | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/libraries/effects_android_23.xml | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/libraries/maps_android_23.xml | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/libraries/mockable_Google_Inc__Google_APIs_23.xml | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/libraries/usb_android_23.xml | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/misc.xml | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/modules.xml | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/runConfigurations.xml | ||||
| /src/java/Keepass2AndroidPluginSDK2/.idea/workspace.xml | ||||
|   | ||||
| @@ -10,6 +10,28 @@ namespace keepass2android.Io | ||||
| { | ||||
| 	public static class IoUtil | ||||
| 	{ | ||||
|  | ||||
| 		public static bool TryTakePersistablePermissions(ContentResolver contentResolver, Android.Net.Uri uri) | ||||
| 		{ | ||||
| 			if ((int)Build.VERSION.SdkInt >= 19) | ||||
| 			{ | ||||
| 				//try to take persistable permissions | ||||
| 				try | ||||
| 				{ | ||||
| 					Kp2aLog.Log("TakePersistableUriPermission"); | ||||
| 					var takeFlags = (ActivityFlags.GrantReadUriPermission | ||||
| 							| ActivityFlags.GrantWriteUriPermission); | ||||
| 					contentResolver.TakePersistableUriPermission(uri, takeFlags); | ||||
| 					return true; | ||||
| 				} | ||||
| 				catch (Exception e) | ||||
| 				{ | ||||
| 					Kp2aLog.Log(e.ToString()); | ||||
| 				} | ||||
|  | ||||
| 			} | ||||
| 			return false; | ||||
| 		} | ||||
| 		public static bool DeleteDir(File dir, bool contentsOnly=false) | ||||
| 		{ | ||||
| 			if (dir != null && dir.IsDirectory) | ||||
| @@ -102,5 +124,6 @@ namespace keepass2android.Io | ||||
| 			else | ||||
| 				return ctx.FilesDir; | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -47,13 +47,23 @@ | ||||
|     <WarningLevel>4</WarningLevel> | ||||
|   </PropertyGroup> | ||||
|   <ItemGroup> | ||||
|     <Reference Include="ModernHttpClient"> | ||||
|       <HintPath>..\Components\modernhttpclient-2.4.2\lib\android\ModernHttpClient.dll</HintPath> | ||||
|     </Reference> | ||||
|     <Reference Include="Mono.Android" /> | ||||
|     <Reference Include="Mono.Security" /> | ||||
|     <Reference Include="mscorlib" /> | ||||
|     <Reference Include="OkHttp"> | ||||
|       <HintPath>..\Components\modernhttpclient-2.4.2\lib\android\OkHttp.dll</HintPath> | ||||
|     </Reference> | ||||
|     <Reference Include="System" /> | ||||
|     <Reference Include="System.Core" /> | ||||
|     <Reference Include="System.Net.Http" /> | ||||
|     <Reference Include="System.Xml.Linq" /> | ||||
|     <Reference Include="System.Xml" /> | ||||
|     <Reference Include="Xamarin.Insights"> | ||||
|       <HintPath>..\packages\Xamarin.Insights.1.11.3\lib\MonoAndroid10\Xamarin.Insights.dll</HintPath> | ||||
|     </Reference> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <Compile Include="database\CheckDatabaseForChanges.cs" /> | ||||
| @@ -123,6 +133,10 @@ | ||||
|     <Compile Include="Utils\Spr\SprEngine.PickChars.cs" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj"> | ||||
|       <Project>{48574278-4779-4b3a-a9e4-9cf1bc285d0b}</Project> | ||||
|       <Name>JavaFileStorageBindings</Name> | ||||
|     </ProjectReference> | ||||
|     <ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj"> | ||||
|       <Project>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</Project> | ||||
|       <Name>KeePassLib2Android</Name> | ||||
| @@ -131,6 +145,10 @@ | ||||
|       <Project>{70D3844A-D9FA-4A64-B205-A84C6A822196}</Project> | ||||
|       <Name>KP2AKdbLibraryBinding</Name> | ||||
|     </ProjectReference> | ||||
|     <ProjectReference Include="..\netftpandroid\System.Net.FtpClient\System.Net.FtpClient.Android.csproj"> | ||||
|       <Project>{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}</Project> | ||||
|       <Name>System.Net.FtpClient.Android</Name> | ||||
|     </ProjectReference> | ||||
|     <ProjectReference Include="..\TwofishCipher\TwofishCipher.csproj"> | ||||
|       <Project>{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}</Project> | ||||
|       <Name>TwofishCipher</Name> | ||||
| @@ -139,6 +157,12 @@ | ||||
|   <ItemGroup> | ||||
|     <Folder Include="Resources\" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <XamarinComponentReference Include="modernhttpclient"> | ||||
|       <Visible>False</Visible> | ||||
|       <Version>2.4.2</Version> | ||||
|     </XamarinComponentReference> | ||||
|   </ItemGroup> | ||||
|   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> | ||||
|   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.  | ||||
|        Other similar extension points exist, see Microsoft.Common.targets. | ||||
|   | ||||
| @@ -122,23 +122,7 @@ namespace keepass2android | ||||
| 					{ | ||||
| 						if (data.Data.Scheme == "content") | ||||
| 						{ | ||||
| 							if ((int) Build.VERSION.SdkInt >= 19) | ||||
| 							{ | ||||
| 								//try to take persistable permissions | ||||
| 								try | ||||
| 								{ | ||||
| 									Kp2aLog.Log("TakePersistableUriPermission"); | ||||
| 									var takeFlags = data.Flags | ||||
| 											& (ActivityFlags.GrantReadUriPermission | ||||
| 											| ActivityFlags.GrantWriteUriPermission); | ||||
| 									this.ContentResolver.TakePersistableUriPermission(data.Data, takeFlags); | ||||
| 								} | ||||
| 								catch (Exception e) | ||||
| 								{ | ||||
| 									Kp2aLog.Log(e.ToString()); | ||||
| 								} | ||||
| 								 | ||||
| 							} | ||||
| 							IoUtil.TryTakePersistablePermissions(this.ContentResolver, data.Data); | ||||
| 							 | ||||
| 							IocSelected(IOConnectionInfo.FromPath(data.DataString), requestCode); | ||||
|  | ||||
|   | ||||
| @@ -62,13 +62,6 @@ | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> | ||||
| @@ -76,6 +69,19 @@ | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotations" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-compat/24.2.0/jars" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-core-ui/24.2.0/jars" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-core-utils/24.2.0/jars" /> | ||||
| @@ -86,6 +92,11 @@ | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.microsoft.aad/adal/1.1.19/jars" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.microsoft.services.msa/msa-auth/0.8.6/jars" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.onedrive.sdk/onedrive-sdk-android/1.2.2/jars" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard-rules" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" /> | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -32,3 +32,6 @@ | ||||
| -keep interface keepass2android.javafilestorage.** {*; } | ||||
|  | ||||
| -keep interface keepass2android.javafilestorage.JavaFileStorage$FileStorageSetupActivity {*; } | ||||
|  | ||||
| -dontwarn | ||||
| -ignorewarnings | ||||
| @@ -15,7 +15,7 @@ | ||||
|             android:layout_height="wrap_content" | ||||
|             android:singleLine="true" | ||||
|             android:inputType="textNoSuggestions" | ||||
|             android:text="" | ||||
|             android:text="https://daigers.diskstation.me:5006/Keepass2Android/Apps/Keepass2Android/" | ||||
|             android:hint="Server URL" /> | ||||
|        </LinearLayout> | ||||
|     <EditText | ||||
| @@ -32,7 +32,7 @@ | ||||
|         android:layout_height="wrap_content" | ||||
|         android:inputType="textPassword" | ||||
|         android:singleLine="true" | ||||
|         android:text="" | ||||
|         android:text="$T3st17$" | ||||
|         android:hint="@string/hint_pass" /> | ||||
|  | ||||
| </LinearLayout> | ||||
							
								
								
									
										56
									
								
								src/java/KP2ASoftkeyboard_AS/.idea/workspace.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										56
									
								
								src/java/KP2ASoftkeyboard_AS/.idea/workspace.xml
									
									
									
										generated
									
									
									
								
							| @@ -38,7 +38,19 @@ | ||||
|           <provider selected="true" editor-type-id="text-editor"> | ||||
|             <state vertical-scroll-proportion="0.0"> | ||||
|               <caret line="406" column="0" selection-start-line="406" selection-start-column="0" selection-end-line="406" selection-end-column="0" /> | ||||
|               <folding /> | ||||
|               <folding> | ||||
|                 <element signature="imports" expanded="false" /> | ||||
|                 <element signature="e#1586#1587#0" expanded="false" /> | ||||
|                 <element signature="e#1622#1623#0" expanded="false" /> | ||||
|                 <element signature="e#1697#1698#0" expanded="false" /> | ||||
|                 <element signature="e#1749#1750#0" expanded="false" /> | ||||
|                 <element signature="e#2936#2937#0" expanded="false" /> | ||||
|                 <element signature="e#2969#2970#0" expanded="false" /> | ||||
|                 <element signature="e#13182#13183#0" expanded="false" /> | ||||
|                 <element signature="e#13236#13237#0" expanded="false" /> | ||||
|                 <element signature="e#13294#13295#0" expanded="false" /> | ||||
|                 <element signature="e#13348#13349#0" expanded="false" /> | ||||
|               </folding> | ||||
|             </state> | ||||
|           </provider> | ||||
|         </entry> | ||||
| @@ -118,8 +130,8 @@ | ||||
|       <file leaf-file-name="AndroidManifest.xml" pinned="false" current-in-tab="true"> | ||||
|         <entry file="file://$PROJECT_DIR$/app/src/main/AndroidManifest.xml"> | ||||
|           <provider selected="true" editor-type-id="text-editor"> | ||||
|             <state vertical-scroll-proportion="0.60714287"> | ||||
|               <caret line="19" column="19" selection-start-line="19" selection-start-column="19" selection-end-line="19" selection-end-column="19" /> | ||||
|             <state vertical-scroll-proportion="0.2236842"> | ||||
|               <caret line="7" column="25" selection-start-line="7" selection-start-column="25" selection-end-line="7" selection-end-column="25" /> | ||||
|               <folding /> | ||||
|             </state> | ||||
|           </provider> | ||||
| @@ -1682,7 +1694,7 @@ | ||||
|   </component> | ||||
|   <component name="ToolWindowManager"> | ||||
|     <frame x="-8" y="-8" width="1382" height="744" extended-state="6" /> | ||||
|     <editor active="false" /> | ||||
|     <editor active="true" /> | ||||
|     <layout> | ||||
|       <window_info id="Palette	" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Designer" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> | ||||
| @@ -1698,10 +1710,11 @@ | ||||
|       <window_info id="Gradle Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" /> | ||||
|       <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Build Variants" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" /> | ||||
|       <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32764506" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Gradle" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.24962063" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.24886535" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" /> | ||||
|       <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.24886535" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" /> | ||||
|       <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> | ||||
| @@ -1709,7 +1722,6 @@ | ||||
|       <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32764506" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32764506" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Android" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32879046" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> | ||||
|       <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" /> | ||||
| @@ -1736,7 +1748,19 @@ | ||||
|       <provider selected="true" editor-type-id="text-editor"> | ||||
|         <state vertical-scroll-proportion="0.0"> | ||||
|           <caret line="406" column="0" selection-start-line="406" selection-start-column="0" selection-end-line="406" selection-end-column="0" /> | ||||
|           <folding /> | ||||
|           <folding> | ||||
|             <element signature="imports" expanded="false" /> | ||||
|             <element signature="e#1586#1587#0" expanded="false" /> | ||||
|             <element signature="e#1622#1623#0" expanded="false" /> | ||||
|             <element signature="e#1697#1698#0" expanded="false" /> | ||||
|             <element signature="e#1749#1750#0" expanded="false" /> | ||||
|             <element signature="e#2936#2937#0" expanded="false" /> | ||||
|             <element signature="e#2969#2970#0" expanded="false" /> | ||||
|             <element signature="e#13182#13183#0" expanded="false" /> | ||||
|             <element signature="e#13236#13237#0" expanded="false" /> | ||||
|             <element signature="e#13294#13295#0" expanded="false" /> | ||||
|             <element signature="e#13348#13349#0" expanded="false" /> | ||||
|           </folding> | ||||
|         </state> | ||||
|       </provider> | ||||
|     </entry> | ||||
| @@ -1960,7 +1984,19 @@ | ||||
|       <provider selected="true" editor-type-id="text-editor"> | ||||
|         <state vertical-scroll-proportion="0.0"> | ||||
|           <caret line="406" column="0" selection-start-line="406" selection-start-column="0" selection-end-line="406" selection-end-column="0" /> | ||||
|           <folding /> | ||||
|           <folding> | ||||
|             <element signature="imports" expanded="false" /> | ||||
|             <element signature="e#1586#1587#0" expanded="false" /> | ||||
|             <element signature="e#1622#1623#0" expanded="false" /> | ||||
|             <element signature="e#1697#1698#0" expanded="false" /> | ||||
|             <element signature="e#1749#1750#0" expanded="false" /> | ||||
|             <element signature="e#2936#2937#0" expanded="false" /> | ||||
|             <element signature="e#2969#2970#0" expanded="false" /> | ||||
|             <element signature="e#13182#13183#0" expanded="false" /> | ||||
|             <element signature="e#13236#13237#0" expanded="false" /> | ||||
|             <element signature="e#13294#13295#0" expanded="false" /> | ||||
|             <element signature="e#13348#13349#0" expanded="false" /> | ||||
|           </folding> | ||||
|         </state> | ||||
|       </provider> | ||||
|     </entry> | ||||
| @@ -1974,8 +2010,8 @@ | ||||
|     </entry> | ||||
|     <entry file="file://$PROJECT_DIR$/app/src/main/AndroidManifest.xml"> | ||||
|       <provider selected="true" editor-type-id="text-editor"> | ||||
|         <state vertical-scroll-proportion="0.60714287"> | ||||
|           <caret line="19" column="19" selection-start-line="19" selection-start-column="19" selection-end-line="19" selection-end-column="19" /> | ||||
|         <state vertical-scroll-proportion="0.2236842"> | ||||
|           <caret line="7" column="25" selection-start-line="7" selection-start-column="25" selection-end-line="7" selection-end-column="25" /> | ||||
|           <folding /> | ||||
|         </state> | ||||
|       </provider> | ||||
|   | ||||
| @@ -0,0 +1,19 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <module external.linked.project.id="Keepass2AndroidPluginSDK2" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> | ||||
|   <component name="FacetManager"> | ||||
|     <facet type="java-gradle" name="Java-Gradle"> | ||||
|       <configuration> | ||||
|         <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" /> | ||||
|         <option name="BUILDABLE" value="false" /> | ||||
|       </configuration> | ||||
|     </facet> | ||||
|   </component> | ||||
|   <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true"> | ||||
|     <exclude-output /> | ||||
|     <content url="file://$MODULE_DIR$"> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/.gradle" /> | ||||
|     </content> | ||||
|     <orderEntry type="inheritedJdk" /> | ||||
|     <orderEntry type="sourceFolder" forTests="false" /> | ||||
|   </component> | ||||
| </module> | ||||
							
								
								
									
										101
									
								
								src/java/Keepass2AndroidPluginSDK2/app/app.iml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/java/Keepass2AndroidPluginSDK2/app/app.iml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="Keepass2AndroidPluginSDK2" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> | ||||
|   <component name="FacetManager"> | ||||
|     <facet type="android-gradle" name="Android-Gradle"> | ||||
|       <configuration> | ||||
|         <option name="GRADLE_PROJECT_PATH" value=":app" /> | ||||
|       </configuration> | ||||
|     </facet> | ||||
|     <facet type="android" name="Android"> | ||||
|       <configuration> | ||||
|         <option name="SELECTED_BUILD_VARIANT" value="debug" /> | ||||
|         <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" /> | ||||
|         <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" /> | ||||
|         <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" /> | ||||
|         <afterSyncTasks> | ||||
|           <task>generateDebugSources</task> | ||||
|         </afterSyncTasks> | ||||
|         <option name="ALLOW_USER_CONFIGURATION" value="false" /> | ||||
|         <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> | ||||
|         <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" /> | ||||
|         <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" /> | ||||
|         <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" /> | ||||
|         <option name="LIBRARY_PROJECT" value="true" /> | ||||
|       </configuration> | ||||
|     </facet> | ||||
|   </component> | ||||
|   <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false"> | ||||
|     <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" /> | ||||
|     <output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" /> | ||||
|     <exclude-output /> | ||||
|     <content url="file://$MODULE_DIR$"> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" /> | ||||
|       <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/mockable-Google-Inc.-Google-APIs-23.jar" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/resources" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/outputs" /> | ||||
|       <excludeFolder url="file://$MODULE_DIR$/build/tmp" /> | ||||
|     </content> | ||||
|     <orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" /> | ||||
|     <orderEntry type="sourceFolder" forTests="false" /> | ||||
|     <orderEntry type="library" exported="" scope="TEST" name="mockable-Google-Inc.-Google-APIs-23" level="project" /> | ||||
|     <orderEntry type="library" exported="" name="effects-android-23" level="project" /> | ||||
|     <orderEntry type="library" exported="" name="usb-android-23" level="project" /> | ||||
|     <orderEntry type="library" exported="" name="maps-android-23" level="project" /> | ||||
|   </component> | ||||
| </module> | ||||
							
								
								
									
										20
									
								
								src/java/Keepass2AndroidPluginSDK2/app/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/java/Keepass2AndroidPluginSDK2/app/build.gradle
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| apply plugin: 'com.android.library' | ||||
| android { | ||||
|     compileSdkVersion 'Google Inc.:Google APIs:23' | ||||
|     buildToolsVersion '23.0.1' | ||||
|  | ||||
|     defaultConfig { | ||||
|         minSdkVersion 8 | ||||
|         targetSdkVersion 19 | ||||
|     } | ||||
|  | ||||
|     buildTypes { | ||||
|         release { | ||||
|             minifyEnabled false | ||||
|             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| dependencies { | ||||
| } | ||||
							
								
								
									
										3
									
								
								src/java/Keepass2AndroidPluginSDK2/app/lint.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/java/Keepass2AndroidPluginSDK2/app/lint.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <lint> | ||||
| </lint> | ||||
| @@ -0,0 +1,18 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     package="keepass2android.pluginsdk" | ||||
|     android:versionCode="1" | ||||
|     android:versionName="1.0" > | ||||
|  | ||||
|     <uses-sdk | ||||
|         android:minSdkVersion="8" | ||||
|         android:targetSdkVersion="19" /> | ||||
|  | ||||
|     <application | ||||
|         android:allowBackup="true" | ||||
|         android:icon="@drawable/ic_launcher" | ||||
|         android:label="@string/app_name" | ||||
|         android:theme="@style/AppTheme" > | ||||
|     </application> | ||||
|  | ||||
| </manifest> | ||||
| @@ -0,0 +1,201 @@ | ||||
| package keepass2android.pluginsdk; | ||||
|  | ||||
| import java.lang.reflect.Field; | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashSet; | ||||
| import java.util.Set; | ||||
|  | ||||
| import org.json.JSONArray; | ||||
| import org.json.JSONException; | ||||
|  | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.SharedPreferences.Editor; | ||||
| import android.content.pm.PackageInfo; | ||||
| import android.content.pm.PackageManager; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.text.TextUtils; | ||||
| import android.util.Log; | ||||
| import android.view.View; | ||||
| import android.widget.PopupMenu; | ||||
|  | ||||
|  | ||||
| public class AccessManager  | ||||
| { | ||||
| 	 | ||||
| 	private static final String _tag = "Kp2aPluginSDK"; | ||||
| 	private static final String PREF_KEY_SCOPE = "scope"; | ||||
| 	private static final String PREF_KEY_TOKEN = "token"; | ||||
|  | ||||
| 	public static String stringArrayToString(ArrayList<String> values) { | ||||
| 	    JSONArray a = new JSONArray(); | ||||
| 	    for (int i = 0; i < values.size(); i++) { | ||||
| 	        a.put(values.get(i)); | ||||
| 	    } | ||||
| 	    if (!values.isEmpty()) { | ||||
| 	        return a.toString(); | ||||
| 	    } else { | ||||
| 	        return null; | ||||
| 	    } | ||||
| 	     | ||||
| 	} | ||||
|  | ||||
| 	public static ArrayList<String> stringToStringArray(String s) { | ||||
| 	    ArrayList<String> strings = new ArrayList<String>(); | ||||
| 	    if (TextUtils.isEmpty(s) == false) { | ||||
| 	        try { | ||||
| 	            JSONArray a = new JSONArray(s); | ||||
| 	            for (int i = 0; i < a.length(); i++) { | ||||
| 	                String url = a.optString(i); | ||||
| 	                strings.add(url); | ||||
| 	            } | ||||
| 	        } catch (JSONException e) { | ||||
| 	            e.printStackTrace(); | ||||
| 	        } | ||||
| 	    } | ||||
| 	    return strings; | ||||
| 	} | ||||
| 	 | ||||
| 	public static void storeAccessToken(Context ctx, String hostPackage, String accessToken, ArrayList<String> scopes) | ||||
| 	{ | ||||
| 		 SharedPreferences prefs = getPrefsForHost(ctx, hostPackage); | ||||
| 		   | ||||
| 		 Editor edit = prefs.edit(); | ||||
| 		 edit.putString(PREF_KEY_TOKEN, accessToken); | ||||
| 		 String scopesString = stringArrayToString(scopes); | ||||
| 		 edit.putString(PREF_KEY_SCOPE, scopesString); | ||||
| 		 edit.commit(); | ||||
| 		 Log.d(_tag, "stored access token " + accessToken.substring(0, 4)+"... for "+scopes.size()+" scopes ("+scopesString+")."); | ||||
| 		  | ||||
| 		 SharedPreferences hostPrefs = ctx.getSharedPreferences("KP2A.PluginAccess.hosts", Context.MODE_PRIVATE); | ||||
| 		 if (!hostPrefs.contains(hostPackage)) | ||||
| 		 { | ||||
| 			 hostPrefs.edit().putString(hostPackage, "").commit(); | ||||
| 		 } | ||||
| 		  | ||||
| 		  | ||||
| 	} | ||||
| 	 | ||||
| 	public static void preparePopup(Object popupMenu) | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			Field[] fields = popupMenu.getClass().getDeclaredFields(); | ||||
| 			for (Field field : fields) { | ||||
| 				if ("mPopup".equals(field.getName())) { | ||||
| 					field.setAccessible(true); | ||||
| 					Object menuPopupHelper = field.get(popupMenu); | ||||
| 					Class<?> classPopupHelper = Class.forName(menuPopupHelper | ||||
| 							.getClass().getName()); | ||||
| 					Method setForceIcons = classPopupHelper.getMethod( | ||||
| 							"setForceShowIcon", boolean.class); | ||||
| 					setForceIcons.invoke(menuPopupHelper, true); | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			 | ||||
| 		} | ||||
| 		catch (Exception e) | ||||
| 		{ | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private static SharedPreferences getPrefsForHost(Context ctx, | ||||
| 			String hostPackage) { | ||||
| 		SharedPreferences prefs = ctx.getSharedPreferences("KP2A.PluginAccess."+hostPackage, Context.MODE_PRIVATE); | ||||
| 		return prefs; | ||||
| 	} | ||||
|  | ||||
| 	public static String tryGetAccessToken(Context ctx, String hostPackage, ArrayList<String> scopes) { | ||||
| 		 | ||||
| 		if (TextUtils.isEmpty(hostPackage)) | ||||
| 		{ | ||||
| 			Log.d(_tag, "hostPackage is empty!"); | ||||
| 			return null; | ||||
| 		} | ||||
| 		Log.d(_tag, "trying to find prefs for "+hostPackage); | ||||
| 		SharedPreferences prefs = getPrefsForHost(ctx, hostPackage); | ||||
| 		String scopesString = prefs.getString(PREF_KEY_SCOPE, ""); | ||||
| 		Log.d(_tag, "available scopes: "+ scopesString); | ||||
| 		ArrayList<String> currentScope = stringToStringArray(scopesString); | ||||
| 		if (isSubset(scopes, currentScope)) | ||||
| 		{ | ||||
| 			return prefs.getString(PREF_KEY_TOKEN, null); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			Log.d(_tag, "looks like scope changed. Access token invalid."); | ||||
| 			return null; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public static boolean isSubset(ArrayList<String> requiredScopes, | ||||
| 			ArrayList<String> availableScopes) { | ||||
| 		for (String r: requiredScopes){ | ||||
| 			if (availableScopes.indexOf(r)<0) | ||||
| 			{ | ||||
| 				Log.d(_tag, "Scope "+r+" not available. "+availableScopes.size()); | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	public static void removeAccessToken(Context ctx, String hostPackage, | ||||
| 			String accessToken) { | ||||
| 		SharedPreferences prefs = getPrefsForHost(ctx, hostPackage); | ||||
|  | ||||
| 		Log.d(_tag, "removing AccessToken."); | ||||
| 		if (prefs.getString(PREF_KEY_TOKEN, "").equals(accessToken)) | ||||
| 		{ | ||||
| 			Editor edit = prefs.edit(); | ||||
| 			edit.clear(); | ||||
| 			edit.commit(); | ||||
|  | ||||
| 		} | ||||
| 		 | ||||
| 		SharedPreferences hostPrefs = ctx.getSharedPreferences("KP2A.PluginAccess.hosts", Context.MODE_PRIVATE); | ||||
| 		if (hostPrefs.contains(hostPackage)) | ||||
| 		{ | ||||
| 			hostPrefs.edit().remove(hostPackage).commit(); | ||||
| 		} | ||||
| 	  | ||||
| 	} | ||||
| 	 | ||||
| 	public static Set<String> getAllHostPackages(Context ctx) | ||||
| 	{ | ||||
| 		SharedPreferences prefs = ctx.getSharedPreferences("KP2A.PluginAccess.hosts", Context.MODE_PRIVATE); | ||||
| 		Set<String> result = new HashSet<String>(); | ||||
| 		for (String host: prefs.getAll().keySet()) | ||||
| 		{ | ||||
| 			try | ||||
| 			{ | ||||
| 				PackageInfo info = ctx.getPackageManager().getPackageInfo(host, PackageManager.GET_META_DATA); | ||||
| 				//if we get here, the package is still there | ||||
| 				result.add(host); | ||||
| 			} | ||||
| 			catch (PackageManager.NameNotFoundException e) | ||||
| 			{ | ||||
| 				//host gone. ignore. | ||||
| 			} | ||||
| 		} | ||||
| 		return result; | ||||
| 		 | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns a valid access token or throws PluginAccessException | ||||
| 	 */ | ||||
| 	public static String getAccessToken(Context context, String hostPackage, | ||||
| 			ArrayList<String> scopes) throws PluginAccessException { | ||||
| 		String accessToken = tryGetAccessToken(context, hostPackage, scopes); | ||||
| 		if (accessToken == null) | ||||
| 			throw new PluginAccessException(hostPackage, scopes); | ||||
| 		return accessToken; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,48 @@ | ||||
| package keepass2android.pluginsdk; | ||||
|  | ||||
| public class KeepassDefs { | ||||
|  | ||||
| 	/// <summary> | ||||
| 	/// Default identifier string for the title field. Should not contain | ||||
| 	/// spaces, tabs or other whitespace. | ||||
| 	/// </summary> | ||||
| 	public static String TitleField = "Title"; | ||||
|  | ||||
| 	/// <summary> | ||||
| 	/// Default identifier string for the user name field. Should not contain | ||||
| 	/// spaces, tabs or other whitespace. | ||||
| 	/// </summary> | ||||
| 	public static String UserNameField = "UserName"; | ||||
|  | ||||
| 	/// <summary> | ||||
| 	/// Default identifier string for the password field. Should not contain | ||||
| 	/// spaces, tabs or other whitespace. | ||||
| 	/// </summary> | ||||
| 	public static String PasswordField = "Password"; | ||||
|  | ||||
| 	/// <summary> | ||||
| 	/// Default identifier string for the URL field. Should not contain | ||||
| 	/// spaces, tabs or other whitespace. | ||||
| 	/// </summary> | ||||
| 	public static String UrlField = "URL"; | ||||
|  | ||||
| 	/// <summary> | ||||
| 	/// Default identifier string for the notes field. Should not contain | ||||
| 	/// spaces, tabs or other whitespace. | ||||
| 	/// </summary> | ||||
| 	public static String NotesField = "Notes"; | ||||
|  | ||||
| 	 | ||||
| 	public static boolean IsStandardField(String strFieldName) | ||||
| 	{ | ||||
| 		if(strFieldName == null) | ||||
| 			return false; | ||||
| 		if(strFieldName.equals(TitleField)) return true; | ||||
| 		if(strFieldName.equals(UserNameField)) return true; | ||||
| 		if(strFieldName.equals(PasswordField)) return true; | ||||
| 		if(strFieldName.equals(UrlField)) return true; | ||||
| 		if(strFieldName.equals(NotesField)) return true; | ||||
|  | ||||
| 		return false; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,111 @@ | ||||
| package keepass2android.pluginsdk; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.Iterator; | ||||
|  | ||||
| import org.json.JSONArray; | ||||
| import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
|  | ||||
| import android.content.Intent; | ||||
| import android.text.TextUtils; | ||||
|  | ||||
| public class Kp2aControl { | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Creates and returns an intent to launch Keepass2Android for adding an entry with the given fields. | ||||
| 	 * @param fields Key/Value pairs of the field values. See KeepassDefs for standard keys. | ||||
| 	 * @param protectedFields List of keys of the protected fields. | ||||
| 	 * @return Intent to start Keepass2Android. | ||||
| 	 * @throws JSONException | ||||
| 	 */ | ||||
| 	public static Intent getAddEntryIntent(HashMap<String, String> fields, ArrayList<String> protectedFields) | ||||
| 	{ | ||||
| 		return getAddEntryIntent(new JSONObject(fields).toString(), protectedFields); | ||||
| 	} | ||||
| 	 | ||||
| 	public static Intent getAddEntryIntent(String outputData, ArrayList<String> protectedFields) | ||||
| 	{ | ||||
| 		Intent startKp2aIntent = new Intent(Strings.ACTION_START_WITH_TASK); | ||||
| 		startKp2aIntent.addCategory(Intent.CATEGORY_DEFAULT); | ||||
| 		startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); | ||||
| 		startKp2aIntent.putExtra("KP2A_APPTASK", "CreateEntryThenCloseTask"); | ||||
| 		startKp2aIntent.putExtra("ShowUserNotifications", "false"); //KP2A expects a StringExtra | ||||
| 		startKp2aIntent.putExtra(Strings.EXTRA_ENTRY_OUTPUT_DATA, outputData); | ||||
| 		if (protectedFields != null) | ||||
| 			startKp2aIntent.putStringArrayListExtra(Strings.EXTRA_PROTECTED_FIELDS_LIST, protectedFields); | ||||
| 		 | ||||
| 			 | ||||
| 		return startKp2aIntent; | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Creates an intent to open a Password Entry matching searchText | ||||
| 	 * @param searchText queryString | ||||
| 	 * @param showUserNotifications if true, the notifications (copy to clipboard, keyboard) are displayed | ||||
| 	 * @param closeAfterOpen if true, the entry is opened and KP2A is immediately closed | ||||
| 	 * @return Intent to start KP2A with | ||||
| 	 */ | ||||
| 	public static Intent getOpenEntryIntent(String searchText, boolean showUserNotifications, boolean closeAfterOpen) | ||||
| 	{ | ||||
| 		Intent startKp2aIntent = new Intent(Strings.ACTION_START_WITH_TASK); | ||||
| 		startKp2aIntent.addCategory(Intent.CATEGORY_DEFAULT); | ||||
| 		startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); | ||||
| 		startKp2aIntent.putExtra("KP2A_APPTASK", "SearchUrlTask"); | ||||
| 		startKp2aIntent.putExtra("ShowUserNotifications", String.valueOf(showUserNotifications)); | ||||
| 		startKp2aIntent.putExtra("CloseAfterCreate", String.valueOf(closeAfterOpen)); | ||||
| 		startKp2aIntent.putExtra("UrlToSearch", searchText); | ||||
| 		return startKp2aIntent; | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Creates an intent to query a password entry from KP2A. The credentials are returned as Activity result. | ||||
| 	 * @param searchText Text to search for. Should be a URL or "androidapp://com.my.package." | ||||
| 	 * @return an Intent to start KP2A with | ||||
| 	 */ | ||||
| 	public static Intent getQueryEntryIntent(String searchText) | ||||
| 	{ | ||||
| 		Intent i = new Intent(Strings.ACTION_QUERY_CREDENTIALS); | ||||
| 		if (!TextUtils.isEmpty(searchText)) | ||||
| 			i.putExtra(Strings.EXTRA_QUERY_STRING, searchText); | ||||
| 		return i; | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Creates an intent to query a password entry from KP2A, matching to the current app's package .  | ||||
| 	 * The credentials are returned as Activity result. | ||||
| 	 * This requires SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE. | ||||
| 	 * @return an Intent to start KP2A with | ||||
| 	 */ | ||||
| 	public static Intent getQueryEntryIntentForOwnPackage() | ||||
| 	{ | ||||
| 		return new Intent(Strings.ACTION_QUERY_CREDENTIALS_FOR_OWN_PACKAGE); | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Converts the entry fields returned in an intent from a query to a hashmap.  | ||||
| 	 * @param intent data received in onActivityResult after getQueryEntryIntent(ForOwnPackage) | ||||
| 	 * @return HashMap with keys = field names (see KeepassDefs for standard keys) and values = values | ||||
| 	 */ | ||||
| 	public static HashMap<String, String> getEntryFieldsFromIntent(Intent intent)   | ||||
| 	{ | ||||
| 		HashMap<String, String> res = new HashMap<String, String>(); | ||||
| 		try { | ||||
| 			JSONObject json = new JSONObject(intent.getStringExtra(Strings.EXTRA_ENTRY_OUTPUT_DATA)); | ||||
| 			for(Iterator<String> iter = json.keys();iter.hasNext();) { | ||||
| 			    String key = iter.next(); | ||||
| 			    String value = json.get(key).toString(); | ||||
| 			    res.put(key, value); | ||||
| 			} | ||||
| 			 | ||||
| 		} catch (JSONException e) { | ||||
| 			e.printStackTrace(); | ||||
| 		} catch (NullPointerException e) { | ||||
| 			e.printStackTrace(); | ||||
| 		}  | ||||
| 		return res; | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,101 @@ | ||||
| package keepass2android.pluginsdk; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
|  | ||||
| import android.R.anim; | ||||
| import android.content.BroadcastReceiver; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.util.Log; | ||||
|  | ||||
| /** | ||||
|  * Broadcast flow between Host and Plugin | ||||
|  * ====================================== | ||||
|  *  | ||||
|  * The host is responsible for deciding when to initiate the session. It  | ||||
|  * should initiate the session as soon as plugins are required or when a plugin  | ||||
|  * has been updated through the OS. | ||||
|  * It will then send a broadcast to request the currently required scope. | ||||
|  * The plugin then sends a broadcast to the app which scope is required. If an  | ||||
|  * access token is already available, it's sent along with the requset. | ||||
|  *  | ||||
|  * If a previous permission has been revoked (or the app settings cleared or the  | ||||
|  * permissions have been extended or the token is invalid for any other reason)  | ||||
|  * the host will answer with a Revoked-Permission broadcast (i.e. the plugin is  | ||||
|  * unconnected.) | ||||
|  *  | ||||
|  *  Unconnected plugins must be permitted by the user (requiring user action).  | ||||
|  *  When the user grants access, the plugin will receive an access token for  | ||||
|  *  the host. This access token is valid for the requested scope. If the scope | ||||
|  *  changes (e.g after an update of the plugin), the access token becomes invalid. | ||||
|  * | ||||
|  */ | ||||
| public abstract class PluginAccessBroadcastReceiver extends BroadcastReceiver { | ||||
| 	 | ||||
| 	private static final String _tag = "Kp2aPluginSDK"; | ||||
| 	 | ||||
| 	@Override | ||||
| 	public void onReceive(Context ctx, Intent intent) { | ||||
| 		String action = intent.getAction(); | ||||
| 		android.util.Log.d(_tag, "received broadcast with action="+action); | ||||
| 		if (action == null) | ||||
| 			return; | ||||
| 		if (action.equals(Strings.ACTION_TRIGGER_REQUEST_ACCESS)) | ||||
| 		{ | ||||
| 			requestAccess(ctx, intent);	 | ||||
| 		} else if (action.equals(Strings.ACTION_RECEIVE_ACCESS)) | ||||
| 		{ | ||||
| 			receiveAccess(ctx, intent); | ||||
| 		} else if (action.equals(Strings.ACTION_REVOKE_ACCESS)) | ||||
| 		{ | ||||
| 			revokeAccess(ctx, intent); | ||||
| 		} else | ||||
| 		{ | ||||
| 			//TODO handle unexpected action | ||||
| 		}		 | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
|  | ||||
| 	private void revokeAccess(Context ctx, Intent intent) { | ||||
| 		String senderPackage = intent.getStringExtra(Strings.EXTRA_SENDER); | ||||
| 		String accessToken = intent.getStringExtra(Strings.EXTRA_ACCESS_TOKEN); | ||||
| 		//this intent must send the invalid(ated) token to prevent malicious apps | ||||
| 		//from revoking access of all plugins. | ||||
| 		AccessManager.removeAccessToken(ctx, senderPackage, accessToken); | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
| 	private void receiveAccess(Context ctx, Intent intent) { | ||||
| 		String senderPackage = intent.getStringExtra(Strings.EXTRA_SENDER); | ||||
| 		String accessToken = intent.getStringExtra(Strings.EXTRA_ACCESS_TOKEN); | ||||
| 		AccessManager.storeAccessToken(ctx, senderPackage, accessToken, getScopes()); | ||||
| 	} | ||||
|  | ||||
| 	public void requestAccess(Context ctx, Intent intent) { | ||||
| 		String senderPackage = intent.getStringExtra(Strings.EXTRA_SENDER); | ||||
| 		String requestToken = intent.getStringExtra(Strings.EXTRA_REQUEST_TOKEN); | ||||
| 		Intent rpi = new Intent(Strings.ACTION_REQUEST_ACCESS); | ||||
| 		rpi.setPackage(senderPackage); | ||||
| 		rpi.putExtra(Strings.EXTRA_SENDER, ctx.getPackageName()); | ||||
| 		rpi.putExtra(Strings.EXTRA_REQUEST_TOKEN, requestToken); | ||||
| 		 | ||||
| 		String token = AccessManager.tryGetAccessToken(ctx, senderPackage, getScopes()); | ||||
| 		if (token != null) | ||||
| 		{ | ||||
| 			rpi.putExtra(Strings.EXTRA_ACCESS_TOKEN, token); | ||||
| 		} | ||||
| 		 | ||||
| 		rpi.putStringArrayListExtra(Strings.EXTRA_SCOPES, getScopes()); | ||||
| 		Log.d(_tag, "requesting access for "+getScopes().size()+" tokens."); | ||||
| 		ctx.sendBroadcast(rpi); | ||||
| 	} | ||||
|  | ||||
| 	/**  | ||||
| 	 *  | ||||
| 	 * @return the list of required scopes for this plugin.  | ||||
| 	 */ | ||||
| 	abstract public ArrayList<String> getScopes(); | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,21 @@ | ||||
| package keepass2android.pluginsdk; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
|  | ||||
| public class PluginAccessException extends Exception { | ||||
| 	 | ||||
| 	public PluginAccessException(String what) | ||||
| 	{ | ||||
| 		super(what); | ||||
| 	} | ||||
|  | ||||
| 	public PluginAccessException(String hostPackage, ArrayList<String> scopes) { | ||||
| 		 | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 *  | ||||
| 	 */ | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,303 @@ | ||||
| package keepass2android.pluginsdk; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.Iterator; | ||||
|  | ||||
| import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
|  | ||||
| import android.content.BroadcastReceiver; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.os.Bundle; | ||||
| import android.util.Log; | ||||
|  | ||||
| public abstract class PluginActionBroadcastReceiver extends BroadcastReceiver { | ||||
| 	 | ||||
| 	protected abstract class PluginActionBase | ||||
| 	{ | ||||
| 		protected Context _context; | ||||
| 		protected Intent _intent; | ||||
| 		 | ||||
|  | ||||
| 		public PluginActionBase(Context context, Intent intent)  | ||||
| 		{ | ||||
| 			_context = context; | ||||
| 			_intent = intent; | ||||
| 		} | ||||
|  | ||||
| 		public String getHostPackage() { | ||||
| 			return _intent.getStringExtra(Strings.EXTRA_SENDER); | ||||
| 		} | ||||
| 		 | ||||
| 		public Context getContext() | ||||
| 		{ | ||||
| 			return _context; | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
| 	 | ||||
| 	protected abstract class PluginEntryActionBase extends PluginActionBase | ||||
| 	{ | ||||
| 		 | ||||
| 		public PluginEntryActionBase(Context context, Intent intent) | ||||
| 		{ | ||||
| 			super(context, intent); | ||||
| 		} | ||||
| 		 | ||||
| 		protected HashMap<String, String> getEntryFieldsFromIntent()   | ||||
| 		{ | ||||
| 			HashMap<String, String> res = new HashMap<String, String>(); | ||||
| 			try { | ||||
| 				JSONObject json = new JSONObject(_intent.getStringExtra(Strings.EXTRA_ENTRY_OUTPUT_DATA)); | ||||
| 				for(Iterator<String> iter = json.keys();iter.hasNext();) { | ||||
| 				    String key = iter.next(); | ||||
| 				    String value = json.get(key).toString(); | ||||
| 				    Log.d("KP2APluginSDK", "received " + key+"/"+value); | ||||
| 				    res.put(key, value); | ||||
| 				} | ||||
| 				 | ||||
| 			} catch (JSONException e) { | ||||
| 				e.printStackTrace(); | ||||
| 			}  | ||||
| 			return res; | ||||
| 		} | ||||
| 		 | ||||
| 		protected String[] getProtectedFieldsListFromIntent() | ||||
| 		{ | ||||
| 			return _intent.getStringArrayExtra(Strings.EXTRA_PROTECTED_FIELDS_LIST); | ||||
| 		} | ||||
| 		 | ||||
|  | ||||
| 		public String getEntryId() | ||||
| 		{ | ||||
| 			return _intent.getStringExtra(Strings.EXTRA_ENTRY_ID); | ||||
| 		} | ||||
| 		 | ||||
|  | ||||
| 		public void setEntryField(String fieldId, String fieldValue, boolean isProtected) throws PluginAccessException | ||||
| 		{ | ||||
| 			Intent i = new Intent(Strings.ACTION_SET_ENTRY_FIELD); | ||||
| 			ArrayList<String> scope = new ArrayList<String>(); | ||||
| 			scope.add(Strings.SCOPE_CURRENT_ENTRY); | ||||
| 			i.putExtra(Strings.EXTRA_ACCESS_TOKEN, AccessManager.getAccessToken(_context, getHostPackage(), scope)); | ||||
| 			i.setPackage(getHostPackage()); | ||||
| 			i.putExtra(Strings.EXTRA_SENDER, _context.getPackageName()); | ||||
| 			i.putExtra(Strings.EXTRA_FIELD_VALUE, fieldValue); | ||||
| 			i.putExtra(Strings.EXTRA_ENTRY_ID, getEntryId()); | ||||
| 			i.putExtra(Strings.EXTRA_FIELD_ID, fieldId); | ||||
| 			i.putExtra(Strings.EXTRA_FIELD_PROTECTED, isProtected); | ||||
| 			 | ||||
| 			_context.sendBroadcast(i); | ||||
| 		} | ||||
| 	 | ||||
| 	} | ||||
| 	 | ||||
| 	protected class ActionSelectedAction extends PluginEntryActionBase | ||||
| 	{ | ||||
| 		public ActionSelectedAction(Context ctx, Intent intent) { | ||||
| 			super(ctx, intent); | ||||
|  | ||||
| 		} | ||||
| 		 | ||||
|  | ||||
| 		 | ||||
| 		 | ||||
| 		/** | ||||
| 		 *  | ||||
| 		 * @return the Bundle associated with the action. This bundle can be set in OpenEntry.add(Entry)FieldAction | ||||
| 		 */ | ||||
| 		public Bundle getActionData() | ||||
| 		{ | ||||
| 			return _intent.getBundleExtra(Strings.EXTRA_ACTION_DATA); | ||||
| 		} | ||||
|  | ||||
| 		/** | ||||
| 		 *  | ||||
| 		 * @return the field id which was selected. null if an entry action (in the options menu) was selected. | ||||
| 		 */ | ||||
| 		public String getFieldId() | ||||
| 		{ | ||||
| 			return _intent.getStringExtra(Strings.EXTRA_FIELD_ID); | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 *  | ||||
| 		 * @return true if an entry action, i.e. an option from the options menu, was selected. False if an option | ||||
| 		 * in a popup menu for a certain field was selected.  | ||||
| 		 */ | ||||
| 		public boolean isEntryAction() | ||||
| 		{ | ||||
| 			return getFieldId() == null; | ||||
| 		} | ||||
|  | ||||
| 		/** | ||||
| 		 *  | ||||
| 		 * @return a hashmap containing the entry fields in key/value form | ||||
| 		 */ | ||||
| 		public HashMap<String, String> getEntryFields()  | ||||
| 		{ | ||||
| 			return getEntryFieldsFromIntent(); | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 *  | ||||
| 		 * @return an array with the keys of all protected fields in the entry | ||||
| 		 */ | ||||
| 		public String[] getProtectedFieldsList() | ||||
| 		{ | ||||
| 			return getProtectedFieldsListFromIntent(); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	protected class CloseEntryViewAction extends PluginEntryActionBase | ||||
| 	{ | ||||
| 		public CloseEntryViewAction(Context context, Intent intent) { | ||||
| 			super(context, intent); | ||||
| 		} | ||||
|  | ||||
| 		public String getEntryId() | ||||
| 		{ | ||||
| 			return _intent.getStringExtra(Strings.EXTRA_ENTRY_ID); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	protected class OpenEntryAction extends PluginEntryActionBase | ||||
| 	{ | ||||
| 	 | ||||
| 		public OpenEntryAction(Context context, Intent intent) | ||||
| 		{ | ||||
| 			super(context, intent); | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		public HashMap<String, String> getEntryFields()  | ||||
| 		{ | ||||
| 			return getEntryFieldsFromIntent(); | ||||
| 		} | ||||
| 		 | ||||
| 		/** | ||||
| 		 *  | ||||
| 		 * @return an array with the keys of all protected fields in the entry | ||||
| 		 */ | ||||
| 		public String[] getProtectedFieldsList() | ||||
| 		{ | ||||
| 			return getProtectedFieldsListFromIntent(); | ||||
| 		} | ||||
| 		 | ||||
| 		public void addEntryAction(String actionDisplayText, int actionIconResourceId, Bundle actionData) throws PluginAccessException | ||||
| 		{ | ||||
| 			addEntryFieldAction(null, null, actionDisplayText, actionIconResourceId, actionData); | ||||
| 		} | ||||
|  | ||||
| 		public void addEntryFieldAction(String actionId, String fieldId, String actionDisplayText, int actionIconResourceId, Bundle actionData) throws PluginAccessException | ||||
| 		{ | ||||
| 			Intent i = new Intent(Strings.ACTION_ADD_ENTRY_ACTION); | ||||
| 			ArrayList<String> scope = new ArrayList<String>(); | ||||
| 			scope.add(Strings.SCOPE_CURRENT_ENTRY); | ||||
| 			i.putExtra(Strings.EXTRA_ACCESS_TOKEN, AccessManager.getAccessToken(_context, getHostPackage(), scope)); | ||||
| 			i.setPackage(getHostPackage()); | ||||
| 			i.putExtra(Strings.EXTRA_SENDER, _context.getPackageName()); | ||||
| 			i.putExtra(Strings.EXTRA_ACTION_DATA, actionData); | ||||
| 			i.putExtra(Strings.EXTRA_ACTION_DISPLAY_TEXT, actionDisplayText); | ||||
| 			i.putExtra(Strings.EXTRA_ACTION_ICON_RES_ID, actionIconResourceId); | ||||
| 			i.putExtra(Strings.EXTRA_ENTRY_ID, getEntryId()); | ||||
| 			i.putExtra(Strings.EXTRA_FIELD_ID, fieldId); | ||||
| 			i.putExtra(Strings.EXTRA_ACTION_ID, actionId); | ||||
| 			 | ||||
| 			_context.sendBroadcast(i); | ||||
| 		} | ||||
|  | ||||
| 		 | ||||
| 		 | ||||
| 		 | ||||
| 	} | ||||
| 	 | ||||
| 	protected class DatabaseAction extends PluginActionBase | ||||
| 	{ | ||||
|  | ||||
| 		public DatabaseAction(Context context, Intent intent) { | ||||
| 			super(context, intent); | ||||
| 		} | ||||
| 		 | ||||
| 		public String getFileDisplayName() | ||||
| 		{ | ||||
| 			return _intent.getStringExtra(Strings.EXTRA_DATABASE_FILE_DISPLAYNAME); | ||||
| 		} | ||||
| 		 | ||||
| 		public String getFilePath() | ||||
| 		{ | ||||
| 			return _intent.getStringExtra(Strings.EXTRA_DATABASE_FILEPATH); | ||||
| 		} | ||||
| 		 | ||||
| 		public String getAction() | ||||
| 		{ | ||||
| 			return _intent.getAction(); | ||||
| 		} | ||||
| 		 | ||||
| 	} | ||||
| 	//EntryOutputModified is very similar to OpenEntry because it receives the same  | ||||
| 	//data (+ the field id which was modified) | ||||
| 	protected class EntryOutputModifiedAction extends OpenEntryAction | ||||
| 	{ | ||||
| 	 | ||||
| 		public EntryOutputModifiedAction(Context context, Intent intent) | ||||
| 		{ | ||||
| 			super(context, intent); | ||||
| 		} | ||||
| 		 | ||||
| 		public String getModifiedFieldId() | ||||
| 		{ | ||||
| 			return _intent.getStringExtra(Strings.EXTRA_FIELD_ID); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void onReceive(Context ctx, Intent intent) { | ||||
| 		String action = intent.getAction(); | ||||
| 		android.util.Log.d("KP2A.pluginsdk", "received broadcast in PluginActionBroadcastReceiver with action="+action); | ||||
| 		if (action == null) | ||||
| 			return; | ||||
| 		if (action.equals(Strings.ACTION_OPEN_ENTRY)) | ||||
| 		{ | ||||
| 			openEntry(new OpenEntryAction(ctx, intent));	 | ||||
| 		} | ||||
| 		else if (action.equals(Strings.ACTION_CLOSE_ENTRY_VIEW)) | ||||
| 		{ | ||||
| 			closeEntryView(new CloseEntryViewAction(ctx, intent));	 | ||||
| 		}		 | ||||
| 		else if (action.equals(Strings.ACTION_ENTRY_ACTION_SELECTED)) | ||||
| 		{ | ||||
| 			actionSelected(new ActionSelectedAction(ctx, intent)); | ||||
| 		} | ||||
| 		else if (action.equals(Strings.ACTION_ENTRY_OUTPUT_MODIFIED)) | ||||
| 		{ | ||||
| 			entryOutputModified(new EntryOutputModifiedAction(ctx, intent)); | ||||
| 		} | ||||
| 		else if (action.equals(Strings.ACTION_LOCK_DATABASE) | ||||
| 				|| action.equals(Strings.ACTION_UNLOCK_DATABASE) | ||||
| 				|| action.equals(Strings.ACTION_OPEN_DATABASE) | ||||
| 				|| action.equals(Strings.ACTION_CLOSE_DATABASE)) | ||||
| 		{ | ||||
| 			dbAction(new DatabaseAction(ctx,  intent)); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			//TODO handle unexpected action | ||||
| 		}		 | ||||
|  | ||||
| 		 | ||||
| 	} | ||||
|  | ||||
| 	protected void closeEntryView(CloseEntryViewAction closeEntryView) {} | ||||
|  | ||||
| 	protected void actionSelected(ActionSelectedAction actionSelected) {} | ||||
|  | ||||
| 	protected void openEntry(OpenEntryAction oe) {} | ||||
| 	 | ||||
| 	protected void entryOutputModified(EntryOutputModifiedAction eom) {} | ||||
| 	 | ||||
| 	protected void dbAction(DatabaseAction db) {} | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,190 @@ | ||||
| package keepass2android.pluginsdk; | ||||
|  | ||||
| public class Strings { | ||||
| 	/** | ||||
| 	 * Plugin is notified about actions like open/close/update a database. | ||||
| 	 */ | ||||
| 	public static final String SCOPE_DATABASE_ACTIONS = "keepass2android.SCOPE_DATABASE_ACTIONS"; | ||||
| 	/** | ||||
| 	 * Plugin is notified when an entry is opened.  | ||||
| 	 */ | ||||
| 	public static final String SCOPE_CURRENT_ENTRY = "keepass2android.SCOPE_CURRENT_ENTRY"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Plugin may query credentials for its own package  | ||||
| 	 */ | ||||
| 	public static final String SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE = "keepass2android.SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Plugin may query credentials for a deliberate package  | ||||
| 	 */ | ||||
| 	public static final String SCOPE_QUERY_CREDENTIALS = "keepass2android.SCOPE_QUERY_CREDENTIALS"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Extra key to transfer a (json serialized) list of scopes | ||||
| 	 */ | ||||
| 	public static final String EXTRA_SCOPES = "keepass2android.EXTRA_SCOPES"; | ||||
|  | ||||
| 	 | ||||
| 	public static final String EXTRA_PLUGIN_PACKAGE = "keepass2android.EXTRA_PLUGIN_PACKAGE"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Extra key for sending the package name of the sender of a broadcast. | ||||
| 	 * Should be set in every broadcast.  | ||||
| 	 */ | ||||
| 	public static final String EXTRA_SENDER = "keepass2android.EXTRA_SENDER"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Extra key for sending a request token. The request token is passed from  | ||||
| 	 * KP2A to the plugin. It's used in the authorization process.  | ||||
| 	 */ | ||||
| 	public static final String EXTRA_REQUEST_TOKEN = "keepass2android.EXTRA_REQUEST_TOKEN"; | ||||
|  | ||||
| 	/**  | ||||
| 	 * Action to start KP2A with an AppTask | ||||
| 	 */ | ||||
| 	public static final String ACTION_START_WITH_TASK = "keepass2android.ACTION_START_WITH_TASK"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Action sent from KP2A to the plugin to indicate that the plugin should request | ||||
| 	 * access (sending it's scopes) | ||||
| 	 */ | ||||
| 	public static final String ACTION_TRIGGER_REQUEST_ACCESS = "keepass2android.ACTION_TRIGGER_REQUEST_ACCESS"; | ||||
| 	/**  | ||||
| 	 * Action sent from the plugin to KP2A including the scopes. | ||||
| 	 */ | ||||
| 	public static final String ACTION_REQUEST_ACCESS = "keepass2android.ACTION_REQUEST_ACCESS"; | ||||
| 	/** | ||||
| 	 * Action sent from the KP2A to the plugin when the user grants access. | ||||
| 	 * Will contain an access token. | ||||
| 	 */ | ||||
| 	public static final String ACTION_RECEIVE_ACCESS = "keepass2android.ACTION_RECEIVE_ACCESS"; | ||||
| 	/** | ||||
| 	 * Action sent from KP2A to the plugin to indicate that access is not or no longer valid. | ||||
| 	 */ | ||||
| 	public static final String ACTION_REVOKE_ACCESS = "keepass2android.ACTION_REVOKE_ACCESS"; | ||||
| 	 | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Action for startActivity(). Opens an activity in the Plugin Host to edit the plugin settings (i.e. enable it) | ||||
| 	 */ | ||||
| 	public static final String ACTION_EDIT_PLUGIN_SETTINGS = "keepass2android.ACTION_EDIT_PLUGIN_SETTINGS"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Action sent from KP2A to the plugin to indicate that an entry was opened. | ||||
| 	 * The Intent contains the full entry data. | ||||
| 	 */ | ||||
| 	public static final String ACTION_OPEN_ENTRY= "keepass2android.ACTION_OPEN_ENTRY"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Action sent from KP2A to the plugin to indicate that an entry output field was modified/added. | ||||
| 	 * The Intent contains the full new entry data. | ||||
| 	 */ | ||||
| 	public static final String ACTION_ENTRY_OUTPUT_MODIFIED= "keepass2android.ACTION_ENTRY_OUTPUT_MODIFIED"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Action sent from KP2A to the plugin to indicate that an entry activity was closed. | ||||
| 	 */ | ||||
| 	public static final String ACTION_CLOSE_ENTRY_VIEW= "keepass2android.ACTION_CLOSE_ENTRY_VIEW"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Extra key for a string containing the GUID of the entry.  | ||||
| 	 */ | ||||
| 	public static final String EXTRA_ENTRY_ID= "keepass2android.EXTRA_ENTRY_DATA"; | ||||
| 	 | ||||
| 	/**  | ||||
| 	 * Json serialized data of the PwEntry (C# class) representing the opened entry. | ||||
| 	 * currently not implemented. | ||||
| 	 */ | ||||
| 	//public static final String EXTRA_ENTRY_DATA = "keepass2android.EXTRA_ENTRY_DATA"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Json serialized list of fields, transformed using the database context (i.e. placeholders are replaced already) | ||||
| 	 */ | ||||
| 	public static final String EXTRA_ENTRY_OUTPUT_DATA = "keepass2android.EXTRA_ENTRY_OUTPUT_DATA"; | ||||
|  | ||||
| 	/** | ||||
| 	 * Json serialized lisf of field keys, specifying which field of the EXTRA_ENTRY_OUTPUT_DATA is protected.   | ||||
| 	 */ | ||||
| 	public static final String EXTRA_PROTECTED_FIELDS_LIST = "keepass2android.EXTRA_PROTECTED_FIELDS_LIST"; | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * Extra key for passing the access token (both ways) | ||||
| 	 */ | ||||
| 	public static final String EXTRA_ACCESS_TOKEN = "keepass2android.EXTRA_ACCESS_TOKEN"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Action for an intent from the plugin to KP2A to add menu options regarding the currently open entry. | ||||
| 	 * Requires SCOPE_CURRENT_ENTRY.  | ||||
| 	 */ | ||||
| 	public static final String ACTION_ADD_ENTRY_ACTION = "keepass2android.ACTION_ADD_ENTRY_ACTION"; | ||||
| 	 | ||||
| 	public static final String EXTRA_ACTION_DISPLAY_TEXT = "keepass2android.EXTRA_ACTION_DISPLAY_TEXT"; | ||||
| 	public static final String EXTRA_ACTION_ICON_RES_ID = "keepass2android.EXTRA_ACTION_ICON_RES_ID"; | ||||
|  | ||||
| 	public static final String EXTRA_FIELD_ID = "keepass2android.EXTRA_FIELD_ID"; | ||||
| 	 | ||||
| 	/**  | ||||
| 	 * Used to pass an id for the action. Each actionId may occur only once per field, otherwise the previous | ||||
| 	 * action with same id is replaced by the new action. | ||||
| 	 */ | ||||
| 	public static final String EXTRA_ACTION_ID = "keepass2android.EXTRA_ACTION_ID"; | ||||
|  | ||||
| 	/** Extra for ACTION_ADD_ENTRY_ACTION and ACTION_ENTRY_ACTION_SELECTED to pass data specifying the action parameters.*/ | ||||
| 	public static final String EXTRA_ACTION_DATA = "keepass2android.EXTRA_ACTION_DATA"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Action for an intent from KP2A to the plugin when an action added with ACTION_ADD_ENTRY_ACTION was selected by the user. | ||||
| 	 *  | ||||
| 	 */ | ||||
| 	public static final String ACTION_ENTRY_ACTION_SELECTED = "keepass2android.ACTION_ENTRY_ACTION_SELECTED"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Extra key for the string which is used to query the credentials. This should be either a URL for  | ||||
| 	 * a web login (google.com or a full URI) or something in the form "androidapp://com.my.package" | ||||
| 	 */ | ||||
| 	public static final String EXTRA_QUERY_STRING = "keepass2android.EXTRA_QUERY_STRING"; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Action when plugin wants to query credentials for its own package  | ||||
| 	 */ | ||||
| 	public static final String ACTION_QUERY_CREDENTIALS_FOR_OWN_PACKAGE = "keepass2android.ACTION_QUERY_CREDENTIALS_FOR_OWN_PACKAGE"; | ||||
| 	 | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Action when plugin wants to query credentials for a deliberate package | ||||
| 	 * The query string is passed as intent data  | ||||
| 	 */ | ||||
| 	public static final String ACTION_QUERY_CREDENTIALS = "keepass2android.ACTION_QUERY_CREDENTIALS";	 | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Action for an intent from the plugin to KP2A to set (i.e. add or update) a field in the entry. | ||||
| 	 * May be used to update existing or add new fields at any time while the entry is opened. | ||||
| 	 */ | ||||
| 	public static final String ACTION_SET_ENTRY_FIELD = "keepass2android.ACTION_SET_ENTRY_FIELD"; | ||||
| 	 | ||||
| 	/** Actions for an intent from KP2A to the plugin to inform that a database was opened, closed, quicklocked or quickunlocked.*/ | ||||
| 	public static final String ACTION_OPEN_DATABASE = "keepass2android.ACTION_OPEN_DATABASE"; | ||||
| 	public static final String ACTION_CLOSE_DATABASE = "keepass2android.ACTION_CLOSE_DATABASE"; | ||||
| 	public static final String ACTION_LOCK_DATABASE = "keepass2android.ACTION_LOCK_DATABASE"; | ||||
| 	public static final String ACTION_UNLOCK_DATABASE = "keepass2android.ACTION_UNLOCK_DATABASE"; | ||||
| 	 | ||||
| 	/** Extra for ACTION_OPEN_DATABASE and ACTION_CLOSE_DATABASE containing a filepath which is used  | ||||
| 	 * by KP2A internally to identify the file. Use only where necessary, might contain credentials  | ||||
| 	 * for accessing the file (on remote storage).*/ | ||||
| 	public static final String EXTRA_DATABASE_FILEPATH = "keepass2android.EXTRA_DATABASE_FILEPATH"; | ||||
| 	/** Extra for ACTION_OPEN_DATABASE and ACTION_CLOSE_DATABASE containing a filepath which can be | ||||
| 	 * displayed to the user.*/ | ||||
| 	public static final String EXTRA_DATABASE_FILE_DISPLAYNAME = "keepass2android.EXTRA_DATABASE_FILE_DISPLAYNAME"; | ||||
| 	 | ||||
| 	 | ||||
| 	public static final String EXTRA_FIELD_VALUE = "keepass2android.EXTRA_FIELD_VALUE"; | ||||
| 	public static final String EXTRA_FIELD_PROTECTED = "keepass2android.EXTRA_FIELD_PROTECTED"; | ||||
| 	 | ||||
| 	public static final String PREFIX_STRING = "STRING_"; | ||||
| 	public static final String PREFIX_BINARY = "BINARY_"; | ||||
| 	 | ||||
| 	 | ||||
|  | ||||
| } | ||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 9.2 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 5.1 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 14 KiB | 
| @@ -0,0 +1,11 @@ | ||||
| <resources> | ||||
|  | ||||
|     <!-- | ||||
|         Base application theme for API 11+. This theme completely replaces | ||||
|         AppBaseTheme from res/values/styles.xml on API 11+ devices. | ||||
|     --> | ||||
|     <style name="AppBaseTheme" parent="android:Theme.Holo.Light"> | ||||
|         <!-- API 11 theme customizations can go here. --> | ||||
|     </style> | ||||
|  | ||||
| </resources> | ||||
| @@ -0,0 +1,12 @@ | ||||
| <resources> | ||||
|  | ||||
|     <!-- | ||||
|         Base application theme for API 14+. This theme completely replaces | ||||
|         AppBaseTheme from BOTH res/values/styles.xml and | ||||
|         res/values-v11/styles.xml on API 14+ devices. | ||||
|     --> | ||||
|     <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar"> | ||||
|         <!-- API 14 theme customizations can go here. --> | ||||
|     </style> | ||||
|  | ||||
| </resources> | ||||
| @@ -0,0 +1,10 @@ | ||||
| <resources> | ||||
|  | ||||
|     <!-- | ||||
|          Example customization of dimensions originally defined in res/values/dimens.xml | ||||
|          (such as screen margins) for screens with more than 820dp of available width. This | ||||
|          would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). | ||||
|     --> | ||||
|     <dimen name="activity_horizontal_margin">64dp</dimen> | ||||
|  | ||||
| </resources> | ||||
| @@ -0,0 +1,7 @@ | ||||
| <resources> | ||||
|  | ||||
|     <!-- Default screen margins, per the Android Design guidelines. --> | ||||
|     <dimen name="activity_horizontal_margin">16dp</dimen> | ||||
|     <dimen name="activity_vertical_margin">16dp</dimen> | ||||
|  | ||||
| </resources> | ||||
| @@ -0,0 +1,6 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <resources> | ||||
|  | ||||
|     <string name="app_name">Keepass2Android Plugin SDK</string> | ||||
|  | ||||
| </resources> | ||||
| @@ -0,0 +1,20 @@ | ||||
| <resources> | ||||
|  | ||||
|     <!-- | ||||
|         Base application theme, dependent on API level. This theme is replaced | ||||
|         by AppBaseTheme from res/values-vXX/styles.xml on newer devices. | ||||
|     --> | ||||
|     <style name="AppBaseTheme" parent="android:Theme.Light"> | ||||
|         <!-- | ||||
|             Theme customizations available in newer API levels can go in | ||||
|             res/values-vXX/styles.xml, while customizations related to | ||||
|             backward-compatibility can go here. | ||||
|         --> | ||||
|     </style> | ||||
|  | ||||
|     <!-- Application theme. --> | ||||
|     <style name="AppTheme" parent="AppBaseTheme"> | ||||
|         <!-- All customizations that are NOT specific to a particular API-level can go here. --> | ||||
|     </style> | ||||
|  | ||||
| </resources> | ||||
							
								
								
									
										15
									
								
								src/java/Keepass2AndroidPluginSDK2/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/java/Keepass2AndroidPluginSDK2/build.gradle
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| // Top-level build file where you can add configuration options common to all sub-projects/modules. | ||||
| buildscript { | ||||
|     repositories { | ||||
|         jcenter() | ||||
|     } | ||||
|     dependencies { | ||||
|         classpath 'com.android.tools.build:gradle:1.2.3' | ||||
|     } | ||||
| } | ||||
|  | ||||
| allprojects { | ||||
|     repositories { | ||||
|         jcenter() | ||||
|     } | ||||
| } | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/java/Keepass2AndroidPluginSDK2/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/java/Keepass2AndroidPluginSDK2/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										6
									
								
								src/java/Keepass2AndroidPluginSDK2/gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/java/Keepass2AndroidPluginSDK2/gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| #Wed Apr 10 15:27:10 PDT 2013 | ||||
| distributionBase=GRADLE_USER_HOME | ||||
| distributionPath=wrapper/dists | ||||
| zipStoreBase=GRADLE_USER_HOME | ||||
| zipStorePath=wrapper/dists | ||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip | ||||
							
								
								
									
										164
									
								
								src/java/Keepass2AndroidPluginSDK2/gradlew
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								src/java/Keepass2AndroidPluginSDK2/gradlew
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,164 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| ############################################################################## | ||||
| ## | ||||
| ##  Gradle start up script for UN*X | ||||
| ## | ||||
| ############################################################################## | ||||
|  | ||||
| # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||
| DEFAULT_JVM_OPTS="" | ||||
|  | ||||
| APP_NAME="Gradle" | ||||
| APP_BASE_NAME=`basename "$0"` | ||||
|  | ||||
| # Use the maximum available, or set MAX_FD != -1 to use that value. | ||||
| MAX_FD="maximum" | ||||
|  | ||||
| warn ( ) { | ||||
|     echo "$*" | ||||
| } | ||||
|  | ||||
| die ( ) { | ||||
|     echo | ||||
|     echo "$*" | ||||
|     echo | ||||
|     exit 1 | ||||
| } | ||||
|  | ||||
| # OS specific support (must be 'true' or 'false'). | ||||
| cygwin=false | ||||
| msys=false | ||||
| darwin=false | ||||
| case "`uname`" in | ||||
|   CYGWIN* ) | ||||
|     cygwin=true | ||||
|     ;; | ||||
|   Darwin* ) | ||||
|     darwin=true | ||||
|     ;; | ||||
|   MINGW* ) | ||||
|     msys=true | ||||
|     ;; | ||||
| esac | ||||
|  | ||||
| # For Cygwin, ensure paths are in UNIX format before anything is touched. | ||||
| if $cygwin ; then | ||||
|     [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` | ||||
| fi | ||||
|  | ||||
| # Attempt to set APP_HOME | ||||
| # Resolve links: $0 may be a link | ||||
| PRG="$0" | ||||
| # Need this for relative symlinks. | ||||
| while [ -h "$PRG" ] ; do | ||||
|     ls=`ls -ld "$PRG"` | ||||
|     link=`expr "$ls" : '.*-> \(.*\)$'` | ||||
|     if expr "$link" : '/.*' > /dev/null; then | ||||
|         PRG="$link" | ||||
|     else | ||||
|         PRG=`dirname "$PRG"`"/$link" | ||||
|     fi | ||||
| done | ||||
| SAVED="`pwd`" | ||||
| cd "`dirname \"$PRG\"`/" >&- | ||||
| APP_HOME="`pwd -P`" | ||||
| cd "$SAVED" >&- | ||||
|  | ||||
| CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||||
|  | ||||
| # Determine the Java command to use to start the JVM. | ||||
| if [ -n "$JAVA_HOME" ] ; then | ||||
|     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||||
|         # IBM's JDK on AIX uses strange locations for the executables | ||||
|         JAVACMD="$JAVA_HOME/jre/sh/java" | ||||
|     else | ||||
|         JAVACMD="$JAVA_HOME/bin/java" | ||||
|     fi | ||||
|     if [ ! -x "$JAVACMD" ] ; then | ||||
|         die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||||
|  | ||||
| Please set the JAVA_HOME variable in your environment to match the | ||||
| location of your Java installation." | ||||
|     fi | ||||
| else | ||||
|     JAVACMD="java" | ||||
|     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||
|  | ||||
| Please set the JAVA_HOME variable in your environment to match the | ||||
| location of your Java installation." | ||||
| fi | ||||
|  | ||||
| # Increase the maximum file descriptors if we can. | ||||
| if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then | ||||
|     MAX_FD_LIMIT=`ulimit -H -n` | ||||
|     if [ $? -eq 0 ] ; then | ||||
|         if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | ||||
|             MAX_FD="$MAX_FD_LIMIT" | ||||
|         fi | ||||
|         ulimit -n $MAX_FD | ||||
|         if [ $? -ne 0 ] ; then | ||||
|             warn "Could not set maximum file descriptor limit: $MAX_FD" | ||||
|         fi | ||||
|     else | ||||
|         warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | ||||
|     fi | ||||
| fi | ||||
|  | ||||
| # For Darwin, add options to specify how the application appears in the dock | ||||
| if $darwin; then | ||||
|     GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | ||||
| fi | ||||
|  | ||||
| # For Cygwin, switch paths to Windows format before running java | ||||
| if $cygwin ; then | ||||
|     APP_HOME=`cygpath --path --mixed "$APP_HOME"` | ||||
|     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | ||||
|  | ||||
|     # We build the pattern for arguments to be converted via cygpath | ||||
|     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | ||||
|     SEP="" | ||||
|     for dir in $ROOTDIRSRAW ; do | ||||
|         ROOTDIRS="$ROOTDIRS$SEP$dir" | ||||
|         SEP="|" | ||||
|     done | ||||
|     OURCYGPATTERN="(^($ROOTDIRS))" | ||||
|     # Add a user-defined pattern to the cygpath arguments | ||||
|     if [ "$GRADLE_CYGPATTERN" != "" ] ; then | ||||
|         OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | ||||
|     fi | ||||
|     # Now convert the arguments - kludge to limit ourselves to /bin/sh | ||||
|     i=0 | ||||
|     for arg in "$@" ; do | ||||
|         CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | ||||
|         CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option | ||||
|  | ||||
|         if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition | ||||
|             eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | ||||
|         else | ||||
|             eval `echo args$i`="\"$arg\"" | ||||
|         fi | ||||
|         i=$((i+1)) | ||||
|     done | ||||
|     case $i in | ||||
|         (0) set -- ;; | ||||
|         (1) set -- "$args0" ;; | ||||
|         (2) set -- "$args0" "$args1" ;; | ||||
|         (3) set -- "$args0" "$args1" "$args2" ;; | ||||
|         (4) set -- "$args0" "$args1" "$args2" "$args3" ;; | ||||
|         (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | ||||
|         (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | ||||
|         (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | ||||
|         (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | ||||
|         (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | ||||
|     esac | ||||
| fi | ||||
|  | ||||
| # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules | ||||
| function splitJvmOpts() { | ||||
|     JVM_OPTS=("$@") | ||||
| } | ||||
| eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS | ||||
| JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" | ||||
|  | ||||
| exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" | ||||
							
								
								
									
										90
									
								
								src/java/Keepass2AndroidPluginSDK2/gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/java/Keepass2AndroidPluginSDK2/gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| @if "%DEBUG%" == "" @echo off | ||||
| @rem ########################################################################## | ||||
| @rem | ||||
| @rem  Gradle startup script for Windows | ||||
| @rem | ||||
| @rem ########################################################################## | ||||
|  | ||||
| @rem Set local scope for the variables with windows NT shell | ||||
| if "%OS%"=="Windows_NT" setlocal | ||||
|  | ||||
| @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||
| set DEFAULT_JVM_OPTS= | ||||
|  | ||||
| set DIRNAME=%~dp0 | ||||
| if "%DIRNAME%" == "" set DIRNAME=. | ||||
| set APP_BASE_NAME=%~n0 | ||||
| set APP_HOME=%DIRNAME% | ||||
|  | ||||
| @rem Find java.exe | ||||
| if defined JAVA_HOME goto findJavaFromJavaHome | ||||
|  | ||||
| set JAVA_EXE=java.exe | ||||
| %JAVA_EXE% -version >NUL 2>&1 | ||||
| if "%ERRORLEVEL%" == "0" goto init | ||||
|  | ||||
| echo. | ||||
| echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||
| echo. | ||||
| echo Please set the JAVA_HOME variable in your environment to match the | ||||
| echo location of your Java installation. | ||||
|  | ||||
| goto fail | ||||
|  | ||||
| :findJavaFromJavaHome | ||||
| set JAVA_HOME=%JAVA_HOME:"=% | ||||
| set JAVA_EXE=%JAVA_HOME%/bin/java.exe | ||||
|  | ||||
| if exist "%JAVA_EXE%" goto init | ||||
|  | ||||
| echo. | ||||
| echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||||
| echo. | ||||
| echo Please set the JAVA_HOME variable in your environment to match the | ||||
| echo location of your Java installation. | ||||
|  | ||||
| goto fail | ||||
|  | ||||
| :init | ||||
| @rem Get command-line arguments, handling Windowz variants | ||||
|  | ||||
| if not "%OS%" == "Windows_NT" goto win9xME_args | ||||
| if "%@eval[2+2]" == "4" goto 4NT_args | ||||
|  | ||||
| :win9xME_args | ||||
| @rem Slurp the command line arguments. | ||||
| set CMD_LINE_ARGS= | ||||
| set _SKIP=2 | ||||
|  | ||||
| :win9xME_args_slurp | ||||
| if "x%~1" == "x" goto execute | ||||
|  | ||||
| set CMD_LINE_ARGS=%* | ||||
| goto execute | ||||
|  | ||||
| :4NT_args | ||||
| @rem Get arguments from the 4NT Shell from JP Software | ||||
| set CMD_LINE_ARGS=%$ | ||||
|  | ||||
| :execute | ||||
| @rem Setup the command line | ||||
|  | ||||
| set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | ||||
|  | ||||
| @rem Execute Gradle | ||||
| "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | ||||
|  | ||||
| :end | ||||
| @rem End local scope for the variables with windows NT shell | ||||
| if "%ERRORLEVEL%"=="0" goto mainEnd | ||||
|  | ||||
| :fail | ||||
| rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | ||||
| rem the _cmd.exe /c_ return code! | ||||
| if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | ||||
| exit /b 1 | ||||
|  | ||||
| :mainEnd | ||||
| if "%OS%"=="Windows_NT" endlocal | ||||
|  | ||||
| :omega | ||||
							
								
								
									
										35
									
								
								src/java/Keepass2AndroidPluginSDK2/import-summary.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/java/Keepass2AndroidPluginSDK2/import-summary.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| ECLIPSE ANDROID PROJECT IMPORT SUMMARY | ||||
| ====================================== | ||||
|  | ||||
| Ignored Files: | ||||
| -------------- | ||||
| The following files were *not* copied into the new Gradle project; you | ||||
| should evaluate whether these are still needed in your project and if | ||||
| so manually move them: | ||||
|  | ||||
| * proguard-project.txt | ||||
|  | ||||
| Moved Files: | ||||
| ------------ | ||||
| Android Gradle projects use a different directory structure than ADT | ||||
| Eclipse projects. Here's how the projects were restructured: | ||||
|  | ||||
| * AndroidManifest.xml => app\src\main\AndroidManifest.xml | ||||
| * lint.xml => app\lint.xml | ||||
| * res\ => app\src\main\res\ | ||||
| * src\ => app\src\main\java\ | ||||
|  | ||||
| Next Steps: | ||||
| ----------- | ||||
| You can now build the project. The Gradle project needs network | ||||
| connectivity to download dependencies. | ||||
|  | ||||
| Bugs: | ||||
| ----- | ||||
| If for some reason your project does not build, and you determine that | ||||
| it is due to a bug or limitation of the Eclipse to Gradle importer, | ||||
| please file a bug at http://b.android.com with category | ||||
| Component-Tools. | ||||
|  | ||||
| (This import summary is for your information only, and can be deleted | ||||
| after import once you are satisfied with the results.) | ||||
							
								
								
									
										11
									
								
								src/java/Keepass2AndroidPluginSDK2/local.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/java/Keepass2AndroidPluginSDK2/local.properties
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| ## This file is automatically generated by Android Studio. | ||||
| # Do not modify this file -- YOUR CHANGES WILL BE ERASED! | ||||
| # | ||||
| # This file must *NOT* be checked into Version Control Systems, | ||||
| # as it contains information specific to your local configuration. | ||||
| # | ||||
| # Location of the SDK. This is only used by Gradle. | ||||
| # For customization when using a Version Control System, please read the | ||||
| # header note. | ||||
| #Mon Apr 10 10:51:25 CEST 2017 | ||||
| sdk.dir=C\:\\Users\\Philipp\\AppData\\Local\\Xamarin\\Universal\\AndroidSDK | ||||
							
								
								
									
										1
									
								
								src/java/Keepass2AndroidPluginSDK2/settings.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/java/Keepass2AndroidPluginSDK2/settings.gradle
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| include ':app' | ||||
| @@ -1157,6 +1157,9 @@ namespace keepass2android | ||||
| 					Finish(); | ||||
| 					return false; | ||||
| 				} | ||||
| 				IoUtil.TryTakePersistablePermissions(this.ContentResolver, i.Data); | ||||
|  | ||||
|  | ||||
| 			} | ||||
|  | ||||
| 			 | ||||
|   | ||||
| @@ -36,7 +36,7 @@ | ||||
|   <string name="app_name_debug">Keepass2Android Debug</string> | ||||
|   <string name="library_name"></string> | ||||
|     <string name="default_file_path">/keepass/keepass.kdbx</string> | ||||
|     <string name="donate_url"><![CDATA[http://philipp.crocoll.net/donate.php?lang=%1$s&app=%2$s]]></string> | ||||
|     <string name="donate_url"><![CDATA[https://philipp.crocoll.net/donate.php?lang=%1$s&app=%2$s]]></string> | ||||
|     <string name="homepage">http://keepass2android.codeplex.com</string> | ||||
|     <string name="homepage_short">keepass2android.codeplex.com</string> | ||||
| 	<string name="further_author_names">Alex Vallat, Ben Rush, Matthieu, Wiktor Ławski</string> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Philipp Crocoll
					Philipp Crocoll