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
326eee8c
Commit
326eee8c
authored
Jun 12, 2019
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate a lot of classes to Kotlin
parent
00bff491
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
649 additions
and
738 deletions
+649
-738
ActivityResultListener.kt
...va/com/topjohnwu/magisk/ui/base/ActivityResultListener.kt
+0
-7
IBaseLeanback.kt
...c/main/java/com/topjohnwu/magisk/ui/base/IBaseLeanback.kt
+0
-11
MagiskActivity.kt
.../main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt
+37
-9
MagiskLeanbackActivity.kt
...va/com/topjohnwu/magisk/ui/base/MagiskLeanbackActivity.kt
+0
-64
ModulesFragment.kt
...in/java/com/topjohnwu/magisk/ui/module/ModulesFragment.kt
+6
-4
ReposFragment.kt
...main/java/com/topjohnwu/magisk/ui/module/ReposFragment.kt
+10
-8
XList.kt
app/src/main/java/com/topjohnwu/magisk/utils/XList.kt
+6
-1
MarkDownWindow.java
...c/main/java/com/topjohnwu/magisk/view/MarkDownWindow.java
+0
-67
MarkDownWindow.kt
...src/main/java/com/topjohnwu/magisk/view/MarkDownWindow.kt
+54
-0
ProgressNotification.java
.../java/com/topjohnwu/magisk/view/ProgressNotification.java
+0
-85
ProgressNotification.kt
...in/java/com/topjohnwu/magisk/view/ProgressNotification.kt
+73
-0
SnackbarMaker.java
...rc/main/java/com/topjohnwu/magisk/view/SnackbarMaker.java
+0
-48
SnackbarMaker.kt
app/src/main/java/com/topjohnwu/magisk/view/SnackbarMaker.kt
+46
-0
CustomAlertDialog.java
.../com/topjohnwu/magisk/view/dialogs/CustomAlertDialog.java
+0
-137
CustomAlertDialog.kt
...va/com/topjohnwu/magisk/view/dialogs/CustomAlertDialog.kt
+113
-0
FingerprintAuthDialog.java
.../topjohnwu/magisk/view/dialogs/FingerprintAuthDialog.java
+0
-108
FingerprintAuthDialog.kt
...om/topjohnwu/magisk/view/dialogs/FingerprintAuthDialog.kt
+88
-0
InstallMethodDialog.java
...om/topjohnwu/magisk/view/dialogs/InstallMethodDialog.java
+0
-100
InstallMethodDialog.kt
.../com/topjohnwu/magisk/view/dialogs/InstallMethodDialog.kt
+90
-0
MagiskInstallDialog.kt
.../com/topjohnwu/magisk/view/dialogs/MagiskInstallDialog.kt
+45
-0
ManagerInstallDialog.java
...m/topjohnwu/magisk/view/dialogs/ManagerInstallDialog.java
+0
-28
ManagerInstallDialog.kt
...com/topjohnwu/magisk/view/dialogs/ManagerInstallDialog.kt
+23
-0
UninstallDialog.java
...va/com/topjohnwu/magisk/view/dialogs/UninstallDialog.java
+0
-61
UninstallDialog.kt
...java/com/topjohnwu/magisk/view/dialogs/UninstallDialog.kt
+58
-0
No files found.
app/src/main/java/com/topjohnwu/magisk/ui/base/ActivityResultListener.kt
deleted
100644 → 0
View file @
00bff491
package
com.topjohnwu.magisk.ui.base
import
android.content.Intent
interface
ActivityResultListener
{
fun
onActivityResult
(
resultCode
:
Int
,
data
:
Intent
?)
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/ui/base/IBaseLeanback.kt
deleted
100644 → 0
View file @
00bff491
package
com.topjohnwu.magisk.ui.base
import
android.content.Intent
interface
IBaseLeanback
{
fun
runWithExternalRW
(
callback
:
Runnable
)
fun
runWithPermissions
(
vararg
permissions
:
String
,
callback
:
Runnable
)
fun
startActivityForResult
(
intent
:
Intent
,
requestCode
:
Int
,
listener
:
ActivityResultListener
)
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt
View file @
326eee8c
package
com.topjohnwu.magisk.ui.base
package
com.topjohnwu.magisk.ui.base
import
android.Manifest
import
android.content.Context
import
android.content.Context
import
android.content.Intent
import
android.content.Intent
import
android.content.res.Configuration
import
android.content.res.Configuration
import
android.os.Bundle
import
android.os.Bundle
import
androidx.annotation.CallSuper
import
androidx.annotation.CallSuper
import
androidx.appcompat.app.AppCompatDelegate
import
androidx.appcompat.app.AppCompatDelegate
import
androidx.collection.SparseArrayCompat
import
androidx.core.net.toUri
import
androidx.core.net.toUri
import
androidx.databinding.ViewDataBinding
import
androidx.databinding.ViewDataBinding
import
androidx.fragment.app.Fragment
import
androidx.fragment.app.Fragment
...
@@ -17,6 +19,7 @@ import com.karumi.dexter.listener.PermissionRequest
...
@@ -17,6 +19,7 @@ import com.karumi.dexter.listener.PermissionRequest
import
com.karumi.dexter.listener.multi.MultiplePermissionsListener
import
com.karumi.dexter.listener.multi.MultiplePermissionsListener
import
com.ncapdevi.fragnav.FragNavController
import
com.ncapdevi.fragnav.FragNavController
import
com.ncapdevi.fragnav.FragNavTransactionOptions
import
com.ncapdevi.fragnav.FragNavTransactionOptions
import
com.skoumal.teanity.view.TeanityActivity
import
com.skoumal.teanity.viewevents.ViewEvent
import
com.skoumal.teanity.viewevents.ViewEvent
import
com.topjohnwu.magisk.Config
import
com.topjohnwu.magisk.Config
import
com.topjohnwu.magisk.model.events.BackPressEvent
import
com.topjohnwu.magisk.model.events.BackPressEvent
...
@@ -28,16 +31,20 @@ import com.topjohnwu.magisk.model.navigation.Navigator
...
@@ -28,16 +31,20 @@ import com.topjohnwu.magisk.model.navigation.Navigator
import
com.topjohnwu.magisk.model.permissions.PermissionRequestBuilder
import
com.topjohnwu.magisk.model.permissions.PermissionRequestBuilder
import
com.topjohnwu.magisk.utils.LocaleManager
import
com.topjohnwu.magisk.utils.LocaleManager
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.utils.set
import
timber.log.Timber
import
timber.log.Timber
import
kotlin.reflect.KClass
import
kotlin.reflect.KClass
typealias
RequestCallback
=
MagiskActivity
<*,
*>.(
Int
,
Intent
?)
->
Unit
abstract
class
MagiskActivity
<
ViewModel
:
MagiskViewModel
,
Binding
:
ViewDataBinding
>
:
abstract
class
MagiskActivity
<
ViewModel
:
MagiskViewModel
,
Binding
:
ViewDataBinding
>
:
MagiskLeanback
Activity
<
ViewModel
,
Binding
>(),
FragNavController
.
RootFragmentListener
,
Teanity
Activity
<
ViewModel
,
Binding
>(),
FragNavController
.
RootFragmentListener
,
Navigator
,
FragNavController
.
TransactionListener
{
Navigator
,
FragNavController
.
TransactionListener
{
override
val
numberOfRootFragments
:
Int
get
()
=
baseFragments
.
size
override
val
numberOfRootFragments
:
Int
get
()
=
baseFragments
.
size
override
val
baseFragments
:
List
<
KClass
<
out
Fragment
>>
=
listOf
()
override
val
baseFragments
:
List
<
KClass
<
out
Fragment
>>
=
listOf
()
private
val
resultCallbacks
=
SparseArrayCompat
<
RequestCallback
>()
protected
open
val
defaultPosition
:
Int
=
0
protected
open
val
defaultPosition
:
Int
=
0
...
@@ -188,19 +195,23 @@ abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBin
...
@@ -188,19 +195,23 @@ abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBin
Dexter
.
withActivity
(
this
)
Dexter
.
withActivity
(
this
)
.
withPermissions
(*
permissions
)
.
withPermissions
(*
permissions
)
.
withListener
(
object
:
MultiplePermissionsListener
{
.
withListener
(
object
:
MultiplePermissionsListener
{
override
fun
onPermissionsChecked
(
report
:
MultiplePermissionsReport
?)
=
override
fun
onPermissionsChecked
(
report
:
MultiplePermissionsReport
)
{
if
(
report
?.
areAllPermissionsGranted
()
==
true
)
{
if
(
report
.
areAllPermissionsGranted
()
)
{
request
.
onSuccess
()
request
.
onSuccess
()
}
else
{
}
else
{
request
.
onFailure
()
request
.
onFailure
()
}
}
}
override
fun
onPermissionRationaleShouldBeShown
(
override
fun
onPermissionRationaleShouldBeShown
(
permissions
:
MutableList
<
PermissionRequest
>?,
permissions
:
MutableList
<
PermissionRequest
>,
token
:
PermissionToken
?
token
:
PermissionToken
)
=
request
.
onShowRationale
(
permissions
.
orEmpty
().
map
{
it
.
name
})
)
=
token
.
continuePermissionRequest
()
})
}).
check
()
.
check
()
}
fun
withExternalRW
(
builder
:
PermissionRequestBuilder
.()
->
Unit
)
{
withPermissions
(
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
,
builder
=
builder
)
}
}
private
fun
FragNavTransactionOptions
.
Builder
.
customAnimations
(
options
:
MagiskAnimBuilder
)
=
private
fun
FragNavTransactionOptions
.
Builder
.
customAnimations
(
options
:
MagiskAnimBuilder
)
=
...
@@ -210,4 +221,21 @@ abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBin
...
@@ -210,4 +221,21 @@ abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBin
}
}
}
}
override
fun
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
data
:
Intent
?)
{
super
.
onActivityResult
(
requestCode
,
resultCode
,
data
)
resultCallbacks
[
requestCode
]
?.
apply
{
resultCallbacks
.
remove
(
requestCode
)
invoke
(
this
@MagiskActivity
,
resultCode
,
data
)
}
}
fun
startActivityForResult
(
intent
:
Intent
,
requestCode
:
Int
,
listener
:
RequestCallback
)
{
resultCallbacks
[
requestCode
]
=
listener
startActivityForResult
(
intent
,
requestCode
)
}
}
}
app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskLeanbackActivity.kt
deleted
100644 → 0
View file @
00bff491
package
com.topjohnwu.magisk.ui.base
import
android.Manifest
import
android.content.Intent
import
androidx.collection.SparseArrayCompat
import
androidx.databinding.ViewDataBinding
import
com.karumi.dexter.Dexter
import
com.karumi.dexter.MultiplePermissionsReport
import
com.karumi.dexter.PermissionToken
import
com.karumi.dexter.listener.PermissionRequest
import
com.karumi.dexter.listener.multi.MultiplePermissionsListener
import
com.skoumal.teanity.view.TeanityActivity
import
com.topjohnwu.magisk.Const
abstract
class
MagiskLeanbackActivity
<
ViewModel
:
MagiskViewModel
,
Binding
:
ViewDataBinding
>
:
TeanityActivity
<
ViewModel
,
Binding
>(),
IBaseLeanback
{
private
val
resultListeners
=
SparseArrayCompat
<
ActivityResultListener
>()
@Deprecated
(
"Permissions will be checked in a different streamlined way"
)
fun
runWithExternalRW
(
callback
:
()
->
Unit
)
=
runWithExternalRW
(
Runnable
{
callback
()
})
@Deprecated
(
"Permissions will be checked in a different streamlined way"
)
override
fun
runWithExternalRW
(
callback
:
Runnable
)
{
runWithPermissions
(
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
,
callback
=
callback
)
}
@Deprecated
(
"Permissions will be checked in a different streamlined way"
)
override
fun
runWithPermissions
(
vararg
permissions
:
String
,
callback
:
Runnable
)
{
Dexter
.
withActivity
(
this
)
.
withPermissions
(*
permissions
)
.
withListener
(
object
:
MultiplePermissionsListener
{
override
fun
onPermissionsChecked
(
report
:
MultiplePermissionsReport
?)
{
if
(
report
?.
areAllPermissionsGranted
()
==
true
)
{
Const
.
EXTERNAL_PATH
.
mkdirs
()
callback
.
run
()
}
}
override
fun
onPermissionRationaleShouldBeShown
(
permissions
:
MutableList
<
PermissionRequest
>?,
token
:
PermissionToken
?
)
=
Unit
})
.
check
()
}
override
fun
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
data
:
Intent
?)
{
super
.
onActivityResult
(
requestCode
,
resultCode
,
data
)
resultListeners
.
get
(
requestCode
)
?.
apply
{
resultListeners
.
remove
(
requestCode
)
onActivityResult
(
resultCode
,
data
)
}
}
override
fun
startActivityForResult
(
intent
:
Intent
,
requestCode
:
Int
,
listener
:
ActivityResultListener
)
{
resultListeners
.
put
(
requestCode
,
listener
)
startActivityForResult
(
intent
,
requestCode
)
}
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/ui/module/ModulesFragment.kt
View file @
326eee8c
...
@@ -85,10 +85,12 @@ class ModulesFragment : MagiskFragment<ModuleViewModel, FragmentModulesBinding>(
...
@@ -85,10 +85,12 @@ class ModulesFragment : MagiskFragment<ModuleViewModel, FragmentModulesBinding>(
}
}
private
fun
selectFile
()
{
private
fun
selectFile
()
{
magiskActivity
.
runWithExternalRW
{
magiskActivity
.
withExternalRW
{
onSuccess
{
val
intent
=
Intent
(
Intent
.
ACTION_GET_CONTENT
)
val
intent
=
Intent
(
Intent
.
ACTION_GET_CONTENT
)
intent
.
type
=
"application/zip"
intent
.
type
=
"application/zip"
startActivityForResult
(
intent
,
Const
.
ID
.
FETCH_ZIP
)
startActivityForResult
(
intent
,
Const
.
ID
.
FETCH_ZIP
)
}
}
}
}
}
}
}
app/src/main/java/com/topjohnwu/magisk/ui/module/ReposFragment.kt
View file @
326eee8c
...
@@ -74,23 +74,25 @@ class ReposFragment : MagiskFragment<ModuleViewModel, FragmentReposBinding>(),
...
@@ -74,23 +74,25 @@ class ReposFragment : MagiskFragment<ModuleViewModel, FragmentReposBinding>(),
}
}
private
fun
openChangelog
(
item
:
Repo
)
{
private
fun
openChangelog
(
item
:
Repo
)
{
MarkDownWindow
.
show
(
context
,
null
,
item
.
detailUrl
)
MarkDownWindow
.
show
(
requireActivity
()
,
null
,
item
.
detailUrl
)
}
}
private
fun
installModule
(
item
:
Repo
)
{
private
fun
installModule
(
item
:
Repo
)
{
val
context
=
magiskActivity
val
context
=
magiskActivity
fun
download
(
install
:
Boolean
)
{
fun
download
(
install
:
Boolean
)
{
context
.
runWithExternalRW
{
context
.
withExternalRW
{
onSuccess
{
val
intent
=
Intent
(
activity
,
ClassMap
[
DownloadModuleService
::
class
.
java
])
val
intent
=
Intent
(
activity
,
ClassMap
[
DownloadModuleService
::
class
.
java
])
.
putExtra
(
"repo"
,
item
).
putExtra
(
"install"
,
install
)
.
putExtra
(
"repo"
,
item
).
putExtra
(
"install"
,
install
)
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
context
.
startForegroundService
(
intent
)
//hmm, service starts itself in foreground, this seems unnecessary
context
.
startForegroundService
(
intent
)
}
else
{
}
else
{
context
.
startService
(
intent
)
context
.
startService
(
intent
)
}
}
}
}
}
}
}
CustomAlertDialog
(
context
)
CustomAlertDialog
(
context
)
.
setTitle
(
context
.
getString
(
R
.
string
.
repo_install_title
,
item
.
name
))
.
setTitle
(
context
.
getString
(
R
.
string
.
repo_install_title
,
item
.
name
))
...
...
app/src/main/java/com/topjohnwu/magisk/utils/XList.kt
View file @
326eee8c
package
com.topjohnwu.magisk.utils
package
com.topjohnwu.magisk.utils
import
androidx.collection.SparseArrayCompat
import
androidx.databinding.ObservableList
import
androidx.databinding.ObservableList
import
com.skoumal.teanity.extensions.subscribeK
import
com.skoumal.teanity.extensions.subscribeK
import
com.skoumal.teanity.util.DiffObservableList
import
com.skoumal.teanity.util.DiffObservableList
...
@@ -77,3 +78,7 @@ fun <T1> ObservableList<T1>.copyNewInputInto(
...
@@ -77,3 +78,7 @@ fun <T1> ObservableList<T1>.copyNewInputInto(
target
.
addAll
(
addedValues
)
target
.
addAll
(
addedValues
)
}
}
})
})
operator
fun
<
E
>
SparseArrayCompat
<
E
>.
set
(
key
:
Int
,
value
:
E
)
{
put
(
key
,
value
)
}
app/src/main/java/com/topjohnwu/magisk/view/MarkDownWindow.java
deleted
100644 → 0
View file @
00bff491
package
com
.
topjohnwu
.
magisk
.
view
;
import
android.content.Context
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.widget.TextView
;
import
androidx.appcompat.app.AlertDialog
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.net.Networking
;
import
com.topjohnwu.net.ResponseListener
;
import
java.io.InputStream
;
import
java.util.Scanner
;
import
ru.noties.markwon.Markwon
;
import
ru.noties.markwon.html.HtmlPlugin
;
import
ru.noties.markwon.image.ImagesPlugin
;
import
ru.noties.markwon.image.svg.SvgPlugin
;
public
class
MarkDownWindow
{
public
static
void
show
(
Context
activity
,
String
title
,
String
url
)
{
Networking
.
get
(
url
).
getAsString
(
new
Listener
(
activity
,
title
));
}
public
static
void
show
(
Context
activity
,
String
title
,
InputStream
is
)
{
try
(
Scanner
s
=
new
Scanner
(
is
,
"UTF-8"
))
{
s
.
useDelimiter
(
"\\A"
);
new
Listener
(
activity
,
title
).
onResponse
(
s
.
next
());
}
}
static
class
Listener
implements
ResponseListener
<
String
>
{
Context
activity
;
String
title
;
Listener
(
Context
a
,
String
t
)
{
activity
=
a
;
title
=
t
;
}
@Override
public
void
onResponse
(
String
md
)
{
Markwon
markwon
=
Markwon
.
builder
(
activity
)
.
usePlugin
(
HtmlPlugin
.
create
())
.
usePlugin
(
ImagesPlugin
.
create
(
activity
))
.
usePlugin
(
SvgPlugin
.
create
(
activity
.
getResources
()))
.
build
();
AlertDialog
.
Builder
alert
=
new
AlertDialog
.
Builder
(
activity
);
alert
.
setTitle
(
title
);
View
mv
=
LayoutInflater
.
from
(
activity
).
inflate
(
R
.
layout
.
markdown_window
,
null
);
TextView
tv
=
mv
.
findViewById
(
R
.
id
.
md_txt
);
try
{
markwon
.
setMarkdown
(
tv
,
md
);
}
catch
(
ExceptionInInitializerError
e
)
{
//Nothing we can do about this error other than show error message
tv
.
setText
(
R
.
string
.
download_file_error
);
}
alert
.
setView
(
mv
);
alert
.
setNegativeButton
(
R
.
string
.
close
,
(
dialog
,
id
)
->
dialog
.
dismiss
());
alert
.
show
();
}
}
}
app/src/main/java/com/topjohnwu/magisk/view/MarkDownWindow.kt
0 → 100644
View file @
326eee8c
package
com.topjohnwu.magisk.view
import
android.content.Context
import
android.view.LayoutInflater
import
android.widget.TextView
import
androidx.appcompat.app.AlertDialog
import
com.topjohnwu.magisk.R
import
com.topjohnwu.net.Networking
import
com.topjohnwu.net.ResponseListener
import
ru.noties.markwon.Markwon
import
ru.noties.markwon.html.HtmlPlugin
import
ru.noties.markwon.image.ImagesPlugin
import
ru.noties.markwon.image.svg.SvgPlugin
import
java.io.InputStream
import
java.util.*
object
MarkDownWindow
{
fun
show
(
activity
:
Context
,
title
:
String
?,
url
:
String
)
{
Networking
.
get
(
url
).
getAsString
(
Listener
(
activity
,
title
))
}
fun
show
(
activity
:
Context
,
title
:
String
?,
input
:
InputStream
)
{
Scanner
(
input
,
"UTF-8"
).
use
{
it
.
useDelimiter
(
"\\A"
)
Listener
(
activity
,
title
).
onResponse
(
it
.
next
())
}
}
internal
class
Listener
(
var
activity
:
Context
,
var
title
:
String
?)
:
ResponseListener
<
String
>
{
override
fun
onResponse
(
md
:
String
)
{
val
markwon
=
Markwon
.
builder
(
activity
)
.
usePlugin
(
HtmlPlugin
.
create
())
.
usePlugin
(
ImagesPlugin
.
create
(
activity
))
.
usePlugin
(
SvgPlugin
.
create
(
activity
.
resources
))
.
build
()
val
alert
=
AlertDialog
.
Builder
(
activity
)
alert
.
setTitle
(
title
)
val
mv
=
LayoutInflater
.
from
(
activity
).
inflate
(
R
.
layout
.
markdown_window
,
null
)
val
tv
=
mv
.
findViewById
<
TextView
>(
R
.
id
.
md_txt
)
try
{
markwon
.
setMarkdown
(
tv
,
md
)
}
catch
(
e
:
ExceptionInInitializerError
)
{
//Nothing we can do about this error other than show error message
tv
.
setText
(
R
.
string
.
download_file_error
)
}
alert
.
setView
(
mv
)
alert
.
setNegativeButton
(
R
.
string
.
close
)
{
dialog
,
_
->
dialog
.
dismiss
()
}
alert
.
show
()
}
}
}
app/src/main/java/com/topjohnwu/magisk/view/ProgressNotification.java
deleted
100644 → 0
View file @
00bff491
package
com
.
topjohnwu
.
magisk
.
view
;
import
android.app.Notification
;
import
android.app.PendingIntent
;
import
android.content.Intent
;
import
android.widget.Toast
;
import
androidx.core.app.NotificationCompat
;
import
com.topjohnwu.magisk.App
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.net.DownloadProgressListener
;
public
class
ProgressNotification
implements
DownloadProgressListener
{
private
NotificationCompat
.
Builder
builder
;
private
Notification
notification
;
private
long
prevTime
;
public
ProgressNotification
(
String
title
)
{
builder
=
Notifications
.
progress
(
title
);
prevTime
=
System
.
currentTimeMillis
();
update
();
Utils
.
INSTANCE
.
toast
(
App
.
self
.
getString
(
R
.
string
.
downloading_toast
,
title
),
Toast
.
LENGTH_SHORT
);
}
@Override
public
void
onProgress
(
long
bytesDownloaded
,
long
totalBytes
)
{
long
cur
=
System
.
currentTimeMillis
();
if
(
cur
-
prevTime
>=
1000
)
{
prevTime
=
cur
;
int
progress
=
(
int
)
(
bytesDownloaded
*
100
/
totalBytes
);
builder
.
setProgress
(
100
,
progress
,
false
);
builder
.
setContentText
(
progress
+
"%"
);
update
();
}
}
public
NotificationCompat
.
Builder
getNotificationBuilder
()
{
return
builder
;
}
public
Notification
getNotification
()
{
return
notification
;
}
public
void
update
()
{
notification
=
builder
.
build
();
Notifications
.
mgr
.
notify
(
hashCode
(),
notification
);
}
private
void
lastUpdate
()
{
notification
=
builder
.
build
();
Notifications
.
mgr
.
cancel
(
hashCode
());
Notifications
.
mgr
.
notify
(
notification
.
hashCode
(),
notification
);
}
public
void
dlDone
()
{
dlDone
(
PendingIntent
.
getActivity
(
App
.
self
,
hashCode
(),
new
Intent
(),
PendingIntent
.
FLAG_UPDATE_CURRENT
));
}
public
void
dlDone
(
PendingIntent
intent
)
{
builder
.
setProgress
(
0
,
0
,
false
)
.
setContentText
(
App
.
self
.
getString
(
R
.
string
.
download_complete
))
.
setSmallIcon
(
android
.
R
.
drawable
.
stat_sys_download_done
)
.
setContentIntent
(
intent
)
.
setOngoing
(
false
)
.
setAutoCancel
(
true
);
lastUpdate
();
}
public
void
dlFail
()
{
builder
.
setProgress
(
0
,
0
,
false
)
.
setContentText
(
App
.
self
.
getString
(
R
.
string
.
download_file_error
))
.
setSmallIcon
(
android
.
R
.
drawable
.
stat_notify_error
)
.
setOngoing
(
false
);
lastUpdate
();
}
public
void
dismiss
()
{
Notifications
.
mgr
.
cancel
(
hashCode
());
}
}
app/src/main/java/com/topjohnwu/magisk/view/ProgressNotification.kt
0 → 100644
View file @
326eee8c
package
com.topjohnwu.magisk.view
import
android.app.Notification
import
android.app.PendingIntent
import
android.content.Intent
import
android.widget.Toast
import
androidx.core.app.NotificationCompat
import
com.topjohnwu.magisk.App
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.net.DownloadProgressListener
class
ProgressNotification
(
title
:
String
)
:
DownloadProgressListener
{
val
notificationBuilder
:
NotificationCompat
.
Builder
=
Notifications
.
progress
(
title
)
lateinit
var
notification
:
Notification
private
set
private
var
prevTime
:
Long
=
0
init
{
prevTime
=
System
.
currentTimeMillis
()
update
()
Utils
.
toast
(
App
.
self
.
getString
(
R
.
string
.
downloading_toast
,
title
),
Toast
.
LENGTH_SHORT
)
}
override
fun
onProgress
(
bytesDownloaded
:
Long
,
totalBytes
:
Long
)
{
val
cur
=
System
.
currentTimeMillis
()
if
(
cur
-
prevTime
>=
1000
)
{
prevTime
=
cur
val
progress
=
(
bytesDownloaded
*
100
/
totalBytes
).
toInt
()
notificationBuilder
.
setProgress
(
100
,
progress
,
false
)
notificationBuilder
.
setContentText
(
"$progress%"
)
update
()
}
}
fun
update
()
{
notification
=
notificationBuilder
.
build
()
Notifications
.
mgr
.
notify
(
hashCode
(),
notification
)
}
private
fun
lastUpdate
()
{
Notifications
.
mgr
.
cancel
(
hashCode
())
notification
=
notificationBuilder
.
build
().
apply
{
Notifications
.
mgr
.
notify
(
hashCode
(),
this
)
}
}
fun
dlDone
(
intent
:
PendingIntent
=
PendingIntent
.
getActivity
(
App
.
self
,
hashCode
(),
Intent
(),
PendingIntent
.
FLAG_UPDATE_CURRENT
))
{
notificationBuilder
.
setProgress
(
0
,
0
,
false
)
.
setContentText
(
App
.
self
.
getString
(
R
.
string
.
download_complete
))
.
setSmallIcon
(
android
.
R
.
drawable
.
stat_sys_download_done
)
.
setContentIntent
(
intent
)
.
setOngoing
(
false
)
.
setAutoCancel
(
true
)
lastUpdate
()
}
fun
dlFail
()
{
notificationBuilder
.
setProgress
(
0
,
0
,
false
)
.
setContentText
(
App
.
self
.
getString
(
R
.
string
.
download_file_error
))
.
setSmallIcon
(
android
.
R
.
drawable
.
stat_notify_error
)
.
setOngoing
(
false
)
lastUpdate
()
}
fun
dismiss
()
{
Notifications
.
mgr
.
cancel
(
hashCode
())
}
}
app/src/main/java/com/topjohnwu/magisk/view/SnackbarMaker.java
deleted
100644 → 0
View file @
00bff491
package
com
.
topjohnwu
.
magisk
.
view
;
import
android.app.Activity
;
import
android.net.Uri
;
import
android.view.View
;
import
android.widget.TextView
;
import
androidx.annotation.StringRes
;
import
com.google.android.material.snackbar.Snackbar
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.utils.XAndroidKt
;
public
class
SnackbarMaker
{
public
static
Snackbar
make
(
Activity
activity
,
CharSequence
text
,
int
duration
)
{
View
view
=
activity
.
findViewById
(
android
.
R
.
id
.
content
);
return
make
(
view
,
text
,
duration
);
}
public
static
Snackbar
make
(
Activity
activity
,
@StringRes
int
resId
,
int
duration
)
{
return
make
(
activity
,
activity
.
getString
(
resId
),
duration
);
}
public
static
Snackbar
make
(
View
view
,
CharSequence
text
,
int
duration
)
{
Snackbar
snack
=
Snackbar
.
make
(
view
,
text
,
duration
);
setup
(
snack
);
return
snack
;
}
public
static
Snackbar
make
(
View
view
,
@StringRes
int
resId
,
int
duration
)
{
Snackbar
snack
=
Snackbar
.
make
(
view
,
resId
,
duration
);
setup
(
snack
);
return
snack
;
}
private
static
void
setup
(
Snackbar
snack
)
{
TextView
text
=
snack
.
getView
().
findViewById
(
com
.
google
.
android
.
material
.
R
.
id
.
snackbar_text
);
text
.
setMaxLines
(
Integer
.
MAX_VALUE
);
}
public
static
void
showUri
(
Activity
activity
,
Uri
uri
)
{
make
(
activity
,
activity
.
getString
(
R
.
string
.
internal_storage
,
"/Download/"
+
XAndroidKt
.
getFileName
(
uri
)),
Snackbar
.
LENGTH_LONG
)
.
setAction
(
R
.
string
.
ok
,
(
v
)->{}).
show
();
}
}
app/src/main/java/com/topjohnwu/magisk/view/SnackbarMaker.kt
0 → 100644
View file @
326eee8c
package
com.topjohnwu.magisk.view
import
android.app.Activity
import
android.net.Uri
import
android.view.View
import
android.widget.TextView
import
androidx.annotation.StringRes
import
com.google.android.material.snackbar.Snackbar
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.utils.fileName
object
SnackbarMaker
{
fun
make
(
activity
:
Activity
,
text
:
CharSequence
,
duration
:
Int
):
Snackbar
{
val
view
=
activity
.
findViewById
<
View
>(
android
.
R
.
id
.
content
)
return
make
(
view
,
text
,
duration
)
}
fun
make
(
activity
:
Activity
,
@StringRes
resId
:
Int
,
duration
:
Int
):
Snackbar
{
return
make
(
activity
,
activity
.
getString
(
resId
),
duration
)
}
fun
make
(
view
:
View
,
text
:
CharSequence
,
duration
:
Int
):
Snackbar
{
val
snack
=
Snackbar
.
make
(
view
,
text
,
duration
)
setup
(
snack
)
return
snack
}
fun
make
(
view
:
View
,
@StringRes
resId
:
Int
,
duration
:
Int
):
Snackbar
{
val
snack
=
Snackbar
.
make
(
view
,
resId
,
duration
)
setup
(
snack
)
return
snack
}
private
fun
setup
(
snack
:
Snackbar
)
{
val
text
=
snack
.
view
.
findViewById
<
TextView
>(
com
.
google
.
android
.
material
.
R
.
id
.
snackbar_text
)
text
.
maxLines
=
Integer
.
MAX_VALUE
}
fun
showUri
(
activity
:
Activity
,
uri
:
Uri
)
{
make
(
activity
,
activity
.
getString
(
R
.
string
.
internal_storage
,
"/Download/"
+
uri
.
fileName
),
Snackbar
.
LENGTH_LONG
)
.
setAction
(
R
.
string
.
ok
)
{
}.
show
()
}
}
app/src/main/java/com/topjohnwu/magisk/view/dialogs/CustomAlertDialog.java
deleted
100644 → 0
View file @
00bff491
package
com
.
topjohnwu
.
magisk
.
view
.
dialogs
;
import
android.content.Context
;
import
android.content.DialogInterface
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.StringRes
;
import
androidx.annotation.StyleRes
;
import
androidx.appcompat.app.AlertDialog
;
import
com.topjohnwu.magisk.databinding.AlertDialogBinding
;
public
class
CustomAlertDialog
extends
AlertDialog
.
Builder
{
private
DialogInterface
.
OnClickListener
positiveListener
;
private
DialogInterface
.
OnClickListener
negativeListener
;
private
DialogInterface
.
OnClickListener
neutralListener
;
protected
AlertDialog
dialog
;
protected
AlertDialogBinding
binding
;
{
binding
=
AlertDialogBinding
.
inflate
(
LayoutInflater
.
from
(
getContext
()));
super
.
setView
(
binding
.
getRoot
());
binding
.
message
.
setVisibility
(
View
.
GONE
);
binding
.
negative
.
setVisibility
(
View
.
GONE
);
binding
.
positive
.
setVisibility
(
View
.
GONE
);
binding
.
neutral
.
setVisibility
(
View
.
GONE
);
binding
.
buttonPanel
.
setVisibility
(
View
.
GONE
);
}
public
CustomAlertDialog
(
@NonNull
Context
context
)
{
super
(
context
);
}
public
CustomAlertDialog
(
@NonNull
Context
context
,
@StyleRes
int
themeResId
)
{
super
(
context
,
themeResId
);
}
@Override
public
CustomAlertDialog
setView
(
int
layoutResId
)
{
return
this
;
}
@Override
public
CustomAlertDialog
setView
(
View
view
)
{
return
this
;
}
@Override
public
CustomAlertDialog
setMessage
(
@Nullable
CharSequence
message
)
{
binding
.
message
.
setVisibility
(
View
.
VISIBLE
);
binding
.
message
.
setText
(
message
);
return
this
;
}
@Override
public
CustomAlertDialog
setMessage
(
@StringRes
int
messageId
)
{
return
setMessage
(
getContext
().
getString
(
messageId
));
}
@Override
public
CustomAlertDialog
setPositiveButton
(
CharSequence
text
,
DialogInterface
.
OnClickListener
listener
)
{
binding
.
buttonPanel
.
setVisibility
(
View
.
VISIBLE
);
binding
.
positive
.
setVisibility
(
View
.
VISIBLE
);
binding
.
positive
.
setText
(
text
);
positiveListener
=
listener
;
binding
.
positive
.
setOnClickListener
(
v
->
{
if
(
positiveListener
!=
null
)
{
positiveListener
.
onClick
(
dialog
,
DialogInterface
.
BUTTON_POSITIVE
);
}
dialog
.
dismiss
();
});
return
this
;
}
@Override
public
CustomAlertDialog
setPositiveButton
(
@StringRes
int
textId
,
DialogInterface
.
OnClickListener
listener
)
{
return
setPositiveButton
(
getContext
().
getString
(
textId
),
listener
);
}
@Override
public
CustomAlertDialog
setNegativeButton
(
CharSequence
text
,
DialogInterface
.
OnClickListener
listener
)
{
binding
.
buttonPanel
.
setVisibility
(
View
.
VISIBLE
);
binding
.
negative
.
setVisibility
(
View
.
VISIBLE
);
binding
.
negative
.
setText
(
text
);
negativeListener
=
listener
;
binding
.
negative
.
setOnClickListener
(
v
->
{
if
(
negativeListener
!=
null
)
{
negativeListener
.
onClick
(
dialog
,
DialogInterface
.
BUTTON_NEGATIVE
);
}
dialog
.
dismiss
();
});
return
this
;
}
@Override
public
CustomAlertDialog
setNegativeButton
(
@StringRes
int
textId
,
DialogInterface
.
OnClickListener
listener
)
{
return
setNegativeButton
(
getContext
().
getString
(
textId
),
listener
);
}
@Override
public
CustomAlertDialog
setNeutralButton
(
CharSequence
text
,
DialogInterface
.
OnClickListener
listener
)
{
binding
.
buttonPanel
.
setVisibility
(
View
.
VISIBLE
);
binding
.
neutral
.
setVisibility
(
View
.
VISIBLE
);
binding
.
neutral
.
setText
(
text
);
neutralListener
=
listener
;
binding
.
neutral
.
setOnClickListener
(
v
->
{
if
(
neutralListener
!=
null
)
{
neutralListener
.
onClick
(
dialog
,
DialogInterface
.
BUTTON_NEUTRAL
);
}
dialog
.
dismiss
();
});
return
this
;
}
@Override
public
CustomAlertDialog
setNeutralButton
(
@StringRes
int
textId
,
DialogInterface
.
OnClickListener
listener
)
{
return
setNeutralButton
(
getContext
().
getString
(
textId
),
listener
);
}
@Override
public
AlertDialog
create
()
{
dialog
=
super
.
create
();
return
dialog
;
}
@Override
public
AlertDialog
show
()
{
create
();
dialog
.
show
();
return
dialog
;
}
public
void
dismiss
()
{
dialog
.
dismiss
();
}
}
app/src/main/java/com/topjohnwu/magisk/view/dialogs/CustomAlertDialog.kt
0 → 100644
View file @
326eee8c
package
com.topjohnwu.magisk.view.dialogs
import
android.content.Context
import
android.content.DialogInterface
import
android.view.LayoutInflater
import
android.view.View
import
androidx.annotation.StringRes
import
androidx.annotation.StyleRes
import
androidx.appcompat.app.AlertDialog
import
com.topjohnwu.magisk.databinding.AlertDialogBinding
open
class
CustomAlertDialog
:
AlertDialog
.
Builder
{
private
var
positiveListener
:
DialogInterface
.
OnClickListener
?
=
null
private
var
negativeListener
:
DialogInterface
.
OnClickListener
?
=
null
private
var
neutralListener
:
DialogInterface
.
OnClickListener
?
=
null
protected
var
dialog
:
AlertDialog
?
=
null
protected
var
binding
:
AlertDialogBinding
=
AlertDialogBinding
.
inflate
(
LayoutInflater
.
from
(
context
))
init
{
super
.
setView
(
binding
.
root
)
binding
.
message
.
visibility
=
View
.
GONE
binding
.
negative
.
visibility
=
View
.
GONE
binding
.
positive
.
visibility
=
View
.
GONE
binding
.
neutral
.
visibility
=
View
.
GONE
binding
.
buttonPanel
.
visibility
=
View
.
GONE
}
constructor
(
context
:
Context
)
:
super
(
context
)
constructor
(
context
:
Context
,
@StyleRes
themeResId
:
Int
)
:
super
(
context
,
themeResId
)
override
fun
setView
(
layoutResId
:
Int
):
CustomAlertDialog
{
return
this
}
override
fun
setView
(
view
:
View
):
CustomAlertDialog
{
return
this
}
override
fun
setMessage
(
message
:
CharSequence
?):
CustomAlertDialog
{
binding
.
message
.
visibility
=
View
.
VISIBLE
binding
.
message
.
text
=
message
return
this
}
override
fun
setMessage
(
@StringRes
messageId
:
Int
):
CustomAlertDialog
{
return
setMessage
(
context
.
getString
(
messageId
))
}
override
fun
setPositiveButton
(
text
:
CharSequence
,
listener
:
DialogInterface
.
OnClickListener
?):
CustomAlertDialog
{
binding
.
buttonPanel
.
visibility
=
View
.
VISIBLE
binding
.
positive
.
visibility
=
View
.
VISIBLE
binding
.
positive
.
text
=
text
positiveListener
=
listener
binding
.
positive
.
setOnClickListener
{
positiveListener
?.
onClick
(
dialog
,
DialogInterface
.
BUTTON_POSITIVE
)
dialog
?.
dismiss
()
}
return
this
}
override
fun
setPositiveButton
(
@StringRes
textId
:
Int
,
listener
:
DialogInterface
.
OnClickListener
?):
CustomAlertDialog
{
return
setPositiveButton
(
context
.
getString
(
textId
),
listener
)
}
override
fun
setNegativeButton
(
text
:
CharSequence
,
listener
:
DialogInterface
.
OnClickListener
?):
CustomAlertDialog
{
binding
.
buttonPanel
.
visibility
=
View
.
VISIBLE
binding
.
negative
.
visibility
=
View
.
VISIBLE
binding
.
negative
.
text
=
text
negativeListener
=
listener
binding
.
negative
.
setOnClickListener
{
negativeListener
?.
onClick
(
dialog
,
DialogInterface
.
BUTTON_NEGATIVE
)
dialog
?.
dismiss
()
}
return
this
}
override
fun
setNegativeButton
(
@StringRes
textId
:
Int
,
listener
:
DialogInterface
.
OnClickListener
?):
CustomAlertDialog
{
return
setNegativeButton
(
context
.
getString
(
textId
),
listener
)
}
override
fun
setNeutralButton
(
text
:
CharSequence
,
listener
:
DialogInterface
.
OnClickListener
?):
CustomAlertDialog
{
binding
.
buttonPanel
.
visibility
=
View
.
VISIBLE
binding
.
neutral
.
visibility
=
View
.
VISIBLE
binding
.
neutral
.
text
=
text
neutralListener
=
listener
binding
.
neutral
.
setOnClickListener
{
neutralListener
?.
onClick
(
dialog
,
DialogInterface
.
BUTTON_NEUTRAL
)
dialog
?.
dismiss
()
}
return
this
}
override
fun
setNeutralButton
(
@StringRes
textId
:
Int
,
listener
:
DialogInterface
.
OnClickListener
?):
CustomAlertDialog
{
return
setNeutralButton
(
context
.
getString
(
textId
),
listener
)
}
override
fun
create
():
AlertDialog
{
return
super
.
create
().
apply
{
dialog
=
this
}
}
override
fun
show
():
AlertDialog
{
return
create
().
apply
{
show
()
}
}
fun
dismiss
()
{
dialog
?.
dismiss
()
}
}
app/src/main/java/com/topjohnwu/magisk/view/dialogs/FingerprintAuthDialog.java
deleted
100644 → 0
View file @
00bff491
package
com
.
topjohnwu
.
magisk
.
view
.
dialogs
;
import
android.annotation.TargetApi
;
import
android.app.Activity
;
import
android.content.res.Resources
;
import
android.content.res.TypedArray
;
import
android.graphics.Color
;
import
android.graphics.drawable.Drawable
;
import
android.hardware.fingerprint.FingerprintManager
;
import
android.os.Build
;
import
android.view.Gravity
;
import
android.widget.Toast
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
import
androidx.appcompat.app.AlertDialog
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.utils.FingerprintHelper
;
import
com.topjohnwu.magisk.utils.Utils
;
@TargetApi
(
Build
.
VERSION_CODES
.
M
)
public
class
FingerprintAuthDialog
extends
CustomAlertDialog
{
private
final
Runnable
callback
;
@Nullable
private
Runnable
failureCallback
;
private
DialogFingerprintHelper
helper
;
public
FingerprintAuthDialog
(
@NonNull
Activity
activity
,
@NonNull
Runnable
onSuccess
)
{
super
(
activity
);
callback
=
onSuccess
;
Drawable
fingerprint
=
activity
.
getResources
().
getDrawable
(
R
.
drawable
.
ic_fingerprint
);
fingerprint
.
setBounds
(
0
,
0
,
Utils
.
INSTANCE
.
dpInPx
(
50
),
Utils
.
INSTANCE
.
dpInPx
(
50
));
Resources
.
Theme
theme
=
activity
.
getTheme
();
TypedArray
ta
=
theme
.
obtainStyledAttributes
(
new
int
[]
{
R
.
attr
.
imageColorTint
});
fingerprint
.
setTint
(
ta
.
getColor
(
0
,
Color
.
GRAY
));
ta
.
recycle
();
binding
.
message
.
setCompoundDrawables
(
null
,
null
,
null
,
fingerprint
);
binding
.
message
.
setCompoundDrawablePadding
(
Utils
.
INSTANCE
.
dpInPx
(
20
));
binding
.
message
.
setGravity
(
Gravity
.
CENTER
);
setMessage
(
R
.
string
.
auth_fingerprint
);
setNegativeButton
(
R
.
string
.
close
,
(
d
,
w
)
->
{
helper
.
cancel
();
if
(
failureCallback
!=
null
)
{
failureCallback
.
run
();
}
});
setOnCancelListener
(
d
->
{
helper
.
cancel
();
if
(
failureCallback
!=
null
)
{
failureCallback
.
run
();
}
});
try
{
helper
=
new
DialogFingerprintHelper
();
}
catch
(
Exception
ignored
)
{
ignored
.
printStackTrace
();
}
}
public
FingerprintAuthDialog
(
@NonNull
Activity
activity
,
@NonNull
Runnable
onSuccess
,
@NonNull
Runnable
onFailure
)
{
this
(
activity
,
onSuccess
);
failureCallback
=
onFailure
;
}
@Override
public
AlertDialog
show
()
{
create
();
if
(
helper
==
null
)
{
dialog
.
dismiss
();
Utils
.
INSTANCE
.
toast
(
R
.
string
.
auth_fail
,
Toast
.
LENGTH_SHORT
);
}
else
{
helper
.
authenticate
();
dialog
.
show
();
}
return
dialog
;
}
class
DialogFingerprintHelper
extends
FingerprintHelper
{
DialogFingerprintHelper
()
throws
Exception
{}
@Override
public
void
onAuthenticationError
(
int
errorCode
,
CharSequence
errString
)
{
binding
.
message
.
setTextColor
(
Color
.
RED
);
binding
.
message
.
setText
(
errString
);
}
@Override
public
void
onAuthenticationHelp
(
int
helpCode
,
CharSequence
helpString
)
{
binding
.
message
.
setTextColor
(
Color
.
RED
);
binding
.
message
.
setText
(
helpString
);
}
@Override
public
void
onAuthenticationFailed
()
{
binding
.
message
.
setTextColor
(
Color
.
RED
);
binding
.
message
.
setText
(
R
.
string
.
auth_fail
);
}
@Override
public
void
onAuthenticationSucceeded
(
FingerprintManager
.
AuthenticationResult
result
)
{
dismiss
();
callback
.
run
();
}
}
}
app/src/main/java/com/topjohnwu/magisk/view/dialogs/FingerprintAuthDialog.kt
0 → 100644
View file @
326eee8c
package
com.topjohnwu.magisk.view.dialogs
import
android.annotation.TargetApi
import
android.app.Activity
import
android.graphics.Color
import
android.hardware.fingerprint.FingerprintManager
import
android.os.Build
import
android.view.Gravity
import
android.widget.Toast
import
androidx.appcompat.app.AlertDialog
import
androidx.core.content.ContextCompat
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.utils.FingerprintHelper
import
com.topjohnwu.magisk.utils.Utils
@TargetApi
(
Build
.
VERSION_CODES
.
M
)
class
FingerprintAuthDialog
(
activity
:
Activity
,
private
val
callback
:
()
->
Unit
)
:
CustomAlertDialog
(
activity
)
{
private
var
failureCallback
:
(()
->
Unit
)?
=
null
private
var
helper
:
DialogFingerprintHelper
?
=
null
init
{
val
fingerprint
=
ContextCompat
.
getDrawable
(
activity
,
R
.
drawable
.
ic_fingerprint
)
fingerprint
?.
setBounds
(
0
,
0
,
Utils
.
dpInPx
(
50
),
Utils
.
dpInPx
(
50
))
val
theme
=
activity
.
theme
val
ta
=
theme
.
obtainStyledAttributes
(
intArrayOf
(
R
.
attr
.
imageColorTint
))
fingerprint
?.
setTint
(
ta
.
getColor
(
0
,
Color
.
GRAY
))
ta
.
recycle
()
binding
.
message
.
setCompoundDrawables
(
null
,
null
,
null
,
fingerprint
)
binding
.
message
.
compoundDrawablePadding
=
Utils
.
dpInPx
(
20
)
binding
.
message
.
gravity
=
Gravity
.
CENTER
setMessage
(
R
.
string
.
auth_fingerprint
)
setNegativeButton
(
R
.
string
.
close
)
{
_
,
_
->
helper
?.
cancel
()
failureCallback
?.
invoke
()
}
setOnCancelListener
{
helper
?.
cancel
()
failureCallback
?.
invoke
()
}
runCatching
{
helper
=
DialogFingerprintHelper
()
}
}
constructor
(
activity
:
Activity
,
onSuccess
:
()
->
Unit
,
onFailure
:
()
->
Unit
)
:
this
(
activity
,
onSuccess
)
{
failureCallback
=
onFailure
}
override
fun
show
():
AlertDialog
{
return
create
().
apply
{
if
(
helper
==
null
)
{
dismiss
()
Utils
.
toast
(
R
.
string
.
auth_fail
,
Toast
.
LENGTH_SHORT
)
}
else
{
helper
?.
authenticate
()
show
()
}
}
}
internal
inner
class
DialogFingerprintHelper
@Throws
(
Exception
::
class
)
constructor
()
:
FingerprintHelper
()
{
override
fun
onAuthenticationError
(
errorCode
:
Int
,
errString
:
CharSequence
)
{
binding
.
message
.
setTextColor
(
Color
.
RED
)
binding
.
message
.
text
=
errString
}
override
fun
onAuthenticationHelp
(
helpCode
:
Int
,
helpString
:
CharSequence
)
{
binding
.
message
.
setTextColor
(
Color
.
RED
)
binding
.
message
.
text
=
helpString
}
override
fun
onAuthenticationFailed
()
{
binding
.
message
.
setTextColor
(
Color
.
RED
)
binding
.
message
.
setText
(
R
.
string
.
auth_fail
)
}
override
fun
onAuthenticationSucceeded
(
result
:
FingerprintManager
.
AuthenticationResult
)
{
dismiss
()
callback
()
}
}
}
app/src/main/java/com/topjohnwu/magisk/view/dialogs/InstallMethodDialog.java
deleted
100644 → 0
View file @
00bff491
package
com
.
topjohnwu
.
magisk
.
view
.
dialogs
;
import
android.app.Activity
;
import
android.content.Intent
;
import
android.widget.Toast
;
import
androidx.appcompat.app.AlertDialog
;
import
com.google.android.material.snackbar.Snackbar
;
import
com.topjohnwu.magisk.ClassMap
;
import
com.topjohnwu.magisk.Const
;
import
com.topjohnwu.magisk.Info
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.ui.base.IBaseLeanback
;
import
com.topjohnwu.magisk.ui.flash.FlashActivity
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.view.ProgressNotification
;
import
com.topjohnwu.magisk.view.SnackbarMaker
;
import
com.topjohnwu.net.Networking
;
import
java.io.File
;
import
java.util.List
;
class
InstallMethodDialog
extends
AlertDialog
.
Builder
{
<
Ctxt
extends
Activity
&
IBaseLeanback
>
InstallMethodDialog
(
Ctxt
activity
,
List
<
String
>
options
)
{
super
(
activity
);
setTitle
(
R
.
string
.
select_method
);
setItems
(
options
.
toArray
(
new
String
[
0
]),
(
dialog
,
idx
)
->
{
Intent
intent
;
switch
(
idx
)
{
case
1
:
patchBoot
(
activity
);
break
;
case
0
:
downloadOnly
(
activity
);
break
;
case
2
:
intent
=
new
Intent
(
activity
,
ClassMap
.
get
(
FlashActivity
.
class
))
.
putExtra
(
Const
.
Key
.
FLASH_ACTION
,
Const
.
Value
.
FLASH_MAGISK
);
activity
.
startActivity
(
intent
);
break
;
case
3
:
installInactiveSlot
(
activity
);
break
;
default
:
}
});
}
private
<
Ctxt
extends
Activity
&
IBaseLeanback
>
void
patchBoot
(
Ctxt
activity
)
{
activity
.
runWithExternalRW
(()
->
{
Utils
.
INSTANCE
.
toast
(
R
.
string
.
patch_file_msg
,
Toast
.
LENGTH_LONG
);
Intent
intent
=
new
Intent
(
Intent
.
ACTION_GET_CONTENT
)
.
setType
(
"*/*"
)
.
addCategory
(
Intent
.
CATEGORY_OPENABLE
);
activity
.
startActivityForResult
(
intent
,
Const
.
ID
.
SELECT_BOOT
,
(
resultCode
,
data
)
->
{
if
(
resultCode
==
Activity
.
RESULT_OK
&&
data
!=
null
)
{
Intent
i
=
new
Intent
(
activity
,
ClassMap
.
get
(
FlashActivity
.
class
))
.
setData
(
data
.
getData
())
.
putExtra
(
Const
.
Key
.
FLASH_ACTION
,
Const
.
Value
.
PATCH_FILE
);
activity
.
startActivity
(
i
);
}
});
});
}
private
<
Ctxt
extends
Activity
&
IBaseLeanback
>
void
downloadOnly
(
Ctxt
activity
)
{
activity
.
runWithExternalRW
(()
->
{
String
filename
=
Utils
.
INSTANCE
.
fmt
(
"Magisk-v%s(%d).zip"
,
Info
.
remoteMagiskVersionString
,
Info
.
remoteMagiskVersionCode
);
File
zip
=
new
File
(
Const
.
EXTERNAL_PATH
,
filename
);
ProgressNotification
progress
=
new
ProgressNotification
(
filename
);
Networking
.
get
(
Info
.
magiskLink
)
.
setDownloadProgressListener
(
progress
)
.
setErrorHandler
((
conn
,
e
)
->
progress
.
dlFail
())
.
getAsFile
(
zip
,
f
->
{
progress
.
dlDone
();
SnackbarMaker
.
make
(
activity
,
activity
.
getString
(
R
.
string
.
internal_storage
,
"/Download/"
+
filename
),
Snackbar
.
LENGTH_LONG
).
show
();
});
});
}
private
<
Ctxt
extends
Activity
&
IBaseLeanback
>
void
installInactiveSlot
(
Ctxt
activity
)
{
new
CustomAlertDialog
(
activity
)
.
setTitle
(
R
.
string
.
warning
)
.
setMessage
(
R
.
string
.
install_inactive_slot_msg
)
.
setCancelable
(
true
)
.
setPositiveButton
(
R
.
string
.
yes
,
(
d
,
i
)
->
{
Intent
intent
=
new
Intent
(
activity
,
ClassMap
.
get
(
FlashActivity
.
class
))
.
putExtra
(
Const
.
Key
.
FLASH_ACTION
,
Const
.
Value
.
FLASH_INACTIVE_SLOT
);
activity
.
startActivity
(
intent
);
})
.
setNegativeButton
(
R
.
string
.
no_thanks
,
null
)
.
show
();
}
}
app/src/main/java/com/topjohnwu/magisk/view/dialogs/InstallMethodDialog.kt
0 → 100644
View file @
326eee8c
package
com.topjohnwu.magisk.view.dialogs
import
android.app.Activity
import
android.content.Intent
import
android.widget.Toast
import
androidx.appcompat.app.AlertDialog
import
com.google.android.material.snackbar.Snackbar
import
com.topjohnwu.magisk.ClassMap
import
com.topjohnwu.magisk.Const
import
com.topjohnwu.magisk.Info
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.ui.base.MagiskActivity
import
com.topjohnwu.magisk.ui.flash.FlashActivity
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.view.ProgressNotification
import
com.topjohnwu.magisk.view.SnackbarMaker
import
com.topjohnwu.net.Networking
import
java.io.File
internal
class
InstallMethodDialog
(
activity
:
MagiskActivity
<
*
,
*
>,
options
:
List
<
String
>)
:
AlertDialog
.
Builder
(
activity
)
{
init
{
setTitle
(
R
.
string
.
select_method
)
setItems
(
options
.
toTypedArray
())
{
_
,
idx
->
when
(
idx
)
{
0
->
downloadOnly
(
activity
)
1
->
patchBoot
(
activity
)
2
->
{
val
intent
=
Intent
(
activity
,
ClassMap
[
FlashActivity
::
class
.
java
])
.
putExtra
(
Const
.
Key
.
FLASH_ACTION
,
Const
.
Value
.
FLASH_MAGISK
)
activity
.
startActivity
(
intent
)
}
3
->
installInactiveSlot
(
activity
)
}
}
}
private
fun
patchBoot
(
activity
:
MagiskActivity
<
*
,
*
>)
{
activity
.
withExternalRW
{
onSuccess
{
Utils
.
toast
(
R
.
string
.
patch_file_msg
,
Toast
.
LENGTH_LONG
)
val
intent
=
Intent
(
Intent
.
ACTION_GET_CONTENT
)
.
setType
(
"*/*"
)
.
addCategory
(
Intent
.
CATEGORY_OPENABLE
)
activity
.
startActivityForResult
(
intent
,
Const
.
ID
.
SELECT_BOOT
)
{
resultCode
,
data
->
if
(
resultCode
==
Activity
.
RESULT_OK
&&
data
!=
null
)
{
val
i
=
Intent
(
this
,
ClassMap
[
FlashActivity
::
class
.
java
])
.
setData
(
data
.
data
)
.
putExtra
(
Const
.
Key
.
FLASH_ACTION
,
Const
.
Value
.
PATCH_FILE
)
startActivity
(
i
)
}
}
}
}
}
private
fun
downloadOnly
(
activity
:
MagiskActivity
<
*
,
*
>)
{
activity
.
withExternalRW
{
onSuccess
{
val
filename
=
"Magisk-v${Info.remoteMagiskVersionString}"
+
"(${Info.remoteMagiskVersionCode}).zip"
val
zip
=
File
(
Const
.
EXTERNAL_PATH
,
filename
)
val
progress
=
ProgressNotification
(
filename
)
Networking
.
get
(
Info
.
magiskLink
)
.
setDownloadProgressListener
(
progress
)
.
setErrorHandler
{
_
,
_
->
progress
.
dlFail
()
}
.
getAsFile
(
zip
)
{
progress
.
dlDone
()
SnackbarMaker
.
make
(
activity
,
activity
.
getString
(
R
.
string
.
internal_storage
,
"/Download/$filename"
),
Snackbar
.
LENGTH_LONG
).
show
()
}
}
}
}
private
fun
installInactiveSlot
(
activity
:
MagiskActivity
<
*
,
*
>)
{
CustomAlertDialog
(
activity
)
.
setTitle
(
R
.
string
.
warning
)
.
setMessage
(
R
.
string
.
install_inactive_slot_msg
)
.
setCancelable
(
true
)
.
setPositiveButton
(
R
.
string
.
yes
)
{
_
,
_
->
val
intent
=
Intent
(
activity
,
ClassMap
[
FlashActivity
::
class
.
java
])
.
putExtra
(
Const
.
Key
.
FLASH_ACTION
,
Const
.
Value
.
FLASH_INACTIVE_SLOT
)
activity
.
startActivity
(
intent
)
}
.
setNegativeButton
(
R
.
string
.
no_thanks
,
null
)
.
show
()
}
}
app/src/main/java/com/topjohnwu/magisk/view/dialogs/MagiskInstallDialog.
java
→
app/src/main/java/com/topjohnwu/magisk/view/dialogs/MagiskInstallDialog.
kt
View file @
326eee8c
package
com
.
topjohnwu
.
magisk
.
view
.
dialogs
;
package
com.topjohnwu.magisk.view.dialogs
import
android.app.Activity
;
import
android.net.Uri
import
android.net.Uri
;
import
android.text.TextUtils
import
android.text.TextUtils
;
import
com.topjohnwu.magisk.Info
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.ui.base.MagiskActivity
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.view.MarkDownWindow
import
com.topjohnwu.superuser.Shell
import
com.topjohnwu.superuser.ShellUtils
import
java.util.*
import
com.topjohnwu.magisk.Info
;
class
MagiskInstallDialog
(
a
:
MagiskActivity
<
*
,
*
>)
:
CustomAlertDialog
(
a
)
{
import
com.topjohnwu.magisk.R
;
init
{
import
com.topjohnwu.magisk.ui.base.IBaseLeanback
;
val
filename
=
"Magisk v${Info.remoteMagiskVersionString}"
+
import
com.topjohnwu.magisk.utils.Utils
;
"(${Info.remoteMagiskVersionCode})"
import
com.topjohnwu.magisk.view.MarkDownWindow
;
setTitle
(
a
.
getString
(
R
.
string
.
repo_install_title
,
a
.
getString
(
R
.
string
.
magisk
)))
import
com.topjohnwu.superuser.Shell
;
setMessage
(
a
.
getString
(
R
.
string
.
repo_install_msg
,
filename
))
import
com.topjohnwu.superuser.ShellUtils
;
setCancelable
(
true
)
setPositiveButton
(
R
.
string
.
install
)
{
_
,
_
->
import
java.util.ArrayList
;
val
options
=
ArrayList
<
String
>()
import
java.util.List
;
options
.
add
(
a
.
getString
(
R
.
string
.
download_zip_only
))
options
.
add
(
a
.
getString
(
R
.
string
.
select_patch_file
))
public
class
MagiskInstallDialog
extends
CustomAlertDialog
{
public
<
Ctxt
extends
Activity
&
IBaseLeanback
>
MagiskInstallDialog
(
Ctxt
a
)
{
super
(
a
);
String
filename
=
Utils
.
INSTANCE
.
fmt
(
"Magisk-v%s(%d).zip"
,
Info
.
remoteMagiskVersionString
,
Info
.
remoteMagiskVersionCode
);
setTitle
(
a
.
getString
(
R
.
string
.
repo_install_title
,
a
.
getString
(
R
.
string
.
magisk
)));
setMessage
(
a
.
getString
(
R
.
string
.
repo_install_msg
,
filename
));
setCancelable
(
true
);
setPositiveButton
(
R
.
string
.
install
,
(
d
,
i
)
->
{
List
<
String
>
options
=
new
ArrayList
<>();
options
.
add
(
a
.
getString
(
R
.
string
.
download_zip_only
));
options
.
add
(
a
.
getString
(
R
.
string
.
select_patch_file
));
if
(
Shell
.
rootAccess
())
{
if
(
Shell
.
rootAccess
())
{
options
.
add
(
a
.
getString
(
R
.
string
.
direct_install
))
;
options
.
add
(
a
.
getString
(
R
.
string
.
direct_install
))
String
s
=
ShellUtils
.
fastCmd
(
"grep_prop ro.build.ab_update"
);
val
s
=
ShellUtils
.
fastCmd
(
"grep_prop ro.build.ab_update"
)
if
(
!
s
.
isEmpty
()
&&
Boolean
.
parseBoolean
(
s
))
{
if
(
s
.
isNotEmpty
()
&&
s
.
toBoolean
(
))
{
options
.
add
(
a
.
getString
(
R
.
string
.
install_inactive_slot
))
;
options
.
add
(
a
.
getString
(
R
.
string
.
install_inactive_slot
))
}
}
}
}
new
InstallMethodDialog
(
a
,
options
).
show
();
InstallMethodDialog
(
a
,
options
).
show
()
}
);
}
if
(!
TextUtils
.
isEmpty
(
Info
.
magiskNoteLink
))
{
if
(!
TextUtils
.
isEmpty
(
Info
.
magiskNoteLink
))
{
setNeutralButton
(
R
.
string
.
release_notes
,
(
d
,
i
)
->
{
setNeutralButton
(
R
.
string
.
release_notes
)
{
_
,
_
->
if
(
Info
.
magiskNoteLink
.
contains
(
"forum.xda-developers"
))
{
if
(
Info
.
magiskNoteLink
.
contains
(
"forum.xda-developers"
))
{
// Open forum links in browser
// Open forum links in browser
Utils
.
INSTANCE
.
openLink
(
a
,
Uri
.
parse
(
Info
.
magiskNoteLink
));
Utils
.
openLink
(
a
,
Uri
.
parse
(
Info
.
magiskNoteLink
))
}
else
{
}
else
{
MarkDownWindow
.
show
(
a
,
null
,
Info
.
magiskNoteLink
);
MarkDownWindow
.
show
(
a
,
null
,
Info
.
magiskNoteLink
)
}
}
}
});
}
}
}
}
}
}
app/src/main/java/com/topjohnwu/magisk/view/dialogs/ManagerInstallDialog.java
deleted
100644 → 0
View file @
00bff491
package
com
.
topjohnwu
.
magisk
.
view
.
dialogs
;
import
android.app.Activity
;
import
android.text.TextUtils
;
import
androidx.annotation.NonNull
;
import
com.topjohnwu.magisk.Info
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.utils.DownloadApp
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.view.MarkDownWindow
;
public
class
ManagerInstallDialog
extends
CustomAlertDialog
{
public
ManagerInstallDialog
(
@NonNull
Activity
a
)
{
super
(
a
);
String
name
=
Utils
.
INSTANCE
.
fmt
(
"MagiskManager v%s(%d)"
,
Info
.
remoteManagerVersionString
,
Info
.
remoteManagerVersionCode
);
setTitle
(
a
.
getString
(
R
.
string
.
repo_install_title
,
a
.
getString
(
R
.
string
.
app_name
)));
setMessage
(
a
.
getString
(
R
.
string
.
repo_install_msg
,
name
));
setCancelable
(
true
);
setPositiveButton
(
R
.
string
.
install
,
(
d
,
i
)
->
DownloadApp
.
upgrade
(
name
));
if
(!
TextUtils
.
isEmpty
(
Info
.
managerNoteLink
))
{
setNeutralButton
(
R
.
string
.
app_changelog
,
(
d
,
i
)
->
MarkDownWindow
.
show
(
a
,
null
,
Info
.
managerNoteLink
));
}
}
}
app/src/main/java/com/topjohnwu/magisk/view/dialogs/ManagerInstallDialog.kt
0 → 100644
View file @
326eee8c
package
com.topjohnwu.magisk.view.dialogs
import
android.app.Activity
import
com.topjohnwu.magisk.Info
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.utils.DownloadApp
import
com.topjohnwu.magisk.view.MarkDownWindow
class
ManagerInstallDialog
(
a
:
Activity
)
:
CustomAlertDialog
(
a
)
{
init
{
val
name
=
"MagiskManager v${Info.remoteManagerVersionString}"
+
"(${Info.remoteManagerVersionCode})"
setTitle
(
a
.
getString
(
R
.
string
.
repo_install_title
,
a
.
getString
(
R
.
string
.
app_name
)))
setMessage
(
a
.
getString
(
R
.
string
.
repo_install_msg
,
name
))
setCancelable
(
true
)
setPositiveButton
(
R
.
string
.
install
)
{
_
,
_
->
DownloadApp
.
upgrade
(
name
)
}
if
(
Info
.
managerNoteLink
.
isNotEmpty
())
{
setNeutralButton
(
R
.
string
.
app_changelog
)
{
_
,
_
->
MarkDownWindow
.
show
(
a
,
null
,
Info
.
managerNoteLink
)
}
}
}
}
app/src/main/java/com/topjohnwu/magisk/view/dialogs/UninstallDialog.java
deleted
100644 → 0
View file @
00bff491
package
com
.
topjohnwu
.
magisk
.
view
.
dialogs
;
import
android.app.Activity
;
import
android.app.ProgressDialog
;
import
android.content.Intent
;
import
android.net.Uri
;
import
android.text.TextUtils
;
import
android.widget.Toast
;
import
androidx.annotation.NonNull
;
import
com.topjohnwu.magisk.ClassMap
;
import
com.topjohnwu.magisk.Const
;
import
com.topjohnwu.magisk.Info
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.ui.flash.FlashActivity
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.view.ProgressNotification
;
import
com.topjohnwu.net.Networking
;
import
com.topjohnwu.superuser.Shell
;
import
java.io.File
;
public
class
UninstallDialog
extends
CustomAlertDialog
{
public
UninstallDialog
(
@NonNull
Activity
activity
)
{
super
(
activity
);
setTitle
(
R
.
string
.
uninstall_magisk_title
);
setMessage
(
R
.
string
.
uninstall_magisk_msg
);
setNeutralButton
(
R
.
string
.
restore_img
,
(
d
,
i
)
->
{
ProgressDialog
dialog
=
ProgressDialog
.
show
(
activity
,
activity
.
getString
(
R
.
string
.
restore_img
),
activity
.
getString
(
R
.
string
.
restore_img_msg
));
Shell
.
su
(
"restore_imgs"
).
submit
(
result
->
{
dialog
.
cancel
();
if
(
result
.
isSuccess
())
{
Utils
.
INSTANCE
.
toast
(
R
.
string
.
restore_done
,
Toast
.
LENGTH_SHORT
);
}
else
{
Utils
.
INSTANCE
.
toast
(
R
.
string
.
restore_fail
,
Toast
.
LENGTH_LONG
);
}
});
});
if
(!
TextUtils
.
isEmpty
(
Info
.
uninstallerLink
))
{
setPositiveButton
(
R
.
string
.
complete_uninstall
,
(
d
,
i
)
->
{
File
zip
=
new
File
(
activity
.
getFilesDir
(),
"uninstaller.zip"
);
ProgressNotification
progress
=
new
ProgressNotification
(
zip
.
getName
());
Networking
.
get
(
Info
.
uninstallerLink
)
.
setDownloadProgressListener
(
progress
)
.
setErrorHandler
(((
conn
,
e
)
->
progress
.
dlFail
()))
.
getAsFile
(
zip
,
f
->
{
progress
.
dismiss
();
Intent
intent
=
new
Intent
(
activity
,
ClassMap
.
get
(
FlashActivity
.
class
))
.
addFlags
(
Intent
.
FLAG_ACTIVITY_NEW_TASK
)
.
setData
(
Uri
.
fromFile
(
f
))
.
putExtra
(
Const
.
Key
.
FLASH_ACTION
,
Const
.
Value
.
UNINSTALL
);
activity
.
startActivity
(
intent
);
});
});
}
}
}
app/src/main/java/com/topjohnwu/magisk/view/dialogs/UninstallDialog.kt
0 → 100644
View file @
326eee8c
package
com.topjohnwu.magisk.view.dialogs
import
android.app.Activity
import
android.app.ProgressDialog
import
android.content.Intent
import
android.net.Uri
import
android.text.TextUtils
import
android.widget.Toast
import
com.topjohnwu.magisk.ClassMap
import
com.topjohnwu.magisk.Const
import
com.topjohnwu.magisk.Info
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.ui.flash.FlashActivity
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.view.ProgressNotification
import
com.topjohnwu.net.Networking
import
com.topjohnwu.superuser.Shell
import
java.io.File
class
UninstallDialog
(
activity
:
Activity
)
:
CustomAlertDialog
(
activity
)
{
init
{
setTitle
(
R
.
string
.
uninstall_magisk_title
)
setMessage
(
R
.
string
.
uninstall_magisk_msg
)
setNeutralButton
(
R
.
string
.
restore_img
)
{
_
,
_
->
val
dialog
=
ProgressDialog
.
show
(
activity
,
activity
.
getString
(
R
.
string
.
restore_img
),
activity
.
getString
(
R
.
string
.
restore_img_msg
))
Shell
.
su
(
"restore_imgs"
).
submit
{
result
->
dialog
.
cancel
()
if
(
result
.
isSuccess
)
{
Utils
.
toast
(
R
.
string
.
restore_done
,
Toast
.
LENGTH_SHORT
)
}
else
{
Utils
.
toast
(
R
.
string
.
restore_fail
,
Toast
.
LENGTH_LONG
)
}
}
}
if
(!
TextUtils
.
isEmpty
(
Info
.
uninstallerLink
))
{
setPositiveButton
(
R
.
string
.
complete_uninstall
)
{
d
,
i
->
val
zip
=
File
(
activity
.
filesDir
,
"uninstaller.zip"
)
val
progress
=
ProgressNotification
(
zip
.
name
)
Networking
.
get
(
Info
.
uninstallerLink
)
.
setDownloadProgressListener
(
progress
)
.
setErrorHandler
{
_
,
_
->
progress
.
dlFail
()
}
.
getAsFile
(
zip
)
{
f
->
progress
.
dismiss
()
val
intent
=
Intent
(
activity
,
ClassMap
[
FlashActivity
::
class
.
java
])
.
addFlags
(
Intent
.
FLAG_ACTIVITY_NEW_TASK
)
.
setData
(
Uri
.
fromFile
(
f
))
.
putExtra
(
Const
.
Key
.
FLASH_ACTION
,
Const
.
Value
.
UNINSTALL
)
activity
.
startActivity
(
intent
)
}
}
}
}
}
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