diff --git a/app/build.gradle b/app/build.gradle index dd0260879..fe33134e8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -115,4 +115,5 @@ dependencies { implementation project(path: ':icon-pack-classic') implementation project(path: ':icon-pack-material') implementation project(path: ':magikeyboard') + implementation project(path: ':keepass-model') } diff --git a/app/src/main/java/com/kunzisoft/keepass/selection/EntrySelectionHelper.java b/app/src/main/java/com/kunzisoft/keepass/selection/EntrySelectionHelper.java index cc17b04d6..8054a7e64 100644 --- a/app/src/main/java/com/kunzisoft/keepass/selection/EntrySelectionHelper.java +++ b/app/src/main/java/com/kunzisoft/keepass/selection/EntrySelectionHelper.java @@ -5,6 +5,7 @@ import android.content.Intent; import android.util.Log; import com.kunzisoft.keepass.database.PwEntry; +import com.kunzisoft.keepass_model.Entry; public class EntrySelectionHelper { @@ -30,9 +31,17 @@ public class EntrySelectionHelper { if (entrySelectionMode) { mReplyIntent = new Intent(); Log.d(activity.getClass().getName(), "Reply entry selection"); + + Entry entryModel = new Entry(); + entryModel.setUsername(entry.getUsername()); + entryModel.setPassword(entry.getPassword()); + entryModel.setUrl(entry.getUrl()); + // TODO Fields + //entryModel.setCustomField(entry.getFields()); + mReplyIntent.putExtra( EXTRA_ENTRY_SELECTION_MODE, - entry); + entryModel); activity.setResult(Activity.RESULT_OK, mReplyIntent); } else { activity.setResult(Activity.RESULT_CANCELED); diff --git a/keepass-model/.gitignore b/keepass-model/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/keepass-model/.gitignore @@ -0,0 +1 @@ +/build diff --git a/keepass-model/build.gradle b/keepass-model/build.gradle new file mode 100644 index 000000000..176fe1e78 --- /dev/null +++ b/keepass-model/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 27 + + + + defaultConfig { + minSdkVersion 14 + targetSdkVersion 27 + versionCode 1 + versionName "1.0" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) +} diff --git a/keepass-model/proguard-rules.pro b/keepass-model/proguard-rules.pro new file mode 100644 index 000000000..f1b424510 --- /dev/null +++ b/keepass-model/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# 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 *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/keepass-model/src/main/AndroidManifest.xml b/keepass-model/src/main/AndroidManifest.xml new file mode 100644 index 000000000..4bb046d14 --- /dev/null +++ b/keepass-model/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/keepass-model/src/main/java/com/kunzisoft/keepass_model/Entry.java b/keepass-model/src/main/java/com/kunzisoft/keepass_model/Entry.java new file mode 100644 index 000000000..31f7dde57 --- /dev/null +++ b/keepass-model/src/main/java/com/kunzisoft/keepass_model/Entry.java @@ -0,0 +1,92 @@ +package com.kunzisoft.keepass_model; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class Entry implements Parcelable { + + private String username; + private String password; + private String url; + private Map customFields; + + public Entry() { + this.username = ""; + this.password = ""; + this.url = ""; + this.customFields = new HashMap<>(); + } + + protected Entry(Parcel in) { + username = in.readString(); + password = in.readString(); + url = in.readString(); + //noinspection unchecked + customFields = in.readHashMap(String.class.getClassLoader()); + } + + public static final Creator CREATOR = new Creator() { + @Override + public Entry createFromParcel(Parcel in) { + return new Entry(in); + } + + @Override + public Entry[] newArray(int size) { + return new Entry[size]; + } + }; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public Set getCustomFieldsKeys() { + return customFields.keySet(); + } + + public String getCustomField(String key) { + return customFields.get(key); + } + + public void setCustomField(String key, String value) { + this.customFields.put(key, value); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(username); + parcel.writeString(password); + parcel.writeString(url); + parcel.writeMap(customFields); + } +} diff --git a/magikeyboard/build.gradle b/magikeyboard/build.gradle index 79f502b08..7aaf84acb 100644 --- a/magikeyboard/build.gradle +++ b/magikeyboard/build.gradle @@ -25,4 +25,5 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:27.1.1' + implementation project(path: ':keepass-model') } diff --git a/magikeyboard/src/main/java/com/kunzisoft/magikeyboard/EntryRetrieverActivity.java b/magikeyboard/src/main/java/com/kunzisoft/magikeyboard/EntryRetrieverActivity.java index d6c7cc873..c8dead0d7 100644 --- a/magikeyboard/src/main/java/com/kunzisoft/magikeyboard/EntryRetrieverActivity.java +++ b/magikeyboard/src/main/java/com/kunzisoft/magikeyboard/EntryRetrieverActivity.java @@ -8,6 +8,8 @@ import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.util.Log; +import com.kunzisoft.keepass_model.Entry; + public class EntryRetrieverActivity extends AppCompatActivity { public static final String TAG = EntryRetrieverActivity.class.getName(); @@ -18,7 +20,6 @@ public class EntryRetrieverActivity extends AppCompatActivity { protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { // TODO lock for < jelly bean Intent intent; try { @@ -38,8 +39,8 @@ public class EntryRetrieverActivity extends AppCompatActivity { Log.i(TAG, "Retrieve the entry selected"); if (requestCode == ENTRY_REQUEST_CODE) { if (resultCode == Activity.RESULT_OK) { - // TODO get entry - Log.e(TAG, data.getSerializableExtra("com.kunzisoft.keepass.extra.ENTRY_SELECTION_MODE").toString()); + Entry entry = data.getParcelableExtra("com.kunzisoft.keepass.extra.ENTRY_SELECTION_MODE"); + MagikIME.setEntryKey(entry); } if (resultCode == Activity.RESULT_CANCELED) { Log.w(TAG, "Entry not retrieved"); diff --git a/magikeyboard/src/main/java/com/kunzisoft/magikeyboard/MagikIME.java b/magikeyboard/src/main/java/com/kunzisoft/magikeyboard/MagikIME.java index 10a9cb67e..dbba6030c 100644 --- a/magikeyboard/src/main/java/com/kunzisoft/magikeyboard/MagikIME.java +++ b/magikeyboard/src/main/java/com/kunzisoft/magikeyboard/MagikIME.java @@ -25,9 +25,12 @@ import android.inputmethodservice.Keyboard; import android.inputmethodservice.KeyboardView; import android.view.KeyEvent; import android.view.View; +import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; +import com.kunzisoft.keepass_model.Entry; + public class MagikIME extends InputMethodService implements KeyboardView.OnKeyboardActionListener { private static final String TAG = MagikIME.class.getName(); @@ -41,6 +44,8 @@ public class MagikIME extends InputMethodService private static final int KEY_URL = 520; private static final int KEY_FIELDS = 530; + private static Entry entryKey = null; + private KeyboardView keyboardView; private Keyboard keyboard; private Keyboard keyboard_entry; @@ -50,13 +55,36 @@ public class MagikIME extends InputMethodService keyboardView = (KeyboardView) getLayoutInflater().inflate(R.layout.keyboard, null); keyboard = new Keyboard(this, R.xml.password_keys); keyboard_entry = new Keyboard(this, R.xml.password_entry_keys); - keyboardView.setKeyboard(keyboard); + + assignKeyboardView(); keyboardView.setOnKeyboardActionListener(this); keyboardView.setPreviewEnabled(false); return keyboardView; } + private void assignKeyboardView() { + if (entryKey != null) { + keyboardView.setKeyboard(keyboard_entry); + } else { + keyboardView.setKeyboard(keyboard); + } + } + + @Override + public void onStartInputView(EditorInfo info, boolean restarting) { + super.onStartInputView(info, restarting); + assignKeyboardView(); + } + + public static void setEntryKey(Entry entry) { + entryKey = entry; + } + + public static void deleteEntryKey() { + entryKey = null; + } + @Override public void onKey(int primaryCode, int[] keyCodes) { InputConnection ic = getCurrentInputConnection(); @@ -66,6 +94,7 @@ public class MagikIME extends InputMethodService if (imeManager != null) imeManager.showInputMethodPicker(); break; + case KEY_ENTRY: case KEY_UNLOCK: Intent intent = new Intent(this, EntryRetrieverActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -74,14 +103,26 @@ public class MagikIME extends InputMethodService case KEY_LOCK: Intent lockIntent = new Intent("com.kunzisoft.keepass.LOCK"); sendBroadcast(lockIntent); - break; - case KEY_ENTRY: + deleteEntryKey(); + assignKeyboardView(); break; case KEY_USERNAME: + if (entryKey != null) { + InputConnection inputConnection = getCurrentInputConnection(); + inputConnection.commitText(entryKey.getUsername(), 1); + } break; case KEY_PASSWORD: + if (entryKey != null) { + InputConnection inputConnection = getCurrentInputConnection(); + inputConnection.commitText(entryKey.getPassword(), 1); + } break; case KEY_URL: + if (entryKey != null) { + InputConnection inputConnection = getCurrentInputConnection(); + inputConnection.commitText(entryKey.getUrl(), 1); + } break; case KEY_FIELDS: break; diff --git a/settings.gradle b/settings.gradle index b1cd735c6..a214e0b2d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':icon-pack-classic', ':icon-pack-material', ':magikeyboard' +include ':app', ':icon-pack-classic', ':icon-pack-material', ':magikeyboard', ':keepass-model'