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
1e24c72c
Commit
1e24c72c
authored
Mar 13, 2019
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use our own existing implementation
parent
21756496
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
269 additions
and
345 deletions
+269
-345
build.gradle
app/build.gradle
+0
-1
AppViewBinder.java
...ain/java/com/topjohnwu/magisk/adapters/AppViewBinder.java
+0
-170
ApplicationAdapter.java
...ava/com/topjohnwu/magisk/adapters/ApplicationAdapter.java
+261
-84
ProcessViewBinder.java
...java/com/topjohnwu/magisk/adapters/ProcessViewBinder.java
+0
-80
MagiskHideFragment.java
...va/com/topjohnwu/magisk/fragments/MagiskHideFragment.java
+8
-10
No files found.
app/build.gradle
View file @
1e24c72c
...
...
@@ -29,7 +29,6 @@ dependencies {
implementation
'com.caverock:androidsvg-aar:1.3'
implementation
'org.kamranzafar:jtar:2.3'
implementation
'net.sourceforge.streamsupport:android-retrostreams:1.7.0'
implementation
'me.drakeet.multitype:multitype:3.5.0'
implementation
'com.github.sevar83:indeterminate-checkbox:1.0.5'
def
androidXVersion
=
"1.0.0"
...
...
app/src/main/java/com/topjohnwu/magisk/adapters/AppViewBinder.java
deleted
100644 → 0
View file @
21756496
package
com
.
topjohnwu
.
magisk
.
adapters
;
import
android.content.res.Resources
;
import
android.graphics.drawable.Drawable
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.ImageView
;
import
android.widget.TextView
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
import
androidx.recyclerview.widget.RecyclerView
;
import
com.buildware.widget.indeterm.IndeterminateCheckBox
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.superuser.Shell
;
import
java.util.ArrayList
;
import
java.util.Comparator
;
import
java.util.List
;
import
butterknife.BindView
;
import
java9.util.Comparators
;
import
me.drakeet.multitype.ItemViewBinder
;
public
class
AppViewBinder
extends
ItemViewBinder
<
AppViewBinder
.
App
,
AppViewBinder
.
ViewHolder
>
{
private
final
List
<
Object
>
items
;
AppViewBinder
(
List
<
Object
>
items
)
{
this
.
items
=
items
;
}
@Override
protected
@NonNull
ViewHolder
onCreateViewHolder
(
@NonNull
LayoutInflater
inflater
,
@NonNull
ViewGroup
parent
)
{
return
new
ViewHolder
(
inflater
.
inflate
(
R
.
layout
.
list_item_hide_app
,
parent
,
false
));
}
@Override
protected
void
onBindViewHolder
(
@NonNull
ViewHolder
holder
,
@NonNull
App
app
)
{
IndeterminateCheckBox
.
OnStateChangedListener
listener
=
(
IndeterminateCheckBox
indeterminateCheckBox
,
@Nullable
Boolean
stat
)
->
{
if
(
stat
!=
null
&&
stat
)
{
for
(
ProcessViewBinder
.
Process
process
:
app
.
processes
)
{
Shell
.
su
(
"magiskhide --add "
+
process
.
fullname
).
submit
();
process
.
hidden
=
true
;
}
}
else
if
(
stat
!=
null
)
{
for
(
ProcessViewBinder
.
Process
process
:
app
.
processes
)
{
Shell
.
su
(
"magiskhide --rm "
+
process
.
fullname
).
submit
();
process
.
hidden
=
false
;
}
}
app
.
getStatBool
(
true
);
};
holder
.
app_name
.
setText
(
app
.
name
);
holder
.
app_icon
.
setImageDrawable
(
app
.
icon
);
holder
.
package_name
.
setText
(
app
.
packageName
);
holder
.
checkBox
.
setOnStateChangedListener
(
null
);
holder
.
checkBox
.
setState
(
app
.
getStatBool
(
false
));
holder
.
checkBox
.
setOnStateChangedListener
(
listener
);
if
(
app
.
expand
)
{
holder
.
checkBox
.
setVisibility
(
View
.
GONE
);
setBottomMargin
(
holder
.
itemView
,
0
);
}
else
{
holder
.
checkBox
.
setVisibility
(
View
.
VISIBLE
);
setBottomMargin
(
holder
.
itemView
,
2
);
}
holder
.
itemView
.
setOnClickListener
((
v
)
->
{
int
index
=
getPosition
(
holder
);
if
(
app
.
expand
)
{
app
.
expand
=
false
;
items
.
removeAll
(
app
.
processes
);
getAdapter
().
notifyItemRangeRemoved
(
index
+
1
,
app
.
processes
.
size
());
setBottomMargin
(
holder
.
itemView
,
2
);
holder
.
checkBox
.
setOnStateChangedListener
(
null
);
holder
.
checkBox
.
setVisibility
(
View
.
VISIBLE
);
holder
.
checkBox
.
setState
(
app
.
getStatBool
(
true
));
holder
.
checkBox
.
setOnStateChangedListener
(
listener
);
}
else
{
holder
.
checkBox
.
setVisibility
(
View
.
GONE
);
setBottomMargin
(
holder
.
itemView
,
0
);
app
.
expand
=
true
;
items
.
addAll
(
index
+
1
,
app
.
processes
);
getAdapter
().
notifyItemRangeInserted
(
index
+
1
,
app
.
processes
.
size
());
}
});
}
private
void
setBottomMargin
(
View
view
,
int
dp
)
{
ViewGroup
.
LayoutParams
params
=
view
.
getLayoutParams
();
ViewGroup
.
MarginLayoutParams
marginParams
;
if
(
params
instanceof
ViewGroup
.
MarginLayoutParams
)
{
marginParams
=
(
ViewGroup
.
MarginLayoutParams
)
params
;
}
else
{
marginParams
=
new
ViewGroup
.
MarginLayoutParams
(
params
);
}
int
px
=
(
int
)
(
0.5f
+
dp
*
Resources
.
getSystem
().
getDisplayMetrics
().
density
);
marginParams
.
bottomMargin
=
px
;
view
.
setLayoutParams
(
marginParams
);
}
static
class
ViewHolder
extends
RecyclerView
.
ViewHolder
{
@BindView
(
R
.
id
.
app_icon
)
ImageView
app_icon
;
@BindView
(
R
.
id
.
app_name
)
TextView
app_name
;
@BindView
(
R
.
id
.
package_name
)
TextView
package_name
;
@BindView
(
R
.
id
.
checkbox
)
IndeterminateCheckBox
checkBox
;
ViewHolder
(
View
itemView
)
{
super
(
itemView
);
new
AppViewBinder$ViewHolder_ViewBinding
(
this
,
itemView
);
}
}
public
static
class
App
implements
Comparable
<
App
>
{
Drawable
icon
;
String
name
;
String
packageName
;
int
flags
;
List
<
ProcessViewBinder
.
Process
>
processes
;
boolean
expand
=
false
;
int
stat
=
-
1
;
App
(
Drawable
icon
,
String
name
,
String
packageName
,
int
flags
)
{
this
.
icon
=
icon
;
this
.
name
=
name
;
this
.
packageName
=
packageName
;
this
.
flags
=
flags
;
this
.
processes
=
new
ArrayList
<>();
}
int
getStat
(
boolean
update
)
{
if
(
stat
>
1
&&
!
update
)
return
stat
;
int
n
=
0
;
for
(
ProcessViewBinder
.
Process
process
:
processes
)
{
if
(
process
.
hidden
)
n
++;
}
if
(
n
==
processes
.
size
())
stat
=
2
;
else
if
(
n
>
0
)
stat
=
1
;
else
stat
=
0
;
return
stat
;
}
Boolean
getStatBool
(
boolean
update
)
{
int
stat
=
getStat
(
update
);
switch
(
stat
)
{
case
2
:
return
true
;
case
1
:
return
null
;
case
0
:
default
:
return
false
;
}
}
@Override
public
int
compareTo
(
App
o
)
{
Comparator
<
App
>
c
;
c
=
Comparators
.
comparing
((
App
t
)
->
t
.
stat
);
c
=
Comparators
.
reversed
(
c
);
c
=
Comparators
.
thenComparing
(
c
,
t
->
t
.
name
,
String:
:
compareToIgnoreCase
);
return
c
.
compare
(
this
,
o
);
}
}
}
app/src/main/java/com/topjohnwu/magisk/adapters/ApplicationAdapter.java
View file @
1e24c72c
...
...
@@ -6,31 +6,43 @@ import android.content.pm.ComponentInfo;
import
android.content.pm.PackageInfo
;
import
android.content.pm.PackageManager
;
import
android.os.AsyncTask
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.CheckBox
;
import
android.widget.ImageView
;
import
android.widget.TextView
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.WorkerThread
;
import
androidx.collection.ArraySet
;
import
androidx.recyclerview.widget.RecyclerView
;
import
com.buildware.widget.indeterm.IndeterminateCheckBox
;
import
com.topjohnwu.magisk.App
;
import
com.topjohnwu.magisk.Config
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.utils.Topic
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.superuser.Shell
;
import
com.topjohnwu.superuser.internal.UiThreadHandler
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.List
;
import
java.util.Set
;
import
butterknife.BindView
;
import
java9.util.Comparators
;
import
java9.util.Objects
;
import
java9.util.stream.Collectors
;
import
java9.util.stream.Stream
;
import
java9.util.stream.StreamSupport
;
import
me.drakeet.multitype.MultiTypeAdapter
;
import
static
com
.
topjohnwu
.
magisk
.
utils
.
Utils
.
getAppLabel
;
public
class
ApplicationAdapter
{
public
class
ApplicationAdapter
extends
SectionedAdapter
<
ApplicationAdapter
.
AppViewHolder
,
ApplicationAdapter
.
ProcessViewHolder
>
{
/* A list of apps that should not be shown as hide-able */
private
static
final
List
<
String
>
HIDE_BLACKLIST
=
Arrays
.
asList
(
...
...
@@ -46,24 +58,137 @@ public class ApplicationAdapter {
private
static
final
String
SAFETYNET_PROCESS
=
"com.google.android.gms.unstable"
;
private
static
final
String
GMS_PACKAGE
=
"com.google.android.gms"
;
private
List
<
AppViewBinder
.
App
>
full
List
;
private
List
<
HideAppInfo
>
fullList
,
show
List
;
private
List
<
HideTarget
>
hideList
;
private
List
<
Object
>
showList
;
private
MultiTypeAdapter
adapter
;
private
PackageManager
pm
;
private
boolean
showSystem
;
public
ApplicationAdapter
(
Context
context
,
MultiTypeAdapter
adapter
)
{
public
ApplicationAdapter
(
Context
context
)
{
fullList
=
showList
=
Collections
.
emptyList
();
hideList
=
Collections
.
emptyList
();
fullList
=
new
ArrayList
<>();
showList
=
new
ArrayList
<>();
this
.
adapter
=
adapter
;
this
.
adapter
.
setItems
(
showList
);
pm
=
context
.
getPackageManager
();
showSystem
=
Config
.
get
(
Config
.
Key
.
SHOW_SYSTEM_APP
);
AsyncTask
.
SERIAL_EXECUTOR
.
execute
(
this
::
loadApps
);
adapter
.
register
(
AppViewBinder
.
App
.
class
,
new
AppViewBinder
(
showList
));
adapter
.
register
(
ProcessViewBinder
.
Process
.
class
,
new
ProcessViewBinder
());
}
@Override
public
int
getSectionCount
()
{
return
showList
.
size
();
}
@Override
public
int
getItemCount
(
int
section
)
{
return
showList
.
get
(
section
).
expanded
?
showList
.
get
(
section
).
processes
.
size
()
:
0
;
}
@Override
public
AppViewHolder
onCreateSectionViewHolder
(
ViewGroup
parent
)
{
View
v
=
LayoutInflater
.
from
(
parent
.
getContext
()).
inflate
(
R
.
layout
.
list_item_hide_app
,
parent
,
false
);
return
new
AppViewHolder
(
v
);
}
@Override
public
ProcessViewHolder
onCreateItemViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
View
v
=
LayoutInflater
.
from
(
parent
.
getContext
()).
inflate
(
R
.
layout
.
list_item_hide_process
,
parent
,
false
);
return
new
ProcessViewHolder
(
v
);
}
@Override
public
void
onBindSectionViewHolder
(
AppViewHolder
holder
,
int
section
)
{
HideAppInfo
app
=
showList
.
get
(
section
);
IndeterminateCheckBox
.
OnStateChangedListener
listener
=
(
IndeterminateCheckBox
indeterminateCheckBox
,
@Nullable
Boolean
stat
)
->
{
if
(
stat
!=
null
)
{
for
(
HideProcessInfo
p
:
app
.
processes
)
{
String
cmd
=
Utils
.
fmt
(
"magiskhide --%s %s %s"
,
stat
?
"add"
:
"rm"
,
app
.
info
.
packageName
,
p
.
name
);
Shell
.
su
(
cmd
).
submit
();
p
.
hidden
=
stat
;
}
}
};
holder
.
app_name
.
setText
(
app
.
name
);
holder
.
app_icon
.
setImageDrawable
(
app
.
info
.
loadIcon
(
pm
));
holder
.
package_name
.
setText
(
app
.
info
.
packageName
);
holder
.
checkBox
.
setOnStateChangedListener
(
null
);
holder
.
checkBox
.
setOnStateChangedListener
(
listener
);
holder
.
checkBox
.
setState
(
app
.
getState
());
if
(
app
.
expanded
)
{
holder
.
checkBox
.
setVisibility
(
View
.
GONE
);
setBottomMargin
(
holder
.
itemView
,
0
);
}
else
{
holder
.
checkBox
.
setVisibility
(
View
.
VISIBLE
);
setBottomMargin
(
holder
.
itemView
,
2
);
}
holder
.
itemView
.
setOnClickListener
((
v
)
->
{
int
index
=
getItemPosition
(
section
,
0
);
if
(
app
.
expanded
)
{
app
.
expanded
=
false
;
notifyItemRangeRemoved
(
index
,
app
.
processes
.
size
());
setBottomMargin
(
holder
.
itemView
,
2
);
holder
.
checkBox
.
setOnStateChangedListener
(
null
);
holder
.
checkBox
.
setVisibility
(
View
.
VISIBLE
);
holder
.
checkBox
.
setState
(
app
.
getState
());
holder
.
checkBox
.
setOnStateChangedListener
(
listener
);
}
else
{
holder
.
checkBox
.
setVisibility
(
View
.
GONE
);
setBottomMargin
(
holder
.
itemView
,
0
);
app
.
expanded
=
true
;
notifyItemRangeInserted
(
index
,
app
.
processes
.
size
());
}
});
}
@Override
public
void
onBindItemViewHolder
(
ProcessViewHolder
holder
,
int
section
,
int
position
)
{
HideAppInfo
hideApp
=
showList
.
get
(
section
);
HideProcessInfo
target
=
hideApp
.
processes
.
get
(
position
);
holder
.
process
.
setText
(
target
.
name
);
holder
.
checkbox
.
setOnCheckedChangeListener
(
null
);
holder
.
checkbox
.
setChecked
(
target
.
hidden
);
holder
.
checkbox
.
setOnCheckedChangeListener
((
v
,
isChecked
)
->
{
String
pair
=
Utils
.
fmt
(
"%s %s"
,
hideApp
.
info
.
packageName
,
target
.
name
);
if
(
isChecked
)
{
Shell
.
su
(
"magiskhide --add "
+
pair
).
submit
();
target
.
hidden
=
true
;
}
else
{
Shell
.
su
(
"magiskhide --rm "
+
pair
).
submit
();
target
.
hidden
=
false
;
}
});
}
public
void
filter
(
String
constraint
)
{
AsyncTask
.
SERIAL_EXECUTOR
.
execute
(()
->
{
Stream
<
HideAppInfo
>
s
=
StreamSupport
.
stream
(
fullList
)
.
filter
(
this
::
systemFilter
)
.
filter
(
t
->
nameFilter
(
t
,
constraint
));
UiThreadHandler
.
run
(()
->
{
showList
=
s
.
collect
(
Collectors
.
toList
());
notifyDataSetChanged
();
});
});
}
public
void
setShowSystem
(
boolean
b
)
{
showSystem
=
b
;
}
public
void
refresh
()
{
AsyncTask
.
SERIAL_EXECUTOR
.
execute
(
this
::
loadApps
);
}
private
void
setBottomMargin
(
View
view
,
int
dp
)
{
ViewGroup
.
LayoutParams
params
=
view
.
getLayoutParams
();
ViewGroup
.
MarginLayoutParams
marginParams
;
if
(
params
instanceof
ViewGroup
.
MarginLayoutParams
)
{
marginParams
=
(
ViewGroup
.
MarginLayoutParams
)
params
;
}
else
{
marginParams
=
new
ViewGroup
.
MarginLayoutParams
(
params
);
}
marginParams
.
bottomMargin
=
Utils
.
dpInPx
(
dp
);
view
.
setLayoutParams
(
marginParams
);
}
private
void
addProcesses
(
Set
<
String
>
set
,
ComponentInfo
[]
infos
)
{
...
...
@@ -93,20 +218,13 @@ public class ApplicationAdapter {
@WorkerThread
private
void
loadApps
()
{
List
<
ApplicationInfo
>
installed
=
pm
.
getInstalledApplications
(
0
);
hideList
=
StreamSupport
.
stream
(
Shell
.
su
(
"magiskhide --ls"
).
exec
().
getOut
())
.
map
(
HideTarget:
:
new
).
collect
(
Collectors
.
toList
());
fullList
.
clear
();
for
(
ApplicationInfo
info
:
installed
)
{
// Do not show black-listed and disabled apps
if
(!
HIDE_BLACKLIST
.
contains
(
info
.
packageName
)
&&
info
.
enabled
)
{
AppViewBinder
.
App
app
=
new
AppViewBinder
.
App
(
info
.
loadIcon
(
pm
),
getAppLabel
(
info
,
pm
),
info
.
packageName
,
info
.
flags
);
fullList
.
add
(
app
);
.
map
(
HideTarget:
:
new
)
.
collect
(
Collectors
.
toList
());
fullList
=
StreamSupport
.
stream
(
pm
.
getInstalledApplications
(
0
))
.
filter
(
info
->
!
HIDE_BLACKLIST
.
contains
(
info
.
packageName
)
&&
info
.
enabled
)
.
map
(
info
->
{
Set
<
String
>
set
=
new
ArraySet
<>();
PackageInfo
pkg
=
getPackageInfo
(
info
.
packageName
);
if
(
pkg
!=
null
)
{
...
...
@@ -114,72 +232,106 @@ public class ApplicationAdapter {
addProcesses
(
set
,
pkg
.
services
);
addProcesses
(
set
,
pkg
.
receivers
);
addProcesses
(
set
,
pkg
.
providers
);
}
else
{
set
.
add
(
info
.
packageName
);
}
if
(
set
.
isEmpty
())
fullList
.
remove
(
app
);
for
(
String
proc
:
set
)
{
boolean
hidden
=
false
;
for
(
HideTarget
tgt
:
hideList
)
{
if
(
info
.
packageName
.
equals
(
tgt
.
pkg
)
&&
proc
.
equals
(
tgt
.
process
))
hidden
=
true
;
}
app
.
processes
.
add
(
new
ProcessViewBinder
.
Process
(
proc
,
hidden
,
info
.
packageName
));
}
app
.
getStat
(
true
);
Collections
.
sort
(
app
.
processes
);
}
}
if
(
set
.
isEmpty
())
return
null
;
return
new
HideAppInfo
(
info
,
set
);
}).
filter
(
Objects:
:
nonNull
).
sorted
()
.
collect
(
Collectors
.
toList
());
Collections
.
sort
(
fullList
);
Topic
.
publish
(
false
,
Topic
.
MAGISK_HIDE_DONE
);
}
public
void
setShowSystem
(
boolean
b
)
{
showSystem
=
b
;
}
// True if not system app and have launch intent, or user already hidden it
private
boolean
systemFilter
(
AppViewBinder
.
App
target
)
{
return
showSystem
||
target
.
stat
!=
0
||
((
target
.
flags
&
ApplicationInfo
.
FLAG_SYSTEM
)
==
0
&&
pm
.
getLaunchIntentForPackage
(
target
.
packageName
)
!=
null
);
// True if not system app or user already hidden it
private
boolean
systemFilter
(
HideAppInfo
target
)
{
return
showSystem
||
target
.
haveHidden
()
||
(
target
.
info
.
flags
&
ApplicationInfo
.
FLAG_SYSTEM
)
==
0
;
}
private
boolean
contains
(
String
s
,
String
filter
)
{
return
s
.
toLowerCase
().
contains
(
filter
);
}
private
boolean
nameFilter
(
AppViewBinder
.
App
target
,
String
filter
)
{
private
boolean
nameFilter
(
HideAppInfo
target
,
String
filter
)
{
if
(
filter
==
null
||
filter
.
isEmpty
())
return
true
;
filter
=
filter
.
toLowerCase
();
return
contains
(
target
.
name
,
filter
)
||
contains
(
target
.
packageName
,
filter
);
if
(
contains
(
target
.
name
,
filter
))
return
true
;
for
(
HideProcessInfo
p
:
target
.
processes
)
{
if
(
contains
(
p
.
name
,
filter
))
return
true
;
}
return
contains
(
target
.
info
.
packageName
,
filter
);
}
public
void
filter
(
String
constraint
)
{
AsyncTask
.
SERIAL_EXECUTOR
.
execute
(()
->
{
Stream
<
AppViewBinder
.
App
>
s
=
StreamSupport
.
stream
(
fullList
)
.
filter
(
this
::
systemFilter
)
.
filter
(
t
->
nameFilter
(
t
,
constraint
));
UiThreadHandler
.
run
(()
->
{
showList
.
clear
();
for
(
AppViewBinder
.
App
target
:
s
.
collect
(
Collectors
.
toList
()))
{
if
(
target
.
expand
)
{
showList
.
add
(
target
);
showList
.
addAll
(
target
.
processes
);
}
else
showList
.
add
(
target
);
}
adapter
.
notifyDataSetChanged
();
});
});
class
HideAppInfo
implements
Comparable
<
HideAppInfo
>
{
String
name
;
ApplicationInfo
info
;
List
<
HideProcessInfo
>
processes
;
boolean
expanded
;
HideAppInfo
(
ApplicationInfo
appInfo
,
Set
<
String
>
set
)
{
info
=
appInfo
;
name
=
Utils
.
getAppLabel
(
info
,
pm
);
expanded
=
false
;
processes
=
StreamSupport
.
stream
(
set
)
.
map
(
process
->
new
HideProcessInfo
(
info
.
packageName
,
process
))
.
sorted
().
collect
(
Collectors
.
toList
());
}
public
void
refresh
()
{
Collections
.
sort
(
fullList
);
Topic
.
publish
(
false
,
Topic
.
MAGISK_HIDE_DONE
);
@Override
public
int
compareTo
(
HideAppInfo
o
)
{
Comparator
<
HideAppInfo
>
c
;
c
=
Comparators
.
comparing
(
HideAppInfo:
:
haveHidden
);
c
=
Comparators
.
reversed
(
c
);
c
=
Comparators
.
thenComparing
(
c
,
t
->
t
.
name
,
String:
:
compareToIgnoreCase
);
c
=
Comparators
.
thenComparing
(
c
,
t
->
t
.
info
.
packageName
);
return
c
.
compare
(
this
,
o
);
}
Boolean
getState
()
{
boolean
all
=
true
;
boolean
hidden
=
false
;
for
(
HideProcessInfo
p
:
processes
)
{
if
(!
p
.
hidden
)
all
=
false
;
else
hidden
=
true
;
}
if
(
all
)
return
true
;
return
hidden
?
null
:
false
;
}
boolean
haveHidden
()
{
Boolean
c
=
getState
();
return
c
==
null
?
true
:
c
;
}
}
class
HideProcessInfo
implements
Comparable
<
HideProcessInfo
>
{
String
name
;
boolean
hidden
;
HideProcessInfo
(
String
pkg
,
String
process
)
{
this
.
name
=
process
;
for
(
HideTarget
t
:
hideList
)
{
if
(
t
.
pkg
.
equals
(
pkg
)
&&
t
.
process
.
equals
(
process
))
{
hidden
=
true
;
break
;
}
}
}
@Override
public
int
compareTo
(
HideProcessInfo
o
)
{
Comparator
<
HideProcessInfo
>
c
;
c
=
Comparators
.
comparing
((
HideProcessInfo
t
)
->
t
.
hidden
);
c
=
Comparators
.
reversed
(
c
);
c
=
Comparators
.
thenComparing
(
c
,
t
->
t
.
name
);
return
c
.
compare
(
this
,
o
);
}
}
class
HideTarget
{
...
...
@@ -197,4 +349,29 @@ public class ApplicationAdapter {
}
}
}
class
AppViewHolder
extends
RecyclerView
.
ViewHolder
{
@BindView
(
R
.
id
.
app_icon
)
ImageView
app_icon
;
@BindView
(
R
.
id
.
app_name
)
TextView
app_name
;
@BindView
(
R
.
id
.
package_name
)
TextView
package_name
;
@BindView
(
R
.
id
.
checkbox
)
IndeterminateCheckBox
checkBox
;
public
AppViewHolder
(
@NonNull
View
itemView
)
{
super
(
itemView
);
new
ApplicationAdapter$AppViewHolder_ViewBinding
(
this
,
itemView
);
}
}
class
ProcessViewHolder
extends
RecyclerView
.
ViewHolder
{
@BindView
(
R
.
id
.
process
)
TextView
process
;
@BindView
(
R
.
id
.
checkbox
)
CheckBox
checkbox
;
public
ProcessViewHolder
(
@NonNull
View
itemView
)
{
super
(
itemView
);
new
ApplicationAdapter$ProcessViewHolder_ViewBinding
(
this
,
itemView
);
}
}
}
app/src/main/java/com/topjohnwu/magisk/adapters/ProcessViewBinder.java
deleted
100644 → 0
View file @
21756496
package
com
.
topjohnwu
.
magisk
.
adapters
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.CheckBox
;
import
android.widget.TextView
;
import
androidx.annotation.NonNull
;
import
androidx.recyclerview.widget.RecyclerView
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.superuser.Shell
;
import
java.util.Comparator
;
import
butterknife.BindView
;
import
java9.util.Comparators
;
import
me.drakeet.multitype.ItemViewBinder
;
public
class
ProcessViewBinder
extends
ItemViewBinder
<
ProcessViewBinder
.
Process
,
ProcessViewBinder
.
ViewHolder
>
{
@Override
protected
@NonNull
ViewHolder
onCreateViewHolder
(
@NonNull
LayoutInflater
inflater
,
@NonNull
ViewGroup
parent
)
{
return
new
ViewHolder
(
inflater
.
inflate
(
R
.
layout
.
list_item_hide_process
,
parent
,
false
));
}
@Override
protected
void
onBindViewHolder
(
@NonNull
ViewHolder
holder
,
@NonNull
Process
process
)
{
holder
.
process
.
setText
(
process
.
name
);
holder
.
checkbox
.
setOnCheckedChangeListener
(
null
);
holder
.
checkbox
.
setChecked
(
process
.
hidden
);
holder
.
checkbox
.
setOnCheckedChangeListener
((
v
,
isChecked
)
->
{
if
(
isChecked
)
{
Shell
.
su
(
"magiskhide --add "
+
process
.
fullname
).
submit
();
process
.
hidden
=
true
;
}
else
{
Shell
.
su
(
"magiskhide --rm "
+
process
.
fullname
).
submit
();
process
.
hidden
=
false
;
}
});
}
static
class
ViewHolder
extends
RecyclerView
.
ViewHolder
{
@BindView
(
R
.
id
.
process
)
TextView
process
;
@BindView
(
R
.
id
.
checkbox
)
CheckBox
checkbox
;
ViewHolder
(
View
itemView
)
{
super
(
itemView
);
new
ProcessViewBinder$ViewHolder_ViewBinding
(
this
,
itemView
);
}
}
public
static
class
Process
implements
Comparable
<
Process
>
{
String
name
;
boolean
hidden
;
String
fullname
;
String
packageName
;
Process
(
String
name
,
boolean
hidden
,
String
packageName
)
{
this
.
name
=
name
;
this
.
hidden
=
hidden
;
this
.
packageName
=
packageName
;
this
.
fullname
=
Utils
.
fmt
(
"%s %s"
,
packageName
,
name
);
}
@Override
public
int
compareTo
(
Process
o
)
{
Comparator
<
Process
>
c
;
c
=
Comparators
.
comparing
((
Process
t
)
->
!
t
.
name
.
startsWith
(
t
.
packageName
));
c
=
Comparators
.
thenComparing
(
c
,
t
->
t
.
name
,
String:
:
compareToIgnoreCase
);
return
c
.
compare
(
this
,
o
);
}
}
}
app/src/main/java/com/topjohnwu/magisk/fragments/MagiskHideFragment.java
View file @
1e24c72c
...
...
@@ -21,7 +21,6 @@ import com.topjohnwu.magisk.components.BaseFragment;
import
com.topjohnwu.magisk.utils.Topic
;
import
butterknife.BindView
;
import
me.drakeet.multitype.MultiTypeAdapter
;
public
class
MagiskHideFragment
extends
BaseFragment
implements
Topic
.
Subscriber
{
...
...
@@ -29,7 +28,7 @@ public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber
@BindView
(
R
.
id
.
recyclerView
)
RecyclerView
recyclerView
;
private
SearchView
search
;
private
ApplicationAdapter
a
pplicationA
dapter
;
private
ApplicationAdapter
adapter
;
private
SearchView
.
OnQueryTextListener
searchListener
;
@Override
...
...
@@ -44,23 +43,22 @@ public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber
View
view
=
inflater
.
inflate
(
R
.
layout
.
fragment_magisk_hide
,
container
,
false
);
unbinder
=
new
MagiskHideFragment_ViewBinding
(
this
,
view
);
MultiTypeAdapter
adapter
=
new
MultiTypeAdapter
();
applicationAdapter
=
new
ApplicationAdapter
(
requireActivity
(),
adapter
);
adapter
=
new
ApplicationAdapter
(
requireActivity
());
recyclerView
.
setAdapter
(
adapter
);
mSwipeRefreshLayout
.
setRefreshing
(
true
);
mSwipeRefreshLayout
.
setOnRefreshListener
(
a
pplicationA
dapter:
:
refresh
);
mSwipeRefreshLayout
.
setOnRefreshListener
(
adapter:
:
refresh
);
searchListener
=
new
SearchView
.
OnQueryTextListener
()
{
@Override
public
boolean
onQueryTextSubmit
(
String
query
)
{
a
pplicationA
dapter
.
filter
(
query
);
adapter
.
filter
(
query
);
return
false
;
}
@Override
public
boolean
onQueryTextChange
(
String
newText
)
{
a
pplicationA
dapter
.
filter
(
newText
);
adapter
.
filter
(
newText
);
return
false
;
}
};
...
...
@@ -84,8 +82,8 @@ public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber
boolean
showSystem
=
!
item
.
isChecked
();
item
.
setChecked
(
showSystem
);
Config
.
set
(
Config
.
Key
.
SHOW_SYSTEM_APP
,
showSystem
);
a
pplicationA
dapter
.
setShowSystem
(
showSystem
);
a
pplicationA
dapter
.
filter
(
search
.
getQuery
().
toString
());
adapter
.
setShowSystem
(
showSystem
);
adapter
.
filter
(
search
.
getQuery
().
toString
());
}
return
true
;
}
...
...
@@ -98,6 +96,6 @@ public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber
@Override
public
void
onPublish
(
int
topic
,
Object
[]
result
)
{
mSwipeRefreshLayout
.
setRefreshing
(
false
);
a
pplicationA
dapter
.
filter
(
search
.
getQuery
().
toString
());
adapter
.
filter
(
search
.
getQuery
().
toString
());
}
}
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