Autofill Service to be able to give password hints directly and save passwords from autofill#162
Autofill Service to be able to give password hints directly and save passwords from autofill#162difanta wants to merge 17 commits intohegocre:mainfrom
Conversation
… opening app; service opens app lock prompt if needed via Dataset.setAuthentication; autofill service can now save from autofill (wip)
|
Hello, Thank you very much for your work! I took a quick look at your code, and it looks nice! To answer your questions:
Thank you again! |
…formation in intents, so no need for a separate lock only activity but rather main activity is in charge of authenticating and answering; fix building Save Info, now should work in most common cases, including delayed username and password insertion; wip: dedicated UI to handle save requests (create/update)
|
Hello! I have been able to install and try the app, and I have found two issues, to an otherwise amazing work!!
Thanks again for your contribution! Best regards. |
only support saving from version P;
|
Hi! I finally managed to get some work done, I have fixed the issue of the first autofill request not showing the correct passwords, it did not wait correctly for the decryption and so they were only ready by the second request. I don't know what might cause the fact that strict domain matching is not followed, I've found a small modification to make in order to make the code identical to NCPNavHost but I would have to investigate further if this is not sufficient. In any case a few updates: Now the autofill service runs only with cached keychain and passwords, this is the only way to make it fast enough to be usable. A deferred update must be the way to sync passwords periodically. The autofill response is always handled by the main app, and specifically a new interface (AutofillData) is passed down by the components of the app until NCPNavHost handles them. There are 4 possible cases I'm missing a translation, which I don't know how to do and, if you agree, an icon to replace the big "Nextcloud Passwords" hint to something smaller such as ">" or any icon that fits the idea. Look for TODO if you'd like to spot these. |
|
This should be ready, the create password bug is solved. |
gradle.properties
Outdated
| # Specifies the JVM arguments used for the daemon process. | ||
| # The setting is particularly useful for tweaking memory settings. | ||
| org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -XX:+UseParallelGC | ||
| org.gradle.java.home=C:\\Program Files\\Java\\latest\\jdk-21 |
There was a problem hiding this comment.
I think this shouldn't be here? It produces a build error in systems where the jdk is not at this exact path
There was a problem hiding this comment.
Sorry I messed up a commit with things i kept local, should be good now
| builder.addDataset( | ||
| AutofillHelper.buildDataset( | ||
| applicationContext, | ||
| PasswordAutofillData(label = ">", id = null, username = null, password = null), // TODO use icon |
There was a problem hiding this comment.
Maybe I would change the > Label with a "More". I think it looks weird otherwise.
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && useInline) { | ||
| request.inlineSuggestionsRequest | ||
| } else null | ||
| // TODO: when to sync with server? |
There was a problem hiding this comment.
Is this done? Should we do it before merging?
There was a problem hiding this comment.
I think yes for now, the sync is done when opening the main app (even to complete/authenticate an autofill) so it is a minor problem in my opinion.
There was a problem hiding this comment.
Pull request overview
This PR implements significant enhancements to the Nextcloud Passwords Android app's Autofill Service, enabling direct password hints, app lock integration, and save functionality. The changes transform the autofill experience from requiring the main app to be opened for every autofill request to providing inline password suggestions directly in the autofill UI.
Changes:
- Introduced
AutofillDatasealed class to represent different autofill operation types (FromId, ChoosePwd, SaveAutofill, Save) - Refactored autofill service to provide inline password suggestions with app lock authentication support
- Added save password functionality that captures credentials and allows saving/updating passwords from autofill contexts
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 28 comments.
Show a summary per file
| File | Description |
|---|---|
| AutofillUtils.kt | New utility file defining data classes for autofill operations |
| PasswordEditView.kt | Changed parameter from boolean flag to AutofillData object for more structured autofill handling |
| NCPTopBar.kt | Updated to accept AutofillData instead of boolean for autofill state |
| NCPNavHost.kt | Major refactoring to handle different autofill scenarios with branching logic based on AutofillData type |
| NCPApp.kt | Updated to pass AutofillData through component hierarchy |
| MainActivity.kt | Modified to extract and process AutofillData from intents |
| NCPAutofillService.kt | Complete rewrite with async processing, password decryption flow, and inline dataset generation |
| AutofillHelper.kt | Enhanced to build datasets with authentication support and save info |
| AssistStructureParser.kt | Improved field detection with content extraction for save functionality |
| build.gradle | Added kotlin-parcelize plugin for Parcelable support |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
app/src/main/java/com/hegocre/nextcloudpasswords/ui/components/NCPNavHost.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/com/hegocre/nextcloudpasswords/ui/activities/MainActivity.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/com/hegocre/nextcloudpasswords/services/autofill/NCPAutofillService.kt
Outdated
Show resolved
Hide resolved
| structure, | ||
| null, | ||
| intentSender | ||
| PasswordAutofillData(label = "Create new password", id = null, username = null, password = null), // TODO: translation |
There was a problem hiding this comment.
Hardcoded user-facing text without translation. The text "Create new password" should be externalized to a string resource for internationalization. Replace with a reference to a string resource using context.getString(R.string.create_new_password) or similar.
| ) | ||
| Log.d(TAG, "Passwords filtered and sorted, count: ${filteredList.size}, needs input for master password: $needsAppForMasterPassword") | ||
|
|
||
| val needsAuth = hasAppLock.first() && (isLocked.firstOrNull() ?: true) |
There was a problem hiding this comment.
The needsAuth flag is computed but there's potential for a race condition or stale data. The isLocked flow is accessed with firstOrNull() which could return null if the flow hasn't emitted yet, defaulting to true (locked). However, this creates uncertainty - if the flow state is unknown, should the system default to locked or unlocked? Consider using a more explicit initial state or add a timeout with clear error handling.
| val needsAuth = hasAppLock.first() && (isLocked.firstOrNull() ?: true) | |
| val hasLockEnabled = hasAppLock.first() | |
| val needsAuth = if (!hasLockEnabled) { | |
| false | |
| } else { | |
| val lockedState = withTimeoutOrNull(1000L) { | |
| isLocked.first() | |
| } | |
| if (lockedState == null) { | |
| Log.w(TAG, "Timed out waiting for isLocked state; defaulting to locked for autofill") | |
| true | |
| } else { | |
| lockedState | |
| } | |
| } |
app/src/main/java/com/hegocre/nextcloudpasswords/ui/components/NCPNavHost.kt
Show resolved
Hide resolved
| label = if(label.isNullOrBlank()) saveData.label else label | ||
| url = if(url.isNullOrBlank()) saveData.url else url | ||
| // prioritize new username and password fields | ||
| username = if(saveData.username.isNullOrBlank()) username else saveData.username | ||
| password = if(saveData.password.isNullOrBlank()) password else saveData.password |
There was a problem hiding this comment.
Inconsistent null safety checks. The code checks for null and blank separately in lines 501-505, but uses isNullOrBlank() elsewhere in the file. For consistency and clarity, use the isNullOrBlank() extension function instead of separate null and blank checks.
app/src/main/java/com/hegocre/nextcloudpasswords/ui/activities/MainActivity.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/com/hegocre/nextcloudpasswords/services/autofill/AutofillHelper.kt
Show resolved
Hide resolved
app/src/main/java/com/hegocre/nextcloudpasswords/services/autofill/NCPAutofillService.kt
Show resolved
Hide resolved
|
I have been using this version to test, and I have seen that I get suggestions for fields that are not username/password, such as the twitter or reddit search bar on the browser. |
…isSave interfaces for clarity
|
Looked trough the AI comments and fixed some concerns, Passwords decrypt lazily to save battery, the (password) state management of NavHost was reverted to what it was before. Regarding your comment that this autofills other textual fields, before this PR the autofill was done only if there were >0 password fields. Now to support username only fields this is no longer true, and so I disabled the autofill of textual fields. In the case where there are no username fields, the last textual field before the password is still used. |
This is a work in progress implementation of some features that I would consider very important for the Autofill Service.
This is still work in progress from an optimization perspective, and also I would like external opinion on a few choices.
If anyone has the time to review this, I would much like to hear your thoughts, cheers.