diff --git a/app/build.gradle b/app/build.gradle index c553917..eddd490 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -41,8 +41,6 @@ dependencies { implementation 'androidx.core:core-ktx:1.12.0' implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7' - implementation 'androidx.navigation:navigation-ui-ktx:2.7.7' implementation 'androidx.camera:camera-camera2:1.3.2' implementation 'androidx.camera:camera-lifecycle:1.3.2' implementation 'androidx.camera:camera-view:1.3.2' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e1a40ea..4edfdf1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ @@ -21,27 +22,13 @@ + android:exported="true" + tools:ignore="ExportedReceiver"> - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/net/helcel/fidelity/activity/MainActivity.kt b/app/src/main/java/net/helcel/fidelity/activity/MainActivity.kt index 065b366..cef1638 100644 --- a/app/src/main/java/net/helcel/fidelity/activity/MainActivity.kt +++ b/app/src/main/java/net/helcel/fidelity/activity/MainActivity.kt @@ -9,8 +9,12 @@ import androidx.activity.addCallback import androidx.appcompat.app.AppCompatActivity import net.helcel.fidelity.R import net.helcel.fidelity.activity.fragment.Launcher +import net.helcel.fidelity.activity.fragment.ViewEntry import net.helcel.fidelity.databinding.ActMainBinding +import net.helcel.fidelity.pluginSDK.Kp2aControl.getEntryFieldsFromIntent import net.helcel.fidelity.tools.CacheManager +import net.helcel.fidelity.tools.KeepassWrapper.bundleCreate +import net.helcel.fidelity.tools.KeepassWrapper.entryExtract @SuppressLint("SourceLockedOrientationActivity") class MainActivity : AppCompatActivity() { @@ -38,7 +42,9 @@ class MainActivity : AppCompatActivity() { } } - if (savedInstanceState == null) + if (intent.extras != null) + loadViewEntry() + else if (savedInstanceState == null) loadLauncher() } @@ -47,5 +53,14 @@ class MainActivity : AppCompatActivity() { .replace(R.id.container, Launcher()) .commit() } + + private fun loadViewEntry() { + val viewEntry = ViewEntry() + val data = getEntryFieldsFromIntent(intent) + viewEntry.arguments = bundleCreate(entryExtract(data)) + supportFragmentManager.beginTransaction() + .replace(R.id.container, viewEntry) + .commit() + } } diff --git a/app/src/main/java/net/helcel/fidelity/activity/adapter/FidelityListAdapter.kt b/app/src/main/java/net/helcel/fidelity/activity/adapter/FidelityListAdapter.kt index b13c884..2827e8c 100644 --- a/app/src/main/java/net/helcel/fidelity/activity/adapter/FidelityListAdapter.kt +++ b/app/src/main/java/net/helcel/fidelity/activity/adapter/FidelityListAdapter.kt @@ -37,7 +37,6 @@ class FidelityListAdapter( inner class FidelityViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - fun bind(triple: Triple) { val text = "${triple.first}" binding.textView.text = text diff --git a/app/src/main/java/net/helcel/fidelity/activity/fragment/CreateEntry.kt b/app/src/main/java/net/helcel/fidelity/activity/fragment/CreateEntry.kt index 8d53636..f39330f 100644 --- a/app/src/main/java/net/helcel/fidelity/activity/fragment/CreateEntry.kt +++ b/app/src/main/java/net/helcel/fidelity/activity/fragment/CreateEntry.kt @@ -7,9 +7,11 @@ import android.os.Looper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.view.inputmethod.EditorInfo import android.widget.ArrayAdapter import androidx.core.widget.addTextChangedListener import androidx.fragment.app.Fragment +import com.google.android.material.textfield.TextInputEditText import com.google.zxing.FormatException import net.helcel.fidelity.R import net.helcel.fidelity.databinding.FragCreateEntryBinding @@ -34,7 +36,7 @@ class CreateEntry : Fragment() { startViewEntry(r.first, r.second, r.third) } - private var isValid: Boolean = false + private var isValidBarcode: Boolean = false override fun onCreateView( inflater: LayoutInflater, @@ -51,41 +53,14 @@ class CreateEntry : Fragment() { binding.editTextCode.setText(res.second) binding.editTextFormat.setText(res.third, false) - val changeListener = { - isValid = false - handler.removeCallbacksAndMessages(null) - handler.postDelayed({ - updatePreview() - }, DEBOUNCE_DELAY) - } - binding.editTextCode.addTextChangedListener { changeListener() } binding.editTextFormat.addTextChangedListener { changeListener() } binding.editTextFormat.addTextChangedListener { binding.editTextFormat.error = null } - binding.btnSave.setOnClickListener { - if (!isValid() || !isValid) { - ErrorToaster.formIncomplete(requireActivity()) + binding.btnSave.setOnClickListener { submit() } + + binding.editTextTitle.onDone { submit() } + binding.editTextCode.onDone { submit() } - } else { - val kpEntry = KeepassWrapper.entryCreate( - this, - binding.editTextTitle.text.toString(), - binding.editTextCode.text.toString(), - binding.editTextFormat.text.toString(), - binding.checkboxProtected.isChecked, - ) - try { - resultLauncherAdd.launch( - Kp2aControl.getAddEntryIntent( - kpEntry.first, - kpEntry.second - ) - ) - } catch (e: ActivityNotFoundException) { - ErrorToaster.noKP2AFound(requireActivity()) - } - } - } updatePreview() return binding.root @@ -99,7 +74,7 @@ class CreateEntry : Fragment() { 600 ) binding.imageViewPreview.setImageBitmap(barcodeBitmap) - isValid = true + isValidBarcode = true } catch (e: FormatException) { binding.imageViewPreview.setImageBitmap(null) binding.editTextCode.error = "Invalid format" @@ -112,19 +87,19 @@ class CreateEntry : Fragment() { } } - private fun isValid(): Boolean { + private fun isValidForm(): Boolean { var valid = true - if (binding.editTextTitle.text.isNullOrEmpty()) { + if (binding.editTextFormat.text.isNullOrEmpty()) { valid = false - binding.editTextTitle.error = "Title cannot be empty" + binding.editTextFormat.error = "Format cannot be empty" } if (binding.editTextCode.text.isNullOrEmpty()) { valid = false binding.editTextCode.error = "Code cannot be empty" } - if (binding.editTextFormat.text.isNullOrEmpty()) { + if (binding.editTextTitle.text.isNullOrEmpty()) { valid = false - binding.editTextFormat.error = "Format cannot be empty" + binding.editTextTitle.error = "Title cannot be empty" } return valid } @@ -138,4 +113,50 @@ class CreateEntry : Fragment() { .replace(R.id.container, viewEntryFragment).commit() } + + private fun changeListener() { + isValidBarcode = false + handler.removeCallbacksAndMessages(null) + handler.postDelayed({ + updatePreview() + }, DEBOUNCE_DELAY) + } + + + private fun TextInputEditText.onDone(callback: () -> Unit) { + setOnEditorActionListener { _, actionId, _ -> + if (actionId == EditorInfo.IME_ACTION_DONE) { + callback.invoke() + return@setOnEditorActionListener true + } + false + } + } + + private fun submit() { + if (!isValidForm() || !isValidBarcode) { + ErrorToaster.formIncomplete(context) + } else { + val kpEntry = KeepassWrapper.entryCreate( + this, + binding.editTextTitle.text.toString(), + binding.editTextCode.text.toString(), + binding.editTextFormat.text.toString(), + binding.checkboxProtected.isChecked, + ) + try { + resultLauncherAdd.launch( + Kp2aControl.getAddEntryIntent( + kpEntry.first, + kpEntry.second + ) + ) + } catch (e: ActivityNotFoundException) { + ErrorToaster.noKP2AFound(context) + } catch (e: Exception) { + e.printStackTrace() + } + } + } + } \ No newline at end of file diff --git a/app/src/main/java/net/helcel/fidelity/pluginSDK/AccessManager.kt b/app/src/main/java/net/helcel/fidelity/pluginSDK/AccessManager.kt index 416276e..8803473 100644 --- a/app/src/main/java/net/helcel/fidelity/pluginSDK/AccessManager.kt +++ b/app/src/main/java/net/helcel/fidelity/pluginSDK/AccessManager.kt @@ -6,9 +6,6 @@ import org.json.JSONArray import org.json.JSONException -class PluginAccessException(msg: String) : Exception(msg) - - object AccessManager { private const val PREF_KEY_SCOPE = "scope" private const val PREF_KEY_TOKEN = "token" @@ -94,12 +91,4 @@ object AccessManager { hostPrefs.edit().remove(hostPackage).apply() } } - - fun getAccessToken( - context: Context, hostPackage: String?, - scopes: ArrayList - ): String { - return tryGetAccessToken(context, hostPackage, scopes) - ?: throw PluginAccessException(hostPackage + scopes) - } } diff --git a/app/src/main/java/net/helcel/fidelity/pluginSDK/KeepassDef.kt b/app/src/main/java/net/helcel/fidelity/pluginSDK/KeepassDef.kt index 58d5337..9b61168 100644 --- a/app/src/main/java/net/helcel/fidelity/pluginSDK/KeepassDef.kt +++ b/app/src/main/java/net/helcel/fidelity/pluginSDK/KeepassDef.kt @@ -1,9 +1,9 @@ package net.helcel.fidelity.pluginSDK +@Suppress("unused") object KeepassDef { var TitleField: String = "Title" var UserNameField: String = "UserName" var PasswordField: String = "Password" var UrlField: String = "URL" - var NotesField: String = "Notes" } diff --git a/app/src/main/java/net/helcel/fidelity/pluginSDK/Kp2aControl.kt b/app/src/main/java/net/helcel/fidelity/pluginSDK/Kp2aControl.kt index 0fbbe3e..98f8f6f 100644 --- a/app/src/main/java/net/helcel/fidelity/pluginSDK/Kp2aControl.kt +++ b/app/src/main/java/net/helcel/fidelity/pluginSDK/Kp2aControl.kt @@ -32,10 +32,10 @@ object Kp2aControl { fun getEntryFieldsFromIntent(intent: Intent?): HashMap { val res = HashMap() try { - val json = JSONObject(intent?.getStringExtra(Strings.EXTRA_ENTRY_OUTPUT_DATA)!!) - val iter = json.keys() - while (iter.hasNext()) { - val key = iter.next() + val json = JSONObject(intent?.getStringExtra(Strings.EXTRA_ENTRY_OUTPUT_DATA) ?: "") + val itr = json.keys() + while (itr.hasNext()) { + val key = itr.next() val value = json[key].toString() res[key] = value } diff --git a/app/src/main/java/net/helcel/fidelity/pluginSDK/PluginAccessBroadcastReceiver.kt b/app/src/main/java/net/helcel/fidelity/pluginSDK/PluginAccessBroadcastReceiver.kt index 097f4a5..8280f7a 100644 --- a/app/src/main/java/net/helcel/fidelity/pluginSDK/PluginAccessBroadcastReceiver.kt +++ b/app/src/main/java/net/helcel/fidelity/pluginSDK/PluginAccessBroadcastReceiver.kt @@ -11,7 +11,7 @@ class PluginAccessBroadcastReceiver : BroadcastReceiver() { Strings.ACTION_TRIGGER_REQUEST_ACCESS -> requestAccess(ctx, intent) Strings.ACTION_RECEIVE_ACCESS -> receiveAccess(ctx, intent) Strings.ACTION_REVOKE_ACCESS -> revokeAccess(ctx, intent) - else -> println(action) + else -> {} } } @@ -46,8 +46,6 @@ class PluginAccessBroadcastReceiver : BroadcastReceiver() { private val scopes: ArrayList = ArrayList( listOf( Strings.SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE, - Strings.SCOPE_DATABASE_ACTIONS, - Strings.SCOPE_CURRENT_ENTRY, ) ) } diff --git a/app/src/main/java/net/helcel/fidelity/pluginSDK/PluginActionBroadcastReceiver.kt b/app/src/main/java/net/helcel/fidelity/pluginSDK/PluginActionBroadcastReceiver.kt deleted file mode 100644 index 5a7d583..0000000 --- a/app/src/main/java/net/helcel/fidelity/pluginSDK/PluginActionBroadcastReceiver.kt +++ /dev/null @@ -1,226 +0,0 @@ -package net.helcel.fidelity.pluginSDK - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.os.Bundle -import android.util.Log -import org.json.JSONArray -import org.json.JSONException -import org.json.JSONObject - -class PluginActionBroadcastReceiver : BroadcastReceiver() { - open class PluginActionBase - (var context: Context, protected var _intent: Intent) { - val hostPackage: String? - get() = _intent.getStringExtra(Strings.EXTRA_SENDER) - } - - open class PluginEntryActionBase(context: Context, intent: Intent) : - PluginActionBase(context, intent) { - protected val entryFieldsFromIntent: HashMap - get() { - val res = HashMap() - try { - val json = - JSONObject(_intent.getStringExtra(Strings.EXTRA_ENTRY_OUTPUT_DATA) ?: "") - val iter = json.keys() - while (iter.hasNext()) { - val key = iter.next() - val value = json[key].toString() - res[key] = value - } - } catch (e: JSONException) { - e.printStackTrace() - } - return res - } - - protected val protectedFieldsListFromIntent: Array? - get() { - try { - val json = - JSONArray(_intent.getStringExtra(Strings.EXTRA_PROTECTED_FIELDS_LIST)) - val res = arrayOfNulls(json.length()) - for (i in 0 until json.length()) res[i] = json.getString(i) - return res - } catch (e: JSONException) { - e.printStackTrace() - return null - } - } - - - open val entryId: String? - get() = _intent.getStringExtra(Strings.EXTRA_ENTRY_ID) - - - fun setEntryField(fieldId: String?, fieldValue: String?, isProtected: Boolean) { - val i = Intent(Strings.ACTION_SET_ENTRY_FIELD) - val scope = ArrayList() - scope.add(Strings.SCOPE_CURRENT_ENTRY) - i.putExtra( - Strings.EXTRA_ACCESS_TOKEN, AccessManager.getAccessToken( - context, hostPackage, scope - ) - ) - i.setPackage(hostPackage) - i.putExtra(Strings.EXTRA_SENDER, context.packageName) - i.putExtra(Strings.EXTRA_FIELD_VALUE, fieldValue) - i.putExtra(Strings.EXTRA_ENTRY_ID, entryId) - i.putExtra(Strings.EXTRA_FIELD_ID, fieldId) - i.putExtra(Strings.EXTRA_FIELD_PROTECTED, isProtected) - - context.sendBroadcast(i) - } - } - - private inner class ActionSelectedAction(ctx: Context, intent: Intent) : - PluginEntryActionBase(ctx, intent) { - val actionData: Bundle? - /** - * - * @return the Bundle associated with the action. This bundle can be set in OpenEntry.add(Entry)FieldAction - */ - get() = _intent.getBundleExtra(Strings.EXTRA_ACTION_DATA) - - private val fieldId: String? - /** - * - * @return the field id which was selected. null if an entry action (in the options menu) was selected. - */ - get() = _intent.getStringExtra(Strings.EXTRA_FIELD_ID) - - val isEntryAction: Boolean - /** - * - * @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. - */ - get() = fieldId == null - - val entryFields: HashMap - /** - * - * @return a hashmap containing the entry fields in key/value form - */ - get() = entryFieldsFromIntent - - val protectedFieldsList: Array? - /** - * - * @return an array with the keys of all protected fields in the entry - */ - get() = protectedFieldsListFromIntent - } - - private inner class CloseEntryViewAction(context: Context, intent: Intent) : - PluginEntryActionBase(context, intent) { - override val entryId: String? - get() = _intent.getStringExtra(Strings.EXTRA_ENTRY_ID) - } - - private open inner class OpenEntryAction(context: Context, intent: Intent) : - PluginEntryActionBase(context, intent) { - val entryFields: HashMap - get() = entryFieldsFromIntent - - val protectedFieldsList: Array? - /** - * - * @return an array with the keys of all protected fields in the entry - */ - get() = protectedFieldsListFromIntent - - fun addEntryAction( - actionDisplayText: String?, - actionIconResourceId: Int, - actionData: Bundle? - ) { - addEntryFieldAction(null, null, actionDisplayText, actionIconResourceId, actionData) - } - - fun addEntryFieldAction( - actionId: String?, - fieldId: String?, - actionDisplayText: String?, - actionIconResourceId: Int, - actionData: Bundle? - ) { - val i = Intent(Strings.ACTION_ADD_ENTRY_ACTION) - val scope = ArrayList() - scope.add(Strings.SCOPE_CURRENT_ENTRY) - i.putExtra( - Strings.EXTRA_ACCESS_TOKEN, AccessManager.getAccessToken( - context, hostPackage!!, scope - ) - ) - i.setPackage(hostPackage) - i.putExtra(Strings.EXTRA_SENDER, context.packageName) - 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, entryId) - i.putExtra(Strings.EXTRA_FIELD_ID, fieldId) - i.putExtra(Strings.EXTRA_ACTION_ID, actionId) - - context.sendBroadcast(i) - } - } - - private inner class DatabaseAction(context: Context, intent: Intent) : - PluginActionBase(context, intent) { - val fileDisplayName: String? - get() = _intent.getStringExtra(Strings.EXTRA_DATABASE_FILE_DISPLAYNAME) - - val filePath: String? - get() = _intent.getStringExtra(Strings.EXTRA_DATABASE_FILEPATH) - - val action: String? - get() = _intent.action - } - - //EntryOutputModified is very similar to OpenEntry because it receives the same - //data (+ the field id which was modified) - private inner class EntryOutputModifiedAction(context: Context, intent: Intent) : - OpenEntryAction(context, intent) { - val modifiedFieldId: String? - get() = _intent.getStringExtra(Strings.EXTRA_FIELD_ID) - } - - override fun onReceive(ctx: Context, intent: Intent) { - val action = intent.action ?: return - Log.d( - "KP2A.pluginsdk", - "received broadcast in PluginActionBroadcastReceiver with action=$action" - ) - println(action) - - when (action) { - Strings.ACTION_OPEN_ENTRY -> openEntry(OpenEntryAction(ctx, intent)) - Strings.ACTION_CLOSE_ENTRY_VIEW -> closeEntryView(CloseEntryViewAction(ctx, intent)) - Strings.ACTION_ENTRY_ACTION_SELECTED -> - actionSelected(ActionSelectedAction(ctx, intent)) - - Strings.ACTION_ENTRY_OUTPUT_MODIFIED -> - entryOutputModified(EntryOutputModifiedAction(ctx, intent)) - - Strings.ACTION_LOCK_DATABASE -> dbAction(DatabaseAction(ctx, intent)) - Strings.ACTION_UNLOCK_DATABASE -> dbAction(DatabaseAction(ctx, intent)) - Strings.ACTION_OPEN_DATABASE -> dbAction(DatabaseAction(ctx, intent)) - Strings.ACTION_CLOSE_DATABASE -> dbAction(DatabaseAction(ctx, intent)) - - else -> println(action) - } - } - - private fun closeEntryView(closeEntryView: CloseEntryViewAction?) {} - - private fun actionSelected(actionSelected: ActionSelectedAction?) {} - - private fun openEntry(oe: OpenEntryAction?) {} - - private fun entryOutputModified(eom: EntryOutputModifiedAction?) {} - - private fun dbAction(db: DatabaseAction?) {} -} diff --git a/app/src/main/java/net/helcel/fidelity/pluginSDK/Strings.kt b/app/src/main/java/net/helcel/fidelity/pluginSDK/Strings.kt index 476c861..4111b42 100644 --- a/app/src/main/java/net/helcel/fidelity/pluginSDK/Strings.kt +++ b/app/src/main/java/net/helcel/fidelity/pluginSDK/Strings.kt @@ -1,176 +1,30 @@ package net.helcel.fidelity.pluginSDK +@Suppress("unused") object Strings { - /** - * Plugin is notified about actions like open/close/update a database. - */ + const val SCOPE_DATABASE_ACTIONS = "keepass2android.SCOPE_DATABASE_ACTIONS" - - /** - * Plugin is notified when an entry is opened. - */ const val SCOPE_CURRENT_ENTRY = "keepass2android.SCOPE_CURRENT_ENTRY" - - /** - * Plugin may query credentials for its own package - */ const val SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE = "keepass2android.SCOPE_QUERY_CREDENTIALS_FOR_OWN_PACKAGE" - /** - * Extra key to transfer a (json serialized) list of scopes - */ const val EXTRA_SCOPES = "keepass2android.EXTRA_SCOPES" - - const val 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. - */ const val 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. - */ const val EXTRA_REQUEST_TOKEN = "keepass2android.EXTRA_REQUEST_TOKEN" - - /** - * Action to start KP2A with an AppTask - */ const val 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) - */ const val ACTION_TRIGGER_REQUEST_ACCESS = "keepass2android.ACTION_TRIGGER_REQUEST_ACCESS" - - /** - * Action sent from the plugin to KP2A including the scopes. - */ const val 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. - */ const val ACTION_RECEIVE_ACCESS = "keepass2android.ACTION_RECEIVE_ACCESS" - - /** - * Action sent from KP2A to the plugin to indicate that access is not or no longer valid. - */ const val 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) - */ - const val 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. - */ - const val 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. - */ - const val ACTION_ENTRY_OUTPUT_MODIFIED = "keepass2android.ACTION_ENTRY_OUTPUT_MODIFIED" - - /** - * Action sent from KP2A to the plugin to indicate that an entry activity was closed. - */ - const val ACTION_CLOSE_ENTRY_VIEW = "keepass2android.ACTION_CLOSE_ENTRY_VIEW" - - /** - * Extra key for a string containing the GUID of the entry. - */ - const val EXTRA_ENTRY_ID = "keepass2android.EXTRA_ENTRY_DATA" - - - /** - * Json serialized list of fields, transformed using the database context (i.e. placeholders are replaced already) - */ const val 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. - */ const val EXTRA_PROTECTED_FIELDS_LIST = "keepass2android.EXTRA_PROTECTED_FIELDS_LIST" - - - /** - * Extra key for passing the access token (both ways) - */ const val 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. - */ - const val ACTION_ADD_ENTRY_ACTION = "keepass2android.ACTION_ADD_ENTRY_ACTION" - - const val EXTRA_ACTION_DISPLAY_TEXT = "keepass2android.EXTRA_ACTION_DISPLAY_TEXT" - const val EXTRA_ACTION_ICON_RES_ID = "keepass2android.EXTRA_ACTION_ICON_RES_ID" - - const val 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. - */ - const val 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.*/ - const val 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. - * - */ - const val 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" - */ - const val EXTRA_QUERY_STRING = "keepass2android.EXTRA_QUERY_STRING" - - /** - * Action when plugin wants to query credentials for its own package - */ const val ACTION_QUERY_CREDENTIALS_FOR_OWN_PACKAGE = "keepass2android.ACTION_QUERY_CREDENTIALS_FOR_OWN_PACKAGE" - - /** - * 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. - */ - const val 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.*/ - const val ACTION_OPEN_DATABASE = "keepass2android.ACTION_OPEN_DATABASE" - const val ACTION_CLOSE_DATABASE = "keepass2android.ACTION_CLOSE_DATABASE" - const val ACTION_LOCK_DATABASE = "keepass2android.ACTION_LOCK_DATABASE" - const val 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).*/ - const val 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.*/ - const val EXTRA_DATABASE_FILE_DISPLAYNAME = "keepass2android.EXTRA_DATABASE_FILE_DISPLAYNAME" - - - const val EXTRA_FIELD_VALUE = "keepass2android.EXTRA_FIELD_VALUE" - const val EXTRA_FIELD_PROTECTED = "keepass2android.EXTRA_FIELD_PROTECTED" - - } diff --git a/app/src/main/java/net/helcel/fidelity/tools/ErrorToaster.kt b/app/src/main/java/net/helcel/fidelity/tools/ErrorToaster.kt index 8f44ed1..70a754f 100644 --- a/app/src/main/java/net/helcel/fidelity/tools/ErrorToaster.kt +++ b/app/src/main/java/net/helcel/fidelity/tools/ErrorToaster.kt @@ -1,22 +1,23 @@ package net.helcel.fidelity.tools -import android.app.Activity +import android.content.Context import android.widget.Toast object ErrorToaster { - private fun helper(activity: Activity, message: String, length: Int) { - Toast.makeText(activity, message, length).show() + private fun helper(activity: Context?, message: String, length: Int) { + if (activity != null) + Toast.makeText(activity, message, length).show() } - fun noKP2AFound(activity: Activity) { + fun noKP2AFound(activity: Context?) { helper(activity, "KeePass2Android Not Installed", Toast.LENGTH_LONG) } - fun formIncomplete(activity: Activity) { + fun formIncomplete(activity: Context?) { helper(activity, "Form Incomplete", Toast.LENGTH_SHORT) } - fun invalidFormat(activity: Activity) { + fun invalidFormat(activity: Context?) { helper(activity, "Invalid Format", Toast.LENGTH_SHORT) } } diff --git a/app/src/main/java/net/helcel/fidelity/tools/KeepassWrapper.kt b/app/src/main/java/net/helcel/fidelity/tools/KeepassWrapper.kt index 065eab5..4d08b52 100644 --- a/app/src/main/java/net/helcel/fidelity/tools/KeepassWrapper.kt +++ b/app/src/main/java/net/helcel/fidelity/tools/KeepassWrapper.kt @@ -42,12 +42,8 @@ object KeepassWrapper { callback: (HashMap) -> Unit ): ActivityResultLauncher { return fragment.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - - println(result.resultCode) - println(result.data.toString()) if (result.resultCode == Activity.RESULT_OK) { val credentials = Kp2aControl.getEntryFieldsFromIntent(result.data) - println(credentials.toList().toString()) callback(credentials) } } @@ -69,6 +65,10 @@ object KeepassWrapper { return data } + fun bundleCreate(triple: Triple): Bundle { + return bundleCreate(triple.first, triple.second, triple.third) + } + fun bundleExtract(data: Bundle?): Triple { return Triple( data?.getString("title"), diff --git a/app/src/main/res/layout/frag_create_entry.xml b/app/src/main/res/layout/frag_create_entry.xml index 7fac51a..449abb4 100644 --- a/app/src/main/res/layout/frag_create_entry.xml +++ b/app/src/main/res/layout/frag_create_entry.xml @@ -22,7 +22,11 @@ + android:layout_height="wrap_content" + android:imeOptions="actionNext" + android:inputType="text" + android:maxLines="1" + android:minLines="1" /> @@ -45,7 +49,11 @@ + android:layout_height="wrap_content" + android:imeOptions="actionDone" + android:inputType="text" + android:maxLines="1" + android:minLines="1" /> @@ -75,6 +83,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" + android:focusable="false" android:inputType="none" /> diff --git a/settings.gradle b/settings.gradle index 9377a07..970eebc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,5 +14,5 @@ dependencyResolutionManagement { maven { url 'https://jitpack.io' } } } -rootProject.name = "BeenDroid" +rootProject.name = "Fidelity" include ':app'