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
10f991b8
Commit
10f991b8
authored
Feb 03, 2022
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Directly stream APK into install session
parent
79620c97
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
67 additions
and
44 deletions
+67
-44
APKInstall.java
.../src/main/java/com/topjohnwu/magisk/utils/APKInstall.java
+51
-27
DownloadService.kt
...ava/com/topjohnwu/magisk/core/download/DownloadService.kt
+3
-3
ManagerHandler.kt
...java/com/topjohnwu/magisk/core/download/ManagerHandler.kt
+5
-2
Subject.kt
...c/main/java/com/topjohnwu/magisk/core/download/Subject.kt
+5
-9
HideAPK.kt
app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt
+2
-2
DownloadActivity.java
.../src/main/java/com/topjohnwu/magisk/DownloadActivity.java
+1
-1
No files found.
app/shared/src/main/java/com/topjohnwu/magisk/utils/APKInstall.java
View file @
10f991b8
...
@@ -18,9 +18,11 @@ import android.util.Log;
...
@@ -18,9 +18,11 @@ import android.util.Log;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileInputStream
;
import
java.io.FilterOutputStream
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.io.OutputStream
;
import
java.util.UUID
;
import
java.util.concurrent.CountDownLatch
;
import
java.util.concurrent.CountDownLatch
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeUnit
;
...
@@ -28,28 +30,50 @@ import io.michaelrocks.paranoid.Obfuscate;
...
@@ -28,28 +30,50 @@ import io.michaelrocks.paranoid.Obfuscate;
@Obfuscate
@Obfuscate
public
final
class
APKInstall
{
public
final
class
APKInstall
{
private
static
final
String
ACTION_SESSION_UPDATE
=
"ACTION_SESSION_UPDATE"
;
// @WorkerThread
// @WorkerThread
public
static
void
installapk
(
Context
context
,
File
apk
)
{
public
static
void
install
(
Context
context
,
File
apk
)
{
try
(
var
src
=
new
FileInputStream
(
apk
);
var
out
=
openStream
(
context
,
true
))
{
if
(
out
!=
null
)
transfer
(
src
,
out
);
}
catch
(
IOException
e
)
{
Log
.
e
(
APKInstall
.
class
.
getSimpleName
(),
""
,
e
);
}
}
public
static
OutputStream
openStream
(
Context
context
,
boolean
silent
)
{
//noinspection InlinedApi
//noinspection InlinedApi
var
flag
=
PendingIntent
.
FLAG_UPDATE_CURRENT
|
PendingIntent
.
FLAG_MUTABLE
;
var
flag
=
PendingIntent
.
FLAG_UPDATE_CURRENT
|
PendingIntent
.
FLAG_MUTABLE
;
var
action
=
APKInstall
.
class
.
getName
();
var
intent
=
new
Intent
(
ACTION_SESSION_UPDATE
).
setPackage
(
context
.
getPackageName
());
var
intent
=
new
Intent
(
action
).
setPackage
(
context
.
getPackageName
());
var
pending
=
PendingIntent
.
getBroadcast
(
context
,
0
,
intent
,
flag
);
var
pending
=
PendingIntent
.
getBroadcast
(
context
,
0
,
intent
,
flag
);
var
installer
=
context
.
getPackageManager
().
getPackageInstaller
();
var
installer
=
context
.
getPackageManager
().
getPackageInstaller
();
var
params
=
new
SessionParams
(
SessionParams
.
MODE_FULL_INSTALL
);
var
params
=
new
SessionParams
(
SessionParams
.
MODE_FULL_INSTALL
);
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
S
)
{
if
(
silent
&&
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
S
)
{
params
.
setRequireUserAction
(
SessionParams
.
USER_ACTION_NOT_REQUIRED
);
params
.
setRequireUserAction
(
SessionParams
.
USER_ACTION_NOT_REQUIRED
);
}
}
try
(
Session
session
=
installer
.
openSession
(
installer
.
createSession
(
params
)))
{
try
{
OutputStream
out
=
session
.
openWrite
(
apk
.
getName
(),
0
,
apk
.
length
());
Session
session
=
installer
.
openSession
(
installer
.
createSession
(
params
));
try
(
var
in
=
new
FileInputStream
(
apk
);
out
)
{
var
out
=
session
.
openWrite
(
UUID
.
randomUUID
().
toString
(),
0
,
-
1
);
transfer
(
in
,
out
);
return
new
FilterOutputStream
(
out
)
{
}
@Override
session
.
commit
(
pending
.
getIntentSender
());
public
void
write
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
out
.
write
(
b
,
off
,
len
);
}
@Override
public
void
close
()
throws
IOException
{
super
.
close
();
session
.
commit
(
pending
.
getIntentSender
());
session
.
close
();
}
};
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
Log
.
e
(
APKInstall
.
class
.
getSimpleName
(),
""
,
e
);
Log
.
e
(
APKInstall
.
class
.
getSimpleName
(),
""
,
e
);
}
}
return
null
;
}
}
public
static
void
transfer
(
InputStream
in
,
OutputStream
out
)
throws
IOException
{
public
static
void
transfer
(
InputStream
in
,
OutputStream
out
)
throws
IOException
{
...
@@ -62,46 +86,47 @@ public final class APKInstall {
...
@@ -62,46 +86,47 @@ public final class APKInstall {
}
}
public
static
InstallReceiver
register
(
Context
context
,
String
packageName
,
Runnable
onSuccess
)
{
public
static
InstallReceiver
register
(
Context
context
,
String
packageName
,
Runnable
onSuccess
)
{
var
receiver
=
new
InstallReceiver
(
context
,
packageName
,
onSuccess
);
var
receiver
=
new
InstallReceiver
(
packageName
,
onSuccess
);
var
filter
=
new
IntentFilter
(
Intent
.
ACTION_PACKAGE_ADDED
);
var
filter
=
new
IntentFilter
(
Intent
.
ACTION_PACKAGE_ADDED
);
filter
.
addDataScheme
(
"package"
);
filter
.
addDataScheme
(
"package"
);
context
.
registerReceiver
(
receiver
,
filter
);
context
.
registerReceiver
(
receiver
,
filter
);
context
.
registerReceiver
(
receiver
,
new
IntentFilter
(
A
PKInstall
.
class
.
getName
()
));
context
.
registerReceiver
(
receiver
,
new
IntentFilter
(
A
CTION_SESSION_UPDATE
));
return
receiver
;
return
receiver
;
}
}
public
static
class
InstallReceiver
extends
BroadcastReceiver
{
public
static
class
InstallReceiver
extends
BroadcastReceiver
{
private
final
Context
context
;
private
final
String
packageName
;
private
final
String
packageName
;
private
final
Runnable
onSuccess
;
private
final
Runnable
onSuccess
;
private
final
CountDownLatch
latch
=
new
CountDownLatch
(
1
);
private
final
CountDownLatch
latch
=
new
CountDownLatch
(
1
);
private
Intent
intent
=
null
;
private
Intent
userAction
=
null
;
private
InstallReceiver
(
Context
context
,
String
packageName
,
Runnable
onSuccess
)
{
private
InstallReceiver
(
String
packageName
,
Runnable
onSuccess
)
{
this
.
context
=
context
;
this
.
packageName
=
packageName
;
this
.
packageName
=
packageName
;
this
.
onSuccess
=
onSuccess
;
this
.
onSuccess
=
onSuccess
;
}
}
@Override
@Override
public
void
onReceive
(
Context
c
,
Intent
i
)
{
public
void
onReceive
(
Context
context
,
Intent
intent
)
{
if
(
Intent
.
ACTION_PACKAGE_ADDED
.
equals
(
i
.
getAction
()))
{
if
(
Intent
.
ACTION_PACKAGE_ADDED
.
equals
(
intent
.
getAction
()))
{
Uri
data
=
i
.
getData
();
Uri
data
=
intent
.
getData
();
if
(
data
==
null
||
onSuccess
==
null
)
return
;
if
(
data
==
null
)
return
;
String
pkg
=
data
.
getSchemeSpecificPart
();
String
pkg
=
data
.
getSchemeSpecificPart
();
if
(
pkg
.
equals
(
packageName
))
{
if
(
pkg
.
equals
(
packageName
))
{
onSuccess
.
run
();
if
(
onSuccess
!=
null
)
onSuccess
.
run
();
context
.
unregisterReceiver
(
this
);
context
.
unregisterReceiver
(
this
);
}
}
return
;
return
;
}
}
int
status
=
i
.
getIntExtra
(
EXTRA_STATUS
,
STATUS_FAILURE_INVALID
);
int
status
=
i
ntent
.
getIntExtra
(
EXTRA_STATUS
,
STATUS_FAILURE_INVALID
);
switch
(
status
)
{
switch
(
status
)
{
case
STATUS_PENDING_USER_ACTION:
case
STATUS_PENDING_USER_ACTION:
intent
=
i
.
getParcelableExtra
(
Intent
.
EXTRA_INTENT
);
userAction
=
intent
.
getParcelableExtra
(
Intent
.
EXTRA_INTENT
);
break
;
break
;
case
STATUS_SUCCESS:
case
STATUS_SUCCESS:
if
(
onSuccess
!=
null
)
onSuccess
.
run
();
if
(
onSuccess
!=
null
)
onSuccess
.
run
();
default
:
default
:
context
.
unregisterReceiver
(
this
);
context
.
unregisterReceiver
(
this
);
}
}
...
@@ -113,9 +138,8 @@ public final class APKInstall {
...
@@ -113,9 +138,8 @@ public final class APKInstall {
try
{
try
{
//noinspection ResultOfMethodCallIgnored
//noinspection ResultOfMethodCallIgnored
latch
.
await
(
5
,
TimeUnit
.
SECONDS
);
latch
.
await
(
5
,
TimeUnit
.
SECONDS
);
}
catch
(
Exception
ignored
)
{
}
catch
(
Exception
ignored
)
{}
}
return
userAction
;
return
intent
;
}
}
}
}
}
}
app/src/main/java/com/topjohnwu/magisk/core/download/DownloadService.kt
View file @
10f991b8
...
@@ -70,7 +70,7 @@ class DownloadService : BaseService() {
...
@@ -70,7 +70,7 @@ class DownloadService : BaseService() {
val
activity
=
ActivityTracker
.
foreground
val
activity
=
ActivityTracker
.
foreground
if
(
activity
!=
null
&&
subject
.
autoStart
)
{
if
(
activity
!=
null
&&
subject
.
autoStart
)
{
remove
(
subject
.
notifyId
)
remove
(
subject
.
notifyId
)
subject
.
pendingIntent
(
activity
).
send
()
subject
.
pendingIntent
(
activity
)
?
.
send
()
}
else
{
}
else
{
notifyFinish
(
subject
)
notifyFinish
(
subject
)
}
}
...
@@ -117,13 +117,13 @@ class DownloadService : BaseService() {
...
@@ -117,13 +117,13 @@ class DownloadService : BaseService() {
private
fun
notifyFinish
(
subject
:
Subject
)
=
finalNotify
(
subject
.
notifyId
)
{
private
fun
notifyFinish
(
subject
:
Subject
)
=
finalNotify
(
subject
.
notifyId
)
{
broadcast
(
1f
,
subject
)
broadcast
(
1f
,
subject
)
it
.
setContentIntent
(
subject
.
pendingIntent
(
this
))
it
.
setContentTitle
(
subject
.
title
)
.
setContentTitle
(
subject
.
title
)
.
setContentText
(
getString
(
R
.
string
.
download_complete
))
.
setContentText
(
getString
(
R
.
string
.
download_complete
))
.
setSmallIcon
(
android
.
R
.
drawable
.
stat_sys_download_done
)
.
setSmallIcon
(
android
.
R
.
drawable
.
stat_sys_download_done
)
.
setProgress
(
0
,
0
,
false
)
.
setProgress
(
0
,
0
,
false
)
.
setOngoing
(
false
)
.
setOngoing
(
false
)
.
setAutoCancel
(
true
)
.
setAutoCancel
(
true
)
subject
.
pendingIntent
(
this
)
?.
let
{
intent
->
it
.
setContentIntent
(
intent
)
}
}
}
private
fun
finalNotify
(
id
:
Int
,
editor
:
(
Notification
.
Builder
)
->
Unit
):
Int
{
private
fun
finalNotify
(
id
:
Int
,
editor
:
(
Notification
.
Builder
)
->
Unit
):
Int
{
...
...
app/src/main/java/com/topjohnwu/magisk/core/download/ManagerHandler.kt
View file @
10f991b8
...
@@ -10,6 +10,7 @@ import com.topjohnwu.magisk.core.tasks.HideAPK
...
@@ -10,6 +10,7 @@ import com.topjohnwu.magisk.core.tasks.HideAPK
import
com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import
com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import
com.topjohnwu.magisk.ktx.copyAndClose
import
com.topjohnwu.magisk.ktx.copyAndClose
import
com.topjohnwu.magisk.ktx.writeTo
import
com.topjohnwu.magisk.ktx.writeTo
import
com.topjohnwu.magisk.utils.APKInstall
import
java.io.File
import
java.io.File
import
java.io.InputStream
import
java.io.InputStream
import
java.io.OutputStream
import
java.io.OutputStream
...
@@ -57,8 +58,10 @@ suspend fun DownloadService.handleAPK(subject: Subject.Manager, stream: InputStr
...
@@ -57,8 +58,10 @@ suspend fun DownloadService.handleAPK(subject: Subject.Manager, stream: InputStr
}
else
{
}
else
{
val
clz
=
Info
.
stub
!!
.
classToComponent
[
"PHOENIX"
]
!!
val
clz
=
Info
.
stub
!!
.
classToComponent
[
"PHOENIX"
]
!!
PhoenixActivity
.
rebirth
(
this
,
clz
)
PhoenixActivity
.
rebirth
(
this
,
clz
)
return
}
}
}
else
{
write
(
subject
.
file
.
outputStream
())
}
}
val
receiver
=
APKInstall
.
register
(
this
,
null
,
null
)
write
(
APKInstall
.
openStream
(
this
,
false
))
subject
.
intent
=
receiver
.
waitIntent
()
}
}
app/src/main/java/com/topjohnwu/magisk/core/download/Subject.kt
View file @
10f991b8
...
@@ -6,7 +6,6 @@ import android.content.Context
...
@@ -6,7 +6,6 @@ import android.content.Context
import
android.content.Intent
import
android.content.Intent
import
android.net.Uri
import
android.net.Uri
import
android.os.Parcelable
import
android.os.Parcelable
import
androidx.core.net.toFile
import
androidx.core.net.toUri
import
androidx.core.net.toUri
import
com.topjohnwu.magisk.core.Info
import
com.topjohnwu.magisk.core.Info
import
com.topjohnwu.magisk.core.model.MagiskJson
import
com.topjohnwu.magisk.core.model.MagiskJson
...
@@ -16,7 +15,6 @@ import com.topjohnwu.magisk.core.utils.MediaStoreUtils
...
@@ -16,7 +15,6 @@ import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import
com.topjohnwu.magisk.di.AppContext
import
com.topjohnwu.magisk.di.AppContext
import
com.topjohnwu.magisk.ktx.cachedFile
import
com.topjohnwu.magisk.ktx.cachedFile
import
com.topjohnwu.magisk.ui.flash.FlashFragment
import
com.topjohnwu.magisk.ui.flash.FlashFragment
import
com.topjohnwu.magisk.utils.APKInstall
import
com.topjohnwu.magisk.view.Notifications
import
com.topjohnwu.magisk.view.Notifications
import
kotlinx.parcelize.IgnoredOnParcel
import
kotlinx.parcelize.IgnoredOnParcel
import
kotlinx.parcelize.Parcelize
import
kotlinx.parcelize.Parcelize
...
@@ -36,7 +34,7 @@ sealed class Subject : Parcelable {
...
@@ -36,7 +34,7 @@ sealed class Subject : Parcelable {
abstract
val
notifyId
:
Int
abstract
val
notifyId
:
Int
open
val
autoStart
:
Boolean
get
()
=
true
open
val
autoStart
:
Boolean
get
()
=
true
abstract
fun
pendingIntent
(
context
:
Context
):
PendingIntent
abstract
fun
pendingIntent
(
context
:
Context
):
PendingIntent
?
@Parcelize
@Parcelize
class
Module
(
class
Module
(
...
@@ -71,14 +69,12 @@ sealed class Subject : Parcelable {
...
@@ -71,14 +69,12 @@ sealed class Subject : Parcelable {
cachedFile
(
"manager.apk"
)
cachedFile
(
"manager.apk"
)
}
}
@IgnoredOnParcel
var
intent
:
Intent
?
=
null
val
externalFile
get
()
=
MediaStoreUtils
.
getFile
(
"$title.apk"
).
uri
val
externalFile
get
()
=
MediaStoreUtils
.
getFile
(
"$title.apk"
).
uri
override
fun
pendingIntent
(
context
:
Context
):
PendingIntent
{
override
fun
pendingIntent
(
context
:
Context
)
=
intent
?.
toPending
(
context
)
val
receiver
=
APKInstall
.
register
(
context
,
null
,
null
)
APKInstall
.
installapk
(
context
,
file
.
toFile
())
val
intent
=
receiver
.
waitIntent
()
?:
Intent
()
return
intent
.
toPending
(
context
)
}
}
}
@SuppressLint
(
"InlinedApi"
)
@SuppressLint
(
"InlinedApi"
)
...
...
app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt
View file @
10f991b8
...
@@ -125,7 +125,7 @@ object HideAPK {
...
@@ -125,7 +125,7 @@ object HideAPK {
}
}
val
cmd
=
"adb_pm_install $repack ${activity.applicationInfo.uid}"
val
cmd
=
"adb_pm_install $repack ${activity.applicationInfo.uid}"
if
(!
Shell
.
su
(
cmd
).
exec
().
isSuccess
)
{
if
(!
Shell
.
su
(
cmd
).
exec
().
isSuccess
)
{
APKInstall
.
install
apk
(
activity
,
repack
)
APKInstall
.
install
(
activity
,
repack
)
receiver
.
waitIntent
()
?.
let
{
activity
.
startActivity
(
it
)
}
receiver
.
waitIntent
()
?.
let
{
activity
.
startActivity
(
it
)
}
}
}
return
true
return
true
...
@@ -164,7 +164,7 @@ object HideAPK {
...
@@ -164,7 +164,7 @@ object HideAPK {
val
cmd
=
"adb_pm_install $apk ${activity.applicationInfo.uid}"
val
cmd
=
"adb_pm_install $apk ${activity.applicationInfo.uid}"
Shell
.
su
(
cmd
).
submit
(
Shell
.
EXECUTOR
)
{
ret
->
Shell
.
su
(
cmd
).
submit
(
Shell
.
EXECUTOR
)
{
ret
->
if
(
ret
.
isSuccess
)
return
@submit
if
(
ret
.
isSuccess
)
return
@submit
APKInstall
.
install
apk
(
activity
,
apk
)
APKInstall
.
install
(
activity
,
apk
)
receiver
.
waitIntent
()
?.
let
{
activity
.
startActivity
(
it
)
}
receiver
.
waitIntent
()
?.
let
{
activity
.
startActivity
(
it
)
}
}
}
}
}
...
...
stub/src/main/java/com/topjohnwu/magisk/DownloadActivity.java
View file @
10f991b8
...
@@ -119,7 +119,7 @@ public class DownloadActivity extends Activity {
...
@@ -119,7 +119,7 @@ public class DownloadActivity extends Activity {
runOnUiThread
(
onSuccess
);
runOnUiThread
(
onSuccess
);
}
else
{
}
else
{
var
receiver
=
APKInstall
.
register
(
this
,
BuildConfig
.
APPLICATION_ID
,
onSuccess
);
var
receiver
=
APKInstall
.
register
(
this
,
BuildConfig
.
APPLICATION_ID
,
onSuccess
);
APKInstall
.
install
apk
(
this
,
file
);
APKInstall
.
install
(
this
,
file
);
Intent
intent
=
receiver
.
waitIntent
();
Intent
intent
=
receiver
.
waitIntent
();
if
(
intent
!=
null
)
startActivity
(
intent
);
if
(
intent
!=
null
)
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