@@ -2,13 +2,16 @@ package com.github.capntrips.kernelflasher
22
33import android.animation.ObjectAnimator
44import android.animation.PropertyValuesHolder
5+ import android.annotation.SuppressLint
56import android.app.Activity
67import android.content.ComponentName
78import android.content.Intent
89import android.content.ServiceConnection
10+ import android.net.Uri
911import android.os.Build
1012import android.os.Bundle
1113import android.os.IBinder
14+ import android.provider.DocumentsContract
1215import android.util.Log
1316import android.view.View
1417import android.view.ViewTreeObserver
@@ -141,7 +144,11 @@ class MainActivity : ComponentActivity() {
141144 super .onCreate(savedInstanceState)
142145 WindowCompat .setDecorFitsSystemWindows(window, false )
143146
147+ val isZipIntent = intent?.action == Intent .ACTION_VIEW &&
148+ (intent.type == " application/zip" || intent.data?.toString()?.endsWith(" .zip" ) == true )
149+
144150 splashScreen.setOnExitAnimationListener { splashScreenView ->
151+ val duration = if (isZipIntent) 100L else 250L
145152 val scale = ObjectAnimator .ofPropertyValuesHolder(
146153 splashScreenView.view,
147154 PropertyValuesHolder .ofFloat(
@@ -156,7 +163,7 @@ class MainActivity : ComponentActivity() {
156163 )
157164 )
158165 scale.interpolator = AccelerateInterpolator ()
159- scale.duration = 250L
166+ scale.duration = duration
160167 scale.doOnEnd { splashScreenView.remove() }
161168 scale.start()
162169 }
@@ -175,6 +182,8 @@ class MainActivity : ComponentActivity() {
175182 }
176183 )
177184
185+
186+
178187 Shell .getShell()
179188 if (Shell .isAppGrantedRoot()!! ) {
180189 val intent = Intent (this , FilesystemService ::class .java)
@@ -188,6 +197,49 @@ class MainActivity : ComponentActivity() {
188197 }
189198 }
190199
200+ @SuppressLint(" WrongConstant" )
201+ private fun handleZipIntent (intent : Intent ? ) {
202+ val action = intent?.action ? : return
203+ val uri = when (action) {
204+ Intent .ACTION_VIEW -> intent.data
205+ Intent .ACTION_SEND -> intent.getParcelableExtra<Uri >(Intent .EXTRA_STREAM )
206+ else -> null
207+ } ? : return
208+ Log .d(MainViewModel .Companion .TAG , intent?.data.toString())
209+
210+ if (intent.action == Intent .ACTION_VIEW || intent.action == Intent .ACTION_SEND ) {
211+ if (uri.scheme == " content" && DocumentsContract .isDocumentUri(this , uri)) {
212+ val takeFlags =
213+ intent.flags and (Intent .FLAG_GRANT_READ_URI_PERMISSION or Intent .FLAG_GRANT_WRITE_URI_PERMISSION )
214+ try {
215+ contentResolver.takePersistableUriPermission(uri, takeFlags)
216+ } catch (se: SecurityException ) {
217+ Log .e(MainViewModel .Companion .TAG , se.message, se)
218+ }
219+ }
220+
221+ viewModel?.pendingFlashUri = uri
222+ if (viewModel?.isAb == true )
223+ viewModel?.showSlotIntentDialog?.value = true
224+ else {
225+ viewModel?.slotSuffixForFlash?.value = null
226+ viewModel?.slotSuffixForFlash?.value = viewModel?.slotSuffix
227+ }
228+ }
229+ }
230+
231+ override fun onNewIntent (intent : Intent ) {
232+ super .onNewIntent(intent)
233+ setIntent(intent)
234+ if (Shell .isAppGrantedRoot() == true ) {
235+ handleZipIntent(intent)
236+ if (intent.action == Intent .ACTION_VIEW || intent.action == Intent .ACTION_SEND ) {
237+ intent.replaceExtras(Bundle ()) // Clear any existing data
238+ setIntent(Intent ()) // Replace with empty intent
239+ }
240+ }
241+ }
242+
191243 fun onAidlConnected (fileSystemManager : FileSystemManager ) {
192244 try {
193245 Shell .cmd(" cd $filesDir " ).exec()
@@ -217,6 +269,14 @@ class MainActivity : ComponentActivity() {
217269 val mainViewModel = viewModel!!
218270 SharedViewModels .mainViewModel = mainViewModel
219271
272+ val slotSuffix by viewModel!! .slotSuffixForFlash
273+
274+ handleZipIntent(intent)
275+ if (intent.action == Intent .ACTION_VIEW || intent.action == Intent .ACTION_SEND ) {
276+ intent.replaceExtras(Bundle ()) // Clear any existing data
277+ setIntent(Intent ()) // Replace with empty intent
278+ }
279+
220280 val context = LocalContext .current
221281 val dialogData = viewModel!! .updateDialogData
222282 LaunchedEffect (Unit ) {
@@ -228,6 +288,31 @@ class MainActivity : ComponentActivity() {
228288 viewModel!! .showUpdateDialog(title, lines, confirm)
229289 }
230290 }
291+
292+ val uri = viewModel?.pendingFlashUri
293+
294+ if (uri != null ) {
295+ if (viewModel?.isAb == true && slotSuffix == null ) {
296+ viewModel?.pendingFlashUri = uri
297+ viewModel?.showSlotIntentDialog?.value = true
298+ } else {
299+ // Already have slot or not AB - flash directly
300+ navController.navigate(" slot${slotSuffix} /flash/ak3" ) {
301+ popUpTo(" slot${slotSuffix} " )
302+ }
303+ if (viewModel?.isAb == true && slotSuffix == " _b" )
304+ {
305+ viewModel?.slotB?.flashAk3(context, uri)
306+ }
307+ else
308+ {
309+ viewModel?.slotA?.flashAk3(context, uri)
310+ }
311+
312+ viewModel?.pendingFlashUri = null
313+ viewModel?.slotSuffixForFlash?.value = null
314+ }
315+ }
231316 }
232317
233318 var showExitDialog by remember { mutableStateOf(false ) }
@@ -530,6 +615,53 @@ class MainActivity : ComponentActivity() {
530615 }
531616 )
532617 }
618+
619+ if (viewModel?.showSlotIntentDialog?.value == true ) {
620+ AlertDialog (
621+ onDismissRequest = { viewModel?.showSlotIntentDialog?.value = false },
622+ title = { Text (" Select Slot to Flash" ) },
623+ text = { Text (" Choose the slot where the zip should be flashed." ) },
624+ confirmButton = {
625+ TextButton (onClick = {
626+ viewModel?.slotSuffixForFlash?.value = null
627+ viewModel?.slotSuffixForFlash?.value = if (viewModel?.slotSuffix == " _a" ) " _b" else " _a"
628+ viewModel?.showSlotIntentDialog?.value = false
629+ }) {
630+ Text (" Inactive Slot" )
631+ }
632+ },
633+ dismissButton = {
634+ TextButton (onClick = {
635+ viewModel?.slotSuffixForFlash?.value = null
636+ viewModel?.slotSuffixForFlash?.value = viewModel?.slotSuffix
637+ viewModel?.showSlotIntentDialog?.value = false
638+ }) {
639+ Text (" Active Slot" )
640+ }
641+ }
642+ )
643+ }
644+
645+ LaunchedEffect (slotSuffix) {
646+ val uri = viewModel!! .pendingFlashUri
647+
648+ if (uri != null && slotSuffix != null ) {
649+ navController.navigate(" slot${slotSuffix} /flash/ak3" ) {
650+ popUpTo(" slot${slotSuffix} " )
651+ }
652+ if (viewModel?.isAb == true && slotSuffix == " _b" )
653+ {
654+ viewModel?.slotB?.flashAk3(context, uri)
655+ }
656+ else
657+ {
658+ viewModel?.slotA?.flashAk3(context, uri)
659+ }
660+
661+ viewModel!! .pendingFlashUri = null
662+ viewModel!! .slotSuffixForFlash.value = null
663+ }
664+ }
533665 }
534666 }
535667 }
0 commit comments