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
9126cf0c
Commit
9126cf0c
authored
Oct 26, 2021
by
vvb2060
Committed by
John Wu
Nov 05, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrite deny list UI
parent
16322ab3
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
130 additions
and
364 deletions
+130
-364
XAndroid.kt
app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt
+0
-8
AppProcessInfo.kt
.../main/java/com/topjohnwu/magisk/ui/deny/AppProcessInfo.kt
+42
-53
DenyListFragment.kt
...ain/java/com/topjohnwu/magisk/ui/deny/DenyListFragment.kt
+35
-28
DenyListViewModel.kt
...in/java/com/topjohnwu/magisk/ui/deny/DenyListViewModel.kt
+25
-49
ic_search_md2.xml
app/src/main/res/drawable/ic_search_md2.xml
+5
-14
app_list_filter.xml
app/src/main/res/layout/app_list_filter.xml
+0
-166
fragment_deny_md2.xml
app/src/main/res/layout/fragment_deny_md2.xml
+2
-36
item_hide_md2.xml
app/src/main/res/layout/item_hide_md2.xml
+1
-1
menu_deny_md2.xml
app/src/main/res/menu/menu_deny_md2.xml
+20
-0
menu_hide_md2.xml
app/src/main/res/menu/menu_hide_md2.xml
+0
-9
No files found.
app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt
View file @
9126cf0c
...
@@ -9,9 +9,6 @@ import android.content.Intent
...
@@ -9,9 +9,6 @@ import android.content.Intent
import
android.content.pm.ApplicationInfo
import
android.content.pm.ApplicationInfo
import
android.content.pm.PackageManager
import
android.content.pm.PackageManager
import
android.content.pm.PackageManager.*
import
android.content.pm.PackageManager.*
import
android.content.pm.ServiceInfo
import
android.content.pm.ServiceInfo.FLAG_ISOLATED_PROCESS
import
android.content.pm.ServiceInfo.FLAG_USE_APP_ZYGOTE
import
android.content.res.Configuration
import
android.content.res.Configuration
import
android.content.res.Resources
import
android.content.res.Resources
import
android.database.Cursor
import
android.database.Cursor
...
@@ -58,11 +55,6 @@ import kotlinx.coroutines.launch
...
@@ -58,11 +55,6 @@ import kotlinx.coroutines.launch
import
java.io.File
import
java.io.File
import
java.lang.reflect.Array
as
JArray
import
java.lang.reflect.Array
as
JArray
val
ServiceInfo
.
isIsolated
get
()
=
(
flags
and
FLAG_ISOLATED_PROCESS
)
!=
0
@get
:
SuppressLint
(
"InlinedApi"
)
val
ServiceInfo
.
useAppZygote
get
()
=
(
flags
and
FLAG_USE_APP_ZYGOTE
)
!=
0
fun
Context
.
rawResource
(
id
:
Int
)
=
resources
.
openRawResource
(
id
)
fun
Context
.
rawResource
(
id
:
Int
)
=
resources
.
openRawResource
(
id
)
fun
Context
.
getBitmap
(
id
:
Int
):
Bitmap
{
fun
Context
.
getBitmap
(
id
:
Int
):
Bitmap
{
...
...
app/src/main/java/com/topjohnwu/magisk/ui/deny/AppProcessInfo.kt
View file @
9126cf0c
...
@@ -10,8 +10,6 @@ import android.graphics.drawable.Drawable
...
@@ -10,8 +10,6 @@ import android.graphics.drawable.Drawable
import
android.os.Build.VERSION.SDK_INT
import
android.os.Build.VERSION.SDK_INT
import
com.topjohnwu.magisk.core.utils.currentLocale
import
com.topjohnwu.magisk.core.utils.currentLocale
import
com.topjohnwu.magisk.ktx.getLabel
import
com.topjohnwu.magisk.ktx.getLabel
import
com.topjohnwu.magisk.ktx.isIsolated
import
com.topjohnwu.magisk.ktx.useAppZygote
class
CmdlineListItem
(
line
:
String
)
{
class
CmdlineListItem
(
line
:
String
)
{
val
packageName
:
String
val
packageName
:
String
...
@@ -27,72 +25,63 @@ class CmdlineListItem(line: String) {
...
@@ -27,72 +25,63 @@ class CmdlineListItem(line: String) {
const
val
ISOLATED_MAGIC
=
"isolated"
const
val
ISOLATED_MAGIC
=
"isolated"
@SuppressLint
(
"InlinedApi"
)
@SuppressLint
(
"InlinedApi"
)
class
AppProcessInfo
(
info
:
ApplicationInfo
,
pm
:
PackageManager
,
denyList
:
List
<
CmdlineListItem
>)
class
AppProcessInfo
(
val
applicationInfo
:
ApplicationInfo
,
pm
:
PackageManager
,
:
ApplicationInfo
(
info
),
Comparable
<
AppProcessInfo
>
{
denyList
:
List
<
CmdlineListItem
>)
:
Comparable
<
AppProcessInfo
>
{
val
label
=
info
.
getLabel
(
pm
)
private
val
denyList
=
denyList
.
filter
{
val
iconImage
:
Drawable
=
info
.
loadIcon
(
pm
)
it
.
packageName
==
applicationInfo
.
packageName
||
it
.
packageName
==
ISOLATED_MAGIC
val
processes
=
fetchProcesses
(
pm
,
denyList
)
}
val
label
=
applicationInfo
.
getLabel
(
pm
)
val
iconImage
:
Drawable
=
applicationInfo
.
loadIcon
(
pm
)
val
processes
=
fetchProcesses
(
pm
)
override
fun
compareTo
(
other
:
AppProcessInfo
)
=
comparator
.
compare
(
this
,
other
)
override
fun
compareTo
(
other
:
AppProcessInfo
)
=
comparator
.
compare
(
this
,
other
)
private
fun
fetchProcesses
(
private
fun
createProcess
(
name
:
String
,
pkg
:
String
=
applicationInfo
.
packageName
)
=
pm
:
PackageManager
,
ProcessInfo
(
name
,
pkg
,
denyList
.
any
{
it
.
process
==
name
&&
it
.
packageName
==
pkg
})
denylist
:
List
<
CmdlineListItem
>
):
List
<
ProcessInfo
>
{
// Fetch full PackageInfo
val
baseFlag
=
MATCH_DISABLED_COMPONENTS
or
MATCH_UNINSTALLED_PACKAGES
val
packageInfo
=
try
{
val
request
=
GET_ACTIVITIES
or
GET_SERVICES
or
GET_RECEIVERS
or
GET_PROVIDERS
pm
.
getPackageInfo
(
packageName
,
baseFlag
or
request
)
}
catch
(
e
:
NameNotFoundException
)
{
// EdXposed hooked, issue#3276
return
emptyList
()
}
catch
(
e
:
Exception
)
{
// Exceed binder data transfer limit, fetch each component type separately
pm
.
getPackageInfo
(
packageName
,
baseFlag
).
apply
{
runCatching
{
activities
=
pm
.
getPackageInfo
(
packageName
,
baseFlag
or
GET_ACTIVITIES
).
activities
}
runCatching
{
services
=
pm
.
getPackageInfo
(
packageName
,
baseFlag
or
GET_SERVICES
).
services
}
runCatching
{
receivers
=
pm
.
getPackageInfo
(
packageName
,
baseFlag
or
GET_RECEIVERS
).
receivers
}
runCatching
{
providers
=
pm
.
getPackageInfo
(
packageName
,
baseFlag
or
GET_PROVIDERS
).
providers
}
}
}
val
enabledList
=
denylist
.
filter
{
it
.
packageName
==
packageName
||
it
.
packageName
==
ISOLATED_MAGIC
}
private
fun
ComponentInfo
.
getProcName
():
String
=
processName
fun
createProcess
(
name
:
String
,
pkg
:
String
=
packageName
):
ProcessInfo
{
?:
applicationInfo
.
processName
return
ProcessInfo
(
name
,
pkg
,
enabledList
.
any
{
it
.
process
==
name
&&
it
.
packageName
==
pkg
})
?:
applicationInfo
.
packageName
}
var
haveAppZygote
=
false
private
fun
Array
<
out
ComponentInfo
>.
processes
()
=
map
{
createProcess
(
it
.
getProcName
())
}
fun
Array
<
out
ComponentInfo
>.
processes
()
=
map
{
createProcess
(
it
.
processName
)
}
fun
Array
<
ServiceInfo
>.
processes
()
=
map
{
private
fun
Array
<
ServiceInfo
>.
processes
()
=
map
{
if
(
it
.
isIsolated
)
{
if
((
it
.
flags
and
ServiceInfo
.
FLAG_ISOLATED_PROCESS
)
!=
0
)
{
if
(
it
.
useAppZygote
)
{
if
((
it
.
flags
and
ServiceInfo
.
FLAG_USE_APP_ZYGOTE
)
!=
0
)
{
haveAppZygote
=
true
val
proc
=
applicationInfo
.
processName
?:
applicationInfo
.
packageName
// Using app zygote, don't need to track the process
createProcess
(
"${proc}_zygote"
)
null
}
else
{
}
else
{
val
proc
=
if
(
SDK_INT
>=
29
)
"${it.processName}:${it.name}"
else
it
.
processName
val
proc
=
if
(
SDK_INT
>=
29
)
"${it.getProcName()}:${it.name}"
else
it
.
getProcName
()
createProcess
(
proc
,
ISOLATED_MAGIC
)
createProcess
(
proc
,
ISOLATED_MAGIC
)
}
}
}
else
{
}
else
{
createProcess
(
it
.
processName
)
createProcess
(
it
.
getProcName
())
}
}
}
private
fun
fetchProcesses
(
pm
:
PackageManager
):
List
<
ProcessInfo
>
{
val
flag
=
MATCH_DISABLED_COMPONENTS
or
MATCH_UNINSTALLED_PACKAGES
or
GET_ACTIVITIES
or
GET_SERVICES
or
GET_RECEIVERS
or
GET_PROVIDERS
val
packageInfo
=
try
{
pm
.
getPackageInfo
(
applicationInfo
.
packageName
,
flag
)
}
catch
(
e
:
Exception
)
{
// Exceed binder data transfer limit, local parsing package
pm
.
getPackageArchiveInfo
(
applicationInfo
.
sourceDir
,
flag
)
?:
return
emptyList
()
}
}
return
with
(
packageInfo
)
{
val
list
=
LinkedHashSet
<
ProcessInfo
>()
activities
?.
processes
().
orEmpty
()
+
list
+=
packageInfo
.
activities
?.
processes
().
orEmpty
()
services
?.
processes
().
orEmpty
()
+
list
+=
packageInfo
.
services
?.
processes
().
orEmpty
()
receivers
?.
processes
().
orEmpty
()
+
list
+=
packageInfo
.
receivers
?.
processes
().
orEmpty
()
providers
?.
processes
().
orEmpty
()
+
list
+=
packageInfo
.
providers
?.
processes
().
orEmpty
()
listOf
(
if
(
haveAppZygote
)
createProcess
(
"${processName}_zygote"
)
else
null
)
return
list
.
sortedBy
{
it
.
name
}
}.
filterNotNull
().
distinct
().
sortedBy
{
it
.
name
}
}
}
companion
object
{
companion
object
{
private
val
comparator
=
compareBy
<
AppProcessInfo
>(
private
val
comparator
=
compareBy
<
AppProcessInfo
>(
{
it
.
label
.
lowercase
(
currentLocale
)
},
{
it
.
label
.
lowercase
(
currentLocale
)
},
{
it
.
packageName
}
{
it
.
applicationInfo
.
packageName
}
)
)
}
}
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/ui/deny/DenyListFragment.kt
View file @
9126cf0c
...
@@ -6,8 +6,7 @@ import android.view.Menu
...
@@ -6,8 +6,7 @@ import android.view.Menu
import
android.view.MenuInflater
import
android.view.MenuInflater
import
android.view.MenuItem
import
android.view.MenuItem
import
android.view.View
import
android.view.View
import
androidx.core.view.isVisible
import
androidx.appcompat.widget.SearchView
import
androidx.recyclerview.widget.LinearLayoutManager
import
androidx.recyclerview.widget.RecyclerView
import
androidx.recyclerview.widget.RecyclerView
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.arch.BaseUIFragment
import
com.topjohnwu.magisk.arch.BaseUIFragment
...
@@ -17,19 +16,13 @@ import com.topjohnwu.magisk.ktx.addSimpleItemDecoration
...
@@ -17,19 +16,13 @@ import com.topjohnwu.magisk.ktx.addSimpleItemDecoration
import
com.topjohnwu.magisk.ktx.addVerticalPadding
import
com.topjohnwu.magisk.ktx.addVerticalPadding
import
com.topjohnwu.magisk.ktx.fixEdgeEffect
import
com.topjohnwu.magisk.ktx.fixEdgeEffect
import
com.topjohnwu.magisk.ktx.hideKeyboard
import
com.topjohnwu.magisk.ktx.hideKeyboard
import
com.topjohnwu.magisk.utils.MotionRevealHelper
class
DenyListFragment
:
BaseUIFragment
<
DenyListViewModel
,
FragmentDenyMd2Binding
>()
{
class
DenyListFragment
:
BaseUIFragment
<
DenyListViewModel
,
FragmentDenyMd2Binding
>()
{
override
val
layoutRes
=
R
.
layout
.
fragment_deny_md2
override
val
layoutRes
=
R
.
layout
.
fragment_deny_md2
override
val
viewModel
by
viewModel
<
DenyListViewModel
>()
override
val
viewModel
by
viewModel
<
DenyListViewModel
>()
private
var
isFilterVisible
private
lateinit
var
searchView
:
SearchView
get
()
=
binding
.
processFilter
.
isVisible
set
(
value
)
{
if
(!
value
)
hideKeyboard
()
MotionRevealHelper
.
withViews
(
binding
.
processFilter
,
binding
.
filterToggle
,
value
)
}
override
fun
onAttach
(
context
:
Context
)
{
override
fun
onAttach
(
context
:
Context
)
{
super
.
onAttach
(
context
)
super
.
onAttach
(
context
)
...
@@ -40,12 +33,6 @@ class DenyListFragment : BaseUIFragment<DenyListViewModel, FragmentDenyMd2Bindin
...
@@ -40,12 +33,6 @@ class DenyListFragment : BaseUIFragment<DenyListViewModel, FragmentDenyMd2Bindin
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
super
.
onViewCreated
(
view
,
savedInstanceState
)
binding
.
filterToggle
.
setOnClickListener
{
isFilterVisible
=
true
}
binding
.
appFilterInclude
.
filterDone
.
setOnClickListener
{
isFilterVisible
=
false
}
binding
.
appList
.
addOnScrollListener
(
object
:
RecyclerView
.
OnScrollListener
()
{
binding
.
appList
.
addOnScrollListener
(
object
:
RecyclerView
.
OnScrollListener
()
{
override
fun
onScrollStateChanged
(
recyclerView
:
RecyclerView
,
newState
:
Int
)
{
override
fun
onScrollStateChanged
(
recyclerView
:
RecyclerView
,
newState
:
Int
)
{
if
(
newState
!=
RecyclerView
.
SCROLL_STATE_IDLE
)
hideKeyboard
()
if
(
newState
!=
RecyclerView
.
SCROLL_STATE_IDLE
)
hideKeyboard
()
...
@@ -66,36 +53,56 @@ class DenyListFragment : BaseUIFragment<DenyListViewModel, FragmentDenyMd2Bindin
...
@@ -66,36 +53,56 @@ class DenyListFragment : BaseUIFragment<DenyListViewModel, FragmentDenyMd2Bindin
bottom
=
l_50
,
bottom
=
l_50
,
)
)
binding
.
appList
.
fixEdgeEffect
()
binding
.
appList
.
fixEdgeEffect
()
val
lama
=
binding
.
appList
.
layoutManager
?:
return
lama
.
isAutoMeasureEnabled
=
false
}
}
override
fun
onPreBind
(
binding
:
FragmentDenyMd2Binding
)
=
Unit
override
fun
onPreBind
(
binding
:
FragmentDenyMd2Binding
)
=
Unit
override
fun
onBackPressed
():
Boolean
{
override
fun
onBackPressed
():
Boolean
{
if
(
isFilterVisible
)
{
if
(
searchView
.
isIconfiedByDefault
&&
!
searchView
.
isIconified
)
{
isFilterVisible
=
fals
e
searchView
.
isIconified
=
tru
e
return
true
return
true
}
}
return
super
.
onBackPressed
()
return
super
.
onBackPressed
()
}
}
// ---
override
fun
onCreateOptionsMenu
(
menu
:
Menu
,
inflater
:
MenuInflater
)
{
override
fun
onCreateOptionsMenu
(
menu
:
Menu
,
inflater
:
MenuInflater
)
{
inflater
.
inflate
(
R
.
menu
.
menu_hide_md2
,
menu
)
inflater
.
inflate
(
R
.
menu
.
menu_deny_md2
,
menu
)
searchView
=
menu
.
findItem
(
R
.
id
.
action_search
).
actionView
as
SearchView
searchView
.
queryHint
=
searchView
.
context
.
getString
(
R
.
string
.
hide_filter_hint
)
searchView
.
setOnQueryTextListener
(
object
:
SearchView
.
OnQueryTextListener
{
override
fun
onQueryTextSubmit
(
query
:
String
?):
Boolean
{
viewModel
.
query
=
query
?:
""
return
true
}
override
fun
onQueryTextChange
(
newText
:
String
?):
Boolean
{
viewModel
.
query
=
newText
?:
""
return
true
}
})
}
}
override
fun
onOptionsItemSelected
(
item
:
MenuItem
):
Boolean
{
override
fun
onOptionsItemSelected
(
item
:
MenuItem
):
Boolean
{
when
(
item
.
itemId
)
{
when
(
item
.
itemId
)
{
R
.
id
.
action_focus_up
->
binding
.
appList
R
.
id
.
action_show_system
->
{
.
takeIf
{
(
it
.
layoutManager
as
?
LinearLayoutManager
)
?.
findFirstVisibleItemPosition
()
?:
0
>
10
}
val
check
=
!
item
.
isChecked
?.
also
{
it
.
scrollToPosition
(
10
)
}
viewModel
.
isShowSystem
=
check
.
let
{
binding
.
appList
}
item
.
isChecked
=
check
.
also
{
it
.
post
{
it
.
smoothScrollToPosition
(
0
)
}
}
return
true
}
R
.
id
.
action_show_OS
->
{
val
check
=
!
item
.
isChecked
viewModel
.
isShowOS
=
check
item
.
isChecked
=
check
return
true
}
}
}
return
super
.
onOptionsItemSelected
(
item
)
return
super
.
onOptionsItemSelected
(
item
)
}
}
override
fun
onPrepareOptionsMenu
(
menu
:
Menu
)
{
val
showSystem
=
menu
.
findItem
(
R
.
id
.
action_show_system
)
val
showOS
=
menu
.
findItem
(
R
.
id
.
action_show_OS
)
showOS
.
isEnabled
=
showSystem
.
isChecked
}
}
}
app/src/main/java/com/topjohnwu/magisk/ui/deny/DenyListViewModel.kt
View file @
9126cf0c
...
@@ -4,42 +4,39 @@ import android.annotation.SuppressLint
...
@@ -4,42 +4,39 @@ import android.annotation.SuppressLint
import
android.content.pm.ApplicationInfo
import
android.content.pm.ApplicationInfo
import
android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
import
android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
import
android.os.Process
import
android.os.Process
import
androidx.databinding.Bindable
import
androidx.lifecycle.viewModelScope
import
androidx.lifecycle.viewModelScope
import
com.topjohnwu.magisk.BR
import
com.topjohnwu.magisk.BR
import
com.topjohnwu.magisk.arch.BaseViewModel
import
com.topjohnwu.magisk.arch.BaseViewModel
import
com.topjohnwu.magisk.arch.Queryable
import
com.topjohnwu.magisk.arch.Queryable
import
com.topjohnwu.magisk.core.Config
import
com.topjohnwu.magisk.databinding.filterableListOf
import
com.topjohnwu.magisk.databinding.filterableListOf
import
com.topjohnwu.magisk.databinding.itemBindingOf
import
com.topjohnwu.magisk.databinding.itemBindingOf
import
com.topjohnwu.magisk.databinding.set
import
com.topjohnwu.magisk.di.AppContext
import
com.topjohnwu.magisk.di.AppContext
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.superuser.Shell
import
com.topjohnwu.superuser.Shell
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.launch
import
kotlinx.coroutines.launch
import
kotlinx.coroutines.withContext
import
kotlinx.coroutines.withContext
import
java.util.stream.Collectors
class
DenyListViewModel
:
BaseViewModel
(),
Queryable
{
class
DenyListViewModel
:
BaseViewModel
(),
Queryable
{
override
val
queryDelay
=
100
0L
override
val
queryDelay
=
0L
@get
:
Bindable
var
isShowSystem
=
false
var
isShowSystem
=
Config
.
showSystemApp
set
(
value
)
{
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
showSystem
)
{
field
=
value
Config
.
showSystemApp
=
it
submitQuery
()
submitQuery
()
}
}
@get
:
Bindable
var
isShowOS
=
false
var
isShowOS
=
false
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
showOS
)
{
set
(
value
)
{
field
=
value
submitQuery
()
submitQuery
()
}
}
@get
:
Bindable
var
query
=
""
var
query
=
""
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
query
)
{
set
(
value
)
{
field
=
value
submitQuery
()
submitQuery
()
}
}
...
@@ -60,64 +57,43 @@ class DenyListViewModel : BaseViewModel(), Queryable {
...
@@ -60,64 +57,43 @@ class DenyListViewModel : BaseViewModel(), Queryable {
state
=
State
.
LOADING
state
=
State
.
LOADING
val
(
apps
,
diff
)
=
withContext
(
Dispatchers
.
Default
)
{
val
(
apps
,
diff
)
=
withContext
(
Dispatchers
.
Default
)
{
val
pm
=
AppContext
.
packageManager
val
pm
=
AppContext
.
packageManager
val
hideList
=
Shell
.
su
(
"magisk --denylist ls"
).
exec
().
out
.
map
{
CmdlineListItem
(
it
)
}
val
denyList
=
Shell
.
su
(
"magisk --denylist ls"
).
exec
().
out
val
apps
=
pm
.
getInstalledApplications
(
MATCH_UNINSTALLED_PACKAGES
)
.
map
{
CmdlineListItem
(
it
)
}
.
asSequence
()
val
apps
=
pm
.
getInstalledApplications
(
MATCH_UNINSTALLED_PACKAGES
).
parallelStream
()
.
filter
Not
{
blacklist
.
contains
(
it
.
packageName
)
}
.
filter
{
AppContext
.
packageName
!=
it
.
packageName
}
.
map
{
AppProcessInfo
(
it
,
pm
,
hide
List
)
}
.
map
{
AppProcessInfo
(
it
,
pm
,
deny
List
)
}
.
filter
{
it
.
processes
.
isNotEmpty
()
}
.
filter
{
it
.
processes
.
isNotEmpty
()
}
.
filter
{
info
->
info
.
enabled
||
info
.
processes
.
any
{
it
.
isEnabled
}
}
.
map
{
DenyListRvItem
(
it
)
}
.
map
{
DenyListRvItem
(
it
)
}
.
toList
()
.
sorted
()
.
sorted
()
.
collect
(
Collectors
.
toList
())
apps
to
items
.
calculateDiff
(
apps
)
apps
to
items
.
calculateDiff
(
apps
)
}
}
items
.
update
(
apps
,
diff
)
items
.
update
(
apps
,
diff
)
submitQuery
()
submitQuery
()
}
}
// ---
override
fun
query
()
{
override
fun
query
()
{
items
.
filter
{
fun
showHidden
()
=
it
.
itemsChecked
!=
0
fun
filterSystem
()
=
isShowSystem
||
it
.
info
.
flags
and
ApplicationInfo
.
FLAG_SYSTEM
==
0
fun
isApp
(
uid
:
Int
)
=
run
{
fun
isApp
(
uid
:
Int
)
=
run
{
val
appId
:
Int
=
uid
%
100000
val
appId
:
Int
=
uid
%
100000
appId
>=
Process
.
FIRST_APPLICATION_UID
&&
appId
<=
Process
.
LAST_APPLICATION_UID
appId
>=
Process
.
FIRST_APPLICATION_UID
&&
appId
<=
Process
.
LAST_APPLICATION_UID
}
}
fun
filterOS
()
=
(
isShowSystem
&&
isShowOS
)
||
isApp
(
it
.
info
.
uid
)
fun
isSystemApp
(
flag
:
Int
)
=
flag
and
ApplicationInfo
.
FLAG_SYSTEM
!=
0
items
.
filter
{
fun
filterSystem
()
=
isShowSystem
||
!
isSystemApp
(
it
.
info
.
applicationInfo
.
flags
)
fun
filterOS
()
=
(
isShowSystem
&&
isShowOS
)
||
isApp
(
it
.
info
.
applicationInfo
.
uid
)
fun
filterQuery
():
Boolean
{
fun
filterQuery
():
Boolean
{
fun
inName
()
=
it
.
info
.
label
.
contains
(
query
,
true
)
fun
inName
()
=
it
.
info
.
label
.
contains
(
query
,
true
)
fun
inPackage
()
=
it
.
info
.
packageName
.
contains
(
query
,
true
)
fun
inPackage
()
=
it
.
info
.
applicationInfo
.
packageName
.
contains
(
query
,
true
)
fun
inProcesses
()
=
it
.
processes
.
any
{
p
->
p
.
process
.
name
.
contains
(
query
,
true
)
}
fun
inProcesses
()
=
it
.
processes
.
any
{
p
->
p
.
process
.
name
.
contains
(
query
,
true
)
}
return
inName
()
||
inPackage
()
||
inProcesses
()
return
inName
()
||
inPackage
()
||
inProcesses
()
}
}
showHidden
()
||
(
filterSystem
()
&&
filterOS
()
&&
filterQuery
()
)
filterSystem
()
&&
filterOS
()
&&
filterQuery
(
)
}
}
state
=
State
.
LOADED
state
=
State
.
LOADED
}
}
// ---
fun
resetQuery
()
{
query
=
""
}
companion
object
{
private
val
blacklist
by
lazy
{
listOf
(
AppContext
.
packageName
,
"com.android.chrome"
,
"com.chrome.beta"
,
"com.chrome.dev"
,
"com.chrome.canary"
,
"com.android.webview"
,
"com.google.android.webview"
)
}
}
}
}
app/src/main/res/drawable/ic_search_md2.xml
View file @
9126cf0c
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:width=
"24dp"
android:width=
"24dp"
android:height=
"24dp"
android:height=
"24dp"
android:viewportWidth=
"475.084"
android:viewportWidth=
"24"
android:viewportHeight=
"475.084"
>
android:viewportHeight=
"24"
>
<group
android:pivotX=
"237.542"
android:pivotY=
"237.542"
android:scaleX=
"0.8"
android:scaleY=
"0.8"
>
<path
<path
android:fillColor=
"?colorOnSurface"
android:fillColor=
"?colorOnSurface"
android:pathData=
"M464.524,412.846l-97.929,-97.925c23.6,-34.068 35.406,-72.047 35.406,-113.917c0,-27.218 -5.284,-53.249 -15.852,-78.087c-10.561,-24.842 -24.838,-46.254 -42.825,-64.241c-17.987,-17.987 -39.396,-32.264 -64.233,-42.826C254.246,5.285 228.217,0.003 200.999,0.003c-27.216,0 -53.247,5.282 -78.085,15.847C98.072,26.412 76.66,40.689 58.673,58.676c-17.989,17.987 -32.264,39.403 -42.827,64.241C5.282,147.758 0,173.786 0,201.004c0,27.216 5.282,53.238 15.846,78.083c10.562,24.838 24.838,46.247 42.827,64.234c17.987,17.993 39.403,32.264 64.241,42.832c24.841,10.563 50.869,15.844 78.085,15.844c41.879,0 79.852,-11.807 113.922,-35.405l97.929,97.641c6.852,7.231 15.406,10.849 25.693,10.849c9.897,0 18.467,-3.617 25.694,-10.849c7.23,-7.23 10.848,-15.796 10.848,-25.693C475.088,428.458 471.567,419.889 464.524,412.846zM291.363,291.358c-25.029,25.033 -55.148,37.549 -90.364,37.549c-35.21,0 -65.329,-12.519 -90.36,-37.549c-25.031,-25.029 -37.546,-55.144 -37.546,-90.36c0,-35.21 12.518,-65.334 37.546,-90.36c25.026,-25.032 55.15,-37.546 90.36,-37.546c35.212,0 65.331,12.519 90.364,37.546c25.033,25.026 37.548,55.15 37.548,90.36C328.911,236.214 316.392,266.329 291.363,291.358z"
android:pathData=
"M15.5,14h-0.79l-0.28,-0.27c1.2,-1.4 1.82,-3.31 1.48,-5.34 -0.47,-2.78 -2.79,-5 -5.59,-5.34 -4.23,-0.52 -7.79,3.04 -7.27,7.27 0.34,2.8 2.56,5.12 5.34,5.59 2.03,0.34 3.94,-0.28 5.34,-1.48l0.27,0.28v0.79l4.25,4.25c0.41,0.41 1.08,0.41 1.49,0 0.41,-0.41 0.41,-1.08 0,-1.49L15.5,14zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"
/>
tools:fillColor=
"@android:color/black"
/>
</group>
</vector>
</vector>
app/src/main/res/layout/app_list_filter.xml
deleted
100644 → 0
View file @
16322ab3
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
>
<data>
<import
type=
"com.topjohnwu.magisk.R"
/>
<variable
name=
"viewModel"
type=
"com.topjohnwu.magisk.ui.deny.DenyListViewModel"
/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:clipToPadding=
"false"
android:orientation=
"vertical"
android:paddingStart=
"@dimen/l1"
android:paddingTop=
"@dimen/l1"
android:paddingEnd=
"@dimen/l1"
android:paddingBottom=
"@dimen/l1"
app:fitsSystemWindowsInsets=
"bottom"
tools:layout_gravity=
"bottom"
tools:paddingBottom=
"64dp"
>
<TextView
android:id=
"@+id/filter_title"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"@string/hide_filters"
android:textAllCaps=
"true"
android:textAppearance=
"@style/AppearanceFoundation.Caption"
android:textColor=
"?colorPrimary"
android:textStyle=
"bold"
app:layout_constraintTop_toTopOf=
"parent"
/>
<com.google.android.material.chip.ChipGroup
android:id=
"@+id/hide_filter_chip_group"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"@dimen/l1"
app:chipSpacing=
"2dp"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/filter_title"
>
<com.google.android.material.chip.Chip
android:id=
"@+id/hide_filter_system_chip"
style=
"@style/Widget.MaterialComponents.Chip.Filter"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:checked=
"@={viewModel.showSystem}"
android:nextFocusRight=
"@id/hide_filter_chip_data"
android:nextFocusDown=
"@id/hide_filter_search_field"
android:text=
"@string/show_system_app"
android:textAppearance=
"@style/AppearanceFoundation.Caption"
app:checkedIcon=
"@drawable/ic_check_md2"
app:chipBackgroundColor=
"?colorSurfaceVariant"
tools:checked=
"true"
/>
<com.google.android.material.chip.Chip
android:id=
"@+id/hide_filter_os_chip"
style=
"@style/Widget.MaterialComponents.Chip.Filter"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:checked=
"@={viewModel.showOS}"
android:nextFocusRight=
"@id/hide_filter_chip_data"
android:nextFocusDown=
"@id/hide_filter_search_field"
android:text=
"@string/show_os_app"
android:textAppearance=
"@style/AppearanceFoundation.Caption"
app:checkedIcon=
"@drawable/ic_check_md2"
app:chipBackgroundColor=
"?colorSurfaceVariant"
tools:checked=
"true"
/>
<com.google.android.material.chip.Chip
android:id=
"@+id/hide_filter_chip_data"
style=
"@style/Widget.MaterialComponents.Chip.Entry"
gone=
"@{viewModel.query.empty}"
onCloseClicked=
"@{() -> viewModel.resetQuery()}"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:checkable=
"false"
android:nextFocusRight=
"@id/filter_done"
android:nextFocusDown=
"@id/hide_filter_search_field"
android:text=
"@{viewModel.query}"
android:textAppearance=
"@style/AppearanceFoundation.Caption"
app:chipBackgroundColor=
"?colorSurfaceVariant"
/>
</com.google.android.material.chip.ChipGroup>
<TextView
android:id=
"@+id/hide_filter_title_search"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"@dimen/l1"
android:text=
"@string/hide_search"
android:textAllCaps=
"true"
android:textAppearance=
"@style/AppearanceFoundation.Caption"
android:textColor=
"?colorPrimary"
android:textStyle=
"bold"
app:layout_constraintTop_toBottomOf=
"@+id/hide_filter_chip_group"
/>
<com.google.android.material.card.MaterialCardView
android:id=
"@+id/hide_filter_search"
style=
"@style/WidgetFoundation.Card"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"@dimen/l1"
android:layout_marginEnd=
"@dimen/l1"
android:layout_marginBottom=
"@dimen/l_50"
app:cardCornerRadius=
"18dp"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toStartOf=
"@+id/filter_done"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/hide_filter_title_search"
>
<ImageView
style=
"@style/WidgetFoundation.Icon"
android:layout_width=
"48dp"
android:layout_height=
"36dp"
android:layout_gravity=
"center_vertical|start"
android:padding=
"6dp"
app:srcCompat=
"@drawable/ic_search_md2"
app:tint=
"?colorDisabled"
/>
<EditText
android:id=
"@+id/hide_filter_search_field"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"48dp"
android:background=
"@null"
android:gravity=
"start|center_vertical"
android:hint=
"@string/hide_filter_hint"
android:inputType=
"textUri"
android:minHeight=
"36dp"
android:nextFocusRight=
"@id/filter_done"
android:paddingStart=
"0dp"
android:paddingEnd=
"@dimen/l1"
android:singleLine=
"true"
android:text=
"@={viewModel.query}"
android:textAppearance=
"@style/AppearanceFoundation.Body"
android:textColor=
"@color/color_text_transient"
android:textColorHint=
"?colorOnSurfaceVariant"
/>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id=
"@+id/filter_done"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:nextFocusLeft=
"@id/hide_filter_system_chip"
app:backgroundTint=
"?colorPrimary"
app:elevation=
"0dp"
app:fabSize=
"mini"
app:layout_constraintBottom_toBottomOf=
"@+id/hide_filter_search"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintTop_toTopOf=
"@+id/hide_filter_search"
app:srcCompat=
"@drawable/ic_check_md2"
app:tint=
"?colorOnPrimary"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
app/src/main/res/layout/fragment_deny_md2.xml
View file @
9126cf0c
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
<androidx.recyclerview.widget.RecyclerView
<androidx.recyclerview.widget.RecyclerView
android:id=
"@+id/app_list"
android:id=
"@+id/app_list"
invisibleUnless=
"@{viewModel.loaded
|| !viewModel.items.empty
}"
invisibleUnless=
"@{viewModel.loaded}"
itemBinding=
"@{viewModel.itemBinding}"
itemBinding=
"@{viewModel.itemBinding}"
items=
"@{viewModel.items}"
items=
"@{viewModel.items}"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
...
@@ -30,42 +30,8 @@
...
@@ -30,42 +30,8 @@
tools:listitem=
"@layout/item_hide_md2"
tools:listitem=
"@layout/item_hide_md2"
tools:paddingTop=
"40dp"
/>
tools:paddingTop=
"40dp"
/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id=
"@+id/filter_toggle"
invisibleUnless=
"@{viewModel.loaded || !viewModel.items.empty}"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"bottom|end"
android:layout_marginStart=
"@dimen/l1"
android:layout_marginEnd=
"@dimen/l1"
android:layout_marginBottom=
"@dimen/l1"
app:backgroundTint=
"?colorSurfaceSurfaceVariant"
app:layout_fitsSystemWindowsInsets=
"bottom"
app:srcCompat=
"@drawable/ic_search_md2"
app:tint=
"?colorPrimary"
tools:layout_marginBottom=
"64dp"
/>
<com.google.android.material.circularreveal.cardview.CircularRevealCardView
android:id=
"@+id/process_filter"
style=
"@style/WidgetFoundation.Card"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_gravity=
"bottom"
android:visibility=
"invisible"
app:layout_fitsSystemWindowsInsets=
"bottom"
app:cardCornerRadius=
"0dp"
>
<include
android:id=
"@+id/app_filter_include"
layout=
"@layout/app_list_filter"
viewModel=
"@{viewModel}"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
/>
</com.google.android.material.circularreveal.cardview.CircularRevealCardView>
<LinearLayout
<LinearLayout
goneUnless=
"@{viewModel.loading
&& viewModel.items.empty
}"
goneUnless=
"@{viewModel.loading}"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:layout_gravity=
"center"
...
...
app/src/main/res/layout/item_hide_md2.xml
View file @
9126cf0c
...
@@ -70,7 +70,7 @@
...
@@ -70,7 +70,7 @@
android:id=
"@+id/hide_package"
android:id=
"@+id/hide_package"
android:layout_width=
"0dp"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"@{item.info.packageName}"
android:text=
"@{item.info.
applicationInfo.
packageName}"
android:textAppearance=
"@style/AppearanceFoundation.Caption.Variant"
android:textAppearance=
"@style/AppearanceFoundation.Caption.Variant"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"@+id/hide_name"
app:layout_constraintEnd_toEndOf=
"@+id/hide_name"
...
...
app/src/main/res/menu/menu_deny_md2.xml
0 → 100644
View file @
9126cf0c
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
>
<item
android:id=
"@+id/action_search"
android:icon=
"@drawable/ic_search_md2"
android:title=
"@string/hide_search"
app:actionViewClass=
"androidx.appcompat.widget.SearchView"
app:showAsAction=
"ifRoom"
/>
<item
android:id=
"@+id/action_show_system"
android:checkable=
"true"
android:title=
"@string/show_system_app"
app:showAsAction=
"never"
/>
<item
android:id=
"@+id/action_show_OS"
android:checkable=
"true"
android:title=
"@string/show_os_app"
app:showAsAction=
"never"
/>
</menu>
app/src/main/res/menu/menu_hide_md2.xml
deleted
100644 → 0
View file @
16322ab3
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
>
<item
android:id=
"@+id/action_focus_up"
android:icon=
"@drawable/ic_up_md2"
android:title=
"@string/hide_scroll_up"
app:showAsAction=
"ifRoom"
/>
</menu>
\ No newline at end of file
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