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
import
android.content.pm.ApplicationInfo
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.Resources
import
android.database.Cursor
...
...
@@ -58,11 +55,6 @@ import kotlinx.coroutines.launch
import
java.io.File
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
.
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
import
android.os.Build.VERSION.SDK_INT
import
com.topjohnwu.magisk.core.utils.currentLocale
import
com.topjohnwu.magisk.ktx.getLabel
import
com.topjohnwu.magisk.ktx.isIsolated
import
com.topjohnwu.magisk.ktx.useAppZygote
class
CmdlineListItem
(
line
:
String
)
{
val
packageName
:
String
...
...
@@ -27,72 +25,63 @@ class CmdlineListItem(line: String) {
const
val
ISOLATED_MAGIC
=
"isolated"
@SuppressLint
(
"InlinedApi"
)
class
AppProcessInfo
(
info
:
ApplicationInfo
,
pm
:
PackageManager
,
denyList
:
List
<
CmdlineListItem
>)
:
ApplicationInfo
(
info
),
Comparable
<
AppProcessInfo
>
{
class
AppProcessInfo
(
val
applicationInfo
:
ApplicationInfo
,
pm
:
PackageManager
,
denyList
:
List
<
CmdlineListItem
>)
:
Comparable
<
AppProcessInfo
>
{
val
label
=
info
.
getLabel
(
pm
)
val
iconImage
:
Drawable
=
info
.
loadIcon
(
pm
)
val
processes
=
fetchProcesses
(
pm
,
denyList
)
private
val
denyList
=
denyList
.
filter
{
it
.
packageName
==
applicationInfo
.
packageName
||
it
.
packageName
==
ISOLATED_MAGIC
}
val
label
=
applicationInfo
.
getLabel
(
pm
)
val
iconImage
:
Drawable
=
applicationInfo
.
loadIcon
(
pm
)
val
processes
=
fetchProcesses
(
pm
)
override
fun
compareTo
(
other
:
AppProcessInfo
)
=
comparator
.
compare
(
this
,
other
)
private
fun
fetchProcesses
(
pm
:
PackageManager
,
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
}
}
}
private
fun
createProcess
(
name
:
String
,
pkg
:
String
=
applicationInfo
.
packageName
)
=
ProcessInfo
(
name
,
pkg
,
denyList
.
any
{
it
.
process
==
name
&&
it
.
packageName
==
pkg
})
val
enabledList
=
denylist
.
filter
{
it
.
packageName
==
packageName
||
it
.
packageName
==
ISOLATED_MAGIC
}
fun
createProcess
(
name
:
String
,
pkg
:
String
=
packageName
):
ProcessInfo
{
return
ProcessInfo
(
name
,
pkg
,
enabledList
.
any
{
it
.
process
==
name
&&
it
.
packageName
==
pkg
})
}
private
fun
ComponentInfo
.
getProcName
():
String
=
processName
?:
applicationInfo
.
processName
?:
applicationInfo
.
packageName
var
haveAppZygote
=
false
fun
Array
<
out
ComponentInfo
>.
processes
()
=
map
{
createProcess
(
it
.
processName
)
}
fun
Array
<
ServiceInfo
>.
processes
()
=
map
{
if
(
it
.
isIsolated
)
{
if
(
it
.
useAppZygote
)
{
haveAppZygote
=
true
// Using app zygote, don't need to track the process
null
private
fun
Array
<
out
ComponentInfo
>.
processes
()
=
map
{
createProcess
(
it
.
getProcName
())
}
private
fun
Array
<
ServiceInfo
>.
processes
()
=
map
{
if
((
it
.
flags
and
ServiceInfo
.
FLAG_ISOLATED_PROCESS
)
!=
0
)
{
if
((
it
.
flags
and
ServiceInfo
.
FLAG_USE_APP_ZYGOTE
)
!=
0
)
{
val
proc
=
applicationInfo
.
processName
?:
applicationInfo
.
packageName
createProcess
(
"${proc}_zygote"
)
}
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
)
}
}
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
)
{
activities
?.
processes
().
orEmpty
()
+
services
?.
processes
().
orEmpty
()
+
receivers
?.
processes
().
orEmpty
()
+
providers
?.
processes
().
orEmpty
()
+
listOf
(
if
(
haveAppZygote
)
createProcess
(
"${processName}_zygote"
)
else
null
)
}.
filterNotNull
().
distinct
().
sortedBy
{
it
.
name
}
val
list
=
LinkedHashSet
<
ProcessInfo
>()
list
+=
packageInfo
.
activities
?.
processes
().
orEmpty
()
list
+=
packageInfo
.
services
?.
processes
().
orEmpty
()
list
+=
packageInfo
.
receivers
?.
processes
().
orEmpty
()
list
+=
packageInfo
.
providers
?.
processes
().
orEmpty
()
return
list
.
sortedBy
{
it
.
name
}
}
companion
object
{
private
val
comparator
=
compareBy
<
AppProcessInfo
>(
{
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
import
android.view.MenuInflater
import
android.view.MenuItem
import
android.view.View
import
androidx.core.view.isVisible
import
androidx.recyclerview.widget.LinearLayoutManager
import
androidx.appcompat.widget.SearchView
import
androidx.recyclerview.widget.RecyclerView
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.arch.BaseUIFragment
...
...
@@ -17,19 +16,13 @@ import com.topjohnwu.magisk.ktx.addSimpleItemDecoration
import
com.topjohnwu.magisk.ktx.addVerticalPadding
import
com.topjohnwu.magisk.ktx.fixEdgeEffect
import
com.topjohnwu.magisk.ktx.hideKeyboard
import
com.topjohnwu.magisk.utils.MotionRevealHelper
class
DenyListFragment
:
BaseUIFragment
<
DenyListViewModel
,
FragmentDenyMd2Binding
>()
{
override
val
layoutRes
=
R
.
layout
.
fragment_deny_md2
override
val
viewModel
by
viewModel
<
DenyListViewModel
>()
private
var
isFilterVisible
get
()
=
binding
.
processFilter
.
isVisible
set
(
value
)
{
if
(!
value
)
hideKeyboard
()
MotionRevealHelper
.
withViews
(
binding
.
processFilter
,
binding
.
filterToggle
,
value
)
}
private
lateinit
var
searchView
:
SearchView
override
fun
onAttach
(
context
:
Context
)
{
super
.
onAttach
(
context
)
...
...
@@ -40,12 +33,6 @@ class DenyListFragment : BaseUIFragment<DenyListViewModel, FragmentDenyMd2Bindin
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
binding
.
filterToggle
.
setOnClickListener
{
isFilterVisible
=
true
}
binding
.
appFilterInclude
.
filterDone
.
setOnClickListener
{
isFilterVisible
=
false
}
binding
.
appList
.
addOnScrollListener
(
object
:
RecyclerView
.
OnScrollListener
()
{
override
fun
onScrollStateChanged
(
recyclerView
:
RecyclerView
,
newState
:
Int
)
{
if
(
newState
!=
RecyclerView
.
SCROLL_STATE_IDLE
)
hideKeyboard
()
...
...
@@ -66,36 +53,56 @@ class DenyListFragment : BaseUIFragment<DenyListViewModel, FragmentDenyMd2Bindin
bottom
=
l_50
,
)
binding
.
appList
.
fixEdgeEffect
()
val
lama
=
binding
.
appList
.
layoutManager
?:
return
lama
.
isAutoMeasureEnabled
=
false
}
override
fun
onPreBind
(
binding
:
FragmentDenyMd2Binding
)
=
Unit
override
fun
onBackPressed
():
Boolean
{
if
(
isFilterVisible
)
{
isFilterVisible
=
fals
e
if
(
searchView
.
isIconfiedByDefault
&&
!
searchView
.
isIconified
)
{
searchView
.
isIconified
=
tru
e
return
true
}
return
super
.
onBackPressed
()
}
// ---
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
{
when
(
item
.
itemId
)
{
R
.
id
.
action_focus_up
->
binding
.
appList
.
takeIf
{
(
it
.
layoutManager
as
?
LinearLayoutManager
)
?.
findFirstVisibleItemPosition
()
?:
0
>
10
}
?.
also
{
it
.
scrollToPosition
(
10
)
}
.
let
{
binding
.
appList
}
.
also
{
it
.
post
{
it
.
smoothScrollToPosition
(
0
)
}
}
R
.
id
.
action_show_system
->
{
val
check
=
!
item
.
isChecked
viewModel
.
isShowSystem
=
check
item
.
isChecked
=
check
return
true
}
R
.
id
.
action_show_OS
->
{
val
check
=
!
item
.
isChecked
viewModel
.
isShowOS
=
check
item
.
isChecked
=
check
return
true
}
}
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
import
android.content.pm.ApplicationInfo
import
android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
import
android.os.Process
import
androidx.databinding.Bindable
import
androidx.lifecycle.viewModelScope
import
com.topjohnwu.magisk.BR
import
com.topjohnwu.magisk.arch.BaseViewModel
import
com.topjohnwu.magisk.arch.Queryable
import
com.topjohnwu.magisk.core.Config
import
com.topjohnwu.magisk.databinding.filterableListOf
import
com.topjohnwu.magisk.databinding.itemBindingOf
import
com.topjohnwu.magisk.databinding.set
import
com.topjohnwu.magisk.di.AppContext
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.superuser.Shell
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.launch
import
kotlinx.coroutines.withContext
import
java.util.stream.Collectors
class
DenyListViewModel
:
BaseViewModel
(),
Queryable
{
override
val
queryDelay
=
100
0L
override
val
queryDelay
=
0L
@get
:
Bindable
var
isShowSystem
=
Config
.
showSystemApp
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
showSystem
)
{
Config
.
showSystemApp
=
it
var
isShowSystem
=
false
set
(
value
)
{
field
=
value
submitQuery
()
}
@get
:
Bindable
var
isShowOS
=
false
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
showOS
)
{
set
(
value
)
{
field
=
value
submitQuery
()
}
@get
:
Bindable
var
query
=
""
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
query
)
{
set
(
value
)
{
field
=
value
submitQuery
()
}
...
...
@@ -60,64 +57,43 @@ class DenyListViewModel : BaseViewModel(), Queryable {
state
=
State
.
LOADING
val
(
apps
,
diff
)
=
withContext
(
Dispatchers
.
Default
)
{
val
pm
=
AppContext
.
packageManager
val
hideList
=
Shell
.
su
(
"magisk --denylist ls"
).
exec
().
out
.
map
{
CmdlineListItem
(
it
)
}
val
apps
=
pm
.
getInstalledApplications
(
MATCH_UNINSTALLED_PACKAGES
)
.
asSequence
()
.
filter
Not
{
blacklist
.
contains
(
it
.
packageName
)
}
.
map
{
AppProcessInfo
(
it
,
pm
,
hide
List
)
}
val
denyList
=
Shell
.
su
(
"magisk --denylist ls"
).
exec
().
out
.
map
{
CmdlineListItem
(
it
)
}
val
apps
=
pm
.
getInstalledApplications
(
MATCH_UNINSTALLED_PACKAGES
).
parallelStream
()
.
filter
{
AppContext
.
packageName
!=
it
.
packageName
}
.
map
{
AppProcessInfo
(
it
,
pm
,
deny
List
)
}
.
filter
{
it
.
processes
.
isNotEmpty
()
}
.
filter
{
info
->
info
.
enabled
||
info
.
processes
.
any
{
it
.
isEnabled
}
}
.
map
{
DenyListRvItem
(
it
)
}
.
toList
()
.
sorted
()
.
collect
(
Collectors
.
toList
())
apps
to
items
.
calculateDiff
(
apps
)
}
items
.
update
(
apps
,
diff
)
submitQuery
()
}
// ---
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
{
val
appId
:
Int
=
uid
%
100000
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
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
)
}
return
inName
()
||
inPackage
()
||
inProcesses
()
}
showHidden
()
||
(
filterSystem
()
&&
filterOS
()
&&
filterQuery
()
)
filterSystem
()
&&
filterOS
()
&&
filterQuery
(
)
}
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"
xmlns:tools=
"http://schemas.android.com/tools"
android:width=
"24dp"
android:height=
"24dp"
android:viewportWidth=
"475.084"
android:viewportHeight=
"475.084"
>
<group
android:pivotX=
"237.542"
android:pivotY=
"237.542"
android:scaleX=
"0.8"
android:scaleY=
"0.8"
>
android:viewportWidth=
"24"
android:viewportHeight=
"24"
>
<path
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"
tools:fillColor=
"@android:color/black"
/>
</group>
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"
/>
</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 @@
<androidx.recyclerview.widget.RecyclerView
android:id=
"@+id/app_list"
invisibleUnless=
"@{viewModel.loaded
|| !viewModel.items.empty
}"
invisibleUnless=
"@{viewModel.loaded}"
itemBinding=
"@{viewModel.itemBinding}"
items=
"@{viewModel.items}"
android:layout_width=
"match_parent"
...
...
@@ -30,42 +30,8 @@
tools:listitem=
"@layout/item_hide_md2"
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
goneUnless=
"@{viewModel.loading
&& viewModel.items.empty
}"
goneUnless=
"@{viewModel.loading}"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
...
...
app/src/main/res/layout/item_hide_md2.xml
View file @
9126cf0c
...
...
@@ -70,7 +70,7 @@
android:id=
"@+id/hide_package"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:text=
"@{item.info.packageName}"
android:text=
"@{item.info.
applicationInfo.
packageName}"
android:textAppearance=
"@style/AppearanceFoundation.Caption.Variant"
app:layout_constraintBottom_toBottomOf=
"parent"
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