1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/*
* Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
* SPDX-License-Identifier: GPL-3.0-only
*/
package dev.msfjarvis.aps.ui.autofill
import android.annotation.TargetApi
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.IntentSender
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.service.autofill.FillResponse
import android.text.format.DateUtils
import android.view.View
import android.view.autofill.AutofillManager
import androidx.appcompat.app.AppCompatActivity
import com.github.androidpasswordstore.autofillparser.FormOrigin
import com.github.androidpasswordstore.autofillparser.computeCertificatesHash
import com.github.michaelbull.result.onFailure
import com.github.michaelbull.result.runCatching
import dev.msfjarvis.aps.R
import dev.msfjarvis.aps.databinding.ActivityOreoAutofillPublisherChangedBinding
import dev.msfjarvis.aps.util.autofill.AutofillMatcher
import dev.msfjarvis.aps.util.autofill.AutofillPublisherChangedException
import dev.msfjarvis.aps.util.extensions.asLog
import dev.msfjarvis.aps.util.extensions.viewBinding
import logcat.LogPriority.ERROR
import logcat.logcat
@TargetApi(Build.VERSION_CODES.O)
class AutofillPublisherChangedActivity : AppCompatActivity() {
companion object {
private const val EXTRA_APP_PACKAGE = "dev.msfjarvis.aps.autofill.oreo.ui.EXTRA_APP_PACKAGE"
private const val EXTRA_FILL_RESPONSE_AFTER_RESET =
"dev.msfjarvis.aps.autofill.oreo.ui.EXTRA_FILL_RESPONSE_AFTER_RESET"
private var publisherChangedRequestCode = 1
fun makePublisherChangedIntentSender(
context: Context,
publisherChangedException: AutofillPublisherChangedException,
fillResponseAfterReset: FillResponse?,
): IntentSender {
val intent =
Intent(context, AutofillPublisherChangedActivity::class.java).apply {
putExtra(EXTRA_APP_PACKAGE, publisherChangedException.formOrigin.identifier)
putExtra(EXTRA_FILL_RESPONSE_AFTER_RESET, fillResponseAfterReset)
}
return PendingIntent.getActivity(
context,
publisherChangedRequestCode++,
intent,
if (Build.VERSION.SDK_INT >= 31) {
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_MUTABLE
} else {
PendingIntent.FLAG_CANCEL_CURRENT
},
)
.intentSender
}
}
private lateinit var appPackage: String
private val binding by viewBinding(ActivityOreoAutofillPublisherChangedBinding::inflate)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
setFinishOnTouchOutside(true)
appPackage =
intent.getStringExtra(EXTRA_APP_PACKAGE)
?: run {
logcat(ERROR) { "AutofillPublisherChangedActivity started without EXTRA_PACKAGE_NAME" }
finish()
return
}
supportActionBar?.hide()
showPackageInfo()
with(binding) {
okButton.setOnClickListener { finish() }
advancedButton.setOnClickListener {
advancedButton.visibility = View.GONE
warningAppAdvancedInfo.visibility = View.VISIBLE
resetButton.visibility = View.VISIBLE
}
resetButton.setOnClickListener {
AutofillMatcher.clearMatchesFor(
this@AutofillPublisherChangedActivity,
FormOrigin.App(appPackage)
)
val fillResponse = intent.getParcelableExtra<FillResponse>(EXTRA_FILL_RESPONSE_AFTER_RESET)
setResult(
RESULT_OK,
Intent().apply { putExtra(AutofillManager.EXTRA_AUTHENTICATION_RESULT, fillResponse) }
)
finish()
}
}
}
private fun showPackageInfo() {
runCatching {
with(binding) {
val packageInfo = packageManager.getPackageInfo(appPackage, PackageManager.GET_META_DATA)
val installTime = DateUtils.getRelativeTimeSpanString(packageInfo.firstInstallTime)
warningAppInstallDate.text =
getString(R.string.oreo_autofill_warning_publisher_install_time, installTime)
val appInfo = packageManager.getApplicationInfo(appPackage, PackageManager.GET_META_DATA)
warningAppName.text =
getString(
R.string.oreo_autofill_warning_publisher_app_name,
packageManager.getApplicationLabel(appInfo)
)
val currentHash = computeCertificatesHash(this@AutofillPublisherChangedActivity, appPackage)
warningAppAdvancedInfo.text =
getString(
R.string.oreo_autofill_warning_publisher_advanced_info_template,
appPackage,
currentHash
)
}
}
.onFailure { e ->
logcat(ERROR) { e.asLog("Failed to retrieve package info for $appPackage") }
finish()
}
}
}
|