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
ec2d7d77
Commit
ec2d7d77
authored
Jul 15, 2020
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reduce usage of ObservableField
parent
6c6368fd
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
130 additions
and
148 deletions
+130
-148
Info.kt
app/src/main/java/com/topjohnwu/magisk/core/Info.kt
+3
-4
DataBinding.kt
app/src/main/java/com/topjohnwu/magisk/ktx/DataBinding.kt
+0
-65
XBinding.kt
app/src/main/java/com/topjohnwu/magisk/ktx/XBinding.kt
+0
-6
HideRvItem.kt
.../com/topjohnwu/magisk/model/entity/recycler/HideRvItem.kt
+28
-22
PolicyRvItem.kt
...om/topjohnwu/magisk/model/entity/recycler/PolicyRvItem.kt
+29
-18
HideViewModel.kt
...c/main/java/com/topjohnwu/magisk/ui/hide/HideViewModel.kt
+2
-3
HomeViewModel.kt
...c/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt
+1
-2
SettingsViewModel.kt
...ava/com/topjohnwu/magisk/ui/settings/SettingsViewModel.kt
+1
-2
SuperuserViewModel.kt
...a/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt
+1
-2
ObservableHost.kt
...rc/main/java/com/topjohnwu/magisk/utils/ObservableHost.kt
+16
-0
MagiskDialog.kt
app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt
+49
-24
No files found.
app/src/main/java/com/topjohnwu/magisk/core/Info.kt
View file @
ec2d7d77
package
com.topjohnwu.magisk.core
package
com.topjohnwu.magisk.core
import
androidx.databinding.Observable
Field
import
androidx.databinding.Observable
Boolean
import
com.topjohnwu.magisk.DynAPK
import
com.topjohnwu.magisk.DynAPK
import
com.topjohnwu.magisk.core.model.UpdateInfo
import
com.topjohnwu.magisk.core.model.UpdateInfo
import
com.topjohnwu.magisk.core.net.NetworkObserver
import
com.topjohnwu.magisk.core.net.NetworkObserver
import
com.topjohnwu.magisk.ktx.get
import
com.topjohnwu.magisk.ktx.get
import
com.topjohnwu.magisk.ktx.value
import
com.topjohnwu.magisk.utils.CachedValue
import
com.topjohnwu.magisk.utils.CachedValue
import
com.topjohnwu.superuser.Shell
import
com.topjohnwu.superuser.Shell
import
com.topjohnwu.superuser.ShellUtils.fastCmd
import
com.topjohnwu.superuser.ShellUtils.fastCmd
...
@@ -36,9 +35,9 @@ object Info {
...
@@ -36,9 +35,9 @@ object Info {
@JvmStatic
var
ramdisk
=
false
@JvmStatic
var
ramdisk
=
false
val
isConnected
by
lazy
{
val
isConnected
by
lazy
{
Observable
Field
(
false
).
also
{
field
->
Observable
Boolean
(
false
).
also
{
field
->
NetworkObserver
.
observe
(
get
())
{
NetworkObserver
.
observe
(
get
())
{
UiThreadHandler
.
run
{
field
.
value
=
it
.
isAvailable
}
UiThreadHandler
.
run
{
field
.
set
(
it
.
isAvailable
)
}
}
}
}
}
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/ktx/DataBinding.kt
deleted
100644 → 0
View file @
6c6368fd
package
com.topjohnwu.magisk.ktx
import
androidx.databinding.Observable
import
androidx.databinding.ObservableBoolean
import
androidx.databinding.ObservableField
import
androidx.databinding.ObservableInt
fun
<
T
>
ObservableField
<
T
>.
addOnPropertyChangedCallback
(
removeAfterChanged
:
Boolean
=
false
,
callback
:
(
T
?)
->
Unit
)
{
addOnPropertyChangedCallback
(
object
:
Observable
.
OnPropertyChangedCallback
()
{
override
fun
onPropertyChanged
(
sender
:
Observable
?,
propertyId
:
Int
)
{
callback
(
get
())
if
(
removeAfterChanged
)
removeOnPropertyChangedCallback
(
this
)
}
})
}
fun
ObservableInt
.
addOnPropertyChangedCallback
(
removeAfterChanged
:
Boolean
=
false
,
callback
:
(
Int
)
->
Unit
)
{
addOnPropertyChangedCallback
(
object
:
Observable
.
OnPropertyChangedCallback
()
{
override
fun
onPropertyChanged
(
sender
:
Observable
?,
propertyId
:
Int
)
{
callback
(
get
())
if
(
removeAfterChanged
)
removeOnPropertyChangedCallback
(
this
)
}
})
}
fun
ObservableBoolean
.
addOnPropertyChangedCallback
(
removeAfterChanged
:
Boolean
=
false
,
callback
:
(
Boolean
)
->
Unit
)
{
addOnPropertyChangedCallback
(
object
:
Observable
.
OnPropertyChangedCallback
()
{
override
fun
onPropertyChanged
(
sender
:
Observable
?,
propertyId
:
Int
)
{
callback
(
get
())
if
(
removeAfterChanged
)
removeOnPropertyChangedCallback
(
this
)
}
})
}
inline
fun
<
T
>
ObservableField
<
T
>.
update
(
block
:
(
T
?)
->
Unit
)
{
set
(
get
().
apply
(
block
))
}
inline
fun
<
T
>
ObservableField
<
T
>.
updateNonNull
(
block
:
(
T
)
->
Unit
)
{
update
{
it
?:
return
@update
block
(
it
)
}
}
inline
fun
ObservableInt
.
update
(
block
:
(
Int
)
->
Unit
)
{
set
(
get
().
apply
(
block
))
}
inline
var
<
T
>
ObservableField
<
T
>.
value
get
()
=
get
()
as
T
set
(
value
)
{
// Use Kotlin comparision (Any.equals)
if
(
value
!=
get
())
set
(
value
)
}
app/src/main/java/com/topjohnwu/magisk/ktx/XBinding.kt
View file @
ec2d7d77
package
com.topjohnwu.magisk.ktx
package
com.topjohnwu.magisk.ktx
import
androidx.databinding.ObservableField
import
androidx.databinding.ObservableList
import
androidx.databinding.ObservableList
fun
ObservableField
<
Boolean
>.
toggle
()
{
value
=
!
value
}
fun
<
T
>
ObservableList
<
T
>.
addOnListChangedCallback
(
fun
<
T
>
ObservableList
<
T
>.
addOnListChangedCallback
(
onChanged
:
((
sender
:
ObservableList
<
T
>)
->
Unit
)?
=
null
,
onChanged
:
((
sender
:
ObservableList
<
T
>)
->
Unit
)?
=
null
,
onItemRangeRemoved
:
((
sender
:
ObservableList
<
T
>,
positionStart
:
Int
,
itemCount
:
Int
)
->
Unit
)?
=
null
,
onItemRangeRemoved
:
((
sender
:
ObservableList
<
T
>,
positionStart
:
Int
,
itemCount
:
Int
)
->
Unit
)?
=
null
,
...
...
app/src/main/java/com/topjohnwu/magisk/model/entity/recycler/HideRvItem.kt
View file @
ec2d7d77
...
@@ -2,54 +2,57 @@ package com.topjohnwu.magisk.model.entity.recycler
...
@@ -2,54 +2,57 @@ package com.topjohnwu.magisk.model.entity.recycler
import
android.view.View
import
android.view.View
import
android.view.ViewGroup
import
android.view.ViewGroup
import
androidx.databinding.ObservableField
import
androidx.databinding.Bindable
import
com.topjohnwu.magisk.BR
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.databinding.ComparableRvItem
import
com.topjohnwu.magisk.databinding.ObservableItem
import
com.topjohnwu.magisk.ktx.addOnPropertyChangedCallback
import
com.topjohnwu.magisk.ktx.startAnimations
import
com.topjohnwu.magisk.ktx.startAnimations
import
com.topjohnwu.magisk.ktx.toggle
import
com.topjohnwu.magisk.ktx.value
import
com.topjohnwu.magisk.model.entity.ProcessHideApp
import
com.topjohnwu.magisk.model.entity.ProcessHideApp
import
com.topjohnwu.magisk.model.entity.StatefulProcess
import
com.topjohnwu.magisk.model.entity.StatefulProcess
import
com.topjohnwu.magisk.model.observer.Observer
import
com.topjohnwu.magisk.ui.hide.HideViewModel
import
com.topjohnwu.magisk.ui.hide.HideViewModel
import
com.topjohnwu.magisk.utils.addOnPropertyChangedCallback
import
com.topjohnwu.magisk.utils.set
import
kotlin.math.roundToInt
import
kotlin.math.roundToInt
class
HideItem
(
val
item
:
ProcessHideApp
)
:
ComparableRv
Item
<
HideItem
>()
{
class
HideItem
(
val
item
:
ProcessHideApp
)
:
Observable
Item
<
HideItem
>()
{
override
val
layoutRes
=
R
.
layout
.
item_hide_md2
override
val
layoutRes
=
R
.
layout
.
item_hide_md2
val
packageName
=
item
.
info
.
info
.
packageName
.
orEmpty
()
val
packageName
=
item
.
info
.
info
.
packageName
.
orEmpty
()
val
items
=
item
.
processes
.
map
{
HideProcessItem
(
it
)
}
val
items
=
item
.
processes
.
map
{
HideProcessItem
(
it
)
}
val
isExpanded
=
ObservableField
(
false
)
@get
:
Bindable
val
itemsChecked
=
ObservableField
(
0
)
var
isExpanded
=
false
val
itemsCheckedPercent
=
Observer
(
itemsChecked
)
{
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
expanded
)
(
itemsChecked
.
value
.
toFloat
()
/
items
.
size
*
100
).
roundToInt
()
}
@get
:
Bindable
var
itemsChecked
=
0
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
itemsChecked
,
BR
.
itemsCheckedPercent
)
/** [toggle] depends on this functionality */
@get
:
Bindable
private
val
isHidden
get
()
=
itemsChecked
.
value
==
items
.
size
val
itemsCheckedPercent
get
()
=
(
itemsChecked
.
toFloat
()
/
items
.
size
*
100
).
roundToInt
()
private
val
isHidden
get
()
=
itemsChecked
==
items
.
size
init
{
init
{
items
.
forEach
{
it
.
isHidden
.
addOnPropertyChangedCallback
{
recalculateChecked
()
}
}
items
.
forEach
{
it
.
addOnPropertyChangedCallback
(
BR
.
hidden
)
{
recalculateChecked
()
}
}
recalculateChecked
()
recalculateChecked
()
}
}
fun
collapse
(
v
:
View
)
{
fun
collapse
(
v
:
View
)
{
(
v
.
parent
.
parent
as
?
ViewGroup
)
?.
startAnimations
()
(
v
.
parent
.
parent
as
?
ViewGroup
)
?.
startAnimations
()
isExpanded
.
value
=
false
isExpanded
=
false
}
}
fun
toggle
(
v
:
View
)
{
fun
toggle
(
v
:
View
)
{
(
v
.
parent
as
?
ViewGroup
)
?.
startAnimations
()
(
v
.
parent
as
?
ViewGroup
)
?.
startAnimations
()
isExpanded
.
toggle
()
isExpanded
=
!
isExpanded
}
}
fun
toggle
(
viewModel
:
HideViewModel
):
Boolean
{
fun
toggle
(
viewModel
:
HideViewModel
):
Boolean
{
// contract implies that isHidden == all checked
// contract implies that isHidden == all checked
if
(!
isHidden
)
{
if
(!
isHidden
)
{
items
.
filterNot
{
it
.
isHidden
.
value
}
items
.
filterNot
{
it
.
isHidden
}
}
else
{
}
else
{
items
items
}.
forEach
{
it
.
toggle
(
viewModel
)
}
}.
forEach
{
it
.
toggle
(
viewModel
)
}
...
@@ -57,7 +60,7 @@ class HideItem(val item: ProcessHideApp) : ComparableRvItem<HideItem>() {
...
@@ -57,7 +60,7 @@ class HideItem(val item: ProcessHideApp) : ComparableRvItem<HideItem>() {
}
}
private
fun
recalculateChecked
()
{
private
fun
recalculateChecked
()
{
itemsChecked
.
value
=
items
.
count
{
it
.
isHidden
.
value
}
itemsChecked
=
items
.
count
{
it
.
isHidden
}
}
}
override
fun
contentSameAs
(
other
:
HideItem
):
Boolean
=
item
==
other
.
item
override
fun
contentSameAs
(
other
:
HideItem
):
Boolean
=
item
==
other
.
item
...
@@ -65,14 +68,17 @@ class HideItem(val item: ProcessHideApp) : ComparableRvItem<HideItem>() {
...
@@ -65,14 +68,17 @@ class HideItem(val item: ProcessHideApp) : ComparableRvItem<HideItem>() {
}
}
class
HideProcessItem
(
val
item
:
StatefulProcess
)
:
ComparableRv
Item
<
HideProcessItem
>()
{
class
HideProcessItem
(
val
item
:
StatefulProcess
)
:
Observable
Item
<
HideProcessItem
>()
{
override
val
layoutRes
=
R
.
layout
.
item_hide_process_md2
override
val
layoutRes
=
R
.
layout
.
item_hide_process_md2
val
isHidden
=
ObservableField
(
item
.
isHidden
)
@get
:
Bindable
var
isHidden
=
item
.
isHidden
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
hidden
)
fun
toggle
(
viewModel
:
HideViewModel
)
{
fun
toggle
(
viewModel
:
HideViewModel
)
{
isHidden
.
toggle
()
isHidden
=
!
isHidden
viewModel
.
toggleItem
(
this
)
viewModel
.
toggleItem
(
this
)
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/model/entity/recycler/PolicyRvItem.kt
View file @
ec2d7d77
package
com.topjohnwu.magisk.model.entity.recycler
package
com.topjohnwu.magisk.model.entity.recycler
import
android.graphics.drawable.Drawable
import
android.graphics.drawable.Drawable
import
androidx.databinding.
ObservableField
import
androidx.databinding.
Bindable
import
androidx.databinding.ViewDataBinding
import
androidx.databinding.ViewDataBinding
import
androidx.recyclerview.widget.StaggeredGridLayoutManager
import
androidx.recyclerview.widget.StaggeredGridLayoutManager
import
com.topjohnwu.magisk.BR
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.core.model.MagiskPolicy
import
com.topjohnwu.magisk.core.model.MagiskPolicy
import
com.topjohnwu.magisk.databinding.ComparableRvItem
import
com.topjohnwu.magisk.databinding.ObservableItem
import
com.topjohnwu.magisk.ktx.toggle
import
com.topjohnwu.magisk.ktx.value
import
com.topjohnwu.magisk.ui.superuser.SuperuserViewModel
import
com.topjohnwu.magisk.ui.superuser.SuperuserViewModel
import
com.topjohnwu.magisk.utils.set
class
PolicyItem
(
val
item
:
MagiskPolicy
,
val
icon
:
Drawable
)
:
ComparableRv
Item
<
PolicyItem
>()
{
class
PolicyItem
(
val
item
:
MagiskPolicy
,
val
icon
:
Drawable
)
:
Observable
Item
<
PolicyItem
>()
{
override
val
layoutRes
=
R
.
layout
.
item_policy_md2
override
val
layoutRes
=
R
.
layout
.
item_policy_md2
val
isExpanded
=
ObservableField
(
false
)
@get
:
Bindable
val
isEnabled
=
ObservableField
(
item
.
policy
==
MagiskPolicy
.
ALLOW
)
var
isExpanded
=
false
val
shouldNotify
=
ObservableField
(
item
.
notification
)
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
expanded
)
val
shouldLog
=
ObservableField
(
item
.
logging
)
@get
:
Bindable
var
isEnabled
=
item
.
policy
==
MagiskPolicy
.
ALLOW
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
enabled
)
@get
:
Bindable
var
shouldNotify
=
item
.
notification
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
shouldNotify
)
@get
:
Bindable
var
shouldLog
=
item
.
logging
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
shouldLog
)
private
val
updatedPolicy
private
val
updatedPolicy
get
()
=
item
.
copy
(
get
()
=
item
.
copy
(
policy
=
if
(
isEnabled
.
value
)
MagiskPolicy
.
ALLOW
else
MagiskPolicy
.
DENY
,
policy
=
if
(
isEnabled
)
MagiskPolicy
.
ALLOW
else
MagiskPolicy
.
DENY
,
notification
=
shouldNotify
.
value
,
notification
=
shouldNotify
,
logging
=
shouldLog
.
value
logging
=
shouldLog
)
)
fun
toggle
(
viewModel
:
SuperuserViewModel
)
{
fun
toggle
(
viewModel
:
SuperuserViewModel
)
{
if
(
isExpanded
.
value
)
{
if
(
isExpanded
)
{
toggle
()
toggle
()
return
return
}
}
isEnabled
.
toggle
()
isEnabled
=
!
isEnabled
viewModel
.
togglePolicy
(
this
,
isEnabled
.
value
)
viewModel
.
togglePolicy
(
this
,
isEnabled
)
}
}
fun
toggle
()
{
fun
toggle
()
{
isExpanded
.
toggle
()
isExpanded
=
!
isExpanded
}
}
fun
toggleNotify
(
viewModel
:
SuperuserViewModel
)
{
fun
toggleNotify
(
viewModel
:
SuperuserViewModel
)
{
shouldNotify
.
toggle
()
shouldNotify
=
!
shouldNotify
viewModel
.
updatePolicy
(
updatedPolicy
,
isLogging
=
false
)
viewModel
.
updatePolicy
(
updatedPolicy
,
isLogging
=
false
)
}
}
fun
toggleLog
(
viewModel
:
SuperuserViewModel
)
{
fun
toggleLog
(
viewModel
:
SuperuserViewModel
)
{
shouldLog
.
toggle
()
shouldLog
=
!
shouldLog
viewModel
.
updatePolicy
(
updatedPolicy
,
isLogging
=
true
)
viewModel
.
updatePolicy
(
updatedPolicy
,
isLogging
=
true
)
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/ui/hide/HideViewModel.kt
View file @
ec2d7d77
...
@@ -6,7 +6,6 @@ import androidx.lifecycle.viewModelScope
...
@@ -6,7 +6,6 @@ import androidx.lifecycle.viewModelScope
import
com.topjohnwu.magisk.BR
import
com.topjohnwu.magisk.BR
import
com.topjohnwu.magisk.core.utils.currentLocale
import
com.topjohnwu.magisk.core.utils.currentLocale
import
com.topjohnwu.magisk.data.repository.MagiskRepository
import
com.topjohnwu.magisk.data.repository.MagiskRepository
import
com.topjohnwu.magisk.ktx.value
import
com.topjohnwu.magisk.model.entity.HideAppInfo
import
com.topjohnwu.magisk.model.entity.HideAppInfo
import
com.topjohnwu.magisk.model.entity.HideTarget
import
com.topjohnwu.magisk.model.entity.HideTarget
import
com.topjohnwu.magisk.model.entity.ProcessHideApp
import
com.topjohnwu.magisk.model.entity.ProcessHideApp
...
@@ -71,7 +70,7 @@ class HideViewModel(
...
@@ -71,7 +70,7 @@ class HideViewModel(
return
ProcessHideApp
(
a
,
processes
)
return
ProcessHideApp
(
a
,
processes
)
}
}
private
fun
List
<
HideItem
>.
sort
()
=
compareByDescending
<
HideItem
>
{
it
.
itemsChecked
.
value
}
private
fun
List
<
HideItem
>.
sort
()
=
compareByDescending
<
HideItem
>
{
it
.
itemsChecked
}
.
thenBy
{
it
.
item
.
info
.
name
.
toLowerCase
(
currentLocale
)
}
.
thenBy
{
it
.
item
.
info
.
name
.
toLowerCase
(
currentLocale
)
}
.
thenBy
{
it
.
item
.
info
.
info
.
packageName
}
.
thenBy
{
it
.
item
.
info
.
info
.
packageName
}
.
let
{
sortedWith
(
it
)
}
.
let
{
sortedWith
(
it
)
}
...
@@ -96,7 +95,7 @@ class HideViewModel(
...
@@ -96,7 +95,7 @@ class HideViewModel(
// ---
// ---
fun
toggleItem
(
item
:
HideProcessItem
)
=
magiskRepo
fun
toggleItem
(
item
:
HideProcessItem
)
=
magiskRepo
.
toggleHide
(
item
.
isHidden
.
value
,
item
.
item
.
packageName
,
item
.
item
.
name
)
.
toggleHide
(
item
.
isHidden
,
item
.
item
.
packageName
,
item
.
item
.
name
)
fun
resetQuery
()
{
fun
resetQuery
()
{
query
=
""
query
=
""
...
...
app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt
View file @
ec2d7d77
...
@@ -15,7 +15,6 @@ import com.topjohnwu.magisk.data.repository.MagiskRepository
...
@@ -15,7 +15,6 @@ import com.topjohnwu.magisk.data.repository.MagiskRepository
import
com.topjohnwu.magisk.ktx.await
import
com.topjohnwu.magisk.ktx.await
import
com.topjohnwu.magisk.ktx.packageName
import
com.topjohnwu.magisk.ktx.packageName
import
com.topjohnwu.magisk.ktx.res
import
com.topjohnwu.magisk.ktx.res
import
com.topjohnwu.magisk.ktx.value
import
com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Manager
import
com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Manager
import
com.topjohnwu.magisk.model.entity.recycler.DeveloperItem
import
com.topjohnwu.magisk.model.entity.recycler.DeveloperItem
import
com.topjohnwu.magisk.model.entity.recycler.HomeItem
import
com.topjohnwu.magisk.model.entity.recycler.HomeItem
...
@@ -101,7 +100,7 @@ class HomeViewModel(
...
@@ -101,7 +100,7 @@ class HomeViewModel(
}
}
stateManager
=
when
{
stateManager
=
when
{
!
app
.
isUpdateChannelCorrect
&&
isConnected
.
value
->
MagiskState
.
NOT_INSTALLED
!
app
.
isUpdateChannelCorrect
&&
isConnected
.
get
()
->
MagiskState
.
NOT_INSTALLED
app
.
isObsolete
->
MagiskState
.
OBSOLETE
app
.
isObsolete
->
MagiskState
.
OBSOLETE
else
->
MagiskState
.
UP_TO_DATE
else
->
MagiskState
.
UP_TO_DATE
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsViewModel.kt
View file @
ec2d7d77
...
@@ -12,7 +12,6 @@ import com.topjohnwu.magisk.core.download.DownloadService
...
@@ -12,7 +12,6 @@ import com.topjohnwu.magisk.core.download.DownloadService
import
com.topjohnwu.magisk.core.utils.PatchAPK
import
com.topjohnwu.magisk.core.utils.PatchAPK
import
com.topjohnwu.magisk.core.utils.Utils
import
com.topjohnwu.magisk.core.utils.Utils
import
com.topjohnwu.magisk.data.database.RepoDao
import
com.topjohnwu.magisk.data.database.RepoDao
import
com.topjohnwu.magisk.ktx.value
import
com.topjohnwu.magisk.model.entity.internal.Configuration
import
com.topjohnwu.magisk.model.entity.internal.Configuration
import
com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import
com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import
com.topjohnwu.magisk.model.entity.recycler.SettingsItem
import
com.topjohnwu.magisk.model.entity.recycler.SettingsItem
...
@@ -56,7 +55,7 @@ class SettingsViewModel(
...
@@ -56,7 +55,7 @@ class SettingsViewModel(
))
))
if
(
Info
.
env
.
isActive
)
{
if
(
Info
.
env
.
isActive
)
{
list
.
add
(
ClearRepoCache
)
list
.
add
(
ClearRepoCache
)
if
(
Const
.
USER_ID
==
0
&&
Info
.
isConnected
.
value
)
if
(
Const
.
USER_ID
==
0
&&
Info
.
isConnected
.
get
()
)
list
.
add
(
HideOrRestore
())
list
.
add
(
HideOrRestore
())
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt
View file @
ec2d7d77
...
@@ -11,7 +11,6 @@ import com.topjohnwu.magisk.core.model.MagiskPolicy
...
@@ -11,7 +11,6 @@ import com.topjohnwu.magisk.core.model.MagiskPolicy
import
com.topjohnwu.magisk.core.utils.BiometricHelper
import
com.topjohnwu.magisk.core.utils.BiometricHelper
import
com.topjohnwu.magisk.core.utils.currentLocale
import
com.topjohnwu.magisk.core.utils.currentLocale
import
com.topjohnwu.magisk.databinding.ComparableRvItem
import
com.topjohnwu.magisk.databinding.ComparableRvItem
import
com.topjohnwu.magisk.ktx.toggle
import
com.topjohnwu.magisk.model.entity.recycler.PolicyItem
import
com.topjohnwu.magisk.model.entity.recycler.PolicyItem
import
com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem
import
com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem
import
com.topjohnwu.magisk.model.entity.recycler.TextItem
import
com.topjohnwu.magisk.model.entity.recycler.TextItem
...
@@ -140,7 +139,7 @@ class SuperuserViewModel(
...
@@ -140,7 +139,7 @@ class SuperuserViewModel(
if
(
BiometricHelper
.
isEnabled
)
{
if
(
BiometricHelper
.
isEnabled
)
{
BiometricDialog
{
BiometricDialog
{
onSuccess
{
updateState
()
}
onSuccess
{
updateState
()
}
onFailure
{
item
.
isEnabled
.
toggle
()
}
onFailure
{
item
.
isEnabled
=
!
item
.
isEnabled
}
}.
publish
()
}.
publish
()
}
else
{
}
else
{
updateState
()
updateState
()
...
...
app/src/main/java/com/topjohnwu/magisk/utils/ObservableHost.kt
View file @
ec2d7d77
...
@@ -49,6 +49,22 @@ interface ObservableHost : Observable {
...
@@ -49,6 +49,22 @@ interface ObservableHost : Observable {
}
}
}
}
fun
ObservableHost
.
addOnPropertyChangedCallback
(
fieldId
:
Int
,
removeAfterChanged
:
Boolean
=
false
,
callback
:
()
->
Unit
)
{
addOnPropertyChangedCallback
(
object
:
Observable
.
OnPropertyChangedCallback
()
{
override
fun
onPropertyChanged
(
sender
:
Observable
?,
propertyId
:
Int
)
{
if
(
fieldId
==
propertyId
)
{
callback
()
if
(
removeAfterChanged
)
removeOnPropertyChangedCallback
(
this
)
}
}
})
}
/**
/**
* Injects boilerplate implementation for {@literal @}[androidx.databinding.Bindable] field setters.
* Injects boilerplate implementation for {@literal @}[androidx.databinding.Bindable] field setters.
*
*
...
...
app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt
View file @
ec2d7d77
...
@@ -15,7 +15,8 @@ import androidx.annotation.StringRes
...
@@ -15,7 +15,8 @@ import androidx.annotation.StringRes
import
androidx.appcompat.app.AppCompatDialog
import
androidx.appcompat.app.AppCompatDialog
import
androidx.core.view.ViewCompat
import
androidx.core.view.ViewCompat
import
androidx.core.view.updatePadding
import
androidx.core.view.updatePadding
import
androidx.databinding.ObservableField
import
androidx.databinding.Bindable
import
androidx.databinding.PropertyChangeRegistry
import
androidx.databinding.ViewDataBinding
import
androidx.databinding.ViewDataBinding
import
androidx.recyclerview.widget.LinearLayoutManager
import
androidx.recyclerview.widget.LinearLayoutManager
import
androidx.recyclerview.widget.RecyclerView
import
androidx.recyclerview.widget.RecyclerView
...
@@ -23,8 +24,9 @@ import com.topjohnwu.magisk.BR
...
@@ -23,8 +24,9 @@ import com.topjohnwu.magisk.BR
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.databinding.ComparableRvItem
import
com.topjohnwu.magisk.databinding.ComparableRvItem
import
com.topjohnwu.magisk.databinding.DialogMagiskBaseBinding
import
com.topjohnwu.magisk.databinding.DialogMagiskBaseBinding
import
com.topjohnwu.magisk.ktx.value
import
com.topjohnwu.magisk.ui.base.itemBindingOf
import
com.topjohnwu.magisk.ui.base.itemBindingOf
import
com.topjohnwu.magisk.utils.ObservableHost
import
com.topjohnwu.magisk.utils.set
import
me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapters
import
me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapters
import
me.tatarka.bindingcollectionadapter2.ItemBinding
import
me.tatarka.bindingcollectionadapter2.ItemBinding
...
@@ -71,11 +73,24 @@ class MagiskDialog(
...
@@ -71,11 +73,24 @@ class MagiskDialog(
binding
.
dialogBaseOutsideContainer
.
setOnClickListener
(
listener
)
binding
.
dialogBaseOutsideContainer
.
setOnClickListener
(
listener
)
}
}
inner
class
Data
{
inner
class
Data
:
ObservableHost
{
val
icon
=
ObservableField
(
0
)
override
var
callbacks
:
PropertyChangeRegistry
?
=
null
val
iconRaw
=
ObservableField
(
null
as
Drawable
?)
val
title
=
ObservableField
<
CharSequence
>(
""
)
@get
:
Bindable
val
message
=
ObservableField
<
CharSequence
>(
""
)
var
icon
=
0
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
icon
)
@get
:
Bindable
var
iconRaw
:
Drawable
?
=
null
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
iconRaw
)
@get
:
Bindable
var
title
:
CharSequence
=
""
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
title
)
@get
:
Bindable
var
message
:
CharSequence
=
""
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
message
)
val
buttonPositive
=
Button
()
val
buttonPositive
=
Button
()
val
buttonNeutral
=
Button
()
val
buttonNeutral
=
Button
()
...
@@ -87,10 +102,20 @@ class MagiskDialog(
...
@@ -87,10 +102,20 @@ class MagiskDialog(
POSITIVE
,
NEUTRAL
,
NEGATIVE
,
IDGAF
POSITIVE
,
NEUTRAL
,
NEGATIVE
,
IDGAF
}
}
inner
class
Button
{
inner
class
Button
:
ObservableHost
{
val
icon
=
ObservableField
(
0
)
override
var
callbacks
:
PropertyChangeRegistry
?
=
null
val
title
=
ObservableField
<
CharSequence
>(
""
)
val
isEnabled
=
ObservableField
(
true
)
@get
:
Bindable
var
icon
=
0
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
icon
)
@get
:
Bindable
var
title
:
CharSequence
=
""
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
title
)
@get
:
Bindable
var
isEnabled
=
true
set
(
value
)
=
set
(
value
,
field
,
{
field
=
it
},
BR
.
enabled
)
var
onClickAction
:
OnDialogButtonClickListener
=
{}
var
onClickAction
:
OnDialogButtonClickListener
=
{}
var
preventDismiss
=
false
var
preventDismiss
=
false
...
@@ -117,24 +142,24 @@ class MagiskDialog(
...
@@ -117,24 +142,24 @@ class MagiskDialog(
inner
class
ButtonBuilder
(
private
val
button
:
Button
)
{
inner
class
ButtonBuilder
(
private
val
button
:
Button
)
{
var
icon
:
Int
var
icon
:
Int
get
()
=
button
.
icon
.
value
get
()
=
button
.
icon
set
(
value
)
{
set
(
value
)
{
button
.
icon
.
value
=
value
button
.
icon
=
value
}
}
var
title
:
CharSequence
var
title
:
CharSequence
get
()
=
button
.
title
.
value
get
()
=
button
.
title
set
(
value
)
{
set
(
value
)
{
button
.
title
.
value
=
value
button
.
title
=
value
}
}
var
titleRes
:
Int
var
titleRes
:
Int
get
()
=
0
get
()
=
0
set
(
value
)
{
set
(
value
)
{
button
.
title
.
value
=
context
.
getString
(
value
)
button
.
title
=
context
.
getString
(
value
)
}
}
var
isEnabled
:
Boolean
var
isEnabled
:
Boolean
get
()
=
button
.
isEnabled
.
value
get
()
=
button
.
isEnabled
set
(
value
)
{
set
(
value
)
{
button
.
isEnabled
.
value
=
value
button
.
isEnabled
=
value
}
}
var
preventDismiss
:
Boolean
var
preventDismiss
:
Boolean
get
()
=
button
.
preventDismiss
get
()
=
button
.
preventDismiss
...
@@ -148,22 +173,22 @@ class MagiskDialog(
...
@@ -148,22 +173,22 @@ class MagiskDialog(
}
}
fun
applyTitle
(
@StringRes
stringRes
:
Int
)
=
fun
applyTitle
(
@StringRes
stringRes
:
Int
)
=
apply
{
data
.
title
.
value
=
context
.
getString
(
stringRes
)
}
apply
{
data
.
title
=
context
.
getString
(
stringRes
)
}
fun
applyTitle
(
title
:
CharSequence
)
=
fun
applyTitle
(
title
:
CharSequence
)
=
apply
{
data
.
title
.
value
=
title
}
apply
{
data
.
title
=
title
}
fun
applyMessage
(
@StringRes
stringRes
:
Int
,
vararg
args
:
Any
)
=
fun
applyMessage
(
@StringRes
stringRes
:
Int
,
vararg
args
:
Any
)
=
apply
{
data
.
message
.
value
=
context
.
getString
(
stringRes
,
*
args
)
}
apply
{
data
.
message
=
context
.
getString
(
stringRes
,
*
args
)
}
fun
applyMessage
(
message
:
CharSequence
)
=
fun
applyMessage
(
message
:
CharSequence
)
=
apply
{
data
.
message
.
value
=
message
}
apply
{
data
.
message
=
message
}
fun
applyIcon
(
@DrawableRes
drawableRes
:
Int
)
=
fun
applyIcon
(
@DrawableRes
drawableRes
:
Int
)
=
apply
{
data
.
icon
.
value
=
drawableRes
}
apply
{
data
.
icon
=
drawableRes
}
fun
applyIcon
(
drawable
:
Drawable
)
=
fun
applyIcon
(
drawable
:
Drawable
)
=
apply
{
data
.
iconRaw
.
value
=
drawable
}
apply
{
data
.
iconRaw
=
drawable
}
fun
applyButton
(
buttonType
:
ButtonType
,
builder
:
ButtonBuilder
.()
->
Unit
)
=
apply
{
fun
applyButton
(
buttonType
:
ButtonType
,
builder
:
ButtonBuilder
.()
->
Unit
)
=
apply
{
val
button
=
when
(
buttonType
)
{
val
button
=
when
(
buttonType
)
{
...
...
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