diff --git a/app/build.gradle b/app/build.gradle
index 882747298..f07c05e8b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -81,6 +81,7 @@ dependencies {
fullImplementation "androidx.recyclerview:recyclerview:${rootProject.ext.androidXVersion}"
fullImplementation "androidx.cardview:cardview:${rootProject.ext.androidXVersion}"
fullImplementation "com.google.android.material:material:${rootProject.ext.androidXVersion}"
+ fullImplementation 'android.arch.work:work-runtime:1.0.0-beta01'
fullImplementation 'com.github.topjohnwu:libsu:2.1.2'
fullImplementation 'org.kamranzafar:jtar:2.3'
fullImplementation 'ru.noties:markwon:2.0.1'
diff --git a/app/src/full/AndroidManifest.xml b/app/src/full/AndroidManifest.xml
index 95bc21e6d..dae10ff4c 100644
--- a/app/src/full/AndroidManifest.xml
+++ b/app/src/full/AndroidManifest.xml
@@ -75,10 +75,6 @@
android:name="a.j"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />
-
{
+ /* Stub */
+ public g(@NonNull Context context, @NonNull WorkerParameters workerParams) {
+ super(context, workerParams);
+ }
+}
diff --git a/app/src/full/java/a/k.java b/app/src/full/java/a/k.java
deleted file mode 100644
index f29cb69be..000000000
--- a/app/src/full/java/a/k.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package a;
-
-import com.topjohnwu.magisk.services.UpdateCheckService;
-
-public class k extends UpdateCheckService {
- /* stub */
-}
diff --git a/app/src/full/java/a/w.java b/app/src/full/java/a/w.java
new file mode 100644
index 000000000..3b8b94fa9
--- /dev/null
+++ b/app/src/full/java/a/w.java
@@ -0,0 +1,35 @@
+package a;
+
+import android.content.Context;
+
+import com.topjohnwu.magisk.services.DelegateWorker;
+
+import java.lang.reflect.ParameterizedType;
+
+import androidx.annotation.NonNull;
+import androidx.work.Worker;
+import androidx.work.WorkerParameters;
+
+public class w extends Worker {
+
+ /* Wrapper class to workaround Proguard -keep class * extends Worker */
+
+ private T base;
+
+ @SuppressWarnings("unchecked")
+ w(@NonNull Context context, @NonNull WorkerParameters workerParams) {
+ super(context, workerParams);
+ try {
+ base = ((Class) ((ParameterizedType) getClass().getGenericSuperclass())
+ .getActualTypeArguments()[0]).newInstance();
+ } catch (IllegalAccessException | InstantiationException ignored) {}
+ }
+
+ @NonNull
+ @Override
+ public Result doWork() {
+ if (base == null)
+ return Result.failure();
+ return base.doWork();
+ }
+}
diff --git a/app/src/full/java/com/topjohnwu/magisk/ClassMap.java b/app/src/full/java/com/topjohnwu/magisk/ClassMap.java
index 580f2af63..b77dc36b3 100644
--- a/app/src/full/java/com/topjohnwu/magisk/ClassMap.java
+++ b/app/src/full/java/com/topjohnwu/magisk/ClassMap.java
@@ -20,15 +20,15 @@ public class ClassMap {
classMap.put(AboutActivity.class, a.d.class);
classMap.put(DonationActivity.class, a.e.class);
classMap.put(FlashActivity.class, a.f.class);
+ classMap.put(UpdateCheckService.class, a.g.class);
classMap.put(GeneralReceiver.class, a.h.class);
classMap.put(ShortcutReceiver.class, a.i.class);
classMap.put(OnBootService.class, a.j.class);
- classMap.put(UpdateCheckService.class, a.k.class);
classMap.put(AboutCardRow.class, a.l.class);
classMap.put(SuRequestActivity.class, a.m.class);
}
- public static Class get(Class c) {
+ public static Class get(Class c) {
return classMap.get(c);
}
}
diff --git a/app/src/full/java/com/topjohnwu/magisk/SplashActivity.java b/app/src/full/java/com/topjohnwu/magisk/SplashActivity.java
index efeca53b2..9e4b2978a 100644
--- a/app/src/full/java/com/topjohnwu/magisk/SplashActivity.java
+++ b/app/src/full/java/com/topjohnwu/magisk/SplashActivity.java
@@ -42,8 +42,6 @@ public class SplashActivity extends BaseActivity {
// Magisk working as expected
if (Shell.rootAccess() && Data.magiskVersionCode > 0) {
- // Update check service
- AppUtils.setupUpdateCheck();
// Load modules
Utils.loadModules();
}
@@ -53,6 +51,9 @@ public class SplashActivity extends BaseActivity {
// Create notification channel on Android O
Notifications.setup(this);
+ // Schedule periodic update checks
+ AppUtils.scheduleUpdateCheck();
+
// Setup shortcuts
sendBroadcast(new Intent(this, ClassMap.get(ShortcutReceiver.class)));
diff --git a/app/src/full/java/com/topjohnwu/magisk/fragments/SettingsFragment.java b/app/src/full/java/com/topjohnwu/magisk/fragments/SettingsFragment.java
index 84ef33fd4..641a1c406 100644
--- a/app/src/full/java/com/topjohnwu/magisk/fragments/SettingsFragment.java
+++ b/app/src/full/java/com/topjohnwu/magisk/fragments/SettingsFragment.java
@@ -252,7 +252,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
CheckUpdates.check();
break;
case Const.Key.CHECK_UPDATES:
- AppUtils.setupUpdateCheck();
+ AppUtils.scheduleUpdateCheck();
break;
}
Data.loadConfig();
diff --git a/app/src/full/java/com/topjohnwu/magisk/services/DelegateWorker.java b/app/src/full/java/com/topjohnwu/magisk/services/DelegateWorker.java
new file mode 100644
index 000000000..4637a372e
--- /dev/null
+++ b/app/src/full/java/com/topjohnwu/magisk/services/DelegateWorker.java
@@ -0,0 +1,9 @@
+package com.topjohnwu.magisk.services;
+
+import androidx.annotation.NonNull;
+import androidx.work.ListenableWorker;
+
+public abstract class DelegateWorker {
+ @NonNull
+ public abstract ListenableWorker.Result doWork();
+}
diff --git a/app/src/full/java/com/topjohnwu/magisk/services/UpdateCheckService.java b/app/src/full/java/com/topjohnwu/magisk/services/UpdateCheckService.java
index 620f91f05..c23457fb3 100644
--- a/app/src/full/java/com/topjohnwu/magisk/services/UpdateCheckService.java
+++ b/app/src/full/java/com/topjohnwu/magisk/services/UpdateCheckService.java
@@ -1,32 +1,29 @@
package com.topjohnwu.magisk.services;
-import android.app.job.JobParameters;
-import android.app.job.JobService;
-
import com.topjohnwu.core.Data;
import com.topjohnwu.core.tasks.CheckUpdates;
import com.topjohnwu.magisk.BuildConfig;
import com.topjohnwu.magisk.components.Notifications;
import com.topjohnwu.superuser.Shell;
-public class UpdateCheckService extends JobService {
+import androidx.annotation.NonNull;
+import androidx.work.ListenableWorker;
+public class UpdateCheckService extends DelegateWorker {
+
+ @NonNull
@Override
- public boolean onStartJob(JobParameters params) {
+ public ListenableWorker.Result doWork() {
Shell.getShell();
- CheckUpdates.check(() -> {
- if (BuildConfig.VERSION_CODE < Data.remoteManagerVersionCode) {
- Notifications.managerUpdate();
- } else if (Data.magiskVersionCode < Data.remoteMagiskVersionCode) {
- Notifications.magiskUpdate();
- }
- jobFinished(params, false);
- });
- return true;
+ CheckUpdates.checkNow(this::onCheckDone);
+ return ListenableWorker.Result.success();
}
- @Override
- public boolean onStopJob(JobParameters params) {
- return true;
+ private void onCheckDone() {
+ if (BuildConfig.VERSION_CODE < Data.remoteManagerVersionCode) {
+ Notifications.managerUpdate();
+ } else if (Data.magiskVersionCode < Data.remoteMagiskVersionCode) {
+ Notifications.magiskUpdate();
+ }
}
}
diff --git a/app/src/full/java/com/topjohnwu/magisk/utils/AppUtils.java b/app/src/full/java/com/topjohnwu/magisk/utils/AppUtils.java
index 1bd572fb9..a38a550fe 100644
--- a/app/src/full/java/com/topjohnwu/magisk/utils/AppUtils.java
+++ b/app/src/full/java/com/topjohnwu/magisk/utils/AppUtils.java
@@ -1,8 +1,5 @@
package com.topjohnwu.magisk.utils;
-import android.app.job.JobInfo;
-import android.app.job.JobScheduler;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
@@ -15,25 +12,29 @@ import com.topjohnwu.magisk.ClassMap;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.services.UpdateCheckService;
+import java.util.concurrent.TimeUnit;
+
+import androidx.work.Constraints;
+import androidx.work.ExistingPeriodicWorkPolicy;
+import androidx.work.NetworkType;
+import androidx.work.PeriodicWorkRequest;
+import androidx.work.WorkManager;
+
public class AppUtils {
- public static void setupUpdateCheck() {
- App app = App.self;
- JobScheduler scheduler = (JobScheduler) app.getSystemService(Context.JOB_SCHEDULER_SERVICE);
-
- if (app.prefs.getBoolean(Const.Key.CHECK_UPDATES, true)) {
- if (scheduler.getAllPendingJobs().isEmpty() ||
- Const.UPDATE_SERVICE_VER > app.prefs.getInt(Const.Key.UPDATE_SERVICE_VER, -1)) {
- ComponentName service = new ComponentName(app, ClassMap.get(UpdateCheckService.class));
- JobInfo info = new JobInfo.Builder(Const.ID.UPDATE_SERVICE_ID, service)
- .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
- .setPersisted(true)
- .setPeriodic(8 * 60 * 60 * 1000)
- .build();
- scheduler.schedule(info);
- }
+ public static void scheduleUpdateCheck() {
+ if (App.self.prefs.getBoolean(Const.Key.CHECK_UPDATES, true)) {
+ Constraints constraints = new Constraints.Builder()
+ .setRequiredNetworkType(NetworkType.CONNECTED)
+ .build();
+ PeriodicWorkRequest request = new PeriodicWorkRequest
+ .Builder(ClassMap.get(UpdateCheckService.class), 12, TimeUnit.HOURS)
+ .setConstraints(constraints)
+ .build();
+ WorkManager.getInstance().enqueueUniquePeriodicWork(Const.ID.CHECK_MAGISK_UPDATE_WORKER_ID,
+ ExistingPeriodicWorkPolicy.REPLACE, request);
} else {
- scheduler.cancel(Const.UPDATE_SERVICE_VER);
+ WorkManager.getInstance().cancelUniqueWork(Const.ID.CHECK_MAGISK_UPDATE_WORKER_ID);
}
}
diff --git a/core/src/main/java/com/topjohnwu/core/Const.java b/core/src/main/java/com/topjohnwu/core/Const.java
index 16544a635..492bebcc1 100644
--- a/core/src/main/java/com/topjohnwu/core/Const.java
+++ b/core/src/main/java/com/topjohnwu/core/Const.java
@@ -62,6 +62,7 @@ public class Const {
public static final int HIDE_MANAGER_NOTIFICATION_ID = 8;
public static final String UPDATE_NOTIFICATION_CHANNEL = "update";
public static final String PROGRESS_NOTIFICATION_CHANNEL = "progress";
+ public static final String CHECK_MAGISK_UPDATE_WORKER_ID = "magisk_update";
}
public static class Url {
diff --git a/core/src/main/java/com/topjohnwu/core/tasks/CheckUpdates.java b/core/src/main/java/com/topjohnwu/core/tasks/CheckUpdates.java
index 8d43c836f..4839e08e4 100644
--- a/core/src/main/java/com/topjohnwu/core/tasks/CheckUpdates.java
+++ b/core/src/main/java/com/topjohnwu/core/tasks/CheckUpdates.java
@@ -5,6 +5,7 @@ import com.topjohnwu.core.Const;
import com.topjohnwu.core.Data;
import com.topjohnwu.core.utils.Topic;
import com.topjohnwu.net.Networking;
+import com.topjohnwu.net.Request;
import com.topjohnwu.net.ResponseListener;
import org.json.JSONException;
@@ -40,26 +41,31 @@ public class CheckUpdates {
}
}
- public static void check(Runnable cb) {
+ private static Request getRequest() {
String url;
switch (Data.updateChannel) {
- case Const.Value.STABLE_CHANNEL:
- url = Const.Url.STABLE_URL;
- break;
case Const.Value.BETA_CHANNEL:
url = Const.Url.BETA_URL;
break;
case Const.Value.CUSTOM_CHANNEL:
url = App.self.prefs.getString(Const.Key.CUSTOM_CHANNEL, "");
break;
+ case Const.Value.STABLE_CHANNEL:
default:
- return;
+ url = Const.Url.STABLE_URL;
+ break;
}
- Networking.get(url).getAsJSONObject(new UpdateListener(cb));
+ return Networking.get(url);
}
public static void check() {
- check(null);
+ getRequest().getAsJSONObject(new UpdateListener(null));
+ }
+
+ public static void checkNow(Runnable cb) {
+ JSONObject json = getRequest().execForJSONObject().getResult();
+ if (json != null)
+ new UpdateListener(cb).onResponse(json);
}
private static class UpdateListener implements ResponseListener {