Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
1bdd6e1a
Commit
1bdd6e1a
authored
Nov 05, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate to Activity Result APIs
parent
98deec23
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
50 additions
and
161 deletions
+50
-161
BaseMainActivity.kt
...c/main/java/com/topjohnwu/magisk/arch/BaseMainActivity.kt
+20
-12
BaseViewModel.kt
app/src/main/java/com/topjohnwu/magisk/arch/BaseViewModel.kt
+1
-1
BaseActivity.kt
.../main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt
+20
-76
PermissionRequestBuilder.kt
...om/topjohnwu/magisk/core/base/PermissionRequestBuilder.kt
+0
-40
ViewEvents.kt
app/src/main/java/com/topjohnwu/magisk/events/ViewEvents.kt
+8
-27
InstallViewModel.kt
.../java/com/topjohnwu/magisk/ui/install/InstallViewModel.kt
+1
-5
No files found.
app/src/main/java/com/topjohnwu/magisk/arch/BaseMainActivity.kt
View file @
1bdd6e1a
package
com.topjohnwu.magisk.arch
import
android.content.Context
import
android.content.Intent
import
android.net.Uri
import
android.os.Bundle
import
androidx.activity.result.contract.ActivityResultContract
import
androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import
androidx.databinding.ViewDataBinding
import
com.topjohnwu.magisk.BuildConfig.APPLICATION_ID
...
...
@@ -23,12 +25,13 @@ import java.util.concurrent.CountDownLatch
abstract
class
BaseMainActivity
<
VM
:
BaseViewModel
,
Binding
:
ViewDataBinding
>
:
BaseUIActivity
<
VM
,
Binding
>()
{
private
val
latch
=
CountDownLatch
(
1
)
companion
object
{
private
var
doPreload
=
true
}
private
val
latch
=
CountDownLatch
(
1
)
private
val
uninstallPkg
=
registerForActivityResult
(
UninstallPackage
)
{
latch
.
countDown
()
}
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
setTheme
(
Theme
.
selected
.
themeRes
)
...
...
@@ -107,19 +110,24 @@ abstract class BaseMainActivity<VM : BaseViewModel, Binding : ViewDataBinding>
if
(
Config
.
suManager
.
isNotEmpty
())
Config
.
suManager
=
""
pkg
?:
return
if
(!
Shell
.
su
(
"(pm uninstall $pkg)& >/dev/null 2>&1"
).
exec
().
isSuccess
)
uninstallApp
(
pkg
)
if
(!
Shell
.
su
(
"(pm uninstall $pkg)& >/dev/null 2>&1"
).
exec
().
isSuccess
)
{
uninstallPkg
.
launch
(
pkg
)
// Wait for the uninstallation to finish
latch
.
await
()
}
}
}
@Suppress
(
"DEPRECATION"
)
private
fun
uninstallApp
(
pkg
:
String
)
{
val
uri
=
Uri
.
Builder
().
scheme
(
"package"
).
opaquePart
(
pkg
).
build
()
val
intent
=
Intent
(
Intent
.
ACTION_UNINSTALL_PACKAGE
,
uri
)
intent
.
putExtra
(
Intent
.
EXTRA_RETURN_RESULT
,
true
)
startActivityForResult
(
intent
)
{
_
,
_
->
latch
.
countDown
()
object
UninstallPackage
:
ActivityResultContract
<
String
,
Boolean
>()
{
@Suppress
(
"DEPRECATION"
)
override
fun
createIntent
(
context
:
Context
,
input
:
String
):
Intent
{
val
uri
=
Uri
.
Builder
().
scheme
(
"package"
).
opaquePart
(
input
).
build
()
val
intent
=
Intent
(
Intent
.
ACTION_UNINSTALL_PACKAGE
,
uri
)
intent
.
putExtra
(
Intent
.
EXTRA_RETURN_RESULT
,
true
)
return
intent
}
latch
.
await
()
override
fun
parseResult
(
resultCode
:
Int
,
intent
:
Intent
?)
=
resultCode
==
RESULT_OK
}
}
app/src/main/java/com/topjohnwu/magisk/arch/BaseViewModel.kt
View file @
1bdd6e1a
...
...
@@ -77,7 +77,7 @@ abstract class BaseViewModel(
PermissionEvent
(
permission
,
callback
).
publish
()
}
fun
withExternalRW
(
callback
:
()
->
Unit
)
{
inline
fun
withExternalRW
(
crossinline
callback
:
()
->
Unit
)
{
withPermission
(
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
)
{
if
(!
it
)
{
SnackbarEvent
(
R
.
string
.
external_rw_permission_denied
).
publish
()
...
...
app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt
View file @
1bdd6e1a
package
com.topjohnwu.magisk.core.base
import
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import
android.content.ActivityNotFoundException
import
android.content.Context
import
android.content.Intent
import
android.content.pm.PackageManager
import
android.content.res.Configuration
import
android.net.Uri
import
android.os.Build
import
android.os.Bundle
import
android
.widget.Toas
t
import
androidx.a
nnotation.CallSuper
import
android
x.activity.result.contract.ActivityResultContracts.GetConten
t
import
androidx.a
ctivity.result.contract.ActivityResultContracts.RequestPermission
import
androidx.appcompat.app.AppCompatActivity
import
androidx.collection.SparseArrayCompat
import
androidx.core.app.ActivityCompat
import
androidx.core.content.ContextCompat
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.core.isRunningAsStub
import
com.topjohnwu.magisk.core.utils.currentLocale
import
com.topjohnwu.magisk.core.wrap
import
com.topjohnwu.magisk.ktx.reflectField
import
com.topjohnwu.magisk.ktx.set
import
com.topjohnwu.magisk.utils.Utils
import
kotlin.random.Random
typealias
ActivityResultCallback
=
BaseActivity
.(
Int
,
Intent
?)
->
Unit
abstract
class
BaseActivity
:
AppCompatActivity
()
{
private
val
resultCallbacks
by
lazy
{
SparseArrayCompat
<
ActivityResultCallback
>()
}
private
val
newRequestCode
:
Int
get
()
{
var
requestCode
:
Int
do
{
requestCode
=
Random
.
nextInt
(
0
,
1
shl
15
)
}
while
(
resultCallbacks
.
containsKey
(
requestCode
))
return
requestCode
private
var
permissionCallback
:
((
Boolean
)
->
Unit
)?
=
null
private
val
requestPermission
=
registerForActivityResult
(
RequestPermission
())
{
permissionCallback
?.
invoke
(
it
)
permissionCallback
=
null
}
private
var
contentCallback
:
((
Uri
)
->
Unit
)?
=
null
private
val
getContent
=
registerForActivityResult
(
GetContent
())
{
if
(
it
!=
null
)
contentCallback
?.
invoke
(
it
)
contentCallback
=
null
}
override
fun
applyOverrideConfiguration
(
config
:
Configuration
?)
{
...
...
@@ -57,72 +50,23 @@ abstract class BaseActivity : AppCompatActivity() {
super
.
onCreate
(
savedInstanceState
)
}
fun
withPermission
(
permission
:
String
,
builder
:
PermissionRequestBuilder
.()
->
Unit
)
{
val
request
=
PermissionRequestBuilder
().
apply
(
builder
).
build
()
fun
withPermission
(
permission
:
String
,
callback
:
(
Boolean
)
->
Unit
)
{
if
(
permission
==
WRITE_EXTERNAL_STORAGE
&&
Build
.
VERSION
.
SDK_INT
>=
30
)
{
// We do not need external rw on 30+
request
.
onSuccess
(
)
callback
(
true
)
return
}
if
(
ContextCompat
.
checkSelfPermission
(
this
,
permission
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
request
.
onSuccess
()
}
else
{
val
requestCode
=
newRequestCode
resultCallbacks
[
requestCode
]
=
{
result
,
_
->
if
(
result
>
0
)
request
.
onSuccess
()
else
request
.
onFailure
()
}
ActivityCompat
.
requestPermissions
(
this
,
arrayOf
(
permission
),
requestCode
)
}
}
fun
withExternalRW
(
builder
:
PermissionRequestBuilder
.()
->
Unit
)
{
withPermission
(
WRITE_EXTERNAL_STORAGE
,
builder
=
builder
)
}
override
fun
onRequestPermissionsResult
(
requestCode
:
Int
,
permissions
:
Array
<
out
String
>,
grantResults
:
IntArray
)
{
super
.
onRequestPermissionsResult
(
requestCode
,
permissions
,
grantResults
)
var
success
=
true
for
(
res
in
grantResults
)
{
if
(
res
!=
PackageManager
.
PERMISSION_GRANTED
)
{
success
=
false
break
}
}
resultCallbacks
[
requestCode
]
?.
also
{
resultCallbacks
.
remove
(
requestCode
)
it
(
this
,
if
(
success
)
1
else
-
1
,
null
)
}
permissionCallback
=
callback
requestPermission
.
launch
(
permission
)
}
@CallSuper
override
fun
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
data
:
Intent
?)
{
super
.
onActivityResult
(
requestCode
,
resultCode
,
data
)
resultCallbacks
[
requestCode
]
?.
also
{
callback
->
resultCallbacks
.
remove
(
requestCode
)
callback
(
this
,
resultCode
,
data
)
}
}
fun
startActivityForResult
(
intent
:
Intent
,
callback
:
ActivityResultCallback
)
{
val
requestCode
=
newRequestCode
resultCallbacks
[
requestCode
]
=
callback
try
{
startActivityForResult
(
intent
,
requestCode
)
}
catch
(
e
:
ActivityNotFoundException
)
{
Utils
.
toast
(
R
.
string
.
app_not_found
,
Toast
.
LENGTH_SHORT
)
}
fun
getContent
(
type
:
String
,
callback
:
(
Uri
)
->
Unit
)
{
contentCallback
=
callback
getContent
.
launch
(
type
)
}
override
fun
recreate
()
{
startActivity
(
Intent
().
setComponent
(
intent
.
component
))
finish
()
}
}
app/src/main/java/com/topjohnwu/magisk/core/base/PermissionRequestBuilder.kt
deleted
100644 → 0
View file @
98deec23
package
com.topjohnwu.magisk.core.base
typealias
SimpleCallback
=
()
->
Unit
typealias
PermissionRationaleCallback
=
(
List
<
String
>)
->
Unit
class
PermissionRequestBuilder
{
private
var
onSuccessCallback
:
SimpleCallback
=
{}
private
var
onFailureCallback
:
SimpleCallback
=
{}
private
var
onShowRationaleCallback
:
PermissionRationaleCallback
=
{}
fun
onSuccess
(
callback
:
SimpleCallback
)
{
onSuccessCallback
=
callback
}
fun
onFailure
(
callback
:
SimpleCallback
)
{
onFailureCallback
=
callback
}
fun
onShowRationale
(
callback
:
PermissionRationaleCallback
)
{
onShowRationaleCallback
=
callback
}
fun
build
():
PermissionRequest
{
return
PermissionRequest
(
onSuccessCallback
,
onFailureCallback
,
onShowRationaleCallback
)
}
}
class
PermissionRequest
(
private
val
onSuccessCallback
:
SimpleCallback
,
private
val
onFailureCallback
:
SimpleCallback
,
private
val
onShowRationaleCallback
:
PermissionRationaleCallback
)
{
fun
onSuccess
()
=
onSuccessCallback
()
fun
onFailure
()
=
onFailureCallback
()
fun
onShowRationale
(
permissions
:
List
<
String
>)
=
onShowRationaleCallback
(
permissions
)
}
app/src/main/java/com/topjohnwu/magisk/events/ViewEvents.kt
View file @
1bdd6e1a
package
com.topjohnwu.magisk.events
import
android.app.Activity
import
android.content.ActivityNotFoundException
import
android.content.Context
import
android.
content.Intent
import
android.
net.Uri
import
android.view.View
import
android.widget.Toast
import
androidx.navigation.NavDirections
...
...
@@ -11,18 +10,12 @@ import com.topjohnwu.magisk.MainDirections
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.arch.*
import
com.topjohnwu.magisk.core.Const
import
com.topjohnwu.magisk.core.base.ActivityResultCallback
import
com.topjohnwu.magisk.core.base.BaseActivity
import
com.topjohnwu.magisk.core.model.module.OnlineModule
import
com.topjohnwu.magisk.events.dialog.MarkDownDialog
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.view.MagiskDialog
import
com.topjohnwu.magisk.view.Shortcuts
class
ViewActionEvent
(
val
action
:
BaseActivity
.()
->
Unit
)
:
ViewEvent
(),
ActivityExecutor
{
override
fun
invoke
(
activity
:
BaseUIActivity
<
*
,
*
>)
=
action
(
activity
)
}
class
OpenReadmeEvent
(
private
val
item
:
OnlineModule
)
:
MarkDownDialog
()
{
override
suspend
fun
getMarkdownText
()
=
item
.
notes
()
override
fun
build
(
dialog
:
MagiskDialog
)
{
...
...
@@ -39,14 +32,7 @@ class PermissionEvent(
)
:
ViewEvent
(),
ActivityExecutor
{
override
fun
invoke
(
activity
:
BaseUIActivity
<
*
,
*
>)
=
activity
.
withPermission
(
permission
)
{
onSuccess
{
callback
(
true
)
}
onFailure
{
callback
(
false
)
}
}
activity
.
withPermission
(
permission
,
callback
)
}
class
BackPressEvent
:
ViewEvent
(),
ActivityExecutor
{
...
...
@@ -75,12 +61,12 @@ class RecreateEvent : ViewEvent(), ActivityExecutor {
}
}
class
MagiskInstallFileEvent
(
private
val
callback
:
ActivityResultCallback
)
:
ViewEvent
(),
ActivityExecutor
{
class
MagiskInstallFileEvent
(
private
val
callback
:
(
Uri
)
->
Unit
)
:
ViewEvent
(),
ActivityExecutor
{
override
fun
invoke
(
activity
:
BaseUIActivity
<
*
,
*
>)
{
val
intent
=
Intent
(
Intent
.
ACTION_GET_CONTENT
).
setType
(
"*/*"
)
try
{
activity
.
startActivityForResult
(
intent
,
callback
)
activity
.
getContent
(
"*/*"
,
callback
)
Utils
.
toast
(
R
.
string
.
patch_file_msg
,
Toast
.
LENGTH_LONG
)
}
catch
(
e
:
ActivityNotFoundException
)
{
Utils
.
toast
(
R
.
string
.
app_not_found
,
Toast
.
LENGTH_SHORT
)
...
...
@@ -106,15 +92,10 @@ class AddHomeIconEvent : ViewEvent(), ContextExecutor {
class
SelectModuleEvent
:
ViewEvent
(),
FragmentExecutor
{
override
fun
invoke
(
fragment
:
BaseUIFragment
<
*
,
*
>)
{
val
intent
=
Intent
(
Intent
.
ACTION_GET_CONTENT
).
setType
(
"application/zip"
)
try
{
fragment
.
apply
{
activity
.
startActivityForResult
(
intent
)
{
code
,
intent
->
if
(
code
==
Activity
.
RESULT_OK
&&
intent
!=
null
)
{
intent
.
data
?.
also
{
MainDirections
.
actionFlashFragment
(
Const
.
Value
.
FLASH_ZIP
,
it
).
navigate
()
}
}
activity
.
getContent
(
"application/zip"
)
{
MainDirections
.
actionFlashFragment
(
Const
.
Value
.
FLASH_ZIP
,
it
).
navigate
()
}
}
}
catch
(
e
:
ActivityNotFoundException
)
{
...
...
app/src/main/java/com/topjohnwu/magisk/ui/install/InstallViewModel.kt
View file @
1bdd6e1a
package
com.topjohnwu.magisk.ui.install
import
android.app.Activity
import
android.net.Uri
import
androidx.databinding.Bindable
import
androidx.lifecycle.viewModelScope
...
...
@@ -42,10 +41,7 @@ class InstallViewModel(
set
(
value
)
=
set
(
value
,
_method
,
{
_method
=
it
},
BR
.
method
)
{
when
(
it
)
{
R
.
id
.
method_patch
->
{
MagiskInstallFileEvent
{
code
,
intent
->
if
(
code
==
Activity
.
RESULT_OK
)
data
=
intent
?.
data
}.
publish
()
MagiskInstallFileEvent
{
uri
->
data
=
uri
}.
publish
()
}
R
.
id
.
method_inactive_slot
->
{
SecondSlotWarningDialog
().
publish
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment