mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 10:35:26 +00:00
Drastically improve module download service
This commit is contained in:
parent
d9c58f307f
commit
6128c24f96
@ -33,7 +33,7 @@ public class App extends Application implements Application.ActivityLifecycleCal
|
|||||||
public SharedPreferences prefs;
|
public SharedPreferences prefs;
|
||||||
public MagiskDB mDB;
|
public MagiskDB mDB;
|
||||||
public RepoDatabaseHelper repoDB;
|
public RepoDatabaseHelper repoDB;
|
||||||
public BaseActivity foreground;
|
private volatile BaseActivity foreground;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Shell.Config.setFlags(Shell.FLAG_MOUNT_MASTER | Shell.FLAG_USE_MAGISK_BUSYBOX);
|
Shell.Config.setFlags(Shell.FLAG_MOUNT_MASTER | Shell.FLAG_USE_MAGISK_BUSYBOX);
|
||||||
@ -68,6 +68,10 @@ public class App extends Application implements Application.ActivityLifecycleCal
|
|||||||
LocaleManager.setLocale(this);
|
LocaleManager.setLocale(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BaseActivity foreground() {
|
||||||
|
return self.foreground;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {}
|
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {}
|
||||||
|
|
||||||
@ -75,12 +79,12 @@ public class App extends Application implements Application.ActivityLifecycleCal
|
|||||||
public void onActivityStarted(@NonNull Activity activity) {}
|
public void onActivityStarted(@NonNull Activity activity) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResumed(@NonNull Activity activity) {
|
public synchronized void onActivityResumed(@NonNull Activity activity) {
|
||||||
foreground = (BaseActivity) activity;
|
foreground = (BaseActivity) activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityPaused(@NonNull Activity activity) {
|
public synchronized void onActivityPaused(@NonNull Activity activity) {
|
||||||
foreground = null;
|
foreground = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
package com.topjohnwu.magisk.components;
|
package com.topjohnwu.magisk.components;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.topjohnwu.magisk.App;
|
||||||
import com.topjohnwu.magisk.ClassMap;
|
import com.topjohnwu.magisk.ClassMap;
|
||||||
import com.topjohnwu.magisk.Const;
|
import com.topjohnwu.magisk.Const;
|
||||||
import com.topjohnwu.magisk.FlashActivity;
|
import com.topjohnwu.magisk.FlashActivity;
|
||||||
import com.topjohnwu.magisk.R;
|
|
||||||
import com.topjohnwu.magisk.container.Repo;
|
import com.topjohnwu.magisk.container.Repo;
|
||||||
|
import com.topjohnwu.magisk.uicomponents.Notifications;
|
||||||
import com.topjohnwu.magisk.uicomponents.ProgressNotification;
|
import com.topjohnwu.magisk.uicomponents.ProgressNotification;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
|
||||||
import com.topjohnwu.net.Networking;
|
import com.topjohnwu.net.Networking;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
import com.topjohnwu.superuser.ShellUtils;
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
@ -25,13 +25,15 @@ import java.io.FileOutputStream;
|
|||||||
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.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
public class DownloadModuleService extends Service {
|
public class DownloadModuleService extends Service {
|
||||||
|
|
||||||
private boolean running = false;
|
private List<ProgressNotification> notifications;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
@ -39,46 +41,82 @@ public class DownloadModuleService extends Service {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
notifications = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
if (flags == 0 && running) {
|
|
||||||
Utils.toast(R.string.dl_one_module, Toast.LENGTH_LONG);
|
|
||||||
} else {
|
|
||||||
running = true;
|
|
||||||
Shell.EXECUTOR.execute(() -> {
|
Shell.EXECUTOR.execute(() -> {
|
||||||
Repo repo = intent.getParcelableExtra("repo");
|
Repo repo = intent.getParcelableExtra("repo");
|
||||||
boolean install = intent.getBooleanExtra("install", false);
|
boolean install = intent.getBooleanExtra("install", false);
|
||||||
dlProcessInstall(repo, install);
|
dlProcessInstall(repo, install);
|
||||||
stopSelf();
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
return START_REDELIVER_INTENT;
|
return START_REDELIVER_INTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void onTaskRemoved(Intent rootIntent) {
|
||||||
|
for (ProgressNotification n : notifications) {
|
||||||
|
Notifications.mgr.cancel(n.hashCode());
|
||||||
|
}
|
||||||
|
notifications.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void addNotification(ProgressNotification n) {
|
||||||
|
if (notifications.isEmpty()) {
|
||||||
|
// Start foreground
|
||||||
|
startForeground(n.hashCode(), n.getNotification());
|
||||||
|
}
|
||||||
|
notifications.add(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void removeNotification(ProgressNotification n) {
|
||||||
|
notifications.remove(n);
|
||||||
|
if (notifications.isEmpty()) {
|
||||||
|
// No more tasks, stop service
|
||||||
|
stopForeground(true);
|
||||||
|
stopSelf();
|
||||||
|
} else {
|
||||||
|
// Pick another notification as our foreground notification
|
||||||
|
n = notifications.get(0);
|
||||||
|
startForeground(n.hashCode(), n.getNotification());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void dlProcessInstall(Repo repo, boolean install) {
|
private void dlProcessInstall(Repo repo, boolean install) {
|
||||||
File output = new File(Const.EXTERNAL_PATH, repo.getDownloadFilename());
|
File output = new File(Const.EXTERNAL_PATH, repo.getDownloadFilename());
|
||||||
ProgressNotification progress = new ProgressNotification(output.getName());
|
ProgressNotification progress = new ProgressNotification(output.getName());
|
||||||
startForeground(progress.hashCode(), progress.getNotification());
|
addNotification(progress);
|
||||||
try {
|
try {
|
||||||
InputStream in = Networking.get(repo.getZipUrl())
|
InputStream in = Networking.get(repo.getZipUrl())
|
||||||
.setDownloadProgressListener(progress)
|
.setDownloadProgressListener(progress)
|
||||||
.execForInputStream().getResult();
|
.execForInputStream().getResult();
|
||||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(output));
|
OutputStream out = new BufferedOutputStream(new FileOutputStream(output));
|
||||||
processZip(in, out, repo.isNewInstaller());
|
processZip(in, out, repo.isNewInstaller());
|
||||||
if (install) {
|
|
||||||
progress.dismiss();
|
|
||||||
Intent intent = new Intent(this, ClassMap.get(FlashActivity.class));
|
Intent intent = new Intent(this, ClassMap.get(FlashActivity.class));
|
||||||
intent.setData(Uri.fromFile(output))
|
intent.setData(Uri.fromFile(output))
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
.putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP);
|
.putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP);
|
||||||
startActivity(intent);
|
synchronized (getApplication()) {
|
||||||
|
if (install && App.foreground() != null &&
|
||||||
|
!(App.foreground() instanceof FlashActivity)) {
|
||||||
|
/* Only start flashing if there is a foreground activity and the
|
||||||
|
* user is not also flashing another module at the same time */
|
||||||
|
App.foreground().startActivity(intent);
|
||||||
} else {
|
} else {
|
||||||
progress.dlDone();
|
/* Or else we preset a notification notifying that we are done */
|
||||||
|
PendingIntent pi = PendingIntent.getActivity(this, progress.hashCode(), intent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
progress.dlDone(pi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
progress.dlFail();
|
progress.dlFail();
|
||||||
}
|
}
|
||||||
|
removeNotification(progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processZip(InputStream in, OutputStream out, boolean inject)
|
private void processZip(InputStream in, OutputStream out, boolean inject)
|
||||||
|
@ -15,7 +15,7 @@ public class UpdateCheckService extends DelegateWorker {
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public ListenableWorker.Result doWork() {
|
public ListenableWorker.Result doWork() {
|
||||||
if (App.self.foreground == null) {
|
if (App.foreground() == null) {
|
||||||
Shell.getShell();
|
Shell.getShell();
|
||||||
CheckUpdates.check(this::onCheckDone);
|
CheckUpdates.check(this::onCheckDone);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.topjohnwu.magisk.uicomponents;
|
package com.topjohnwu.magisk.uicomponents;
|
||||||
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Intent;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
@ -55,10 +57,17 @@ public class ProgressNotification implements DownloadProgressListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void dlDone() {
|
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)
|
builder.setProgress(0, 0, false)
|
||||||
.setContentText(App.self.getString(R.string.download_complete))
|
.setContentText(App.self.getString(R.string.download_complete))
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||||
.setOngoing(false);
|
.setContentIntent(intent)
|
||||||
|
.setOngoing(false)
|
||||||
|
.setAutoCancel(true);
|
||||||
lastUpdate();
|
lastUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user