Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

Commit

Permalink
TODO AutoFill Service
Browse files Browse the repository at this point in the history
  • Loading branch information
M3DZIK committed Jan 13, 2024
1 parent 65aafd5 commit 23baf5e
Show file tree
Hide file tree
Showing 10 changed files with 430 additions and 5 deletions.
12 changes: 11 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
android:supportsRtl="true"
android:theme="@style/Theme.LibrePass">
<activity
android:name=".MainActivity"
android:name=".activity.MainActivity"
android:windowSoftInputMode="adjustResize"
android:exported="true"
android:theme="@style/Theme.LibrePass" >
Expand All @@ -21,5 +21,15 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service
android:name=".autofill.LibrePassAutofillService"
android:label="@string/app_name"
android:permission="android.permission.BIND_AUTOFILL_SERVICE"
android:exported="true">
<intent-filter>
<action android:name="android.service.autofill.AutofillService" />
</intent-filter>
</service>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package dev.medzik.librepass.android.activity

import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity

@RequiresApi(api = Build.VERSION_CODES.O)
class AutofillLauncherActivity : AppCompatActivity() {
companion object {
private val TAG = AutofillLauncherActivity::class.java.name

fun getPendingIntent(context: Context): PendingIntent? {
try {
return PendingIntent.getActivity(
context,
0,
Intent(context, AutofillLauncherActivity::class.java),
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
} else {
PendingIntent.FLAG_CANCEL_CURRENT
}
)
} catch (e: RuntimeException) {
Log.e(TAG, "Unable to create pending intent for selection", e)
return null
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.medzik.librepass.android
package dev.medzik.librepass.android.activity

import android.os.Bundle
import android.util.Log
Expand All @@ -9,6 +9,7 @@ import androidx.fragment.app.FragmentActivity
import androidx.navigation.NavController
import dagger.hilt.android.AndroidEntryPoint
import dev.medzik.android.components.navigate
import dev.medzik.librepass.android.Migrations
import dev.medzik.librepass.android.data.Repository
import dev.medzik.librepass.android.ui.LibrePassNavigation
import dev.medzik.librepass.android.ui.Screen
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package dev.medzik.librepass.android.autofill

import android.annotation.SuppressLint
import android.content.Context
import android.os.Build
import android.os.CancellationSignal
import android.service.autofill.FillCallback
import android.service.autofill.FillRequest
import android.util.Log
import androidx.annotation.RequiresApi
import dev.medzik.librepass.android.autofill.Utils.getWindowNodes
import dev.medzik.librepass.android.utils.Vault

@RequiresApi(Build.VERSION_CODES.O)
object AutofillHandler {
private val TAG = AutofillHandler::class.java.name

fun handleAutofill(
vault: Vault,
context: Context,
request: FillRequest,
cancellationSignal: CancellationSignal,
callback: FillCallback
) {
cancellationSignal.setOnCancelListener {
Log.w(TAG, "Cancelling autofill")
}

val windowNode = getWindowNodes(request.fillContexts).lastOrNull()
if (windowNode?.rootViewNode == null) {
Log.i(TAG, "No window node found")
return callback.onSuccess(null)
}

val structure = request.fillContexts.last().structure
StructureParser(structure).parse()?.let {
// TODO: maybe add blocklist support

launchSelection(it, vault, context, callback)
}

// val exceptionHandler =
// CoroutineExceptionHandler { _, exception ->
// Log.e(TAG, exception.toString())
// callback.onSuccess(null)
// }
// val job =
// CoroutineScope(Dispatchers.IO)
// .launch(exceptionHandler) {
// // TODO: searchAndFill
// }
//
// cancellationSignal.setOnCancelListener {
// job.cancel()
// }
}

@SuppressLint("RemoteViewLayout")
private fun launchSelection(
parsedStructure: StructureParser.AutofillResult,
vault: Vault,
context: Context,
callback: FillCallback
) {
// val responseBuilder = FillResponse.Builder()

// AutofillLauncherActivity.getPendingIntent(context)?.intentSender?.let { intentSender ->
// val remoteViewUnlock = RemoteViews(
// context.packageName,
// R.layout.autofill_unlock
// )
//
// remoteViewUnlock.setTextViewText(R.id.text1, "Test")
//
// responseBuilder.setAuthentication(
// parsedStructure.getAutofillIDs(),
// intentSender,
// remoteViewUnlock
// )
// }
//
// callback.onSuccess(responseBuilder.build())

// val usernamePresentation = RemoteViews(packageName, R.layout.autofill_unlock)
// usernamePresentation.setTextViewText(R.id.text1, "my_username")
//
// val fillResponse = FillResponse.Builder()
// .addDataset(
// Dataset.Builder()
// .setValue(
// parsedStructure.usernameId!!,
// AutofillValue.forText("test"),
// usernamePresentation
// )
// .build())
// .build()
//
// callback.onSuccess(fillResponse)

// if (!vault.openedDatabase) {
//
// }
//
// parserResult.getAutofillIDs().let { autofillId ->
// if (autofillId.isNotEmpty()) {
//
// }
// }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package dev.medzik.librepass.android.autofill

import android.os.Build
import android.os.CancellationSignal
import android.service.autofill.AutofillService
import android.service.autofill.FillCallback
import android.service.autofill.FillRequest
import android.service.autofill.SaveCallback
import android.service.autofill.SaveRequest
import androidx.annotation.RequiresApi
import dev.medzik.librepass.android.utils.Vault
import javax.inject.Inject

@RequiresApi(Build.VERSION_CODES.O)
class LibrePassAutofillService : AutofillService() {
// TODO: does not init, why?
@Inject
lateinit var vault: Vault

override fun onFillRequest(
request: FillRequest,
cancellationSignal: CancellationSignal,
callback: FillCallback
) {
AutofillHandler.handleAutofill(
vault,
context = this,
request,
cancellationSignal,
callback
)
}

override fun onSaveRequest(
request: SaveRequest,
callback: SaveCallback
) {
// TODO: implement
}
}
Loading

0 comments on commit 23baf5e

Please sign in to comment.