mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-12-22 15:08:50 -05:00
First version of AutoFill Plugin
This commit is contained in:
parent
7e593960bd
commit
f6d0778a46
37
src/AutoFillPlugin/AccessReceiver.cs
Normal file
37
src/AutoFillPlugin/AccessReceiver.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Keepass2android.Pluginsdk;
|
||||
|
||||
namespace keepass2android.AutoFillPlugin
|
||||
{
|
||||
[BroadcastReceiver(Exported = true)]
|
||||
[IntentFilter(new[] { Strings.ActionTriggerRequestAccess, Strings.ActionReceiveAccess, Strings.ActionRevokeAccess })]
|
||||
public class AccessReceiver : PluginAccessBroadcastReceiver
|
||||
{
|
||||
public override void OnReceive(Context context, Intent intent)
|
||||
{
|
||||
Android.Util.Log.Debug("KP2AAS", intent.Action);
|
||||
base.OnReceive(context, intent);
|
||||
}
|
||||
|
||||
public override IList<string> Scopes
|
||||
{
|
||||
get
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
Strings.ScopeQueryCredentials
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
19
src/AutoFillPlugin/Assets/AboutAssets.txt
Normal file
19
src/AutoFillPlugin/Assets/AboutAssets.txt
Normal file
@ -0,0 +1,19 @@
|
||||
Any raw assets you want to be deployed with your application can be placed in
|
||||
this directory (and child directories) and given a Build Action of "AndroidAsset".
|
||||
|
||||
These files will be deployed with you package and will be accessible using Android's
|
||||
AssetManager, like this:
|
||||
|
||||
public class ReadAsset : Activity
|
||||
{
|
||||
protected override void OnCreate (Bundle bundle)
|
||||
{
|
||||
base.OnCreate (bundle);
|
||||
|
||||
InputStream input = Assets.Open ("my_asset.txt");
|
||||
}
|
||||
}
|
||||
|
||||
Additionally, some Android functions will automatically load asset files:
|
||||
|
||||
Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
|
105
src/AutoFillPlugin/AutoFillPlugin.csproj
Normal file
105
src/AutoFillPlugin/AutoFillPlugin.csproj
Normal file
@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{6FF440E6-E8FF-4E43-8221-9E3972F14812}</ProjectGuid>
|
||||
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>keepass2android.AutoFillPlugin</RootNamespace>
|
||||
<AssemblyName>AutoFillPlugin</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidApplication>true</AndroidApplication>
|
||||
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
|
||||
<AndroidLinkMode>None</AndroidLinkMode>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
|
||||
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Android" />
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Json" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AccessReceiver.cs" />
|
||||
<Compile Include="Credentials.cs" />
|
||||
<Compile Include="Kp2aAccessibilityService.cs" />
|
||||
<Compile Include="LookupCredentialsActivity.cs" />
|
||||
<Compile Include="MainActivity.cs" />
|
||||
<Compile Include="Resources\Resource.Designer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="GettingStarted.Xamarin" />
|
||||
<None Include="Resources\AboutResources.txt" />
|
||||
<None Include="Assets\AboutAssets.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\values\Strings.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\Icon.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Properties\AndroidManifest.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\accserviceconfig.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_notify_keyboard.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
|
||||
<Project>{545b4a6b-8bba-4fbe-92fc-4ac060122a54}</Project>
|
||||
<Name>KeePassLib2Android</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PluginSdkBinding\PluginSdkBinding.csproj">
|
||||
<Project>{3da3911e-36de-465e-8f15-f1991b6437e5}</Project>
|
||||
<Name>PluginSdkBinding</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\layout\" />
|
||||
</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.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
21
src/AutoFillPlugin/Credentials.cs
Normal file
21
src/AutoFillPlugin/Credentials.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android.AutoFillPlugin
|
||||
{
|
||||
public class Credentials
|
||||
{
|
||||
public string User;
|
||||
public string Password;
|
||||
public string Url;
|
||||
}
|
||||
}
|
4
src/AutoFillPlugin/GettingStarted.Xamarin
Normal file
4
src/AutoFillPlugin/GettingStarted.Xamarin
Normal file
@ -0,0 +1,4 @@
|
||||
<GettingStarted>
|
||||
<LocalContent>GS\Android\CS\AndroidApp\GettingStarted.html</LocalContent>
|
||||
<EmbeddedNavigation>false</EmbeddedNavigation>
|
||||
</GettingStarted>
|
207
src/AutoFillPlugin/Kp2aAccessibilityService.cs
Normal file
207
src/AutoFillPlugin/Kp2aAccessibilityService.cs
Normal file
@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Views.Accessibility;
|
||||
using Android.Widget;
|
||||
|
||||
|
||||
namespace keepass2android.AutoFillPlugin
|
||||
{
|
||||
//<meta-data android:name="android.accessibilityservice" android:resource="@xml/serviceconfig" />
|
||||
[Service(Enabled =true, Permission= "android.permission.BIND_ACCESSIBILITY_SERVICE")]
|
||||
[IntentFilter(new[] { "android.accessibilityservice.AccessibilityService" })]
|
||||
[MetaData("android.accessibilityservice", Resource = "@xml/accserviceconfig")]
|
||||
public class Kp2aAccessibilityService : Android.AccessibilityServices.AccessibilityService, IDialogInterfaceOnCancelListener
|
||||
{
|
||||
const string _logTag = "KP2AAS";
|
||||
private const int autoFillNotificationId = 0;
|
||||
private const string androidAppPrefix = "androidapp://";
|
||||
|
||||
public override void OnCreate()
|
||||
{
|
||||
base.OnCreate();
|
||||
Android.Util.Log.Debug(_logTag, "OnCreate Service");
|
||||
}
|
||||
|
||||
protected override void OnServiceConnected()
|
||||
{
|
||||
Android.Util.Log.Debug(_logTag, "service connected");
|
||||
base.OnServiceConnected();
|
||||
}
|
||||
|
||||
public override void OnAccessibilityEvent(AccessibilityEvent e)
|
||||
{
|
||||
|
||||
Android.Util.Log.Debug(_logTag, "OnAccEvent");
|
||||
bool cancelNotification = true;
|
||||
if (e.EventType == EventTypes.WindowContentChanged || e.EventType == EventTypes.WindowStateChanged)
|
||||
{
|
||||
Android.Util.Log.Debug(_logTag, "event: " + e.EventType + ", package = " + e.PackageName);
|
||||
var root = RootInActiveWindow;
|
||||
if ((ExistsNodeOrChildren(root, n => n.WindowId == e.WindowId) && !ExistsNodeOrChildren(root, n => (n.ViewIdResourceName != null) && (n.ViewIdResourceName.StartsWith("com.android.systemui")))))
|
||||
{
|
||||
var allEditTexts = GetNodeOrChildren(root, n=> { return IsEditText(n); });
|
||||
|
||||
var usernameEdit = allEditTexts.TakeWhile(edit => (edit.Password == false)).LastOrDefault();
|
||||
|
||||
string searchString = androidAppPrefix + root.PackageName;
|
||||
|
||||
string url = androidAppPrefix + root.PackageName;
|
||||
|
||||
if (root.PackageName == "com.android.chrome")
|
||||
{
|
||||
var addressField = root.FindAccessibilityNodeInfosByViewId("com.android.chrome:id/url_bar").FirstOrDefault();
|
||||
UrlFromAddressField(ref url, addressField);
|
||||
|
||||
}
|
||||
else if (root.PackageName == "com.android.browser")
|
||||
{
|
||||
var addressField = root.FindAccessibilityNodeInfosByViewId("com.android.browser:id/url").FirstOrDefault();
|
||||
UrlFromAddressField(ref url, addressField);
|
||||
}
|
||||
|
||||
var emptyPasswordFields = GetNodeOrChildren(root, n => { return IsPasswordField(n); }).ToList();
|
||||
if (emptyPasswordFields.Any())
|
||||
{
|
||||
if ((LookupCredentialsActivity.LastReceivedCredentials != null) && (LookupCredentialsActivity.LastReceivedCredentials.Url == url))
|
||||
{
|
||||
FillPassword(url, usernameEdit, emptyPasswordFields);
|
||||
}
|
||||
else
|
||||
{
|
||||
AskFillPassword(url, usernameEdit, emptyPasswordFields);
|
||||
cancelNotification = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (cancelNotification)
|
||||
((NotificationManager)GetSystemService(NotificationService)).Cancel(autoFillNotificationId);
|
||||
|
||||
}
|
||||
private static void UrlFromAddressField(ref string url, AccessibilityNodeInfo addressField)
|
||||
{
|
||||
if (addressField != null)
|
||||
{
|
||||
url = addressField.Text;
|
||||
if (!url.Contains("://"))
|
||||
url = "http://" + url;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static bool IsPasswordField(AccessibilityNodeInfo n)
|
||||
{
|
||||
//if (n.Password) Android.Util.Log.Debug(_logTag, "pwdx with " + (n.Text == null ? "null" : n.Text));
|
||||
var res = n.Password && string.IsNullOrEmpty(n.Text);
|
||||
// if (n.Password) Android.Util.Log.Debug(_logTag, "pwd with " + n.Text + res);
|
||||
return res;
|
||||
}
|
||||
|
||||
private static bool IsEditText(AccessibilityNodeInfo n)
|
||||
{
|
||||
//it seems like n.Editable is not a good check as this is false for some fields which are actually editable, at least in tests with Chrome.
|
||||
return (n.ClassName != null) && (n.ClassName.Contains("EditText"));
|
||||
}
|
||||
|
||||
private void AskFillPassword(string url, AccessibilityNodeInfo usernameEdit, IEnumerable<AccessibilityNodeInfo> passwordFields)
|
||||
{
|
||||
var runSearchIntent = new Intent(this, typeof(LookupCredentialsActivity));
|
||||
runSearchIntent.PutExtra("url", url);
|
||||
runSearchIntent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop);
|
||||
var pending = PendingIntent.GetActivity(this, 0, runSearchIntent, PendingIntentFlags.UpdateCurrent);
|
||||
|
||||
var targetName = url;
|
||||
|
||||
if (url.StartsWith(androidAppPrefix))
|
||||
{
|
||||
var packageName = url.Substring(androidAppPrefix.Length);
|
||||
try
|
||||
{
|
||||
targetName = PackageManager.GetPackageInfo(packageName, 0).ApplicationInfo.Name;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Android.Util.Log.Debug(_logTag, e.ToString());
|
||||
targetName = packageName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
targetName = KeePassLib.Utility.UrlUtil.GetHost(url);
|
||||
}
|
||||
|
||||
|
||||
var builder = new Notification.Builder(this);
|
||||
//TODO icon
|
||||
//TODO plugin icon
|
||||
builder.SetSmallIcon(Resource.Drawable.ic_notify_keyboard)
|
||||
.SetContentText(GetString(Resource.String.NotificationContentText, new Java.Lang.Object[] { targetName }))
|
||||
.SetContentTitle(GetString(Resource.String.NotificationTitle))
|
||||
.SetWhen(Java.Lang.JavaSystem.CurrentTimeMillis())
|
||||
.SetTicker( GetString(Resource.String.NotificationTickerText, new Java.Lang.Object[] { targetName }))
|
||||
.SetVisibility(Android.App.NotificationVisibility.Secret)
|
||||
.SetContentIntent(pending);
|
||||
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
|
||||
notificationManager.Notify(autoFillNotificationId, builder.Build());
|
||||
|
||||
}
|
||||
|
||||
private void FillPassword(string url, AccessibilityNodeInfo usernameEdit, IEnumerable<AccessibilityNodeInfo> passwordFields)
|
||||
{
|
||||
|
||||
FillDataInTextField(usernameEdit, LookupCredentialsActivity.LastReceivedCredentials.User);
|
||||
foreach (var pwd in passwordFields)
|
||||
FillDataInTextField(pwd, LookupCredentialsActivity.LastReceivedCredentials.Password);
|
||||
|
||||
LookupCredentialsActivity.LastReceivedCredentials = null;
|
||||
}
|
||||
|
||||
private static void FillDataInTextField(AccessibilityNodeInfo edit, string newValue)
|
||||
{
|
||||
Bundle b = new Bundle();
|
||||
b.PutString(AccessibilityNodeInfo.ActionArgumentSetTextCharsequence, newValue);
|
||||
edit.PerformAction(Android.Views.Accessibility.Action.SetText, b);
|
||||
}
|
||||
|
||||
private bool ExistsNodeOrChildren(AccessibilityNodeInfo n, Func<AccessibilityNodeInfo, bool> p)
|
||||
{
|
||||
return GetNodeOrChildren(n, p).Any();
|
||||
}
|
||||
|
||||
private IEnumerable<AccessibilityNodeInfo> GetNodeOrChildren(AccessibilityNodeInfo n, Func<AccessibilityNodeInfo, bool> p)
|
||||
{
|
||||
if (n != null)
|
||||
{
|
||||
if (p(n))
|
||||
yield return n;
|
||||
for (int i = 0; i < n.ChildCount; i++)
|
||||
{
|
||||
foreach (var x in GetNodeOrChildren(n.GetChild(i), p))
|
||||
yield return x;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void OnInterrupt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnCancel(IDialogInterface dialog)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
56
src/AutoFillPlugin/LookupCredentialsActivity.cs
Normal file
56
src/AutoFillPlugin/LookupCredentialsActivity.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
using Keepass2android.Pluginsdk;
|
||||
|
||||
namespace keepass2android.AutoFillPlugin
|
||||
{
|
||||
[Activity(Label = "@string/LookupTitle", LaunchMode = Android.Content.PM.LaunchMode.SingleInstance)]
|
||||
public class LookupCredentialsActivity : Activity
|
||||
{
|
||||
protected override void OnCreate(Bundle bundle)
|
||||
{
|
||||
base.OnCreate(bundle);
|
||||
|
||||
var url = Intent.GetStringExtra("url");
|
||||
_lastQueriedUrl = url;
|
||||
StartActivityForResult(Kp2aControl.GetQueryEntryIntent(url), 123);
|
||||
}
|
||||
|
||||
string _lastQueriedUrl;
|
||||
|
||||
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
|
||||
{
|
||||
base.OnActivityResult(requestCode, resultCode, data);
|
||||
|
||||
var jsonOutput = new Org.Json.JSONObject(data.GetStringExtra(Strings.ExtraEntryOutputData));
|
||||
Dictionary<string, string> output = new Dictionary<string, string>();
|
||||
for (var iter = jsonOutput.Keys(); iter.HasNext;)
|
||||
{
|
||||
string key = iter.Next().ToString();
|
||||
string value = jsonOutput.Get(key).ToString();
|
||||
output[key] = value;
|
||||
}
|
||||
|
||||
|
||||
string user = "", password = "";
|
||||
output.TryGetValue(KeePassLib.PwDefs.UserNameField, out user);
|
||||
output.TryGetValue(KeePassLib.PwDefs.PasswordField, out password);
|
||||
|
||||
LastReceivedCredentials = new Credentials() { User = user, Password = password, Url = _lastQueriedUrl };
|
||||
|
||||
Finish();
|
||||
}
|
||||
|
||||
public static Credentials LastReceivedCredentials;
|
||||
}
|
||||
}
|
25
src/AutoFillPlugin/MainActivity.cs
Normal file
25
src/AutoFillPlugin/MainActivity.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
|
||||
namespace keepass2android.AutoFillPlugin
|
||||
{
|
||||
[Activity(Label = "MainActivity", MainLauncher =true)]
|
||||
public class MainActivity : Activity
|
||||
{
|
||||
protected override void OnCreate(Bundle bundle)
|
||||
{
|
||||
base.OnCreate(bundle);
|
||||
|
||||
// Create your application here
|
||||
}
|
||||
}
|
||||
}
|
5
src/AutoFillPlugin/Properties/AndroidManifest.xml
Normal file
5
src/AutoFillPlugin/Properties/AndroidManifest.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="AutoFillPlugin.AutoFillPlugin" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
|
||||
<uses-sdk android:minSdkVersion="19" />
|
||||
<application android:label="AutoFillPlugin" android:icon="@drawable/Icon"></application>
|
||||
</manifest>
|
30
src/AutoFillPlugin/Properties/AssemblyInfo.cs
Normal file
30
src/AutoFillPlugin/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Android.App;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("AutoFillPlugin")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AutoFillPlugin")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
50
src/AutoFillPlugin/Resources/AboutResources.txt
Normal file
50
src/AutoFillPlugin/Resources/AboutResources.txt
Normal file
@ -0,0 +1,50 @@
|
||||
Images, layout descriptions, binary blobs and string dictionaries can be included
|
||||
in your application as resource files. Various Android APIs are designed to
|
||||
operate on the resource IDs instead of dealing with images, strings or binary blobs
|
||||
directly.
|
||||
|
||||
For example, a sample Android app that contains a user interface layout (main.xml),
|
||||
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
|
||||
would keep its resources in the "Resources" directory of the application:
|
||||
|
||||
Resources/
|
||||
drawable-hdpi/
|
||||
icon.png
|
||||
|
||||
drawable-ldpi/
|
||||
icon.png
|
||||
|
||||
drawable-mdpi/
|
||||
icon.png
|
||||
|
||||
layout/
|
||||
main.xml
|
||||
|
||||
values/
|
||||
strings.xml
|
||||
|
||||
In order to get the build system to recognize Android resources, set the build action to
|
||||
"AndroidResource". The native Android APIs do not operate directly with filenames, but
|
||||
instead operate on resource IDs. When you compile an Android application that uses resources,
|
||||
the build system will package the resources for distribution and generate a class called
|
||||
"Resource" that contains the tokens for each one of the resources included. For example,
|
||||
for the above Resources layout, this is what the Resource class would expose:
|
||||
|
||||
public class Resource {
|
||||
public class drawable {
|
||||
public const int icon = 0x123;
|
||||
}
|
||||
|
||||
public class layout {
|
||||
public const int main = 0x456;
|
||||
}
|
||||
|
||||
public class strings {
|
||||
public const int first_string = 0xabc;
|
||||
public const int second_string = 0xbcd;
|
||||
}
|
||||
}
|
||||
|
||||
You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
|
||||
to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
|
||||
string in the dictionary file values/strings.xml.
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
src/AutoFillPlugin/Resources/drawable/Icon.png
Normal file
BIN
src/AutoFillPlugin/Resources/drawable/Icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
8
src/AutoFillPlugin/Resources/values/Strings.xml
Normal file
8
src/AutoFillPlugin/Resources/values/Strings.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="LookupTitle">Look up credentials</string>
|
||||
<string name="ApplicationName">KP2A AutoFillPlugin</string>
|
||||
<string name="NotificationTitle">Keepass2Android AutoFill</string>
|
||||
<string name="NotificationContentText">AutoFill form for %1$s</string>
|
||||
<string name="NotificationTickerText">AutoFill available for %1$s</string>
|
||||
</resources>
|
11
src/AutoFillPlugin/Resources/xml/accserviceconfig.xml
Normal file
11
src/AutoFillPlugin/Resources/xml/accserviceconfig.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:description="@string/ApplicationName"
|
||||
android:accessibilityEventTypes="typeAllMask"
|
||||
android:accessibilityFlags="flagDefault"
|
||||
android:accessibilityFeedbackType="feedbackSpoken"
|
||||
android:notificationTimeout="100"
|
||||
android:canRetrieveWindowContent="true"
|
||||
|
||||
/>
|
||||
<!--android:settingsActivity="md58dca69cf5ce118dfdacac1ed5b2bbacf.MainActivity"-->
|
@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.23107.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}"
|
||||
EndProject
|
||||
@ -39,6 +39,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZlibAndroid", "ZlibAndroid\
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MaterialTest2", "MaterialTest2\MaterialTest2.csproj", "{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoFillPlugin", "AutoFillPlugin\AutoFillPlugin.csproj", "{6FF440E6-E8FF-4E43-8221-9E3972F14812}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -408,6 +410,42 @@ Global
|
||||
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
|
||||
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Win32.Build.0 = Debug|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Win32.Deploy.0 = Debug|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|x64.Deploy.0 = Debug|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Win32.Build.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Win32.Deploy.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|x64.Build.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|x64.Deploy.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Win32.Deploy.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
|
||||
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|x64.Deploy.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
Loading…
Reference in New Issue
Block a user