Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add autofill service and credit card information saving #940

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" tools:node="remove"/>


<application
android:name=".MyApplication"
android:allowBackup="false"
Expand Down Expand Up @@ -54,6 +53,16 @@
android:enabled="false"
android:exported="false" />

<service
android:name=".autofill.KeyPassAutofillService"
android:permission="android.permission.BIND_AUTOFILL_SERVICE">
<intent-filter>
<action android:name="android.service.autofill.AutofillService" />
</intent-filter>
<meta-data
android:name="android.autofill"
android:resource="@xml/autofill_service" />
</service>
</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.yogeshpaliyal.keypass.autofill

import android.service.autofill.AutofillService
import android.service.autofill.FillRequest
import android.service.autofill.FillResponse
import android.service.autofill.SaveRequest
import android.view.autofill.AutofillManager
import android.view.autofill.AutofillValue
import android.widget.RemoteViews
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.common.data.AccountModel
import com.yogeshpaliyal.common.utils.getAutoFillService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import android.service.autofill.Dataset
import android.service.autofill.FillContext
import android.service.autofill.SaveInfo
import android.view.View
import android.view.autofill.AutofillId
import android.widget.RemoteViews
import com.yogeshpaliyal.common.AppDatabase

class KeyPassAutofillService : AutofillService() {

override fun onFillRequest(request: FillRequest, cancellationSignal: android.os.CancellationSignal, callback: FillCallback) {
// Handle autofill requests
val context = applicationContext
val autofillManager = context.getSystemService(AutofillManager::class.java)

val fillContexts: List<FillContext> = request.fillContexts
val latestFillContext: FillContext = fillContexts[fillContexts.size - 1]
val structure = latestFillContext.structure

val fillResponseBuilder = FillResponse.Builder()

// Fetch accounts and create datasets
fetchAccountsAndShowSuggestions { accounts ->
accounts.forEach { account ->
val datasetBuilder = Dataset.Builder()
structure.autofillIds.forEach { autofillId ->
datasetBuilder.setValue(autofillId, AutofillValue.forText(account.username))
}
val remoteViews = RemoteViews(packageName, R.layout.autofill_service)
remoteViews.setTextViewText(R.id.autofill_text, account.username)
datasetBuilder.setPresentation(remoteViews)
fillResponseBuilder.addDataset(datasetBuilder.build())
}
callback.onSuccess(fillResponseBuilder.build())
}
}

override fun onSaveRequest(request: SaveRequest, callback: SaveCallback) {
// Handle save requests
val context = applicationContext
val autofillManager = context.getSystemService(AutofillManager::class.java)

val fillContexts: List<FillContext> = request.fillContexts
val latestFillContext: FillContext = fillContexts[fillContexts.size - 1]
val structure = latestFillContext.structure

val account = AccountModel()
structure.autofillIds.forEach { autofillId ->
val autofillValue = structure.getAutofillValue(autofillId)
if (autofillValue != null && autofillValue.isText) {
account.username = autofillValue.textValue.toString()
}
}

// Save account to the database
saveAccountToDatabase(account)

callback.onSuccess()
}

override fun onConnected() {
// Handle service connected
}

override fun onDisconnected() {
// Handle service disconnected
}

private fun fetchAccountsAndShowSuggestions(callback: (List<AccountModel>) -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
val accounts = fetchAccounts()
callback(accounts)
}
}

private fun fetchAccounts(): List<AccountModel> {
// Fetch accounts from the database or any other source
val db = AppDatabase.getInstance(applicationContext)
return db.dbDao().getAllAccountsList()
}

private fun saveAccountToDatabase(account: AccountModel) {
CoroutineScope(Dispatchers.IO).launch {
val db = AppDatabase.getInstance(applicationContext)
db.dbDao().insertOrUpdateAccount(account)
}
}
}
10 changes: 10 additions & 0 deletions app/src/main/res/xml/autofill_service.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<autofill-service xmlns:android="http://schemas.android.com/apk/res/android">
<supportedPackages>
<package android:name="com.yogeshpaliyal.keypass" />
</supportedPackages>
<requiredSmartSuggestions>
<smartSuggestion android:type="password" />
<smartSuggestion android:type="creditCard" />
</requiredSmartSuggestions>
</autofill-service>
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.yogeshpaliyal.common.utils

import android.content.Context
import android.content.Intent
import android.provider.Settings
import android.view.autofill.AutofillManager
import androidx.core.content.ContextCompat.getSystemService

Expand All @@ -16,3 +18,16 @@ fun Context?.getAutoFillService() = if (this != null && android.os.Build.VERSION
} else {
null
}

fun Context?.isAutoFillServiceEnabled(): Boolean {
val autofillManager = this?.getAutoFillService()
return autofillManager?.hasEnabledAutofillServices() == true
}

fun Context?.enableAutoFillService() {
if (this != null && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
val intent = Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE)
intent.putExtra(Settings.EXTRA_AUTOFILL_SERVICE_COMPONENT_NAME, "com.yogeshpaliyal.keypass/.autofill.KeyPassAutofillService")
this.startActivity(intent)
}
}
Loading