Support stub APK upgrades

This commit is contained in:
topjohnwu 2019-10-16 05:07:29 -04:00
parent 43bda2d4a4
commit a910c8ccd8
4 changed files with 31 additions and 8 deletions

View File

@ -7,6 +7,7 @@ import android.content.Intent
import android.os.Build import android.os.Build
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import com.topjohnwu.magisk.ProcessPhoenix
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.extensions.chooser import com.topjohnwu.magisk.extensions.chooser
import com.topjohnwu.magisk.extensions.exists import com.topjohnwu.magisk.extensions.exists
@ -18,6 +19,8 @@ import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.* import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.*
import com.topjohnwu.magisk.ui.flash.FlashActivity import com.topjohnwu.magisk.ui.flash.FlashActivity
import com.topjohnwu.magisk.utils.APKInstall import com.topjohnwu.magisk.utils.APKInstall
import com.topjohnwu.magisk.utils.DynAPK
import com.topjohnwu.magisk.utils.isRunningAsStub
import org.koin.core.get import org.koin.core.get
import java.io.File import java.io.File
import kotlin.random.Random.Default.nextInt import kotlin.random.Random.Default.nextInt
@ -62,8 +65,15 @@ open class DownloadService : RemoteFileService() {
) { ) {
remove(id) remove(id)
when (subject.configuration) { when (subject.configuration) {
is APK.Upgrade -> APKInstall.install(this, subject.file) is APK.Upgrade -> {
else -> Unit if (isRunningAsStub) {
subject.file.renameTo(DynAPK.update(this))
ProcessPhoenix.triggerRebirth(this)
} else {
APKInstall.install(this, subject.file)
}
}
is APK.Restore -> Unit
} }
} }

View File

@ -12,6 +12,7 @@ import com.topjohnwu.magisk.extensions.writeTo
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.* import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.*
import com.topjohnwu.magisk.utils.ProgressInputStream import com.topjohnwu.magisk.utils.ProgressInputStream
import com.topjohnwu.magisk.utils.isRunningAsStub
import com.topjohnwu.magisk.view.Notifications import com.topjohnwu.magisk.view.Notifications
import com.topjohnwu.superuser.ShellUtils import com.topjohnwu.superuser.ShellUtils
import io.reactivex.Completable import io.reactivex.Completable
@ -71,7 +72,7 @@ abstract class RemoteFileService : NotificationService() {
else -> Completable.fromAction { stream.writeTo(subject.file) } else -> Completable.fromAction { stream.writeTo(subject.file) }
} }
}.doOnComplete { }.doOnComplete {
if (subject is Manager) if (!isRunningAsStub && subject is Manager)
handleAPK(subject) handleAPK(subject)
} }

View File

@ -8,9 +8,19 @@ public class DynAPK {
private static File dynDir; private static File dynDir;
public static File current(Context context) { private static File getDynDir(Context c) {
if (dynDir == null) if (dynDir == null) {
dynDir = new File(context.getFilesDir().getParent(), "dyn"); dynDir = new File(c.getFilesDir().getParent(), "dyn");
return new File(dynDir, "current.apk"); dynDir.mkdir();
}
return dynDir;
}
public static File current(Context c) {
return new File(getDynDir(c), "current.apk");
}
public static File update(Context c) {
return new File(getDynDir(c), "update.apk");
} }
} }

View File

@ -37,7 +37,9 @@ public class DelegateApplication extends Application {
// If 9.0+, try to dynamically load the APK // If 9.0+, try to dynamically load the APK
DelegateComponentFactory factory = (DelegateComponentFactory) this.factory; DelegateComponentFactory factory = (DelegateComponentFactory) this.factory;
MANAGER_APK = DynAPK.current(this); MANAGER_APK = DynAPK.current(this);
MANAGER_APK.getParentFile().mkdir(); File update = DynAPK.update(this);
if (update.exists())
update.renameTo(MANAGER_APK);
if (MANAGER_APK.exists()) { if (MANAGER_APK.exists()) {
ClassLoader cl = new DynamicClassLoader(MANAGER_APK, factory.loader); ClassLoader cl = new DynamicClassLoader(MANAGER_APK, factory.loader);
try { try {