restore PluginSDK
This commit is contained in:
9
src/java/Keepass2AndroidPluginSDK/.classpath
Normal file
9
src/java/Keepass2AndroidPluginSDK/.classpath
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
33
src/java/Keepass2AndroidPluginSDK/.project
Normal file
33
src/java/Keepass2AndroidPluginSDK/.project
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Keepass2AndroidPluginSDK</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,4 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
|
||||
18
src/java/Keepass2AndroidPluginSDK/AndroidManifest.xml
Normal file
18
src/java/Keepass2AndroidPluginSDK/AndroidManifest.xml
Normal file
@@ -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>
|
||||
Binary file not shown.
3
src/java/Keepass2AndroidPluginSDK/lint.xml
Normal file
3
src/java/Keepass2AndroidPluginSDK/lint.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<lint>
|
||||
</lint>
|
||||
20
src/java/Keepass2AndroidPluginSDK/proguard-project.txt
Normal file
20
src/java/Keepass2AndroidPluginSDK/proguard-project.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
15
src/java/Keepass2AndroidPluginSDK/project.properties
Normal file
15
src/java/Keepass2AndroidPluginSDK/project.properties
Normal file
@@ -0,0 +1,15 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-19
|
||||
android.library=true
|
||||
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 |
11
src/java/Keepass2AndroidPluginSDK/res/values-v11/styles.xml
Normal file
11
src/java/Keepass2AndroidPluginSDK/res/values-v11/styles.xml
Normal file
@@ -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>
|
||||
12
src/java/Keepass2AndroidPluginSDK/res/values-v14/styles.xml
Normal file
12
src/java/Keepass2AndroidPluginSDK/res/values-v14/styles.xml
Normal file
@@ -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>
|
||||
7
src/java/Keepass2AndroidPluginSDK/res/values/dimens.xml
Normal file
7
src/java/Keepass2AndroidPluginSDK/res/values/dimens.xml
Normal file
@@ -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>
|
||||
6
src/java/Keepass2AndroidPluginSDK/res/values/strings.xml
Normal file
6
src/java/Keepass2AndroidPluginSDK/res/values/strings.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="app_name">Keepass2Android Plugin SDK</string>
|
||||
|
||||
</resources>
|
||||
20
src/java/Keepass2AndroidPluginSDK/res/values/styles.xml
Normal file
20
src/java/Keepass2AndroidPluginSDK/res/values/styles.xml
Normal file
@@ -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>
|
||||
@@ -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_";
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user