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
31f88e0f
Commit
31f88e0f
authored
Mar 25, 2022
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update UI for sharedUID support
parent
9f1740cc
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
126 additions
and
121 deletions
+126
-121
PolicyDao.kt
...main/java/com/topjohnwu/magisk/core/magiskdb/PolicyDao.kt
+15
-14
SuPolicy.kt
.../main/java/com/topjohnwu/magisk/core/model/su/SuPolicy.kt
+7
-60
SuRequestHandler.kt
...ain/java/com/topjohnwu/magisk/core/su/SuRequestHandler.kt
+7
-5
PolicyRvItem.kt
...in/java/com/topjohnwu/magisk/ui/superuser/PolicyRvItem.kt
+21
-9
SuperuserViewModel.kt
...a/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt
+62
-23
SuRequestViewModel.kt
...a/com/topjohnwu/magisk/ui/surequest/SuRequestViewModel.kt
+12
-8
item_policy_md2.xml
app/src/main/res/layout/item_policy_md2.xml
+2
-2
No files found.
app/src/main/java/com/topjohnwu/magisk/core/magiskdb/PolicyDao.kt
View file @
31f88e0f
...
@@ -2,9 +2,7 @@ package com.topjohnwu.magisk.core.magiskdb
...
@@ -2,9 +2,7 @@ package com.topjohnwu.magisk.core.magiskdb
import
com.topjohnwu.magisk.core.Const
import
com.topjohnwu.magisk.core.Const
import
com.topjohnwu.magisk.core.model.su.SuPolicy
import
com.topjohnwu.magisk.core.model.su.SuPolicy
import
com.topjohnwu.magisk.core.model.su.createPolicy
import
com.topjohnwu.magisk.di.AppContext
import
com.topjohnwu.magisk.di.AppContext
import
timber.log.Timber
import
java.util.concurrent.TimeUnit
import
java.util.concurrent.TimeUnit
class
PolicyDao
:
MagiskDB
()
{
class
PolicyDao
:
MagiskDB
()
{
...
@@ -23,28 +21,31 @@ class PolicyDao : MagiskDB() {
...
@@ -23,28 +21,31 @@ class PolicyDao : MagiskDB() {
suspend
fun
fetch
(
uid
:
Int
):
SuPolicy
?
{
suspend
fun
fetch
(
uid
:
Int
):
SuPolicy
?
{
val
query
=
"SELECT * FROM ${Table.POLICY} WHERE uid == $uid LIMIT = 1"
val
query
=
"SELECT * FROM ${Table.POLICY} WHERE uid == $uid LIMIT = 1"
return
exec
(
query
)
{
it
.
toPolicyOrNull
()
}
.
firstOrNull
()
return
exec
(
query
,
::
toPolicy
)
.
firstOrNull
()
}
}
suspend
fun
update
(
policy
:
SuPolicy
)
{
suspend
fun
update
(
policy
:
SuPolicy
)
{
val
query
=
"REPLACE INTO ${Table.POLICY} ${policy.toMap().toQuery()}"
val
map
=
policy
.
toMap
()
// Put in package_name for old database
map
[
"package_name"
]
=
AppContext
.
packageManager
.
getNameForUid
(
policy
.
uid
)
!!
val
query
=
"REPLACE INTO ${Table.POLICY} ${map.toQuery()}"
exec
(
query
)
exec
(
query
)
}
}
suspend
fun
fetchAll
():
List
<
SuPolicy
>
{
suspend
fun
fetchAll
():
List
<
SuPolicy
>
{
val
query
=
"SELECT * FROM ${Table.POLICY} WHERE uid/100000 == ${Const.USER_ID}"
val
query
=
"SELECT * FROM ${Table.POLICY} WHERE uid/100000 == ${Const.USER_ID}"
return
exec
(
query
)
{
it
.
toPolicyOrNull
()
}
.
filterNotNull
()
return
exec
(
query
,
::
toPolicy
)
.
filterNotNull
()
}
}
private
suspend
fun
Map
<
String
,
String
>.
toPolicyOrNull
(
):
SuPolicy
?
{
private
fun
toPolicy
(
map
:
Map
<
String
,
String
>
):
SuPolicy
?
{
try
{
val
uid
=
map
[
"uid"
]
?.
toInt
()
?:
return
null
return
AppContext
.
packageManager
.
createPolicy
(
this
)
val
policy
=
SuPolicy
(
uid
)
}
catch
(
e
:
Exception
)
{
Timber
.
w
(
e
)
map
[
"policy"
]
?.
toInt
()
?.
let
{
policy
.
policy
=
it
}
val
uid
=
get
(
"uid"
)
?:
return
null
map
[
"until"
]
?.
toLong
()
?.
let
{
policy
.
until
=
it
}
delete
(
uid
.
toInt
())
map
[
"logging"
]
?.
toInt
()
?.
let
{
policy
.
logging
=
it
!=
0
}
return
null
map
[
"notification"
]
?.
toInt
()
?.
let
{
policy
.
notification
=
it
!=
0
}
}
return
policy
}
}
}
}
app/src/main/java/com/topjohnwu/magisk/core/model/su/SuPolicy.kt
View file @
31f88e0f
package
com.topjohnwu.magisk.core.model.su
package
com.topjohnwu.magisk.core.model.su
import
android.content.pm.PackageInfo
class
SuPolicy
(
val
uid
:
Int
)
{
import
android.content.pm.PackageManager
import
android.graphics.drawable.Drawable
import
com.topjohnwu.magisk.ktx.getLabel
import
com.topjohnwu.magisk.ktx.getPackageInfo
class
SuPolicy
(
val
uid
:
Int
,
val
packageName
:
String
,
val
appName
:
String
,
val
icon
:
Drawable
,
var
policy
:
Int
=
INTERACTIVE
,
var
until
:
Long
=
-
1L
,
var
logging
:
Boolean
=
true
,
var
notification
:
Boolean
=
true
)
{
companion
object
{
companion
object
{
const
val
INTERACTIVE
=
0
const
val
INTERACTIVE
=
0
const
val
DENY
=
1
const
val
DENY
=
1
const
val
ALLOW
=
2
const
val
ALLOW
=
2
}
}
fun
toMap
()
=
mapOf
(
var
policy
:
Int
=
INTERACTIVE
var
until
:
Long
=
-
1L
var
logging
:
Boolean
=
true
var
notification
:
Boolean
=
true
fun
toMap
():
MutableMap
<
String
,
Any
>
=
mutableMapOf
(
"uid"
to
uid
,
"uid"
to
uid
,
"package_name"
to
packageName
,
"policy"
to
policy
,
"policy"
to
policy
,
"until"
to
until
,
"until"
to
until
,
"logging"
to
logging
,
"logging"
to
logging
,
"notification"
to
notification
"notification"
to
notification
)
)
}
}
fun
PackageManager
.
createPolicy
(
info
:
PackageInfo
):
SuPolicy
{
val
appInfo
=
info
.
applicationInfo
val
prefix
=
if
(
info
.
sharedUserId
==
null
)
""
else
"[SharedUID] "
return
SuPolicy
(
uid
=
appInfo
.
uid
,
packageName
=
getNameForUid
(
appInfo
.
uid
)
!!
,
appName
=
"$prefix${appInfo.getLabel(this)}"
,
icon
=
appInfo
.
loadIcon
(
this
),
)
}
@Throws
(
PackageManager
.
NameNotFoundException
::
class
)
fun
PackageManager
.
createPolicy
(
uid
:
Int
):
SuPolicy
{
val
info
=
getPackageInfo
(
uid
,
-
1
)
return
if
(
info
==
null
)
{
// We can assert getNameForUid does not return null because
// getPackageInfo will already throw if UID does not exist
val
name
=
getNameForUid
(
uid
)
!!
SuPolicy
(
uid
=
uid
,
packageName
=
name
,
appName
=
"[SharedUID] $name"
,
icon
=
defaultActivityIcon
,
)
}
else
{
createPolicy
(
info
)
}
}
@Throws
(
PackageManager
.
NameNotFoundException
::
class
)
fun
PackageManager
.
createPolicy
(
map
:
Map
<
String
,
String
>):
SuPolicy
{
val
uid
=
map
[
"uid"
]
?.
toIntOrNull
()
?:
throw
IllegalArgumentException
()
val
policy
=
createPolicy
(
uid
)
map
[
"policy"
]
?.
toInt
()
?.
let
{
policy
.
policy
=
it
}
map
[
"until"
]
?.
toLong
()
?.
let
{
policy
.
until
=
it
}
map
[
"logging"
]
?.
toInt
()
?.
let
{
policy
.
logging
=
it
!=
0
}
map
[
"notification"
]
?.
toInt
()
?.
let
{
policy
.
notification
=
it
!=
0
}
return
policy
}
app/src/main/java/com/topjohnwu/magisk/core/su/SuRequestHandler.kt
View file @
31f88e0f
package
com.topjohnwu.magisk.core.su
package
com.topjohnwu.magisk.core.su
import
android.content.Intent
import
android.content.Intent
import
android.content.pm.PackageInfo
import
android.content.pm.PackageManager
import
android.content.pm.PackageManager
import
com.topjohnwu.magisk.BuildConfig
import
com.topjohnwu.magisk.BuildConfig
import
com.topjohnwu.magisk.core.Config
import
com.topjohnwu.magisk.core.Config
import
com.topjohnwu.magisk.core.magiskdb.PolicyDao
import
com.topjohnwu.magisk.core.magiskdb.PolicyDao
import
com.topjohnwu.magisk.core.model.su.SuPolicy
import
com.topjohnwu.magisk.core.model.su.SuPolicy
import
com.topjohnwu.magisk.core.model.su.createPolicy
import
com.topjohnwu.magisk.ktx.getPackageInfo
import
com.topjohnwu.magisk.ktx.getPackageInfo
import
com.topjohnwu.superuser.Shell
import
com.topjohnwu.superuser.Shell
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.Dispatchers
...
@@ -19,13 +19,15 @@ import java.io.IOException
...
@@ -19,13 +19,15 @@ import java.io.IOException
import
java.util.concurrent.TimeUnit
import
java.util.concurrent.TimeUnit
class
SuRequestHandler
(
class
SuRequestHandler
(
private
val
pm
:
PackageManager
,
val
pm
:
PackageManager
,
private
val
policyDB
:
PolicyDao
private
val
policyDB
:
PolicyDao
)
:
Closeable
{
)
:
Closeable
{
private
lateinit
var
output
:
DataOutputStream
private
lateinit
var
output
:
DataOutputStream
lateinit
var
policy
:
SuPolicy
lateinit
var
policy
:
SuPolicy
private
set
private
set
lateinit
var
pkgInfo
:
PackageInfo
private
set
// Return true to indicate undetermined policy, require user interaction
// Return true to indicate undetermined policy, require user interaction
suspend
fun
start
(
intent
:
Intent
):
Boolean
{
suspend
fun
start
(
intent
:
Intent
):
Boolean
{
...
@@ -33,7 +35,7 @@ class SuRequestHandler(
...
@@ -33,7 +35,7 @@ class SuRequestHandler(
return
false
return
false
// Never allow com.topjohnwu.magisk (could be malware)
// Never allow com.topjohnwu.magisk (could be malware)
if
(
p
olicy
.
packageName
==
BuildConfig
.
APPLICATION_ID
)
{
if
(
p
kgInfo
.
packageName
==
BuildConfig
.
APPLICATION_ID
)
{
Shell
.
cmd
(
"(pm uninstall ${BuildConfig.APPLICATION_ID})& >/dev/null 2>&1"
).
exec
()
Shell
.
cmd
(
"(pm uninstall ${BuildConfig.APPLICATION_ID})& >/dev/null 2>&1"
).
exec
()
return
false
return
false
}
}
...
@@ -64,9 +66,9 @@ class SuRequestHandler(
...
@@ -64,9 +66,9 @@ class SuRequestHandler(
val
fifo
=
intent
.
getStringExtra
(
"fifo"
)
?:
throw
SuRequestError
()
val
fifo
=
intent
.
getStringExtra
(
"fifo"
)
?:
throw
SuRequestError
()
val
uid
=
intent
.
getIntExtra
(
"uid"
,
-
1
).
also
{
if
(
it
<
0
)
throw
SuRequestError
()
}
val
uid
=
intent
.
getIntExtra
(
"uid"
,
-
1
).
also
{
if
(
it
<
0
)
throw
SuRequestError
()
}
val
pid
=
intent
.
getIntExtra
(
"pid"
,
-
1
)
val
pid
=
intent
.
getIntExtra
(
"pid"
,
-
1
)
val
i
nfo
=
pm
.
getPackageInfo
(
uid
,
pid
)
?:
throw
SuRequestError
()
pkgI
nfo
=
pm
.
getPackageInfo
(
uid
,
pid
)
?:
throw
SuRequestError
()
output
=
DataOutputStream
(
FileOutputStream
(
fifo
).
buffered
())
output
=
DataOutputStream
(
FileOutputStream
(
fifo
).
buffered
())
policy
=
pm
.
createPolicy
(
info
)
policy
=
SuPolicy
(
uid
)
true
true
}
catch
(
e
:
Exception
)
{
}
catch
(
e
:
Exception
)
{
when
(
e
)
{
when
(
e
)
{
...
...
app/src/main/java/com/topjohnwu/magisk/ui/superuser/PolicyRvItem.kt
View file @
31f88e0f
...
@@ -10,37 +10,49 @@ import com.topjohnwu.magisk.databinding.RvContainer
...
@@ -10,37 +10,49 @@ import com.topjohnwu.magisk.databinding.RvContainer
import
com.topjohnwu.magisk.databinding.set
import
com.topjohnwu.magisk.databinding.set
class
PolicyRvItem
(
class
PolicyRvItem
(
private
val
viewModel
:
SuperuserViewModel
,
override
val
item
:
SuPolicy
,
override
val
item
:
SuPolicy
,
val
packageName
:
String
,
private
val
isSharedUid
:
Boolean
,
val
icon
:
Drawable
,
val
icon
:
Drawable
,
val
viewModel
:
SuperuserViewModel
val
appName
:
String
)
:
ObservableDiffRvItem
<
PolicyRvItem
>(),
RvContainer
<
SuPolicy
>
{
)
:
ObservableDiffRvItem
<
PolicyRvItem
>(),
RvContainer
<
SuPolicy
>
{
override
val
layoutRes
=
R
.
layout
.
item_policy_md2
override
val
layoutRes
=
R
.
layout
.
item_policy_md2
val
title
get
()
=
if
(
isSharedUid
)
"[SharedUID] $appName"
else
appName
private
inline
fun
<
reified
T
>
setImpl
(
new
:
T
,
old
:
T
,
setter
:
(
T
)
->
Unit
)
{
if
(
old
!=
new
)
{
setter
(
new
)
}
}
@get
:
Bindable
@get
:
Bindable
var
isExpanded
=
false
var
isExpanded
=
false
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
expanded
)
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
expanded
)
// This property binds with the UI state
@get
:
Bindable
@get
:
Bindable
var
isEnabled
var
isEnabled
get
()
=
item
.
policy
==
SuPolicy
.
ALLOW
get
()
=
item
.
policy
==
SuPolicy
.
ALLOW
set
(
value
)
{
set
(
value
)
=
setImpl
(
value
,
isEnabled
)
{
if
(
value
!=
isEnabled
)
viewModel
.
togglePolicy
(
this
,
value
)
viewModel
.
togglePolicy
(
this
,
value
)
}
}
@get
:
Bindable
@get
:
Bindable
var
shouldNotify
var
shouldNotify
get
()
=
item
.
notification
get
()
=
item
.
notification
set
(
value
)
=
set
(
value
,
shouldNotify
,
{
item
.
notification
=
it
},
BR
.
shouldNotify
)
{
private
set
(
value
)
=
setImpl
(
value
,
shouldNotify
)
{
viewModel
.
updatePolicy
(
item
,
isLogging
=
false
)
item
.
notification
=
it
viewModel
.
updateNotify
(
this
)
}
}
@get
:
Bindable
@get
:
Bindable
var
shouldLog
var
shouldLog
get
()
=
item
.
logging
get
()
=
item
.
logging
set
(
value
)
=
set
(
value
,
shouldLog
,
{
item
.
logging
=
it
},
BR
.
shouldLog
)
{
private
set
(
value
)
=
setImpl
(
value
,
shouldLog
)
{
viewModel
.
updatePolicy
(
item
,
isLogging
=
true
)
item
.
logging
=
it
viewModel
.
updateLogging
(
this
)
}
}
fun
toggleExpand
()
{
fun
toggleExpand
()
{
...
...
app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt
View file @
31f88e0f
package
com.topjohnwu.magisk.ui.superuser
package
com.topjohnwu.magisk.ui.superuser
import
android.annotation.SuppressLint
import
android.content.pm.PackageManager
import
android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
import
androidx.databinding.ObservableArrayList
import
androidx.databinding.ObservableArrayList
import
androidx.lifecycle.viewModelScope
import
androidx.lifecycle.viewModelScope
import
com.topjohnwu.magisk.BR
import
com.topjohnwu.magisk.BR
...
@@ -12,9 +15,11 @@ import com.topjohnwu.magisk.core.utils.currentLocale
...
@@ -12,9 +15,11 @@ import com.topjohnwu.magisk.core.utils.currentLocale
import
com.topjohnwu.magisk.databinding.AnyDiffRvItem
import
com.topjohnwu.magisk.databinding.AnyDiffRvItem
import
com.topjohnwu.magisk.databinding.diffListOf
import
com.topjohnwu.magisk.databinding.diffListOf
import
com.topjohnwu.magisk.databinding.itemBindingOf
import
com.topjohnwu.magisk.databinding.itemBindingOf
import
com.topjohnwu.magisk.di.AppContext
import
com.topjohnwu.magisk.events.SnackbarEvent
import
com.topjohnwu.magisk.events.SnackbarEvent
import
com.topjohnwu.magisk.events.dialog.BiometricEvent
import
com.topjohnwu.magisk.events.dialog.BiometricEvent
import
com.topjohnwu.magisk.events.dialog.SuperuserRevokeDialog
import
com.topjohnwu.magisk.events.dialog.SuperuserRevokeDialog
import
com.topjohnwu.magisk.ktx.getLabel
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.utils.asText
import
com.topjohnwu.magisk.utils.asText
import
com.topjohnwu.magisk.view.TextItem
import
com.topjohnwu.magisk.view.TextItem
...
@@ -41,6 +46,7 @@ class SuperuserViewModel(
...
@@ -41,6 +46,7 @@ class SuperuserViewModel(
// ---
// ---
@SuppressLint
(
"InlinedApi"
)
override
fun
refresh
()
=
viewModelScope
.
launch
{
override
fun
refresh
()
=
viewModelScope
.
launch
{
if
(!
Utils
.
showSuperUser
())
{
if
(!
Utils
.
showSuperUser
())
{
state
=
State
.
LOADING_FAILED
state
=
State
.
LOADING_FAILED
...
@@ -49,11 +55,28 @@ class SuperuserViewModel(
...
@@ -49,11 +55,28 @@ class SuperuserViewModel(
state
=
State
.
LOADING
state
=
State
.
LOADING
val
(
policies
,
diff
)
=
withContext
(
Dispatchers
.
IO
)
{
val
(
policies
,
diff
)
=
withContext
(
Dispatchers
.
IO
)
{
db
.
deleteOutdated
()
db
.
deleteOutdated
()
val
policies
=
db
.
fetchAll
().
map
{
val
policies
=
ArrayList
<
PolicyRvItem
>()
PolicyRvItem
(
it
,
it
.
icon
,
this
@SuperuserViewModel
)
val
pm
=
AppContext
.
packageManager
}.
sortedWith
(
compareBy
(
for
(
policy
in
db
.
fetchAll
())
{
{
it
.
item
.
appName
.
lowercase
(
currentLocale
)
},
val
pkgs
=
pm
.
getPackagesForUid
(
policy
.
uid
)
?:
continue
{
it
.
item
.
packageName
}
policies
.
addAll
(
pkgs
.
mapNotNull
{
pkg
->
try
{
val
info
=
pm
.
getPackageInfo
(
pkg
,
MATCH_UNINSTALLED_PACKAGES
)
PolicyRvItem
(
this
@SuperuserViewModel
,
policy
,
info
.
packageName
,
info
.
sharedUserId
!=
null
,
info
.
applicationInfo
.
loadIcon
(
pm
),
info
.
applicationInfo
.
getLabel
(
pm
)
)
}
catch
(
e
:
PackageManager
.
NameNotFoundException
)
{
null
}
})
}
policies
.
sortWith
(
compareBy
(
{
it
.
appName
.
lowercase
(
currentLocale
)
},
{
it
.
packageName
}
))
))
policies
to
itemsPolicies
.
calculateDiff
(
policies
)
policies
to
itemsPolicies
.
calculateDiff
(
policies
)
}
}
...
@@ -82,40 +105,56 @@ class SuperuserViewModel(
...
@@ -82,40 +105,56 @@ class SuperuserViewModel(
}.
publish
()
}.
publish
()
}
else
{
}
else
{
SuperuserRevokeDialog
{
SuperuserRevokeDialog
{
appName
=
item
.
item
.
appNam
e
appName
=
item
.
titl
e
onSuccess
{
updateState
()
}
onSuccess
{
updateState
()
}
}.
publish
()
}.
publish
()
}
}
}
}
//---
fun
updateNotify
(
item
:
PolicyRvItem
)
{
viewModelScope
.
launch
{
fun
updatePolicy
(
policy
:
SuPolicy
,
isLogging
:
Boolean
)
=
viewModelScope
.
launch
{
db
.
update
(
item
.
item
)
db
.
update
(
policy
)
val
res
=
when
{
val
res
=
when
{
item
.
item
.
logging
->
R
.
string
.
su_snack_log_on
isLogging
->
when
{
policy
.
logging
->
R
.
string
.
su_snack_log_on
else
->
R
.
string
.
su_snack_log_off
else
->
R
.
string
.
su_snack_log_off
}
}
else
->
when
{
itemsPolicies
.
forEach
{
policy
.
notification
->
R
.
string
.
su_snack_notif_on
if
(
it
.
item
.
uid
==
item
.
item
.
uid
)
{
it
.
notifyPropertyChanged
(
BR
.
shouldNotify
)
}
}
SnackbarEvent
(
res
.
asText
(
item
.
appName
)).
publish
()
}
}
fun
updateLogging
(
item
:
PolicyRvItem
)
{
viewModelScope
.
launch
{
db
.
update
(
item
.
item
)
val
res
=
when
{
item
.
item
.
notification
->
R
.
string
.
su_snack_notif_on
else
->
R
.
string
.
su_snack_notif_off
else
->
R
.
string
.
su_snack_notif_off
}
}
itemsPolicies
.
forEach
{
if
(
it
.
item
.
uid
==
item
.
item
.
uid
)
{
it
.
notifyPropertyChanged
(
BR
.
shouldLog
)
}
}
SnackbarEvent
(
res
.
asText
(
item
.
appName
)).
publish
()
}
}
SnackbarEvent
(
res
.
asText
(
policy
.
appName
)).
publish
()
}
}
fun
togglePolicy
(
item
:
PolicyRvItem
,
enable
:
Boolean
)
{
fun
togglePolicy
(
item
:
PolicyRvItem
,
enable
:
Boolean
)
{
fun
updateState
()
{
fun
updateState
()
{
val
policy
=
if
(
enable
)
SuPolicy
.
ALLOW
else
SuPolicy
.
DENY
item
.
item
.
policy
=
policy
item
.
notifyPropertyChanged
(
BR
.
enabled
)
viewModelScope
.
launch
{
viewModelScope
.
launch
{
val
res
=
if
(
enable
)
R
.
string
.
su_snack_grant
else
R
.
string
.
su_snack_deny
item
.
item
.
policy
=
if
(
enable
)
SuPolicy
.
ALLOW
else
SuPolicy
.
DENY
db
.
update
(
item
.
item
)
db
.
update
(
item
.
item
)
val
res
=
if
(
item
.
item
.
policy
==
SuPolicy
.
ALLOW
)
R
.
string
.
su_snack_grant
itemsPolicies
.
forEach
{
else
R
.
string
.
su_snack_deny
if
(
it
.
item
.
uid
==
item
.
item
.
uid
)
{
SnackbarEvent
(
res
.
asText
(
item
.
item
.
appName
)).
publish
()
it
.
notifyPropertyChanged
(
BR
.
enabled
)
}
}
SnackbarEvent
(
res
.
asText
(
item
.
appName
)).
publish
()
}
}
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestViewModel.kt
View file @
31f88e0f
...
@@ -21,7 +21,6 @@ import com.topjohnwu.magisk.R
...
@@ -21,7 +21,6 @@ import com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.arch.BaseViewModel
import
com.topjohnwu.magisk.arch.BaseViewModel
import
com.topjohnwu.magisk.core.Config
import
com.topjohnwu.magisk.core.Config
import
com.topjohnwu.magisk.core.magiskdb.PolicyDao
import
com.topjohnwu.magisk.core.magiskdb.PolicyDao
import
com.topjohnwu.magisk.core.model.su.SuPolicy
import
com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW
import
com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW
import
com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.DENY
import
com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.DENY
import
com.topjohnwu.magisk.core.su.SuRequestHandler
import
com.topjohnwu.magisk.core.su.SuRequestHandler
...
@@ -31,6 +30,7 @@ import com.topjohnwu.magisk.di.AppContext
...
@@ -31,6 +30,7 @@ import com.topjohnwu.magisk.di.AppContext
import
com.topjohnwu.magisk.events.DieEvent
import
com.topjohnwu.magisk.events.DieEvent
import
com.topjohnwu.magisk.events.ShowUIEvent
import
com.topjohnwu.magisk.events.ShowUIEvent
import
com.topjohnwu.magisk.events.dialog.BiometricEvent
import
com.topjohnwu.magisk.events.dialog.BiometricEvent
import
com.topjohnwu.magisk.ktx.getLabel
import
com.topjohnwu.magisk.utils.TextHolder
import
com.topjohnwu.magisk.utils.TextHolder
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.utils.Utils
import
kotlinx.coroutines.launch
import
kotlinx.coroutines.launch
...
@@ -100,17 +100,21 @@ class SuRequestViewModel(
...
@@ -100,17 +100,21 @@ class SuRequestViewModel(
fun
handleRequest
(
intent
:
Intent
)
{
fun
handleRequest
(
intent
:
Intent
)
{
viewModelScope
.
launch
{
viewModelScope
.
launch
{
if
(
handler
.
start
(
intent
))
if
(
handler
.
start
(
intent
))
showDialog
(
handler
.
policy
)
showDialog
()
else
else
DieEvent
().
publish
()
DieEvent
().
publish
()
}
}
}
}
private
fun
showDialog
(
policy
:
SuPolicy
)
{
private
fun
showDialog
()
{
icon
=
policy
.
icon
val
pm
=
handler
.
pm
title
=
policy
.
appName
val
info
=
handler
.
pkgInfo
packageName
=
policy
.
packageName
val
prefix
=
if
(
info
.
sharedUserId
==
null
)
""
else
"[SharedUID] "
selectedItemPosition
=
timeoutPrefs
.
getInt
(
policy
.
packageName
,
0
)
icon
=
info
.
applicationInfo
.
loadIcon
(
pm
)
title
=
"$prefix${info.applicationInfo.getLabel(pm)}"
packageName
=
info
.
packageName
selectedItemPosition
=
timeoutPrefs
.
getInt
(
packageName
,
0
)
// Set timer
// Set timer
val
millis
=
SECONDS
.
toMillis
(
Config
.
suDefaultTimeout
.
toLong
())
val
millis
=
SECONDS
.
toMillis
(
Config
.
suDefaultTimeout
.
toLong
())
...
@@ -124,7 +128,7 @@ class SuRequestViewModel(
...
@@ -124,7 +128,7 @@ class SuRequestViewModel(
timer
?.
cancel
()
timer
?.
cancel
()
val
pos
=
selectedItemPosition
val
pos
=
selectedItemPosition
timeoutPrefs
.
edit
().
putInt
(
handler
.
p
olicy
.
packageName
,
pos
).
apply
()
timeoutPrefs
.
edit
().
putInt
(
handler
.
p
kgInfo
.
packageName
,
pos
).
apply
()
viewModelScope
.
launch
{
viewModelScope
.
launch
{
handler
.
respond
(
action
,
Config
.
Value
.
TIMEOUT_LIST
[
pos
])
handler
.
respond
(
action
,
Config
.
Value
.
TIMEOUT_LIST
[
pos
])
...
...
app/src/main/res/layout/item_policy_md2.xml
View file @
31f88e0f
...
@@ -54,7 +54,7 @@
...
@@ -54,7 +54,7 @@
android:ellipsize=
"middle"
android:ellipsize=
"middle"
android:gravity=
"start"
android:gravity=
"start"
android:maxLines=
"2"
android:maxLines=
"2"
android:text=
"@{item.
item.appNam
e}"
android:text=
"@{item.
titl
e}"
android:textAppearance=
"@style/AppearanceFoundation.Body"
android:textAppearance=
"@style/AppearanceFoundation.Body"
android:textIsSelectable=
"false"
android:textIsSelectable=
"false"
android:textStyle=
"bold"
android:textStyle=
"bold"
...
@@ -71,7 +71,7 @@
...
@@ -71,7 +71,7 @@
android:ellipsize=
"middle"
android:ellipsize=
"middle"
android:gravity=
"start"
android:gravity=
"start"
android:maxLines=
"2"
android:maxLines=
"2"
android:text=
"@{item.
item.
packageName}"
android:text=
"@{item.packageName}"
android:textAppearance=
"@style/AppearanceFoundation.Caption.Variant"
android:textAppearance=
"@style/AppearanceFoundation.Caption.Variant"
android:textColor=
"@android:color/tertiary_text_dark"
android:textColor=
"@android:color/tertiary_text_dark"
android:textIsSelectable=
"false"
android:textIsSelectable=
"false"
...
...
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