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
package
com.topjohnwu.magisk.arch
import
android.content.Context
import
android.content.Intent
import
android.content.Intent
import
android.net.Uri
import
android.net.Uri
import
android.os.Bundle
import
android.os.Bundle
import
androidx.activity.result.contract.ActivityResultContract
import
androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import
androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import
androidx.databinding.ViewDataBinding
import
androidx.databinding.ViewDataBinding
import
com.topjohnwu.magisk.BuildConfig.APPLICATION_ID
import
com.topjohnwu.magisk.BuildConfig.APPLICATION_ID
...
@@ -23,12 +25,13 @@ import java.util.concurrent.CountDownLatch
...
@@ -23,12 +25,13 @@ import java.util.concurrent.CountDownLatch
abstract
class
BaseMainActivity
<
VM
:
BaseViewModel
,
Binding
:
ViewDataBinding
>
abstract
class
BaseMainActivity
<
VM
:
BaseViewModel
,
Binding
:
ViewDataBinding
>
:
BaseUIActivity
<
VM
,
Binding
>()
{
:
BaseUIActivity
<
VM
,
Binding
>()
{
private
val
latch
=
CountDownLatch
(
1
)
companion
object
{
companion
object
{
private
var
doPreload
=
true
private
var
doPreload
=
true
}
}
private
val
latch
=
CountDownLatch
(
1
)
private
val
uninstallPkg
=
registerForActivityResult
(
UninstallPackage
)
{
latch
.
countDown
()
}
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
setTheme
(
Theme
.
selected
.
themeRes
)
setTheme
(
Theme
.
selected
.
themeRes
)
...
@@ -107,19 +110,24 @@ abstract class BaseMainActivity<VM : BaseViewModel, Binding : ViewDataBinding>
...
@@ -107,19 +110,24 @@ abstract class BaseMainActivity<VM : BaseViewModel, Binding : ViewDataBinding>
if
(
Config
.
suManager
.
isNotEmpty
())
if
(
Config
.
suManager
.
isNotEmpty
())
Config
.
suManager
=
""
Config
.
suManager
=
""
pkg
?:
return
pkg
?:
return
if
(!
Shell
.
su
(
"(pm uninstall $pkg)& >/dev/null 2>&1"
).
exec
().
isSuccess
)
if
(!
Shell
.
su
(
"(pm uninstall $pkg)& >/dev/null 2>&1"
).
exec
().
isSuccess
)
{
uninstallApp
(
pkg
)
uninstallPkg
.
launch
(
pkg
)
// Wait for the uninstallation to finish
latch
.
await
()
}
}
}
}
}
@Suppress
(
"DEPRECATION"
)
object
UninstallPackage
:
ActivityResultContract
<
String
,
Boolean
>()
{
private
fun
uninstallApp
(
pkg
:
String
)
{
val
uri
=
Uri
.
Builder
().
scheme
(
"package"
).
opaquePart
(
pkg
).
build
()
@Suppress
(
"DEPRECATION"
)
val
intent
=
Intent
(
Intent
.
ACTION_UNINSTALL_PACKAGE
,
uri
)
override
fun
createIntent
(
context
:
Context
,
input
:
String
):
Intent
{
intent
.
putExtra
(
Intent
.
EXTRA_RETURN_RESULT
,
true
)
val
uri
=
Uri
.
Builder
().
scheme
(
"package"
).
opaquePart
(
input
).
build
()
startActivityForResult
(
intent
)
{
_
,
_
->
val
intent
=
Intent
(
Intent
.
ACTION_UNINSTALL_PACKAGE
,
uri
)
latch
.
countDown
()
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(
...
@@ -77,7 +77,7 @@ abstract class BaseViewModel(
PermissionEvent
(
permission
,
callback
).
publish
()
PermissionEvent
(
permission
,
callback
).
publish
()
}
}
fun
withExternalRW
(
callback
:
()
->
Unit
)
{
inline
fun
withExternalRW
(
crossinline
callback
:
()
->
Unit
)
{
withPermission
(
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
)
{
withPermission
(
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
)
{
if
(!
it
)
{
if
(!
it
)
{
SnackbarEvent
(
R
.
string
.
external_rw_permission_denied
).
publish
()
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
package
com.topjohnwu.magisk.core.base
import
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import
android.content.ActivityNotFoundException
import
android.content.Context
import
android.content.Context
import
android.content.Intent
import
android.content.Intent
import
android.content.pm.PackageManager
import
android.content.res.Configuration
import
android.content.res.Configuration
import
android.net.Uri
import
android.os.Build
import
android.os.Build
import
android.os.Bundle
import
android.os.Bundle
import
android
.widget.Toas
t
import
android
x.activity.result.contract.ActivityResultContracts.GetConten
t
import
androidx.a
nnotation.CallSuper
import
androidx.a
ctivity.result.contract.ActivityResultContracts.RequestPermission
import
androidx.appcompat.app.AppCompatActivity
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.isRunningAsStub
import
com.topjohnwu.magisk.core.utils.currentLocale
import
com.topjohnwu.magisk.core.utils.currentLocale
import
com.topjohnwu.magisk.core.wrap
import
com.topjohnwu.magisk.core.wrap
import
com.topjohnwu.magisk.ktx.reflectField
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
()
{
abstract
class
BaseActivity
:
AppCompatActivity
()
{
private
val
resultCallbacks
by
lazy
{
SparseArrayCompat
<
ActivityResultCallback
>()
}
private
var
permissionCallback
:
((
Boolean
)
->
Unit
)?
=
null
private
val
newRequestCode
:
Int
get
()
{
private
val
requestPermission
=
registerForActivityResult
(
RequestPermission
())
{
var
requestCode
:
Int
permissionCallback
?.
invoke
(
it
)
do
{
permissionCallback
=
null
requestCode
=
Random
.
nextInt
(
0
,
1
shl
15
)
}
}
while
(
resultCallbacks
.
containsKey
(
requestCode
))
return
requestCode
private
var
contentCallback
:
((
Uri
)
->
Unit
)?
=
null
private
val
getContent
=
registerForActivityResult
(
GetContent
())
{
if
(
it
!=
null
)
contentCallback
?.
invoke
(
it
)
contentCallback
=
null
}
}
override
fun
applyOverrideConfiguration
(
config
:
Configuration
?)
{
override
fun
applyOverrideConfiguration
(
config
:
Configuration
?)
{
...
@@ -57,72 +50,23 @@ abstract class BaseActivity : AppCompatActivity() {
...
@@ -57,72 +50,23 @@ abstract class BaseActivity : AppCompatActivity() {
super
.
onCreate
(
savedInstanceState
)
super
.
onCreate
(
savedInstanceState
)
}
}
fun
withPermission
(
permission
:
String
,
builder
:
PermissionRequestBuilder
.()
->
Unit
)
{
fun
withPermission
(
permission
:
String
,
callback
:
(
Boolean
)
->
Unit
)
{
val
request
=
PermissionRequestBuilder
().
apply
(
builder
).
build
()
if
(
permission
==
WRITE_EXTERNAL_STORAGE
&&
Build
.
VERSION
.
SDK_INT
>=
30
)
{
if
(
permission
==
WRITE_EXTERNAL_STORAGE
&&
Build
.
VERSION
.
SDK_INT
>=
30
)
{
// We do not need external rw on 30+
// We do not need external rw on 30+
request
.
onSuccess
(
)
callback
(
true
)
return
return
}
}
permissionCallback
=
callback
if
(
ContextCompat
.
checkSelfPermission
(
this
,
permission
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
requestPermission
.
launch
(
permission
)
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
)
}
}
}
@CallSuper
fun
getContent
(
type
:
String
,
callback
:
(
Uri
)
->
Unit
)
{
override
fun
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
data
:
Intent
?)
{
contentCallback
=
callback
super
.
onActivityResult
(
requestCode
,
resultCode
,
data
)
getContent
.
launch
(
type
)
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
)
}
}
}
override
fun
recreate
()
{
override
fun
recreate
()
{
startActivity
(
Intent
().
setComponent
(
intent
.
component
))
startActivity
(
Intent
().
setComponent
(
intent
.
component
))
finish
()
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
package
com.topjohnwu.magisk.events
import
android.app.Activity
import
android.content.ActivityNotFoundException
import
android.content.ActivityNotFoundException
import
android.content.Context
import
android.content.Context
import
android.
content.Intent
import
android.
net.Uri
import
android.view.View
import
android.view.View
import
android.widget.Toast
import
android.widget.Toast
import
androidx.navigation.NavDirections
import
androidx.navigation.NavDirections
...
@@ -11,18 +10,12 @@ import com.topjohnwu.magisk.MainDirections
...
@@ -11,18 +10,12 @@ import com.topjohnwu.magisk.MainDirections
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.arch.*
import
com.topjohnwu.magisk.arch.*
import
com.topjohnwu.magisk.core.Const
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.core.model.module.OnlineModule
import
com.topjohnwu.magisk.events.dialog.MarkDownDialog
import
com.topjohnwu.magisk.events.dialog.MarkDownDialog
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.view.MagiskDialog
import
com.topjohnwu.magisk.view.MagiskDialog
import
com.topjohnwu.magisk.view.Shortcuts
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
()
{
class
OpenReadmeEvent
(
private
val
item
:
OnlineModule
)
:
MarkDownDialog
()
{
override
suspend
fun
getMarkdownText
()
=
item
.
notes
()
override
suspend
fun
getMarkdownText
()
=
item
.
notes
()
override
fun
build
(
dialog
:
MagiskDialog
)
{
override
fun
build
(
dialog
:
MagiskDialog
)
{
...
@@ -39,14 +32,7 @@ class PermissionEvent(
...
@@ -39,14 +32,7 @@ class PermissionEvent(
)
:
ViewEvent
(),
ActivityExecutor
{
)
:
ViewEvent
(),
ActivityExecutor
{
override
fun
invoke
(
activity
:
BaseUIActivity
<
*
,
*
>)
=
override
fun
invoke
(
activity
:
BaseUIActivity
<
*
,
*
>)
=
activity
.
withPermission
(
permission
)
{
activity
.
withPermission
(
permission
,
callback
)
onSuccess
{
callback
(
true
)
}
onFailure
{
callback
(
false
)
}
}
}
}
class
BackPressEvent
:
ViewEvent
(),
ActivityExecutor
{
class
BackPressEvent
:
ViewEvent
(),
ActivityExecutor
{
...
@@ -75,12 +61,12 @@ class RecreateEvent : ViewEvent(), ActivityExecutor {
...
@@ -75,12 +61,12 @@ class RecreateEvent : ViewEvent(), ActivityExecutor {
}
}
}
}
class
MagiskInstallFileEvent
(
private
val
callback
:
ActivityResultCallback
)
class
MagiskInstallFileEvent
(
:
ViewEvent
(),
ActivityExecutor
{
private
val
callback
:
(
Uri
)
->
Unit
)
:
ViewEvent
(),
ActivityExecutor
{
override
fun
invoke
(
activity
:
BaseUIActivity
<
*
,
*
>)
{
override
fun
invoke
(
activity
:
BaseUIActivity
<
*
,
*
>)
{
val
intent
=
Intent
(
Intent
.
ACTION_GET_CONTENT
).
setType
(
"*/*"
)
try
{
try
{
activity
.
startActivityForResult
(
intent
,
callback
)
activity
.
getContent
(
"*/*"
,
callback
)
Utils
.
toast
(
R
.
string
.
patch_file_msg
,
Toast
.
LENGTH_LONG
)
Utils
.
toast
(
R
.
string
.
patch_file_msg
,
Toast
.
LENGTH_LONG
)
}
catch
(
e
:
ActivityNotFoundException
)
{
}
catch
(
e
:
ActivityNotFoundException
)
{
Utils
.
toast
(
R
.
string
.
app_not_found
,
Toast
.
LENGTH_SHORT
)
Utils
.
toast
(
R
.
string
.
app_not_found
,
Toast
.
LENGTH_SHORT
)
...
@@ -106,15 +92,10 @@ class AddHomeIconEvent : ViewEvent(), ContextExecutor {
...
@@ -106,15 +92,10 @@ class AddHomeIconEvent : ViewEvent(), ContextExecutor {
class
SelectModuleEvent
:
ViewEvent
(),
FragmentExecutor
{
class
SelectModuleEvent
:
ViewEvent
(),
FragmentExecutor
{
override
fun
invoke
(
fragment
:
BaseUIFragment
<
*
,
*
>)
{
override
fun
invoke
(
fragment
:
BaseUIFragment
<
*
,
*
>)
{
val
intent
=
Intent
(
Intent
.
ACTION_GET_CONTENT
).
setType
(
"application/zip"
)
try
{
try
{
fragment
.
apply
{
fragment
.
apply
{
activity
.
startActivityForResult
(
intent
)
{
code
,
intent
->
activity
.
getContent
(
"application/zip"
)
{
if
(
code
==
Activity
.
RESULT_OK
&&
intent
!=
null
)
{
MainDirections
.
actionFlashFragment
(
Const
.
Value
.
FLASH_ZIP
,
it
).
navigate
()
intent
.
data
?.
also
{
MainDirections
.
actionFlashFragment
(
Const
.
Value
.
FLASH_ZIP
,
it
).
navigate
()
}
}
}
}
}
}
}
catch
(
e
:
ActivityNotFoundException
)
{
}
catch
(
e
:
ActivityNotFoundException
)
{
...
...
app/src/main/java/com/topjohnwu/magisk/ui/install/InstallViewModel.kt
View file @
1bdd6e1a
package
com.topjohnwu.magisk.ui.install
package
com.topjohnwu.magisk.ui.install
import
android.app.Activity
import
android.net.Uri
import
android.net.Uri
import
androidx.databinding.Bindable
import
androidx.databinding.Bindable
import
androidx.lifecycle.viewModelScope
import
androidx.lifecycle.viewModelScope
...
@@ -42,10 +41,7 @@ class InstallViewModel(
...
@@ -42,10 +41,7 @@ class InstallViewModel(
set
(
value
)
=
set
(
value
,
_method
,
{
_method
=
it
},
BR
.
method
)
{
set
(
value
)
=
set
(
value
,
_method
,
{
_method
=
it
},
BR
.
method
)
{
when
(
it
)
{
when
(
it
)
{
R
.
id
.
method_patch
->
{
R
.
id
.
method_patch
->
{
MagiskInstallFileEvent
{
code
,
intent
->
MagiskInstallFileEvent
{
uri
->
data
=
uri
}.
publish
()
if
(
code
==
Activity
.
RESULT_OK
)
data
=
intent
?.
data
}.
publish
()
}
}
R
.
id
.
method_inactive_slot
->
{
R
.
id
.
method_inactive_slot
->
{
SecondSlotWarningDialog
().
publish
()
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