Skip to content

Commit 31ad130

Browse files
committed
Add manual APK import
1 parent 879cca0 commit 31ad130

File tree

4 files changed

+99
-26
lines changed

4 files changed

+99
-26
lines changed

faceunlock/src/main/java/ax/nd/faceunlock/ChooseLibsDialog.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ class ChooseLibsDialog(private val activity: MainActivity, private val viewModel
133133
button.isEnabled = enabled
134134
button.text = "Browse"
135135
button.setOnClickListener {
136-
activity.browseForFiles(lib)
136+
// activity.browseForFiles(lib)
137137
}
138138
row.addView(button)
139139

faceunlock/src/main/java/ax/nd/faceunlock/ChooseLibsViewModel.kt

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ sealed interface CheckResult {
2828
}
2929

3030
sealed interface DownloadStatus {
31-
object Downloading : DownloadStatus
32-
data class DownloadError(val error: Exception) : DownloadStatus
31+
data class Downloading(val importing: Boolean) : DownloadStatus
32+
object AskImport : DownloadStatus
33+
data class DownloadError(val importing: Boolean, val error: Exception?) : DownloadStatus
3334
}
3435

3536
class ChooseLibsViewModel : ViewModel() {
@@ -38,34 +39,54 @@ class ChooseLibsViewModel : ViewModel() {
3839
val downloadStatus = MutableStateFlow<DownloadStatus?>(null)
3940
private val okhttp = OkHttpClient()
4041

41-
fun downloadLibs(context: Context) {
42-
if(downloadStatus.value != DownloadStatus.Downloading) {
43-
downloadStatus.value = DownloadStatus.Downloading
42+
fun downloadLibs(context: Context, uri: Uri?) {
43+
if(downloadStatus.value !is DownloadStatus.Downloading) {
44+
downloadStatus.value = DownloadStatus.Downloading(uri != null)
4445
viewModelScope.launch {
4546
try {
46-
downloadLibsInternal(context)
47-
downloadStatus.value = null
47+
downloadLibsInternal(context, uri)
48+
downloadStatus.value = DownloadStatus.DownloadError(uri != null, null)
4849
} catch (e: Exception) {
49-
downloadStatus.value = DownloadStatus.DownloadError(e)
50+
downloadStatus.value = DownloadStatus.DownloadError(uri != null, e)
5051
}
5152
}
5253
}
5354
}
5455

55-
private suspend fun downloadLibsInternal(context: Context) {
56+
private fun downloadApk(): InputStream {
5657
val url = "$IPFS_GATEWAY/ipfs/$LIBS_CID"
5758

5859
val req = Request.Builder()
5960
.url(url)
6061
.build()
6162

62-
withContext(Dispatchers.IO) {
63-
okhttp.newCall(req).execute().use { resp ->
64-
val body = resp.body ?: run {
65-
throw IOException("Response body is null!")
66-
}
63+
val body = okhttp.newCall(req).execute().body ?: run {
64+
throw IOException("Response body is null!")
65+
}
66+
67+
try {
68+
return body.byteStream()
69+
} catch (e: Exception) {
70+
body.close()
71+
throw e
72+
}
73+
}
74+
75+
private fun openImportUri(context: Context, uri: Uri): InputStream {
76+
return context.contentResolver.openInputStream(uri) ?: run {
77+
throw NullPointerException("ContentProvider crashed!")
78+
}
79+
}
6780

68-
val zin = ZipInputStream(body.byteStream().buffered())
81+
private suspend fun downloadLibsInternal(context: Context, uri: Uri?) {
82+
withContext(Dispatchers.IO) {
83+
val inputStream = if(uri != null) {
84+
openImportUri(context, uri)
85+
} else {
86+
downloadApk()
87+
}
88+
inputStream.buffered().use { resp ->
89+
val zin = ZipInputStream(resp)
6990
while (true) {
7091
val entry = zin.nextEntry ?: break
7192
val name = entry.name
@@ -142,6 +163,18 @@ class ChooseLibsViewModel : ViewModel() {
142163
}
143164
}
144165

166+
fun setAskImport() {
167+
if(downloadStatus.value !is DownloadStatus.Downloading) {
168+
downloadStatus.value = DownloadStatus.AskImport
169+
}
170+
}
171+
172+
fun clearDownloadResult() {
173+
if(downloadStatus.value !is DownloadStatus.Downloading) {
174+
downloadStatus.value = null
175+
}
176+
}
177+
145178
fun clearCheckResult() {
146179
checkResult.value = null
147180
}

faceunlock/src/main/java/ax/nd/faceunlock/DownloadLibsDialog.kt

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,29 @@ class DownloadLibsDialog(private val activity: MainActivity, private val viewMod
3434
// Ask download
3535
dialog = MaterialDialog(activity).show {
3636
title(text = "Download required")
37-
message(text = "The app needs to download some library files (<35 MB) necessary for face recognition to work. Download them now?")
37+
message(text = "The app needs to download some library files (<35 MB) necessary for face recognition to work. Download them now?" +
38+
"\n\nAlternatively, you can import the file manually.")
3839
positiveButton(android.R.string.ok) {
39-
viewModel.downloadLibs(activity)
40+
viewModel.downloadLibs(activity, null)
41+
}
42+
negativeButton(text = "Manual import") {
43+
viewModel.setAskImport()
44+
}
45+
cancelOnTouchOutside(false)
46+
cancelable(false)
47+
noAutoDismiss()
48+
}
49+
}
50+
status is DownloadStatus.AskImport -> {
51+
// Ask user to import libraries manually
52+
dialog = MaterialDialog(activity).show {
53+
title(text = "Manual import")
54+
message(text = "Please find the APK of version 01.03.0312 of the 'Moto Face Unlock' app. It is about 33 MB. Press OK when you are ready to import the APK.")
55+
positiveButton(android.R.string.ok) {
56+
activity.browseForFiles()
57+
}
58+
negativeButton(android.R.string.cancel) {
59+
viewModel.clearDownloadResult()
4060
}
4161
cancelOnTouchOutside(false)
4262
cancelable(false)
@@ -48,7 +68,7 @@ class DownloadLibsDialog(private val activity: MainActivity, private val viewMod
4868
dialog = ProgressDialog.show(
4969
activity,
5070
"Processing",
51-
"Downloading files...",
71+
if(status.importing) "Importing APK..." else "Downloading files...",
5272
true,
5373
false
5474
)
@@ -57,9 +77,19 @@ class DownloadLibsDialog(private val activity: MainActivity, private val viewMod
5777
// Download failed
5878
dialog = MaterialDialog(activity).show {
5979
title(text = "Error")
60-
message(text = "An error occurred while downloading the files: ${status.error}")
61-
positiveButton(text = "Retry") {
62-
viewModel.downloadLibs(activity)
80+
if(status.importing) {
81+
message(text = "Could not import the APK, are you sure it's the correct APK?")
82+
positiveButton(text = "Ok") {
83+
viewModel.setAskImport()
84+
}
85+
} else {
86+
message(text = "An error occurred while downloading the files: ${status.error ?: "Unknown error"}")
87+
positiveButton(text = "Retry") {
88+
viewModel.downloadLibs(activity, null)
89+
}
90+
negativeButton(text = "Manual import") {
91+
viewModel.setAskImport()
92+
}
6393
}
6494
cancelOnTouchOutside(false)
6595
cancelable(false)

faceunlock/src/main/java/ax/nd/faceunlock/MainActivity.kt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ class MainActivity : AppCompatActivity(), RemoveFaceControllerCallbacks {
2626
private lateinit var binding: ActivityMain2Binding
2727
private var removeFaceController: RemoveFaceController? = null
2828
private val chooseLibsViewModel: ChooseLibsViewModel by viewModels()
29-
private var pickLibsLauncher: Map<String, ActivityResultLauncher<String>>? = null
29+
// private var pickLibsLauncher: Map<String, ActivityResultLauncher<String>>? = null
30+
private var pickApkLauncher: ActivityResultLauncher<String>? = null
3031
private var requestUnlockPermsLauncher: ActivityResultLauncher<String>? = null
3132

3233
override fun onCreate(savedInstanceState: Bundle?) {
@@ -41,11 +42,16 @@ class MainActivity : AppCompatActivity(), RemoveFaceControllerCallbacks {
4142
startActivity(Intent(this, FaceAuthActivity::class.java))
4243
}
4344

44-
pickLibsLauncher = LibManager.requiredLibraries.associate {
45+
/*pickLibsLauncher = LibManager.requiredLibraries.associate {
4546
it.name to registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
4647
if(uri != null)
4748
chooseLibsViewModel.addLib(this, it, uri)
4849
}
50+
}*/
51+
52+
pickApkLauncher = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
53+
if(uri != null)
54+
chooseLibsViewModel.downloadLibs(this, uri)
4955
}
5056

5157
requestUnlockPermsLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) {}
@@ -165,7 +171,11 @@ class MainActivity : AppCompatActivity(), RemoveFaceControllerCallbacks {
165171
}
166172
}
167173

168-
fun browseForFiles(lib: RequiredLib) {
169-
pickLibsLauncher?.get(lib.name)?.launch("*/*")
174+
// fun browseForFiles(lib: RequiredLib) {
175+
// pickLibsLauncher?.get(lib.name)?.launch("*/*")
176+
// }
177+
178+
fun browseForFiles() {
179+
pickApkLauncher?.launch("*/*")
170180
}
171181
}

0 commit comments

Comments
 (0)