From ce5b13824eb307d07450fbbeb1c24763437e267f Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Mon, 6 Nov 2017 04:47:24 +0800 Subject: [PATCH] Organize application initialization --- .../com/topjohnwu/magisk/MagiskFragment.java | 2 +- .../com/topjohnwu/magisk/MagiskManager.java | 141 +----------------- .../com/topjohnwu/magisk/MainActivity.java | 18 ++- .../com/topjohnwu/magisk/SplashActivity.java | 129 +++++++++++++++- .../magisk/asyncs/DownloadBusybox.java | 52 ------- .../magisk/services/UpdateCheckService.java | 2 +- .../com/topjohnwu/magisk/utils/Const.java | 2 - 7 files changed, 146 insertions(+), 200 deletions(-) delete mode 100644 app/src/main/java/com/topjohnwu/magisk/asyncs/DownloadBusybox.java diff --git a/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java b/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java index 7d62e0566..8c3a504ed 100644 --- a/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java @@ -159,7 +159,7 @@ public class MagiskFragment extends Fragment @Override public void onRefresh() { - mm.getMagiskInfo(); + mm.loadMagiskInfo(); updateUI(); magiskUpdateText.setText(R.string.checking_for_updates); diff --git a/app/src/main/java/com/topjohnwu/magisk/MagiskManager.java b/app/src/main/java/com/topjohnwu/magisk/MagiskManager.java index bca9b329a..71cf3f6b3 100644 --- a/app/src/main/java/com/topjohnwu/magisk/MagiskManager.java +++ b/app/src/main/java/com/topjohnwu/magisk/MagiskManager.java @@ -1,43 +1,26 @@ package com.topjohnwu.magisk; -import android.annotation.SuppressLint; import android.app.Application; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.job.JobInfo; -import android.app.job.JobScheduler; -import android.content.ComponentName; -import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; -import android.os.Build; import android.os.Handler; import android.preference.PreferenceManager; import android.widget.Toast; -import com.topjohnwu.magisk.asyncs.CheckUpdates; -import com.topjohnwu.magisk.asyncs.DownloadBusybox; -import com.topjohnwu.magisk.asyncs.LoadModules; -import com.topjohnwu.magisk.asyncs.ParallelTask; -import com.topjohnwu.magisk.asyncs.UpdateRepos; import com.topjohnwu.magisk.container.Module; import com.topjohnwu.magisk.database.RepoDatabaseHelper; import com.topjohnwu.magisk.database.SuDatabaseHelper; -import com.topjohnwu.magisk.services.UpdateCheckService; import com.topjohnwu.magisk.utils.Const; import com.topjohnwu.magisk.utils.Shell; import com.topjohnwu.magisk.utils.Topic; import com.topjohnwu.magisk.utils.Utils; -import java.io.IOException; -import java.io.InputStream; import java.lang.ref.WeakReference; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.concurrent.ExecutionException; public class MagiskManager extends Application { @@ -54,6 +37,7 @@ public class MagiskManager extends Application { public final Topic localeDone = new Topic(); // Info + public boolean hasInit = false; public int userId; public String magiskVersionString; public int magiskVersionCode = -1; @@ -102,7 +86,6 @@ public class MagiskManager extends Application { public Shell shell; private static Handler mHandler = new Handler(); - private boolean started = false; public MagiskManager() { weakSelf = new WeakReference<>(this); @@ -180,127 +163,7 @@ public class MagiskManager extends Application { mHandler.post(() -> Toast.makeText(weakSelf.get(), resId, duration).show()); } - @SuppressLint("StaticFieldLeak") - public void startup() { - if (started) - return; - started = true; - - // Dynamic detect all locales - new ParallelTask() { - @Override - protected Void doInBackground(Void... voids) { - locales = Utils.getAvailableLocale(); - return null; - } - @Override - protected void onPostExecute(Void aVoid) { - localeDone.publish(); - } - }.exec(); - - // Create notification channel on Android O - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel channel = new NotificationChannel(Const.ID.NOTIFICATION_CHANNEL, - getString(R.string.magisk_updates), NotificationManager.IMPORTANCE_DEFAULT); - getSystemService(NotificationManager.class).createNotificationChannel(channel); - } - - getMagiskInfo(); - - // Magisk working as expected - if (Shell.rootAccess() && magiskVersionCode > 0) { - // Load utility shell scripts - try (InputStream in = getAssets().open(Const.UTIL_FUNCTIONS)) { - shell.loadInputStream(in); - } catch (IOException e) { - e.printStackTrace(); - } - - LoadModules loadModuleTask = new LoadModules(); - - if (Utils.checkNetworkStatus()) { - // Make sure we have busybox - if (!Utils.itemExist(Const.BUSYBOXPATH + "/busybox")) { - try { - // Force synchronous, make sure we have busybox to use - new DownloadBusybox().exec().get(); - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); - } - } - - // Fire update check - new CheckUpdates().exec(); - - // Add repo update check - loadModuleTask.setCallBack(() -> new UpdateRepos(false).exec()); - } - - // Root shell initialization - Shell.su_raw( - "export PATH=" + Const.BUSYBOXPATH + ":$PATH", - "mount_partitions", - "BOOTIMAGE=", - "find_boot_image", - "migrate_boot_backup" - ); - List ret = Shell.su("echo \"$BOOTIMAGE\""); - if (Utils.isValidShellResponse(ret)) { - bootBlock = ret.get(0); - } else { - blockList = Shell.su("find /dev/block -type b | grep -vE 'dm|ram|loop'"); - } - - // Setup suDB - SuDatabaseHelper.setupSuDB(); - - // Check alternative Magisk Manager - String pkg; - if (getPackageName().equals(Const.ORIG_PKG_NAME) && - (pkg = suDB.getStrings(Const.Key.SU_REQUESTER, null)) != null) { - Shell.su_raw("pm uninstall " + pkg); - suDB.setStrings(Const.Key.SU_REQUESTER, null); - } - - // Add update checking service - if (Const.Value.UPDATE_SERVICE_VER > updateServiceVersion) { - ComponentName service = new ComponentName(this, 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(); - ((JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE)).schedule(info); - updateServiceVersion = Const.Value.UPDATE_SERVICE_VER; - } - - // Fire asynctasks - loadModuleTask.exec(); - } - - // Write back default values - prefs.edit() - .putBoolean(Const.Key.DARK_THEME, isDarkTheme) - .putBoolean(Const.Key.MAGISKHIDE, magiskHide) - .putBoolean(Const.Key.UPDATE_NOTIFICATION, updateNotification) - .putBoolean(Const.Key.HOSTS, Utils.itemExist(Const.MAGISK_HOST_FILE)) - .putBoolean(Const.Key.DISABLE, Utils.itemExist(Const.MAGISK_DISABLE_FILE)) - .putBoolean(Const.Key.SU_REAUTH, suReauth) - .putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(suRequestTimeout)) - .putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(suResponseType)) - .putString(Const.Key.SU_NOTIFICATION, String.valueOf(suNotificationType)) - .putString(Const.Key.ROOT_ACCESS, String.valueOf(suAccessState)) - .putString(Const.Key.SU_MULTIUSER_MODE, String.valueOf(multiuserMode)) - .putString(Const.Key.SU_MNT_NS, String.valueOf(suNamespaceMode)) - .putString(Const.Key.UPDATE_CHANNEL, String.valueOf(updateChannel)) - .putString(Const.Key.LOCALE, localeConfig) - .putString(Const.Key.BOOT_FORMAT, bootFormat) - .putInt(Const.Key.UPDATE_SERVICE_VER, updateServiceVersion) - .apply(); - } - - public void getMagiskInfo() { + public void loadMagiskInfo() { List ret; ret = Shell.sh("su -v"); if (Utils.isValidShellResponse(ret)) { diff --git a/app/src/main/java/com/topjohnwu/magisk/MainActivity.java b/app/src/main/java/com/topjohnwu/magisk/MainActivity.java index ee3d98bac..a9a5d4a43 100644 --- a/app/src/main/java/com/topjohnwu/magisk/MainActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/MainActivity.java @@ -39,11 +39,22 @@ public class MainActivity extends Activity @Override protected void onCreate(final Bundle savedInstanceState) { - getMagiskManager().startup(); - prefs = getMagiskManager().prefs; + MagiskManager mm = getMagiskManager(); - if (getMagiskManager().isDarkTheme) { + if (!mm.hasInit) { + Intent intent = new Intent(this, SplashActivity.class); + String section = getIntent().getStringExtra(Const.Key.OPEN_SECTION); + if (section != null) { + intent.putExtra(Const.Key.OPEN_SECTION, section); + } + startActivity(intent); + finish(); + } + + prefs = mm.prefs; + + if (mm.isDarkTheme) { setTheme(R.style.AppTheme_Dark); } super.onCreate(savedInstanceState); @@ -74,7 +85,6 @@ public class MainActivity extends Activity navigate(getIntent().getStringExtra(Const.Key.OPEN_SECTION)); navigationView.setNavigationItemSelectedListener(this); - } @Override diff --git a/app/src/main/java/com/topjohnwu/magisk/SplashActivity.java b/app/src/main/java/com/topjohnwu/magisk/SplashActivity.java index 8d27ff438..349462931 100644 --- a/app/src/main/java/com/topjohnwu/magisk/SplashActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/SplashActivity.java @@ -1,10 +1,29 @@ package com.topjohnwu.magisk; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.job.JobInfo; +import android.app.job.JobScheduler; +import android.content.ComponentName; +import android.content.Context; import android.content.Intent; +import android.os.Build; import android.os.Bundle; +import com.topjohnwu.magisk.asyncs.CheckUpdates; +import com.topjohnwu.magisk.asyncs.LoadModules; +import com.topjohnwu.magisk.asyncs.ParallelTask; +import com.topjohnwu.magisk.asyncs.UpdateRepos; import com.topjohnwu.magisk.components.Activity; +import com.topjohnwu.magisk.database.SuDatabaseHelper; +import com.topjohnwu.magisk.services.UpdateCheckService; import com.topjohnwu.magisk.utils.Const; +import com.topjohnwu.magisk.utils.Shell; +import com.topjohnwu.magisk.utils.Utils; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; public class SplashActivity extends Activity { @@ -12,7 +31,103 @@ public class SplashActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - getMagiskManager().startup(); + MagiskManager mm = getMagiskManager(); + + // Dynamic detect all locales + new LoadLocale().exec(); + + // Create notification channel on Android O + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel channel = new NotificationChannel(Const.ID.NOTIFICATION_CHANNEL, + getString(R.string.magisk_updates), NotificationManager.IMPORTANCE_DEFAULT); + getSystemService(NotificationManager.class).createNotificationChannel(channel); + } + + mm.loadMagiskInfo(); + LoadModules loadModuleTask = new LoadModules(); + + if (Utils.checkNetworkStatus()) { + + // Fire update check + new CheckUpdates().exec(); + + // Add repo update check + loadModuleTask.setCallBack(() -> new UpdateRepos(false).exec()); + } + + // Magisk working as expected + if (Shell.rootAccess() && mm.magiskVersionCode > 0) { + // Load utility shell scripts + try (InputStream in = getAssets().open(Const.UTIL_FUNCTIONS)) { + Shell.getShell().loadInputStream(in); + } catch (IOException e) { + e.printStackTrace(); + } + + // Root shell initialization + Shell.su_raw( + "export PATH=" + Const.BUSYBOXPATH + ":$PATH", + "mount_partitions", + "BOOTIMAGE=", + "find_boot_image", + "migrate_boot_backup" + ); + + List ret = Shell.su("echo \"$BOOTIMAGE\""); + if (Utils.isValidShellResponse(ret)) { + mm.bootBlock = ret.get(0); + } else { + mm.blockList = Shell.su("find /dev/block -type b | grep -vE 'dm|ram|loop'"); + } + + // Setup suDB + SuDatabaseHelper.setupSuDB(); + + // Check alternative Magisk Manager + String pkg; + if (getPackageName().equals(Const.ORIG_PKG_NAME) && + (pkg = mm.suDB.getStrings(Const.Key.SU_REQUESTER, null)) != null) { + Shell.su_raw("pm uninstall " + pkg); + mm.suDB.setStrings(Const.Key.SU_REQUESTER, null); + } + + // Add update checking service + if (Const.Value.UPDATE_SERVICE_VER > mm.updateServiceVersion) { + ComponentName service = new ComponentName(this, 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(); + ((JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE)).schedule(info); + mm.updateServiceVersion = Const.Value.UPDATE_SERVICE_VER; + } + + // Fire asynctasks + loadModuleTask.exec(); + } + + // Write back default values + mm.prefs.edit() + .putBoolean(Const.Key.DARK_THEME, mm.isDarkTheme) + .putBoolean(Const.Key.MAGISKHIDE, mm.magiskHide) + .putBoolean(Const.Key.UPDATE_NOTIFICATION, mm.updateNotification) + .putBoolean(Const.Key.HOSTS, Utils.itemExist(Const.MAGISK_HOST_FILE)) + .putBoolean(Const.Key.DISABLE, Utils.itemExist(Const.MAGISK_DISABLE_FILE)) + .putBoolean(Const.Key.SU_REAUTH, mm.suReauth) + .putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(mm.suRequestTimeout)) + .putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(mm.suResponseType)) + .putString(Const.Key.SU_NOTIFICATION, String.valueOf(mm.suNotificationType)) + .putString(Const.Key.ROOT_ACCESS, String.valueOf(mm.suAccessState)) + .putString(Const.Key.SU_MULTIUSER_MODE, String.valueOf(mm.multiuserMode)) + .putString(Const.Key.SU_MNT_NS, String.valueOf(mm.suNamespaceMode)) + .putString(Const.Key.UPDATE_CHANNEL, String.valueOf(mm.updateChannel)) + .putString(Const.Key.LOCALE, mm.localeConfig) + .putString(Const.Key.BOOT_FORMAT, mm.bootFormat) + .putInt(Const.Key.UPDATE_SERVICE_VER, mm.updateServiceVersion) + .apply(); + + mm.hasInit = true; Intent intent = new Intent(this, MainActivity.class); String section = getIntent().getStringExtra(Const.Key.OPEN_SECTION); @@ -22,4 +137,16 @@ public class SplashActivity extends Activity { startActivity(intent); finish(); } + + static class LoadLocale extends ParallelTask { + @Override + protected Void doInBackground(Void... voids) { + MagiskManager.get().locales = Utils.getAvailableLocale(); + return null; + } + @Override + protected void onPostExecute(Void aVoid) { + MagiskManager.get().localeDone.publish(); + } + } } diff --git a/app/src/main/java/com/topjohnwu/magisk/asyncs/DownloadBusybox.java b/app/src/main/java/com/topjohnwu/magisk/asyncs/DownloadBusybox.java deleted file mode 100644 index e53f9ae9b..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/asyncs/DownloadBusybox.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.topjohnwu.magisk.asyncs; - -import android.content.Context; -import android.os.Build; - -import com.topjohnwu.magisk.MagiskManager; -import com.topjohnwu.magisk.utils.Const; -import com.topjohnwu.magisk.utils.Shell; -import com.topjohnwu.magisk.utils.Utils; -import com.topjohnwu.magisk.utils.WebService; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.HttpURLConnection; - -public class DownloadBusybox extends ParallelTask { - - @Override - protected Void doInBackground(Void... voids) { - Context context = MagiskManager.get(); - File busybox = new File(context.getCacheDir(), "busybox"); - Utils.removeItem(context.getApplicationInfo().dataDir + "/busybox"); - try (FileOutputStream out = new FileOutputStream(busybox)) { - - HttpURLConnection conn = WebService.request( - Build.SUPPORTED_32_BIT_ABIS[0].contains("x86") ? - Const.Url.BUSYBOX_X86 : - Const.Url.BUSYBOX_ARM, - null - ); - if (conn == null) throw new IOException(); - BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); - Utils.inToOut(bis, out); - conn.disconnect(); - } catch (IOException e) { - e.printStackTrace(); - } - if (busybox.exists()) { - Shell.su( - "rm -rf " + Const.BUSYBOXPATH, - "mkdir -p " + Const.BUSYBOXPATH, - "cp " + busybox + " " + Const.BUSYBOXPATH, - "chmod -R 755 " + Const.BUSYBOXPATH, - Const.BUSYBOXPATH + "/busybox --install -s " + Const.BUSYBOXPATH - ); - busybox.delete(); - } - return null; - } -} diff --git a/app/src/main/java/com/topjohnwu/magisk/services/UpdateCheckService.java b/app/src/main/java/com/topjohnwu/magisk/services/UpdateCheckService.java index be132f0f1..89a958fc2 100644 --- a/app/src/main/java/com/topjohnwu/magisk/services/UpdateCheckService.java +++ b/app/src/main/java/com/topjohnwu/magisk/services/UpdateCheckService.java @@ -10,7 +10,7 @@ public class UpdateCheckService extends JobService { @Override public boolean onStartJob(JobParameters params) { - Utils.getMagiskManager(this).getMagiskInfo(); + Utils.getMagiskManager(this).loadMagiskInfo(); new CheckUpdates(true) .setCallBack(() -> jobFinished(params, false)).exec(); return true; diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Const.java b/app/src/main/java/com/topjohnwu/magisk/utils/Const.java index 302c4b236..356c63551 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Const.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Const.java @@ -56,8 +56,6 @@ public class Const { public static final String STABLE_URL = "https://raw.githubusercontent.com/topjohnwu/MagiskManager/update/stable.json"; public static final String BETA_URL = "https://raw.githubusercontent.com/topjohnwu/MagiskManager/update/beta.json"; public static final String SNET_URL = "https://www.dropbox.com/s/jg2yhcrn3l9fckc/snet.apk?dl=1"; - public static final String BUSYBOX_ARM = "https://github.com/topjohnwu/ndk-busybox/releases/download/1.27.2/busybox-arm"; - public static final String BUSYBOX_X86 = "https://github.com/topjohnwu/ndk-busybox/releases/download/1.27.2/busybox-x86"; public static final String REPO_URL = "https://api.github.com/users/Magisk-Modules-Repo/repos?per_page=100&page=%d"; public static final String FILE_URL = "https://raw.githubusercontent.com/Magisk-Modules-Repo/%s/master/%s"; public static final String ZIP_URL = "https://github.com/Magisk-Modules-Repo/%s/archive/master.zip";