From 11e1d04dd112b81c7b576a73372e6064383fcc8f Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sun, 18 Sep 2016 02:32:08 +0800 Subject: [PATCH 1/5] Change root detection and toggle --- .../com/topjohnwu/magisk/MagiskFragment.java | 4 +- .../com/topjohnwu/magisk/ModulesFragment.java | 4 +- .../com/topjohnwu/magisk/RootFragment.java | 21 ++-- .../com/topjohnwu/magisk/WelcomeActivity.java | 17 +--- .../topjohnwu/magisk/module/RepoHelper.java | 2 +- .../com/topjohnwu/magisk/utils/Utils.java | 99 ++++++++++--------- .../main/res/drawable/ic_cloud_download.xml | 9 ++ app/src/main/res/menu/drawer.xml | 2 +- app/src/main/res/values-it/strings.xml | 51 ---------- app/src/main/res/values/strings.xml | 10 +- build.gradle | 2 +- 11 files changed, 86 insertions(+), 135 deletions(-) create mode 100644 app/src/main/res/drawable/ic_cloud_download.xml delete mode 100644 app/src/main/res/values-it/strings.xml diff --git a/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java b/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java index b22190f0a..817b39714 100644 --- a/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java @@ -104,7 +104,7 @@ public class MagiskFragment extends Fragment { magiskCheckUpdatesStatus.setText(getString(R.string.magisk_update_available, String.valueOf(Utils.remoteMagiskVersion))); magiskUpdateView.setOnClickListener(view -> new AlertDialog.Builder(getActivity()) .setTitle(getString(R.string.update_title, getString(R.string.magisk))) - .setMessage(Html.fromHtml(getString(R.string.update_msg, getString(R.string.magisk), String.valueOf(Utils.remoteMagiskVersion), Utils.magiskChangelog))) + .setMessage(getString(R.string.update_msg, getString(R.string.magisk), String.valueOf(Utils.remoteMagiskVersion), Utils.magiskChangelog)) .setCancelable(true) .setPositiveButton(R.string.download_install, (dialogInterface, i) -> { Utils.downloadAndReceive( @@ -131,7 +131,7 @@ public class MagiskFragment extends Fragment { appCheckUpdatesStatus.setText(getString(R.string.app_update_available, String.valueOf(Utils.remoteAppVersion))); appUpdateView.setOnClickListener(view -> new AlertDialog.Builder(getActivity()) .setTitle(getString(R.string.update_title, getString(R.string.app_name))) - .setMessage(Html.fromHtml(getString(R.string.update_msg, getString(R.string.app_name), String.valueOf(Utils.remoteAppVersion), Utils.appChangelog))) + .setMessage(getString(R.string.update_msg, getString(R.string.app_name), String.valueOf(Utils.remoteAppVersion), Utils.appChangelog)) .setCancelable(true) .setPositiveButton(R.string.download_install, (dialogInterface, i) -> { Utils.downloadAndReceive(getActivity(), diff --git a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java index 40f932cce..5db423f50 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java @@ -69,7 +69,7 @@ public class ModulesFragment extends Fragment { }); - new Utils.LoadModules(getActivity(), false).execute(); + new Utils.LoadModules(getActivity()).execute(); mTaskDelegate = result -> { if (result.equals("OK")) { RefreshUI(); @@ -121,7 +121,7 @@ public class ModulesFragment extends Fragment { viewPager.setAdapter(new TabsAdapter(getChildFragmentManager())); tabLayout.setupWithViewPager(viewPager); viewPager.setCurrentItem(viewPagePosition); - new Utils.LoadModules(getActivity(), true).execute(); + new Utils.LoadModules(getActivity()).execute(); Collections.sort(listModules, new CustomComparator()); Collections.sort(listModulesCache, new CustomComparator()); new updateUI().execute(); diff --git a/app/src/main/java/com/topjohnwu/magisk/RootFragment.java b/app/src/main/java/com/topjohnwu/magisk/RootFragment.java index afbee15da..489bd2f8d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/RootFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/RootFragment.java @@ -15,6 +15,7 @@ import android.widget.Switch; import android.widget.TextView; import com.topjohnwu.magisk.utils.Shell; +import com.topjohnwu.magisk.utils.Utils; import java.io.File; import java.util.List; @@ -65,13 +66,13 @@ public class RootFragment extends Fragment { new updateUI().execute(); rootToggle.setOnClickListener(toggle -> { - Shell.su(((CompoundButton) toggle).isChecked() ? "setprop magisk.root 1" : "setprop magisk.root 0"); - new Handler().postDelayed(() -> new updateUI().execute(), 1000); + Utils.toggleRoot(((CompoundButton) toggle).isChecked()); + new updateUI().execute(); }); selinuxToggle.setOnClickListener(toggle -> { Shell.su(((CompoundButton) toggle).isChecked() ? "setenforce 1" : "setenforce 0"); - new Handler().postDelayed(() -> new updateUI().execute(), 1000); + new updateUI().execute(); }); return view; @@ -153,25 +154,25 @@ public class RootFragment extends Fragment { break; case 1: // Proper root - if (new File("/magisk/.core/bin/su").exists()) { - // Mounted + if (Utils.rootEnabled()) { + // Enabled rootStatusContainer.setBackgroundColor(accent); rootStatusIcon.setImageResource(statusError); rootStatus.setTextColor(accent); - rootStatus.setText(R.string.root_mounted); + rootStatus.setText(R.string.root_enabled); rootToggle.setChecked(true); safetyNetStatusIcon.setImageResource(statusError); - safetyNetStatus.setText(R.string.root_mounted_info); + safetyNetStatus.setText(R.string.root_enabled_info); break; } else { - // Not Mounted + // Disabled rootStatusContainer.setBackgroundColor(green500); rootStatusIcon.setImageResource(statusOK); rootStatus.setTextColor(green500); - rootStatus.setText(R.string.root_unmounted); + rootStatus.setText(R.string.root_disabled); rootToggle.setChecked(false); safetyNetStatusIcon.setImageResource(statusOK); - safetyNetStatus.setText(R.string.root_unmounted_info); + safetyNetStatus.setText(R.string.root_disabled_info); break; } case 2: diff --git a/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java b/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java index d2902db11..dd3e09d9d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -32,7 +33,6 @@ import butterknife.ButterKnife; public class WelcomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { private static final String SELECTED_ITEM_ID = "SELECTED_ITEM_ID"; - private Context mContext; private final Handler mDrawerHandler = new Handler(); @@ -49,10 +49,6 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView setContentView(R.layout.activity_welcome); ButterKnife.bind(this); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); - } - // Startups if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { @@ -67,15 +63,8 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView if (!prefs.contains("oauth_key")) { } - if (!prefs.contains("hasCachedRepos")) { - new Utils.LoadModules(this, true).execute(); - new Utils.LoadRepos(this, true,delegate).execute(); - - } else { - new Utils.LoadModules(getApplication(),false).execute(); - new Utils.LoadRepos(this, false,delegate).execute(); - - } + new Utils.LoadModules(this).execute(); + new Utils.LoadRepos(this, !prefs.contains("hasCachedRepos"), delegate).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); setSupportActionBar(toolbar); diff --git a/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java b/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java index f360be9cd..664604045 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java @@ -46,7 +46,7 @@ public class RepoHelper { new BuildFromWeb(delegate).execute(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); String date = format.format(Calendar.getInstance().getTime()); - prefs.edit().putString("last_update",date).apply(); + prefs.edit().putString("last_update", date).apply(); } else { Log.d(TAG, "RepoHelper: Building from cache"); BuildFromCache(); diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java index 84957bcc9..fb4d11322 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -69,25 +69,45 @@ public class Utils { public static boolean fileExist(String path) { List ret; - ret = Shell.sh("if [ -f " + path + " ]; then echo true; else echo false; fi"); - if (!Boolean.parseBoolean(ret.get(0)) && Shell.rootAccess()) - ret = Shell.su("if [ -f " + path + " ]; then echo true; else echo false; fi"); + String command = "if [ -f " + path + " ]; then echo true; else echo false; fi"; + if (Shell.rootAccess()) { + ret = Shell.su(command); + } else { + ret = Shell.sh(command); + } + return Boolean.parseBoolean(ret.get(0)); + } + + public static boolean rootEnabled() { + List ret; + String command = "if [ -z $(which su) ]; then echo false; else echo true; fi"; + ret = Shell.sh(command); return Boolean.parseBoolean(ret.get(0)); } public static boolean createFile(String path) { + String command = "touch " + path + " 2>/dev/null; if [ -f " + path + " ]; then echo true; else echo false; fi"; if (!Shell.rootAccess()) { return false; } else { - return Boolean.parseBoolean(Shell.su("touch " + path + " 2>/dev/null; if [ -f " + path + " ]; then echo true; else echo false; fi").get(0)); + return Boolean.parseBoolean(Shell.su(command).get(0)); } } public static boolean removeFile(String path) { + String command = "rm -f " + path + " 2>/dev/null; if [ -f " + path + " ]; then echo false; else echo true; fi"; if (!Shell.rootAccess()) { return false; } else { - return Boolean.parseBoolean(Shell.su("rm -f " + path + " 2>/dev/null; if [ -f " + path + " ]; then echo false; else echo true; fi").get(0)); + return Boolean.parseBoolean(Shell.su(command).get(0)); + } + } + + public static void toggleRoot(Boolean b) { + if (b) { + Shell.su("ln -s $(getprop magisk.supath) /magisk/.core/bin", "setprop magisk.root 1"); + } else { + Shell.su("rm -rf /magisk/.core/bin", "setprop magisk.root 0"); } } @@ -107,10 +127,6 @@ public class Utils { return ret; } - public Utils(Context context) { - Context appContext = context; - } - public static void downloadAndReceive(Context context, DownloadReceiver receiver, String link, String file) { if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { Toast.makeText(context, R.string.permissionNotGranted, Toast.LENGTH_LONG).show(); @@ -129,6 +145,30 @@ public class Utils { context.registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); } + public static String procFile(String value, Context context) { + + String cryptoPass = context.getResources().getString(R.string.pass); + try { + DESKeySpec keySpec = new DESKeySpec(cryptoPass.getBytes("UTF8")); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey key = keyFactory.generateSecret(keySpec); + + byte[] encrypedPwdBytes = Base64.decode(value, Base64.DEFAULT); + // cipher is not thread safe + Cipher cipher = Cipher.getInstance("DES"); + cipher.init(Cipher.DECRYPT_MODE, key); + byte[] decrypedValueBytes = (cipher.doFinal(encrypedPwdBytes)); + + return new String(decrypedValueBytes); + + } catch (InvalidKeyException | UnsupportedEncodingException | NoSuchAlgorithmException + | BadPaddingException | NoSuchPaddingException | IllegalBlockSizeException + | InvalidKeySpecException e) { + e.printStackTrace(); + } + return value; + } + public abstract static class DownloadReceiver extends BroadcastReceiver { public Context mContext; long downloadID; @@ -393,49 +433,12 @@ public class Utils { } } - public static String procFile(String value, Context context) { - - String cryptoPass = context.getResources().getString(R.string.pass); - try { - DESKeySpec keySpec = new DESKeySpec(cryptoPass.getBytes("UTF8")); - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); - SecretKey key = keyFactory.generateSecret(keySpec); - - byte[] encrypedPwdBytes = Base64.decode(value, Base64.DEFAULT); - // cipher is not thread safe - Cipher cipher = Cipher.getInstance("DES"); - cipher.init(Cipher.DECRYPT_MODE, key); - byte[] decrypedValueBytes = (cipher.doFinal(encrypedPwdBytes)); - - String decrypedValue = new String(decrypedValueBytes); - return decrypedValue; - - } catch (InvalidKeyException e) { - e.printStackTrace(); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } catch (InvalidKeySpecException e) { - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (BadPaddingException e) { - e.printStackTrace(); - } catch (NoSuchPaddingException e) { - e.printStackTrace(); - } catch (IllegalBlockSizeException e) { - e.printStackTrace(); - } - return value; - } - public static class LoadModules extends AsyncTask { private Context mContext; - private boolean doReload; - public LoadModules(Context context, boolean reload) { + public LoadModules(Context context) { mContext = context; - doReload = reload; } @Override @@ -443,7 +446,7 @@ public class Utils { ModulesFragment.listModules.clear(); ModulesFragment.listModulesCache.clear(); List magisk = getModList(MAGISK_PATH); - Log.d("Magisk", "Utils: Reload called, loading modules from" + (doReload ? " the internet " : " cache")); + Log.d("Magisk", "Utils: Reload called, loading modules"); List magiskCache = getModList(MAGISK_CACHE_PATH); for (String mod : magisk) { diff --git a/app/src/main/res/drawable/ic_cloud_download.xml b/app/src/main/res/drawable/ic_cloud_download.xml new file mode 100644 index 000000000..261c31217 --- /dev/null +++ b/app/src/main/res/drawable/ic_cloud_download.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/menu/drawer.xml b/app/src/main/res/menu/drawer.xml index 39bb96407..ea0a4f8ae 100644 --- a/app/src/main/res/menu/drawer.xml +++ b/app/src/main/res/menu/drawer.xml @@ -22,7 +22,7 @@ - - Info su… - Changelog dell\'app - Sviluppatori principali - topjohnwu in collaborazione con dvdandroid]]> - Codice sorgente - Traduttori dell\'app - Versione dell\'app - Moduli in cache - Il modulo verrà disabilitato al prossimo riavvio - Il modulo verrà abilitato al prossimo riavvio - Log - Il log è vuoto - Non è possibile leggere il log: - Log pulito correttamente - Non è stato possibile il log nella SD card: - Versione installata di Magisk v%1$s - Pulisci log adesso - Ricarica - Salva nella SD - Invia - Moduli - Chiudi navigation drawer - Apri navigation drawer - Nessun modulo trovato - Accesso root rifiutato; funzionalità limitate - Questa funzionalità non funzionerà senza il permesso di scrittura della memoria esterna. - Il modulo verrà rimosso al prossimo riavvio - Il modulo non verrà rimosso al prossimo riavvio - Root montato - Root montato e abilitato. Safety Net (Android Pay) NON funzionerà - Non rootato - Safety Net (Android Pay) dovrebbe funzionare - Non correttamente installato - Root non correttamente installato. Safety Net (Android Pay) NON funzionerà, è ed impossibile attivare i toggle - Root Toggle - Root non montato - Safety Net (Android Pay) dovrebbe funzionare, ma non il root temporaneo - SD card non trovata o non scrivibile - SELinux è forzato - SELinux è permissivo\nSpegni SELinux solamente se necessario! - Samsung non supporta la modifica dello stato di SELinux - SeLinux Toggle - Thread di supporto - dvdandroid - Hai installato Magisk? - Errore root - Stato Safety Net sconosciuto - Stato SELinux sconosciuto - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c1ad9d57b..cb4aca8e1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -27,10 +27,10 @@ Safety Net Status Unknown Not Rooted Safety Net (Android Pay) should work - Root mounted - Root mounted and enabled. Safety Net (Android Pay) will NOT work - Root not mounted - Safety Net (Android Pay) should work, but no root temporarily\nYou might need to manually add a card in Android Pay app to refresh the root status of AP + Root enabled + Root enabled. Safety Net (Android Pay) will NOT work + Root disabled + Safety Net (Android Pay) should work, but no root temporarily\nYou might need to manually add a card in Android Pay app to refresh the root status of AP Magisk Incompatible Root Detected Root improperly installed. Safety Net (Android Pay) will NOT work, and impossible to toggle @@ -79,7 +79,7 @@ No root access, functionality limited No thanks %1$s Update! - Changelog:
%3$s]]>
+ New version v%2$s of %1$s is available!\nChangelog:\n%3$s Download and install Error downloading file File downloaded in %1$s\nFlash it in recovery manually diff --git a/build.gradle b/build.gradle index ec075a896..24cf38d8a 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.0-beta3' + classpath 'com.android.tools.build:gradle:2.2.0-rc1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From 1e09ccb4d96ca8a5ec8c90c74eabad48da47190f Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sun, 18 Sep 2016 04:32:49 +0800 Subject: [PATCH 2/5] Update FlashZip --- .../com/topjohnwu/magisk/ModulesFragment.java | 14 +++------- .../com/topjohnwu/magisk/utils/Utils.java | 26 +++++++++---------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java index 5db423f50..0354f4184 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java @@ -43,14 +43,10 @@ public class ModulesFragment extends Fragment { private static final int FETCH_ZIP_CODE = 2; public static List listModules = new ArrayList<>(); public static List listModulesCache = new ArrayList<>(); - @BindView(R.id.progressBar) - ProgressBar progressBar; - @BindView(R.id.fab) - FloatingActionButton fabio; - @BindView(R.id.pager) - ViewPager viewPager; - @BindView(R.id.tab_layout) - TabLayout tabLayout; + @BindView(R.id.progressBar) ProgressBar progressBar; + @BindView(R.id.fab) FloatingActionButton fabio; + @BindView(R.id.pager) ViewPager viewPager; + @BindView(R.id.tab_layout) TabLayout tabLayout; private int viewPagePosition; private RepoHelper.TaskDelegate mTaskDelegate; @@ -69,12 +65,10 @@ public class ModulesFragment extends Fragment { }); - new Utils.LoadModules(getActivity()).execute(); mTaskDelegate = result -> { if (result.equals("OK")) { RefreshUI(); } - }; new updateUI().execute(); diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java index fb4d11322..74d0babcc 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -517,13 +517,13 @@ public class Utils { final String docId = DocumentsContract.getDocumentId(mUri); Log.d("Magisk","Utils: FlashZip Running, " + docId + " and " + mUri.toString()); - String[] split = docId.split(":"); - mName = split[1]; - if (mName.contains("/")) { - split = mName.split("/"); - } - if (split[1].contains(".zip")) { - file = mContext.getFilesDir() + "/" + split[1]; + if (docId.contains(":")) + mName = docId.split(":")[1]; + else mName = docId; + if (mName.contains("/")) + mName = mName.substring(mName.lastIndexOf('/') + 1); + if (mName.contains(".zip")) { + file = mContext.getFilesDir() + "/" + mName; Log.d("Magisk", "Utils: FlashZip running for uRI " + mUri.toString()); } else { Log.e("Magisk", "Utils: error parsing Zipfile " + mUri.getPath()); @@ -587,6 +587,7 @@ public class Utils { protected Boolean doInBackground(Void... voids) { if (mPath != null) { Log.e("Magisk", "Utils: Error, flashZIP called without a valid zip file to flash."); + progress.dismiss(); this.cancel(true); return false; } @@ -594,11 +595,11 @@ public class Utils { return false; } else { ret = Shell.su( - "rm -rf /data/tmp", - "mkdir -p /data/tmp", - "cp -af " + mPath + " /data/tmp/install.zip", - "unzip -o /data/tmp/install.zip META-INF/com/google/android/* -d /data/tmp", - "BOOTMODE=true sh /data/tmp/META-INF/com/google/android/update-binary dummy 1 /data/tmp/install.zip", + "rm -rf /dev/tmp", + "mkdir -p /dev/tmp", + "cp -af " + mPath + " /dev/tmp/install.zip", + "unzip -o /dev/tmp/install.zip META-INF/com/google/android/* -d /dev/tmp", + "BOOTMODE=true sh /dev/tmp/META-INF/com/google/android/update-binary dummy 1 /dev/tmp/install.zip", "if [ $? -eq 0 ]; then echo true; else echo false; fi" ); return ret != null && Boolean.parseBoolean(ret.get(ret.size() - 1)); @@ -608,7 +609,6 @@ public class Utils { @Override protected void onPostExecute(Boolean result) { super.onPostExecute(result); - Shell.su("rm -rf /data/tmp"); if (deleteFileAfter) { Shell.su("rm -rf " + mPath); Log.d("Magisk", "Utils: Deleting file " + mPath); From 41295e0c4dbd32c4366369b9fb93c8bb24fa9429 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sun, 18 Sep 2016 22:56:12 +0800 Subject: [PATCH 3/5] Refactor modules fragment --- .../topjohnwu/magisk/BaseModuleFragment.java | 390 ------------------ .../com/topjohnwu/magisk/ModulesAdapter.java | 308 ++++++++++++++ .../com/topjohnwu/magisk/ModulesFragment.java | 212 +++------- .../com/topjohnwu/magisk/ReposFragment.java | 4 +- .../com/topjohnwu/magisk/WelcomeActivity.java | 1 - .../com/topjohnwu/magisk/module/Module.java | 82 ++-- .../com/topjohnwu/magisk/utils/Utils.java | 6 +- app/src/main/res/layout/modules_fragment.xml | 86 ++-- ...e_repo_fragment.xml => repos_fragment.xml} | 0 .../res/layout/single_module_fragment.xml | 31 -- 10 files changed, 435 insertions(+), 685 deletions(-) delete mode 100644 app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java create mode 100644 app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java rename app/src/main/res/layout/{single_repo_fragment.xml => repos_fragment.xml} (100%) delete mode 100644 app/src/main/res/layout/single_module_fragment.xml diff --git a/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java b/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java deleted file mode 100644 index e5fe56942..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java +++ /dev/null @@ -1,390 +0,0 @@ -package com.topjohnwu.magisk; - -import android.animation.Animator; -import android.animation.ValueAnimator; -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.graphics.Color; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.annotation.Nullable; -import android.support.design.widget.Snackbar; -import android.support.v4.app.Fragment; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.app.AlertDialog; -import android.support.v7.widget.RecyclerView; -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.view.WindowManager; -import android.widget.CheckBox; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.topjohnwu.magisk.module.Module; -import com.topjohnwu.magisk.module.RepoHelper; -import com.topjohnwu.magisk.utils.Shell; -import com.topjohnwu.magisk.utils.Utils; -import com.topjohnwu.magisk.utils.WebWindow; - -import java.io.File; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public abstract class BaseModuleFragment extends Fragment { - @BindView(R.id.swipeRefreshLayout) - SwipeRefreshLayout mSwipeRefreshLayout; - @BindView(R.id.recyclerView) - RecyclerView recyclerView; - @BindView(R.id.empty_rv) - TextView emptyTv; - - private RepoHelper.TaskDelegate mDelegate; - private SharedPreferences prefs; - - public BaseModuleFragment SetDelegate(RepoHelper.TaskDelegate delegate) { - mDelegate = delegate; - return null; - } - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View viewMain = inflater.inflate(R.layout.single_module_fragment, container, false); - - - ButterKnife.bind(this, viewMain); - - - prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); - mSwipeRefreshLayout.setOnRefreshListener(() -> { - - mDelegate.taskCompletionResult("OK"); - prefs.edit().putBoolean("ignoreUpdateAlerts", false).apply(); - - - }); - prefs.registerOnSharedPreferenceChangeListener((sharedPreferences, s) -> { - if (s.contains("updated")) { - viewMain.invalidate(); - viewMain.requestLayout(); - - } - }); - if (listModules().size() == 0) { - emptyTv.setVisibility(View.VISIBLE); - recyclerView.setVisibility(View.GONE); - - return viewMain; - } - - recyclerView.setAdapter(new ModulesAdapter(listModules(), (chk, position) -> { - // On Checkbox change listener - CheckBox chbox = (CheckBox) chk; - - if (!chbox.isChecked()) { - listModules().get(position).createDisableFile(); - Snackbar.make(chk, R.string.disable_file_created, Snackbar.LENGTH_SHORT).show(); - } else { - listModules().get(position).removeDisableFile(); - Snackbar.make(chk, R.string.disable_file_removed, Snackbar.LENGTH_SHORT).show(); - } - }, (deleteBtn, position) -> { - // On delete button click listener - - listModules().get(position).createRemoveFile(); - Snackbar.make(deleteBtn, R.string.remove_file_created, Snackbar.LENGTH_SHORT).show(); - }, (undeleteBtn, position) -> { - // On undelete button click listener - - listModules().get(position).deleteRemoveFile(); - Snackbar.make(undeleteBtn, R.string.remove_file_deleted, Snackbar.LENGTH_SHORT).show(); - })); - - - return viewMain; - } - - - protected abstract List listModules(); - - public class ModulesAdapter extends RecyclerView.Adapter { - - private final List mList; - private final List mListToUpdate = new ArrayList<>(); - List mExpandedList; - @BindView(R.id.expand_layout) - LinearLayout expandedLayout; - private View viewMain; - private Context context; - private final Utils.ItemClickListener chboxListener; - private final Utils.ItemClickListener deleteBtnListener; - private final Utils.ItemClickListener unDeleteBtnListener; - private boolean alertUpdate, ignoreAlertUpdate; - - public ModulesAdapter(List list, Utils.ItemClickListener chboxListener, Utils.ItemClickListener deleteBtnListener, Utils.ItemClickListener undeleteBtnListener) { - alertUpdate = false; - this.mList = list; - mExpandedList = new ArrayList<>(mList.size()); - for (int i = 0; i < mList.size(); i++) { - mExpandedList.add(false); - if (listModules().get(i).isUpdateAvailable()) { - alertUpdate = true; - mListToUpdate.add(listModules().get(i)); - } - } - this.chboxListener = chboxListener; - this.deleteBtnListener = deleteBtnListener; - this.unDeleteBtnListener = undeleteBtnListener; - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - viewMain = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_module, parent, false); - context = parent.getContext(); - ButterKnife.bind(this, viewMain); - return new ViewHolder(viewMain); - } - - @Override - public void onBindViewHolder(final ViewHolder holder, int position) { - final Module module = mList.get(position); - Log.d("Magisk", "ModulesAdapter: Trying set up bindview from list pos " + position + " and " + module.getName()); - Log.d("Magisk", "BaseModuleFragment: Log ID is " + module.getmLogUrl()); - holder.title.setText(module.getName()); - holder.versionName.setText(module.getVersion()); - holder.description.setText(module.getDescription()); - holder.author.setText(module.getAuthor()); - String logUrl = module.getmLogUrl(); - String supportUrl = module.getmSupportUrl(); - String donateUrl = module.getmDonateUrl(); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - if (prefs.contains("ignoreUpdateAlerts")) { - ignoreAlertUpdate = prefs.getBoolean("ignoreUpdateAlerts", false); - } - if (prefs.contains("repo-canUpdate_" + module.getId())) { - if (prefs.getBoolean("repo-canUpdate_" + module.getId(), false)) { - holder.updateStatus.setText(R.string.module_update_available); - holder.updateStatus.setVisibility(View.VISIBLE); - } else { - holder.updateStatus.setVisibility(View.GONE); - } - - if (alertUpdate && !ignoreAlertUpdate) { - Iterator iterRepo = mListToUpdate.iterator(); - while (iterRepo.hasNext()) { - Module mModule = iterRepo.next(); - DialogInterface.OnClickListener dialogClickListener = (dialog, which) -> { - switch (which) { - case DialogInterface.BUTTON_POSITIVE: - Utils.DownloadReceiver receiver = new Utils.DownloadReceiver() { - @Override - public void task(File file) { - Log.d("Magisk", "Task firing"); - new Utils.FlashZIP(context, mModule.getId(), file.toString()).execute(); - } - }; - String filename = mModule.getId().replace(" ", "") + ".zip"; - Utils.downloadAndReceive(context, receiver, mModule.getmZipUrl(), filename); - - break; - - case DialogInterface.BUTTON_NEGATIVE: - ignoreAlertUpdate = true; - SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean("ignoreUpdateAlerts", ignoreAlertUpdate); - editor.apply(); - break; - } - }; - - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setMessage("An update is available for " + mModule.getName() + ". Would you like to install it?").setPositiveButton("Yes", dialogClickListener) - .setNegativeButton("No", dialogClickListener).show(); - mListToUpdate.remove(mModule); - } - } - } - - View.OnClickListener oCl = view -> { - if (view.getId() == holder.changeLog.getId()) { - - new WebWindow("Changelog", module.getmLogUrl(), context); - } - if (view.getId() == holder.authorLink.getId()) { - new WebWindow("Donate", module.getmDonateUrl(), context); - } - if (view.getId() == holder.supportLink.getId()) { - new WebWindow("Support", module.getmSupportUrl(), context); - } - }; - - holder.authorLink.setOnClickListener(oCl); - holder.changeLog.setOnClickListener(oCl); - holder.supportLink.setOnClickListener(oCl); - holder.checkBox.setChecked(module.isEnabled()); - holder.checkBox.setOnCheckedChangeListener((compoundButton, b) -> chboxListener.onItemClick(compoundButton, holder.getAdapterPosition())); - - holder.delete.setOnClickListener(view -> { - if (module.willBeRemoved()) { - unDeleteBtnListener.onItemClick(holder.delete, holder.getAdapterPosition()); - } else { - deleteBtnListener.onItemClick(holder.delete, holder.getAdapterPosition()); - } - - updateDeleteButton(holder, module); - }); - - updateDeleteButton(holder, module); - } - - private void updateDeleteButton(ViewHolder holder, Module module) { - holder.warning.setVisibility(module.willBeRemoved() ? View.VISIBLE : View.GONE); - - if (module.willBeRemoved()) { - holder.delete.setImageResource(R.drawable.ic_undelete); - } else { - holder.delete.setImageResource(R.drawable.ic_delete); - } - } - - @Override - public int getItemCount() { - return mList.size(); - } - - class ViewHolder extends RecyclerView.ViewHolder { - - @BindView(R.id.title) - TextView title; - - @BindView(R.id.version_name) - TextView versionName; - @BindView(R.id.description) - TextView description; - @BindView(R.id.warning) - TextView warning; - @BindView(R.id.checkbox) - CheckBox checkBox; - @BindView(R.id.author) - TextView author; - @BindView(R.id.updateStatus) - TextView updateStatus; - @BindView(R.id.delete) - ImageView delete; - @BindView(R.id.changeLog) - ImageView changeLog; - @BindView(R.id.authorLink) - ImageView authorLink; - @BindView(R.id.supportLink) - ImageView supportLink; - @BindView(R.id.expand_layout) - LinearLayout expandLayout; - private ValueAnimator mAnimator; - private int mMeasuredHeight; - - public ViewHolder(View itemView) { - super(itemView); - WindowManager windowmanager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - ButterKnife.bind(this, itemView); - DisplayMetrics dimension = new DisplayMetrics(); - windowmanager.getDefaultDisplay().getMetrics(dimension); - - expandLayout.getViewTreeObserver().addOnPreDrawListener( - new ViewTreeObserver.OnPreDrawListener() { - - - @Override - public boolean onPreDraw() { - expandLayout.getViewTreeObserver().removeOnPreDrawListener(this); - expandLayout.setVisibility(View.GONE); - final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - expandLayout.measure(widthSpec, heightSpec); - mAnimator = slideAnimator(0, expandLayout.getMeasuredHeight()); - return true; - } - }); - - viewMain.setOnClickListener(view -> { - int position = getAdapterPosition(); - Log.d("Magisk", "ReposFragment: CLICK. " + position + " and " + mExpandedList.get(position)); - - if (mExpandedList.get(position)) { - collapse(expandLayout); - } else { - expand(expandLayout); - } - mExpandedList.set(position, !mExpandedList.get(position)); - - }); - if (!Shell.rootAccess()) { - checkBox.setEnabled(false); - delete.setEnabled(false); - } - } - - private void expand(View view) { - - // set Visible - - - Log.d("Magisk", "ReposFragment: Expand anim called " + mMeasuredHeight + " and " + view.getId()); - view.setVisibility(View.VISIBLE); - mAnimator.start(); - } - - private void collapse(View view) { - int finalHeight = view.getHeight(); - ValueAnimator mAnimator = slideAnimator(finalHeight, 0); - Log.d("Magisk", "ReposFragment: Collapse anim called " + finalHeight + " and " + view.getId()); - - mAnimator.addListener(new Animator.AnimatorListener() { - @Override - public void onAnimationEnd(Animator animator) { - // Height=0, but it set visibility to GONE - view.setVisibility(View.GONE); - } - - @Override - public void onAnimationStart(Animator animator) { - } - - @Override - public void onAnimationCancel(Animator animator) { - } - - @Override - public void onAnimationRepeat(Animator animator) { - } - }); - mAnimator.start(); - } - - private ValueAnimator slideAnimator(int start, int end) { - - ValueAnimator animator = ValueAnimator.ofInt(start, end); - - animator.addUpdateListener(valueAnimator -> { - // Update Height - int value = (Integer) valueAnimator.getAnimatedValue(); - - ViewGroup.LayoutParams layoutParams = expandLayout - .getLayoutParams(); - layoutParams.height = value; - expandLayout.setLayoutParams(layoutParams); - }); - return animator; - } - } - } -} diff --git a/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java b/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java new file mode 100644 index 000000000..28d66304c --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java @@ -0,0 +1,308 @@ +package com.topjohnwu.magisk; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.RecyclerView; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.WindowManager; +import android.widget.CheckBox; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.topjohnwu.magisk.module.Module; +import com.topjohnwu.magisk.utils.Shell; +import com.topjohnwu.magisk.utils.Utils; +import com.topjohnwu.magisk.utils.WebWindow; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class ModulesAdapter extends RecyclerView.Adapter { + + private final List mList; + private final List mListToUpdate = new ArrayList<>(); + List mExpandedList; + @BindView(R.id.expand_layout) + LinearLayout expandedLayout; + private View viewMain; + private Context context; + private final Utils.ItemClickListener chboxListener; + private final Utils.ItemClickListener deleteBtnListener; + private final Utils.ItemClickListener unDeleteBtnListener; + private boolean alertUpdate, ignoreAlertUpdate; + + public ModulesAdapter(List list, Utils.ItemClickListener chboxListener, Utils.ItemClickListener deleteBtnListener, Utils.ItemClickListener undeleteBtnListener) { + alertUpdate = false; + this.mList = list; + mExpandedList = new ArrayList<>(mList.size()); + for (int i = 0; i < mList.size(); i++) { + mExpandedList.add(false); + if (mList.get(i).isUpdateAvailable()) { + alertUpdate = true; + mListToUpdate.add(mList.get(i)); + } + } + this.chboxListener = chboxListener; + this.deleteBtnListener = deleteBtnListener; + this.unDeleteBtnListener = undeleteBtnListener; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + viewMain = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_module, parent, false); + context = parent.getContext(); + ButterKnife.bind(this, viewMain); + return new ViewHolder(viewMain); + } + + @Override + public void onBindViewHolder(final ViewHolder holder, int position) { + final Module module = mList.get(position); + Log.d("Magisk", "ModulesAdapter: Trying set up bindview from list pos " + position + " and " + module.getName()); + Log.d("Magisk", "ModulesFragment: Log ID is " + module.getmLogUrl()); + if (module.isCache()) + holder.title.setText("[Cache] " + module.getName()); + else + holder.title.setText(module.getName()); + holder.versionName.setText(module.getVersion()); + holder.description.setText(module.getDescription()); + holder.author.setText(module.getAuthor()); + String logUrl = module.getmLogUrl(); + String supportUrl = module.getmSupportUrl(); + String donateUrl = module.getmDonateUrl(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + if (prefs.contains("ignoreUpdateAlerts")) { + ignoreAlertUpdate = prefs.getBoolean("ignoreUpdateAlerts", false); + } + if (prefs.contains("repo-canUpdate_" + module.getId())) { + if (prefs.getBoolean("repo-canUpdate_" + module.getId(), false)) { + holder.updateStatus.setText(R.string.module_update_available); + holder.updateStatus.setVisibility(View.VISIBLE); + } else { + holder.updateStatus.setVisibility(View.GONE); + } + + if (alertUpdate && !ignoreAlertUpdate) { + Iterator iterRepo = mListToUpdate.iterator(); + while (iterRepo.hasNext()) { + Module mModule = iterRepo.next(); + DialogInterface.OnClickListener dialogClickListener = (dialog, which) -> { + switch (which) { + case DialogInterface.BUTTON_POSITIVE: + Utils.DownloadReceiver receiver = new Utils.DownloadReceiver() { + @Override + public void task(File file) { + Log.d("Magisk", "Task firing"); + new Utils.FlashZIP(context, mModule.getId(), file.toString()).execute(); + } + }; + String filename = mModule.getId().replace(" ", "") + ".zip"; + Utils.downloadAndReceive(context, receiver, mModule.getmZipUrl(), filename); + + break; + + case DialogInterface.BUTTON_NEGATIVE: + ignoreAlertUpdate = true; + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean("ignoreUpdateAlerts", ignoreAlertUpdate); + editor.apply(); + break; + } + }; + + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setMessage("An update is available for " + mModule.getName() + ". Would you like to install it?").setPositiveButton("Yes", dialogClickListener) + .setNegativeButton("No", dialogClickListener).show(); + mListToUpdate.remove(mModule); + } + } + } + + View.OnClickListener oCl = view -> { + if (view.getId() == holder.changeLog.getId()) { + + new WebWindow("Changelog", module.getmLogUrl(), context); + } + if (view.getId() == holder.authorLink.getId()) { + new WebWindow("Donate", module.getmDonateUrl(), context); + } + if (view.getId() == holder.supportLink.getId()) { + new WebWindow("Support", module.getmSupportUrl(), context); + } + }; + + holder.authorLink.setOnClickListener(oCl); + holder.changeLog.setOnClickListener(oCl); + holder.supportLink.setOnClickListener(oCl); + holder.checkBox.setChecked(module.isEnabled()); + holder.checkBox.setOnCheckedChangeListener((compoundButton, b) -> chboxListener.onItemClick(compoundButton, holder.getAdapterPosition())); + + holder.delete.setOnClickListener(view -> { + if (module.willBeRemoved()) { + unDeleteBtnListener.onItemClick(holder.delete, holder.getAdapterPosition()); + } else { + deleteBtnListener.onItemClick(holder.delete, holder.getAdapterPosition()); + } + + updateDeleteButton(holder, module); + }); + + updateDeleteButton(holder, module); + } + + private void updateDeleteButton(ViewHolder holder, Module module) { + holder.warning.setVisibility(module.willBeRemoved() ? View.VISIBLE : View.GONE); + + if (module.willBeRemoved()) { + holder.delete.setImageResource(R.drawable.ic_undelete); + } else { + holder.delete.setImageResource(R.drawable.ic_delete); + } + } + + @Override + public int getItemCount() { + return mList.size(); + } + + class ViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.title) + TextView title; + + @BindView(R.id.version_name) + TextView versionName; + @BindView(R.id.description) + TextView description; + @BindView(R.id.warning) + TextView warning; + @BindView(R.id.checkbox) + CheckBox checkBox; + @BindView(R.id.author) + TextView author; + @BindView(R.id.updateStatus) + TextView updateStatus; + @BindView(R.id.delete) + ImageView delete; + @BindView(R.id.changeLog) + ImageView changeLog; + @BindView(R.id.authorLink) + ImageView authorLink; + @BindView(R.id.supportLink) + ImageView supportLink; + @BindView(R.id.expand_layout) + LinearLayout expandLayout; + private ValueAnimator mAnimator; + private int mMeasuredHeight; + + public ViewHolder(View itemView) { + super(itemView); + WindowManager windowmanager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + ButterKnife.bind(this, itemView); + DisplayMetrics dimension = new DisplayMetrics(); + windowmanager.getDefaultDisplay().getMetrics(dimension); + + expandLayout.getViewTreeObserver().addOnPreDrawListener( + new ViewTreeObserver.OnPreDrawListener() { + + + @Override + public boolean onPreDraw() { + expandLayout.getViewTreeObserver().removeOnPreDrawListener(this); + expandLayout.setVisibility(View.GONE); + final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + expandLayout.measure(widthSpec, heightSpec); + mAnimator = slideAnimator(0, expandLayout.getMeasuredHeight()); + return true; + } + }); + + viewMain.setOnClickListener(view -> { + int position = getAdapterPosition(); + Log.d("Magisk", "ReposFragment: CLICK. " + position + " and " + mExpandedList.get(position)); + + if (mExpandedList.get(position)) { + collapse(expandLayout); + } else { + expand(expandLayout); + } + mExpandedList.set(position, !mExpandedList.get(position)); + + }); + if (!Shell.rootAccess()) { + checkBox.setEnabled(false); + delete.setEnabled(false); + } + } + + private void expand(View view) { + + // set Visible + + + Log.d("Magisk", "ReposFragment: Expand anim called " + mMeasuredHeight + " and " + view.getId()); + view.setVisibility(View.VISIBLE); + mAnimator.start(); + } + + private void collapse(View view) { + int finalHeight = view.getHeight(); + ValueAnimator mAnimator = slideAnimator(finalHeight, 0); + Log.d("Magisk", "ReposFragment: Collapse anim called " + finalHeight + " and " + view.getId()); + + mAnimator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationEnd(Animator animator) { + // Height=0, but it set visibility to GONE + view.setVisibility(View.GONE); + } + + @Override + public void onAnimationStart(Animator animator) { + } + + @Override + public void onAnimationCancel(Animator animator) { + } + + @Override + public void onAnimationRepeat(Animator animator) { + } + }); + mAnimator.start(); + } + + private ValueAnimator slideAnimator(int start, int end) { + + ValueAnimator animator = ValueAnimator.ofInt(start, end); + + animator.addUpdateListener(valueAnimator -> { + // Update Height + int value = (Integer) valueAnimator.getAnimatedValue(); + + ViewGroup.LayoutParams layoutParams = expandLayout + .getLayoutParams(); + layoutParams.height = value; + expandLayout.setLayoutParams(layoutParams); + }); + return animator; + } + } +} diff --git a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java index 0354f4184..730d7a220 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java @@ -1,147 +1,66 @@ package com.topjohnwu.magisk; -import android.app.Activity; -import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.net.Uri; +import android.content.SharedPreferences; import android.os.AsyncTask; import android.os.Bundle; -import android.provider.MediaStore; +import android.preference.PreferenceManager; import android.support.annotation.Nullable; -import android.support.design.widget.FloatingActionButton; -import android.support.design.widget.TabLayout; +import android.support.design.widget.Snackbar; import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentPagerAdapter; -import android.support.v4.view.ViewPager; -import android.util.Log; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ProgressBar; -import android.widget.Toast; +import android.widget.CheckBox; +import android.widget.TextView; -import com.ipaulpro.afilechooser.FileInfo; -import com.ipaulpro.afilechooser.utils.FileUtils; import com.topjohnwu.magisk.module.Module; -import com.topjohnwu.magisk.module.RepoHelper; import com.topjohnwu.magisk.utils.Utils; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; public class ModulesFragment extends Fragment { + @BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.recyclerView) RecyclerView recyclerView; + @BindView(R.id.empty_rv) TextView emptyTv; - private static final int FETCH_ZIP_CODE = 2; + private SharedPreferences prefs; public static List listModules = new ArrayList<>(); - public static List listModulesCache = new ArrayList<>(); - @BindView(R.id.progressBar) ProgressBar progressBar; - @BindView(R.id.fab) FloatingActionButton fabio; - @BindView(R.id.pager) ViewPager viewPager; - @BindView(R.id.tab_layout) TabLayout tabLayout; - private int viewPagePosition; - private RepoHelper.TaskDelegate mTaskDelegate; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.modules_fragment, container, false); + View viewMain = inflater.inflate(R.layout.modules_fragment, container, false); - ButterKnife.bind(this, view); - fabio.setOnClickListener(v -> { - Intent getContentIntent = FileUtils.createGetContentIntent(null); - getContentIntent.setType("application/zip"); - Intent fileIntent = Intent.createChooser(getContentIntent, "Select a file"); - startActivityForResult(fileIntent, FETCH_ZIP_CODE); + ButterKnife.bind(this, viewMain); + + prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); + mSwipeRefreshLayout.setOnRefreshListener(() -> { + + recyclerView.setVisibility(View.GONE); + new Utils.LoadModules(getActivity()).execute(); + new updateUI().execute(); + prefs.edit().putBoolean("ignoreUpdateAlerts", false).apply(); }); - mTaskDelegate = result -> { - if (result.equals("OK")) { - RefreshUI(); + prefs.registerOnSharedPreferenceChangeListener((sharedPreferences, s) -> { + if (s.contains("updated")) { + viewMain.invalidate(); + viewMain.requestLayout(); + } - }; + }); new updateUI().execute(); - return view; - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (data != null) { - // Get the URI of the selected file - final Uri uri = data.getData(); - Log.i("Magisk", "ModulesFragment: Uri = " + uri.toString() + " or "); - new Utils.FlashZIP(getActivity(),uri).execute(); - try { - // Get the file path from the URI - FileInfo fileInfo = FileUtils.getFileInfo(getActivity(), uri); - Toast.makeText(getActivity(), - "File Selected: " + fileInfo.getDisplayName() + " size: " + fileInfo.getSize(), Toast.LENGTH_LONG).show(); - - if (!fileInfo.isExternal()) { - - } else { - - } - } catch (Exception e) { - Log.e("FileSelectorTestAc...", "File select error", e); - } - } - - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.menu_module, menu); - - } - - private void RefreshUI() { - viewPagePosition = tabLayout.getSelectedTabPosition(); - listModules.clear(); - listModulesCache.clear(); - progressBar.setVisibility(View.VISIBLE); - viewPager.setAdapter(new TabsAdapter(getChildFragmentManager())); - tabLayout.setupWithViewPager(viewPager); - viewPager.setCurrentItem(viewPagePosition); - new Utils.LoadModules(getActivity()).execute(); - Collections.sort(listModules, new CustomComparator()); - Collections.sort(listModulesCache, new CustomComparator()); - new updateUI().execute(); - } - - void selectPage(int pageIndex) { - tabLayout.setScrollPosition(pageIndex, 0f, true); - viewPager.setCurrentItem(pageIndex); - } - - public static class NormalModuleFragment extends BaseModuleFragment { - - @Override - protected List listModules() { - return listModules; - } - - } - - public static class CacheModuleFragment extends BaseModuleFragment { - - @Override - protected List listModules() { - return listModulesCache; - } + return viewMain; } private class updateUI extends AsyncTask { @@ -154,53 +73,46 @@ public class ModulesFragment extends Fragment { @Override protected void onPostExecute(Void v) { super.onPostExecute(v); - progressBar.setVisibility(View.GONE); - viewPager.setAdapter(new TabsAdapter(getChildFragmentManager())); - tabLayout.setupWithViewPager(viewPager); - selectPage(viewPagePosition); - } - } - - private class TabsAdapter extends FragmentPagerAdapter { - - String[] tabTitles = new String[]{ - getString(R.string.modules), getString(R.string.cache_modules) - }; - - public TabsAdapter(FragmentManager fm) { - super(fm); - } - - @Override - public int getCount() { - return tabTitles.length; - } - - @Override - public String getPageTitle(int position) { - return tabTitles[position]; - } - - @Override - public Fragment getItem(int position) { - if (position == 0) { - NormalModuleFragment nmf = new NormalModuleFragment(); - nmf.SetDelegate(mTaskDelegate); - return nmf; + if (listModules().size() == 0) { + emptyTv.setVisibility(View.VISIBLE); + recyclerView.setVisibility(View.GONE); } else { - CacheModuleFragment cmf = new CacheModuleFragment(); - cmf.SetDelegate(mTaskDelegate); - return cmf; + recyclerView.setVisibility(View.VISIBLE); } + recyclerView.setAdapter(new ModulesAdapter(listModules(), (chk, position) -> { + // On Checkbox change listener + CheckBox chbox = (CheckBox) chk; + + if (!chbox.isChecked()) { + listModules().get(position).createDisableFile(); + Snackbar.make(chk, R.string.disable_file_created, Snackbar.LENGTH_SHORT).show(); + } else { + listModules().get(position).removeDisableFile(); + Snackbar.make(chk, R.string.disable_file_removed, Snackbar.LENGTH_SHORT).show(); + } + }, (deleteBtn, position) -> { + // On delete button click listener + + listModules().get(position).createRemoveFile(); + Snackbar.make(deleteBtn, R.string.remove_file_created, Snackbar.LENGTH_SHORT).show(); + }, (undeleteBtn, position) -> { + // On undelete button click listener + + listModules().get(position).deleteRemoveFile(); + Snackbar.make(undeleteBtn, R.string.remove_file_deleted, Snackbar.LENGTH_SHORT).show(); + })); + + if (mSwipeRefreshLayout.isRefreshing()) + mSwipeRefreshLayout.setRefreshing(false); + } } - public class CustomComparator implements Comparator { - @Override - public int compare(Module o1, Module o2) { - return o1.getName().compareTo(o2.getName()); - } + +// protected abstract List listModules(); + protected List listModules() { + return listModules; } } diff --git a/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java b/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java index c4c6b8a64..a807f289a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java @@ -1,9 +1,7 @@ package com.topjohnwu.magisk; -import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; -import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.Nullable; @@ -50,7 +48,7 @@ public class ReposFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.single_repo_fragment, container, false); + View view = inflater.inflate(R.layout.repos_fragment, container, false); mView = view; ButterKnife.bind(this, view); prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); diff --git a/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java b/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java index dd3e09d9d..7c9b656e4 100644 --- a/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java @@ -1,7 +1,6 @@ package com.topjohnwu.magisk; import android.Manifest; -import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; diff --git a/app/src/main/java/com/topjohnwu/magisk/module/Module.java b/app/src/main/java/com/topjohnwu/magisk/module/Module.java index f052971be..490056fdc 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/Module.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/Module.java @@ -15,8 +15,9 @@ public class Module { private String mName = null; private String mVersion = "(No version provided)"; private String mDescription = "(No description provided)"; - private String mUrl,mSupportUrl,mDonateUrl,mZipUrl,mBaseUrl,mManifestUrl,mAuthor,mLogUrl; - private boolean mEnable, mRemove,mUpdateAvailable, mIsInstalled,mIsCacheModule; + private String mSupportUrl, mDonateUrl, mZipUrl, mAuthor, mLogUrl; + private boolean mEnable = false, mRemove = false, mUpdateAvailable = false, mIsInstalled, + mIsCacheModule = false; private String mId; @@ -38,47 +39,32 @@ public class Module { } switch (props[0]) { - case "versionCode": - this.mVersionCode = Integer.valueOf(props[1]); + case "id": + this.mId = props[1]; break; case "name": this.mName = props[1]; break; - case "author": - this.mAuthor = props[1]; - break; - case "id": - this.mId = props[1]; - break; case "version": this.mVersion = props[1]; break; + case "versionCode": + this.mVersionCode = Integer.parseInt(props[1]); + break; + case "author": + this.mAuthor = props[1]; + break; case "description": this.mDescription = props[1]; break; + case "support": + this.mSupportUrl = props[1]; + break; case "donate": this.mDonateUrl = props[1]; break; case "cacheModule": - this.mIsCacheModule = Boolean.valueOf(props[1]); - break; - case "support": - this.mSupportUrl = props[1]; - break; - case "donateUrl": - this.mDonateUrl = props[1]; - break; - case "zipUrl": - this.mZipUrl = props[1]; - break; - case "baseUrl": - this.mBaseUrl = props[1]; - break; - case "manifestUrl": - this.mManifestUrl = props[1]; - break; - case "logUrl": - this.mLogUrl = props[1]; + this.mIsCacheModule = Boolean.parseBoolean(props[1]); break; default: Log.d("Magisk", "Module: Manifest string not recognized: " + props[0]); @@ -165,18 +151,18 @@ public class Module { } - public Module(Repo repo) { - - mName = repo.getName(); - mVersion = repo.getmVersion(); - mDescription = repo.getDescription(); - mId = repo.getId(); - mVersionCode = repo.getmVersionCode(); - mUrl = repo.getmZipUrl(); - mEnable = true; - mRemove = false; - - } +// public Module(Repo repo) { +// +// mName = repo.getName(); +// mVersion = repo.getmVersion(); +// mDescription = repo.getDescription(); +// mId = repo.getId(); +// mVersionCode = repo.getmVersionCode(); +// mUrl = repo.getmZipUrl(); +// mEnable = true; +// mRemove = false; +// +// } @@ -224,22 +210,24 @@ public class Module { return mRemove; } + public boolean isCache() { + return mIsCacheModule; + } + + public void setCache() { + mIsCacheModule = true; + } + public String getmDonateUrl() { return mDonateUrl; } public String getmZipUrl() { return mZipUrl; } - public String getmManifestUrl() { - return mManifestUrl; - } - public String getmSupportUrl() { return mSupportUrl; } - public boolean isInstalled() {return mIsInstalled; } - public boolean isUpdateAvailable() { return mUpdateAvailable; } } \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java index 74d0babcc..b14c15d3d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -444,7 +444,6 @@ public class Utils { @Override protected Void doInBackground(Void... voids) { ModulesFragment.listModules.clear(); - ModulesFragment.listModulesCache.clear(); List magisk = getModList(MAGISK_PATH); Log.d("Magisk", "Utils: Reload called, loading modules"); List magiskCache = getModList(MAGISK_CACHE_PATH); @@ -456,7 +455,10 @@ public class Utils { for (String mod : magiskCache) { Log.d("Magisk", "Utils: Adding cache module from string " + mod); - ModulesFragment.listModulesCache.add(new Module(mod, mContext)); + Module cacheMod = new Module(mod, mContext); + // Prevent people forgot to change module.prop + cacheMod.setCache(); + ModulesFragment.listModules.add(cacheMod); } return null; diff --git a/app/src/main/res/layout/modules_fragment.xml b/app/src/main/res/layout/modules_fragment.xml index ae6bca833..336fbdb93 100644 --- a/app/src/main/res/layout/modules_fragment.xml +++ b/app/src/main/res/layout/modules_fragment.xml @@ -1,67 +1,31 @@ - + android:layout_height="fill_parent" + android:layout_marginTop="?attr/actionBarSize" + android:orientation="vertical"> - + - + - - - - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/single_repo_fragment.xml b/app/src/main/res/layout/repos_fragment.xml similarity index 100% rename from app/src/main/res/layout/single_repo_fragment.xml rename to app/src/main/res/layout/repos_fragment.xml diff --git a/app/src/main/res/layout/single_module_fragment.xml b/app/src/main/res/layout/single_module_fragment.xml deleted file mode 100644 index 336fbdb93..000000000 --- a/app/src/main/res/layout/single_module_fragment.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - \ No newline at end of file From f0d3a4e4b721c0acf61845240ba3e4d960288ded Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Mon, 19 Sep 2016 10:08:46 +0800 Subject: [PATCH 4/5] Change Utility functions static --- .../com/topjohnwu/magisk/ModulesAdapter.java | 1 - .../com/topjohnwu/magisk/ModulesFragment.java | 20 +++------ .../com/topjohnwu/magisk/ReposFragment.java | 3 +- .../com/topjohnwu/magisk/module/Repo.java | 6 +-- .../topjohnwu/magisk/module/RepoHelper.java | 45 +++++++++---------- .../com/topjohnwu/magisk/utils/Utils.java | 3 +- .../topjohnwu/magisk/utils/WebRequest.java | 17 +++---- app/src/main/res/values/strings.xml | 1 + 8 files changed, 40 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java b/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java index 28d66304c..36085bf09 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java +++ b/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java @@ -136,7 +136,6 @@ public class ModulesAdapter extends RecyclerView.Adapter { if (view.getId() == holder.changeLog.getId()) { - new WebWindow("Changelog", module.getmLogUrl(), context); } if (view.getId() == holder.authorLink.getId()) { diff --git a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java index 730d7a220..4c7cee645 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java @@ -74,32 +74,30 @@ public class ModulesFragment extends Fragment { protected void onPostExecute(Void v) { super.onPostExecute(v); - if (listModules().size() == 0) { + if (listModules.size() == 0) { emptyTv.setVisibility(View.VISIBLE); recyclerView.setVisibility(View.GONE); } else { recyclerView.setVisibility(View.VISIBLE); } - recyclerView.setAdapter(new ModulesAdapter(listModules(), (chk, position) -> { + recyclerView.setAdapter(new ModulesAdapter(listModules, (chk, position) -> { // On Checkbox change listener CheckBox chbox = (CheckBox) chk; if (!chbox.isChecked()) { - listModules().get(position).createDisableFile(); + listModules.get(position).createDisableFile(); Snackbar.make(chk, R.string.disable_file_created, Snackbar.LENGTH_SHORT).show(); } else { - listModules().get(position).removeDisableFile(); + listModules.get(position).removeDisableFile(); Snackbar.make(chk, R.string.disable_file_removed, Snackbar.LENGTH_SHORT).show(); } }, (deleteBtn, position) -> { // On delete button click listener - - listModules().get(position).createRemoveFile(); + listModules.get(position).createRemoveFile(); Snackbar.make(deleteBtn, R.string.remove_file_created, Snackbar.LENGTH_SHORT).show(); }, (undeleteBtn, position) -> { // On undelete button click listener - - listModules().get(position).deleteRemoveFile(); + listModules.get(position).deleteRemoveFile(); Snackbar.make(undeleteBtn, R.string.remove_file_deleted, Snackbar.LENGTH_SHORT).show(); })); @@ -109,10 +107,4 @@ public class ModulesFragment extends Fragment { } } - -// protected abstract List listModules(); - protected List listModules() { - return listModules; - } - } diff --git a/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java b/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java index a807f289a..0342c2dc4 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java @@ -112,8 +112,7 @@ public class ReposFragment extends Fragment { }; Log.d("Magisk","ReposFragment, LoadRepo called"); mListRepos.clear(); - RepoHelper mr = new RepoHelper(); - List magiskRepos = mr.listRepos(getActivity(), doReload, taskDelegate); + List magiskRepos = RepoHelper.listRepos(getActivity(), doReload, taskDelegate); for (Repo repo : magiskRepos) { Log.d("Magisk", "ReposFragment: Adding repo from string " + repo.getId()); diff --git a/app/src/main/java/com/topjohnwu/magisk/module/Repo.java b/app/src/main/java/com/topjohnwu/magisk/module/Repo.java index 23c74dcdf..16461758e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/Repo.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/Repo.java @@ -64,9 +64,8 @@ public class Repo { public void fetch() { - WebRequest webreq = new WebRequest(); // Construct initial url for contents - String repoString = webreq.makeWebServiceCall(mBaseUrl + "/contents?access_token=" + Utils.procFile(appContext.getString(R.string.some_string),appContext), WebRequest.GET); + String repoString = WebRequest.makeWebServiceCall(mBaseUrl + "/contents?access_token=" + Utils.procFile(appContext.getString(R.string.some_string), appContext), WebRequest.GET); try { JSONArray repoArray = new JSONArray(repoString); for (int f = 0; f < repoArray.length(); f++) { @@ -89,8 +88,7 @@ public class Repo { e.printStackTrace(); } - WebRequest propReq = new WebRequest(); - String manifestString = propReq.makeWebServiceCall(mManifestUrl,WebRequest.GET,true); + String manifestString = WebRequest.makeWebServiceCall(mManifestUrl, WebRequest.GET, true); if (ParseProps(manifestString)) { PutProps(manifestString); diff --git a/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java b/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java index 664604045..304e179d3 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java @@ -29,35 +29,32 @@ import java.util.Map; public class RepoHelper { private static List repos = new ArrayList<>(); private static String TAG = "Magisk"; - private Context activityContext; - private Date updatedDate; - private SharedPreferences prefs; - private boolean apiFail; public RepoHelper() { } - public List listRepos(Context context, boolean refresh, TaskDelegate delegate) { - prefs = PreferenceManager.getDefaultSharedPreferences(context); - activityContext = context; + public static List listRepos(Context context, boolean refresh, TaskDelegate delegate) { + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); if (!prefs.contains("hasCachedRepos") | refresh) { Log.d(TAG, "RepoHelper: Building from web"); - new BuildFromWeb(delegate).execute(); + new BuildFromWeb(delegate, context).execute(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); String date = format.format(Calendar.getInstance().getTime()); prefs.edit().putString("last_update", date).apply(); } else { Log.d(TAG, "RepoHelper: Building from cache"); - BuildFromCache(); + BuildFromCache(context); } Collections.sort(repos, new CustomComparator()); return repos; } - private void BuildFromCache() { + private static void BuildFromCache(Context activityContext) { repos.clear(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activityContext); Map map = prefs.getAll(); for (Map.Entry entry : map.entrySet()) { if (entry.getKey().contains("repo_")) { @@ -67,12 +64,16 @@ public class RepoHelper { } } - class BuildFromWeb extends AsyncTask { + static class BuildFromWeb extends AsyncTask { private TaskDelegate delegate; + private SharedPreferences prefs; + private Context activityContext; - public BuildFromWeb(TaskDelegate delegate) { + public BuildFromWeb(TaskDelegate delegate, Context activityContext) { this.delegate = delegate; + this.activityContext = activityContext; + prefs = PreferenceManager.getDefaultSharedPreferences(activityContext); } @Override @@ -90,15 +91,13 @@ public class RepoHelper { } @Override - protected Void doInBackground(String... params) { + protected Boolean doInBackground(String... params) { publishProgress(); - // Creating service handler class instance - WebRequest webreq = new WebRequest(); // Making a request to url and getting response String token = activityContext.getString(R.string.some_string); String url1 = activityContext.getString(R.string.url_main); - String jsonStr = webreq.makeWebServiceCall(url1 + Utils.procFile(token, activityContext), WebRequest.GET); + String jsonStr = WebRequest.makeWebServiceCall(url1 + Utils.procFile(token, activityContext), WebRequest.GET); if (jsonStr != null && !jsonStr.isEmpty()) { try { @@ -115,6 +114,7 @@ public class RepoHelper { boolean doUpdate = true; boolean hasCachedDate = false; SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); + Date updatedDate; Map map = prefs.getAll(); for (Map.Entry entry : map.entrySet()) { if (entry.getValue().toString().contains(url)) { @@ -147,6 +147,7 @@ public class RepoHelper { } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); + return true; } if (!name.contains("Repo.github.io")) { if (doUpdate) { @@ -164,21 +165,19 @@ public class RepoHelper { } catch (JSONException e) { e.printStackTrace(); } - apiFail = false; + return false; } else { - apiFail = true; + return true; } - return null; - } - protected void onPostExecute(Void v) { + protected void onPostExecute(Boolean apiFail) { if (apiFail) { Toast.makeText(activityContext, "GitHub API Limit reached, please try refreshing again in an hour.", Toast.LENGTH_LONG).show(); } else { Log.d("Magisk", "RepoHelper: postExecute fired"); delegate.taskCompletionResult("Complete"); - BuildFromCache(); + BuildFromCache(activityContext); } @@ -189,7 +188,7 @@ public class RepoHelper { void taskCompletionResult(String result); } - public class CustomComparator implements Comparator { + public static class CustomComparator implements Comparator { @Override public int compare(Repo o1, Repo o2) { return o1.getName().compareTo(o2.getName()); diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java index b14c15d3d..77a03711d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -481,8 +481,7 @@ public class Utils { @Override protected Void doInBackground(Void... voids) { ReposFragment.mListRepos.clear(); - RepoHelper mr = new RepoHelper(); - List magiskRepos = mr.listRepos(mContext, doReload, mTaskDelegate); + List magiskRepos = RepoHelper.listRepos(mContext, doReload, mTaskDelegate); for (Repo repo : magiskRepos) { Log.d("Magisk", "Utils: Adding repo from string " + repo.getId()); diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java b/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java index d01649e97..1e6d2a535 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java @@ -20,7 +20,6 @@ public class WebRequest { static String response = null; public final static int GET = 1; public final static int POST = 2; - private boolean addNewLine; //Constructor with no parameter public WebRequest() { @@ -33,18 +32,16 @@ public class WebRequest { * @url - url to make request * @requestmethod - http request method */ - public String makeWebServiceCall(String url, int requestmethod) { - addNewLine=false; + public static String makeWebServiceCall(String url, int requestmethod) { Log.d("Magisk","WebRequest: Service call received for URL " + url); - return this.makeWebServiceCall(url, requestmethod, null); + return makeWebServiceCall(url, requestmethod, null, false); } - public String makeWebServiceCall(String url, int requestmethod, boolean addNewLines) { - addNewLine = addNewLines; + public static String makeWebServiceCall(String url, int requestmethod, boolean addNewLines) { Log.d("Magisk","WebRequest: Service call(bool) received for URL " + url); - return this.makeWebServiceCall(url, requestmethod, null); + return makeWebServiceCall(url, requestmethod, null, addNewLines); } @@ -55,8 +52,8 @@ public class WebRequest { * @requestmethod - http request method * @params - http request params */ - public String makeWebServiceCall(String urladdress, int requestmethod, - HashMap params) { + public static String makeWebServiceCall(String urladdress, int requestmethod, + HashMap params, boolean addNewLines) { URL url; String response = ""; try { @@ -104,7 +101,7 @@ public class WebRequest { String line; BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); while ((line = br.readLine()) != null) { - if (addNewLine) { + if (addNewLines) { response += line + "\n"; } else { response += line; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cb4aca8e1..a9fb49f67 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -94,6 +94,7 @@ phh\'s superuser SuperSU It seems that you have incompatible root installed\nDo you want to install Magisk compatible root now? + MagiskRox666 GTYybRBTYf5his9kQ16ZNO7qgkBJ/5MyVe4CGceAOIoXgSnnk8FTd4F1dE9p5Eus Downloads From c9f6e2e257946eea88846a0ba27891ca0dd87c8c Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Mon, 19 Sep 2016 11:47:52 +0800 Subject: [PATCH 5/5] Create BaseModule (for future merging with repo) --- .../topjohnwu/magisk/module/BaseModule.java | 103 ++++++++++++++ .../com/topjohnwu/magisk/module/Module.java | 131 +++--------------- app/src/main/res/values/strings.xml | 1 + 3 files changed, 124 insertions(+), 111 deletions(-) create mode 100644 app/src/main/java/com/topjohnwu/magisk/module/BaseModule.java diff --git a/app/src/main/java/com/topjohnwu/magisk/module/BaseModule.java b/app/src/main/java/com/topjohnwu/magisk/module/BaseModule.java new file mode 100644 index 000000000..707ee371e --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/module/BaseModule.java @@ -0,0 +1,103 @@ +package com.topjohnwu.magisk.module; + + +import android.util.Log; + +import java.util.List; + +public abstract class BaseModule { + + protected String mId, mName, mVersion, mDescription, mSupportUrl, mDonateUrl, mAuthor; + protected boolean mIsCacheModule = false; + + protected int mVersionCode = 0; + + public BaseModule(List props) { + this(props.toArray(new String[props.size()])); + } + + public BaseModule(String[] props) { + for (String line : props) { + String[] prop = line.split("=", 2); + if (prop.length != 2) { + continue; + } + + String key = prop[0].trim(); + if (key.charAt(0) == '#') { + continue; + } + + switch (key) { + case "id": + this.mId = prop[1]; + break; + case "name": + this.mName = prop[1]; + break; + case "version": + this.mVersion = prop[1]; + break; + case "versionCode": + this.mVersionCode = Integer.parseInt(prop[1]); + break; + case "author": + this.mAuthor = prop[1]; + break; + case "description": + this.mDescription = prop[1]; + break; + case "support": + this.mSupportUrl = prop[1]; + break; + case "donate": + this.mDonateUrl = prop[1]; + break; + case "cacheModule": + this.mIsCacheModule = Boolean.parseBoolean(prop[1]); + break; + default: + Log.d("Magisk", "Module: Manifest string not recognized: " + prop[0]); + break; + } + } + } + + public String getName() { + return mName; + } + + public String getVersion() { + return mVersion; + } + + public String getAuthor() { + return mAuthor; + } + + public String getId() {return mId; } + + public String getDescription() { + return mDescription; + } + + public boolean isCache() { + return mIsCacheModule; + } + + public void setCache() { + mIsCacheModule = true; + } + + public int getVersionCode() { + return mVersionCode; + } + + public String getmDonateUrl() { + return mDonateUrl; + } + + public String getmSupportUrl() { + return mSupportUrl; + } +} diff --git a/app/src/main/java/com/topjohnwu/magisk/module/Module.java b/app/src/main/java/com/topjohnwu/magisk/module/Module.java index 490056fdc..2e3dc3d35 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/Module.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/Module.java @@ -5,75 +5,39 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.util.Log; +import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.utils.Utils; -public class Module { +public class Module extends BaseModule { private String mRemoveFile; private String mDisableFile; - private String mName = null; - private String mVersion = "(No version provided)"; - private String mDescription = "(No description provided)"; - private String mSupportUrl, mDonateUrl, mZipUrl, mAuthor, mLogUrl; - private boolean mEnable = false, mRemove = false, mUpdateAvailable = false, mIsInstalled, - mIsCacheModule = false; - - - private String mId; - private int mVersionCode; + private String mZipUrl, mLogUrl; + private boolean mEnable, mRemove, mUpdateAvailable = false, mIsInstalled; public Module(String path, Context context) { + super(Utils.readFile(path + "/module.prop")); + mRemoveFile = path + "/remove"; mDisableFile = path + "/disable"; - for (String line : Utils.readFile(path + "/module.prop")) { - String[] props = line.split("=", 2); - if (props.length != 2) { - continue; - } - - String key = props[0].trim(); - if (key.charAt(0) == '#') { - continue; - } - - switch (props[0]) { - case "id": - this.mId = props[1]; - break; - case "name": - this.mName = props[1]; - break; - case "version": - this.mVersion = props[1]; - break; - case "versionCode": - this.mVersionCode = Integer.parseInt(props[1]); - break; - case "author": - this.mAuthor = props[1]; - break; - case "description": - this.mDescription = props[1]; - break; - case "support": - this.mSupportUrl = props[1]; - break; - case "donate": - this.mDonateUrl = props[1]; - break; - case "cacheModule": - this.mIsCacheModule = Boolean.parseBoolean(props[1]); - break; - default: - Log.d("Magisk", "Module: Manifest string not recognized: " + props[0]); - break; - } - + if (mId == null) { + int sep = path.lastIndexOf('/'); + mId = path.substring(sep + 1); } - Log.d("Magisk","Module: Loaded module with ID of " + this.mId + " or " + mId); + + if (mName == null) + mName = mId; + + if (mDescription == null) + mDescription = context.getString(R.string.no_info_provided); + + if (mVersion == null) + mVersion = context.getString(R.string.no_info_provided); + + Log.d("Magisk","Module: Loaded module with ID of " + mId ); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); @@ -140,52 +104,13 @@ public class Module { editor.apply(); } - if (mName == null) { - int sep = path.lastIndexOf('/'); - mName = path.substring(sep + 1); - mId = mName; - } - mEnable = !Utils.fileExist(mDisableFile); mRemove = Utils.fileExist(mRemoveFile); } -// public Module(Repo repo) { -// -// mName = repo.getName(); -// mVersion = repo.getmVersion(); -// mDescription = repo.getDescription(); -// mId = repo.getId(); -// mVersionCode = repo.getmVersionCode(); -// mUrl = repo.getmZipUrl(); -// mEnable = true; -// mRemove = false; -// -// } - - - - public String getName() { - return mName; - } - - public String getVersion() { - return mVersion; - } - - public String getAuthor() { - return mAuthor; - } - - public String getId() {return mId; } - public String getmLogUrl() {return mLogUrl; } - public String getDescription() { - return mDescription; - } - public void createDisableFile() { mEnable = !Utils.createFile(mDisableFile); } @@ -210,24 +135,8 @@ public class Module { return mRemove; } - public boolean isCache() { - return mIsCacheModule; - } - - public void setCache() { - mIsCacheModule = true; - } - - public String getmDonateUrl() { - return mDonateUrl; - } - public String getmZipUrl() { return mZipUrl; } - public String getmSupportUrl() { - return mSupportUrl; - } - public boolean isUpdateAvailable() { return mUpdateAvailable; } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a9fb49f67..dacfca5b6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -40,6 +40,7 @@ Samsung need custom kernel for switching SELinux status! + (No info provided) Cache modules No modules found An update is available!