From aa991b62f40f2f964f08373700e7c06a7ce0fe44 Mon Sep 17 00:00:00 2001 From: d8ahazard Date: Fri, 2 Sep 2016 13:18:37 -0500 Subject: [PATCH] My brain hurts... --- .../topjohnwu/magisk/BaseModuleFragment.java | 45 ++++++++++++- .../topjohnwu/magisk/BaseRepoFragment.java | 23 ++++++- .../com/topjohnwu/magisk/ModulesFragment.java | 11 +++- .../com/topjohnwu/magisk/ReposAdapter.java | 27 +++++--- .../com/topjohnwu/magisk/WelcomeActivity.java | 6 +- .../com/topjohnwu/magisk/module/Module.java | 18 +++++- .../com/topjohnwu/magisk/module/Repo.java | 41 +++++++----- .../com/topjohnwu/magisk/utils/Utils.java | 64 ++++++++++++++++--- .../res/layout/single_module_fragment.xml | 13 ++-- 9 files changed, 199 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java b/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java index 9a01bfa7f..739ec0463 100644 --- a/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java @@ -1,10 +1,14 @@ package com.topjohnwu.magisk; +import android.content.SharedPreferences; 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.widget.RecyclerView; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -15,6 +19,7 @@ import com.topjohnwu.magisk.module.Module; import com.topjohnwu.magisk.utils.Utils; import java.util.List; +import java.util.concurrent.ExecutionException; import butterknife.BindView; import butterknife.ButterKnife; @@ -23,13 +28,30 @@ public abstract class BaseModuleFragment extends Fragment { @BindView(R.id.recyclerView) RecyclerView recyclerView; @BindView(R.id.empty_rv) TextView emptyTv; - + private SwipeRefreshLayout mSwipeRefreshLayout; + private View view; + private SharedPreferences prefs; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.single_module_fragment, container, false); - ButterKnife.bind(this, view); + view = inflater.inflate(R.layout.single_module_fragment, container, false); + mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefreshLayout); + mSwipeRefreshLayout.setOnRefreshListener(() -> { + refreshItems(); + }); + ButterKnife.bind(this, view); + prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); + prefs.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() { + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { + if (s.contains("updated")) { + view.invalidate(); + view.requestLayout(); + + } + } + }); if (listModules().size() == 0) { emptyTv.setVisibility(View.VISIBLE); recyclerView.setVisibility(View.GONE); @@ -62,5 +84,22 @@ public abstract class BaseModuleFragment extends Fragment { return view; } + void refreshItems() { + Log.d("Magisk", "Calling refreshitems for online"); + Utils.LoadModules utils = new Utils.LoadModules(getActivity(),true); + utils.execute(); + onItemsLoadComplete(); + view.requestLayout(); + } + + + void onItemsLoadComplete() { + // Update the adapter and notify data set changed + // ... + + // Stop refresh animation + mSwipeRefreshLayout.setRefreshing(false); + } + protected abstract List listModules(); } diff --git a/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java b/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java index 417f8fc3e..a60bd1043 100644 --- a/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java @@ -3,7 +3,9 @@ package com.topjohnwu.magisk; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; +import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -11,6 +13,7 @@ import android.widget.TextView; import com.topjohnwu.magisk.module.Module; import com.topjohnwu.magisk.module.Repo; +import com.topjohnwu.magisk.utils.Utils; import java.util.List; @@ -23,11 +26,16 @@ public abstract class BaseRepoFragment extends Fragment { RecyclerView recyclerView; @BindView(R.id.empty_rv) TextView emptyTv; - + private SwipeRefreshLayout mSwipeRefreshLayout; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.single_module_fragment, container, false); + mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefreshLayout); + mSwipeRefreshLayout.setOnRefreshListener(() -> { + refreshItems(); + }); + ButterKnife.bind(this, view); if (listRepos().size() == 0) { @@ -43,5 +51,18 @@ public abstract class BaseRepoFragment extends Fragment { return view; } + void refreshItems() { + Log.d("Magisk", "Calling refreshitems for online"); + new Utils.LoadModules(getActivity(),true).execute(); + onItemsLoadComplete(); + } + + void onItemsLoadComplete() { + // Update the adapter and notify data set changed + // ... + + // Stop refresh animation + mSwipeRefreshLayout.setRefreshing(false); + } protected abstract List listRepos(); } diff --git a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java index d65cc7493..3ab89fcc1 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java @@ -2,9 +2,11 @@ package com.topjohnwu.magisk; import android.app.Activity; import android.content.Intent; +import android.content.SharedPreferences; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.annotation.Nullable; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.TabLayout; @@ -50,7 +52,12 @@ public class ModulesFragment extends Fragment { public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.modules_fragment, container, false); ButterKnife.bind(this, view); - new Utils.LoadModules(getContext()).execute(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); + if (prefs.contains("hasCachedRepos")) { + new Utils.LoadModules(getActivity(), false).execute(); + } else { + new Utils.LoadModules(getActivity(), true).execute(); + } new updateUI().execute(); setHasOptionsMenu(true); return view; @@ -99,7 +106,7 @@ public class ModulesFragment extends Fragment { progressBar.setVisibility(View.VISIBLE); viewPager.setAdapter(new TabsAdapter(getChildFragmentManager())); tabLayout.setupWithViewPager(viewPager); - new Utils.LoadModules(getContext()).execute(); + new Utils.LoadModules(getActivity(),false).execute(); new updateUI().execute(); break; } diff --git a/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java b/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java index a07eed510..f543e7d29 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java +++ b/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java @@ -1,6 +1,8 @@ package com.topjohnwu.magisk; import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; @@ -9,6 +11,7 @@ import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; import com.topjohnwu.magisk.module.Module; import com.topjohnwu.magisk.module.Repo; @@ -52,17 +55,21 @@ public class ReposAdapter extends RecyclerView.Adapter view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + if (!prefs.contains("isInstalled_" + repo.getName())) { - Utils.DownloadReceiver reciever = new Utils.DownloadReceiver() { - @Override - public void task(File file) { - Log.d("Magisk","Task firing"); - new Utils.FlashZIP(context,repo.getName(),file.toString()).execute(); - } - }; - String filename = repo.getName().replace(" ","") + ".zip"; - Utils.downloadAndReceive(context,reciever,repo.getZipUrl(),filename); - + Utils.DownloadReceiver reciever = new Utils.DownloadReceiver() { + @Override + public void task(File file) { + Log.d("Magisk", "Task firing"); + new Utils.FlashZIP(context, repo.getName(), file.toString()).execute(); + } + }; + String filename = repo.getName().replace(" ", "") + ".zip"; + Utils.downloadAndReceive(context, reciever, repo.getZipUrl(), filename); + } else { + Toast.makeText(context,repo.getName() + " is already installed.",Toast.LENGTH_SHORT).show(); + } } }); diff --git a/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java b/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java index a7b1a9377..6d34d7cfd 100644 --- a/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java @@ -1,6 +1,8 @@ package com.topjohnwu.magisk; import android.Manifest; +import android.app.Activity; +import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; @@ -28,6 +30,7 @@ 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(); @@ -55,7 +58,7 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView } new Utils.Initialize(this).execute(); new Utils.CheckUpdates(this).execute(); - new Utils.LoadModules(this).execute(); + new Utils.LoadModules(getApplication(),false).execute(); setSupportActionBar(toolbar); @@ -88,6 +91,7 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView } + @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); 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 51e3736bb..c46998f08 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/Module.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/Module.java @@ -1,7 +1,14 @@ package com.topjohnwu.magisk.module; +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.util.Log; + import com.topjohnwu.magisk.utils.Utils; +import java.util.Map; + public class Module { private String mRemoveFile; @@ -18,7 +25,16 @@ public class Module { private String mId; private int mVersionCode; - public Module(String path) { + public Module(String path, Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + Map keys = prefs.getAll(); + + for(Map.Entry entry : keys.entrySet()){ + + if(entry.getValue().toString().contains(path)) { + Log.d("Magisk", "Hey, look a matching path, this guy's name is " + entry.getKey().replace("path_","")); + } + } mRemoveFile = path + "/remove"; mDisableFile = path + "/disable"; for (String line : Utils.readFile(path + "/module.prop")) { 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 ea35ca871..228e7809c 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/Repo.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/Repo.java @@ -11,38 +11,43 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import java.util.HashSet; -import java.util.Set; +import java.text.SimpleDateFormat; +import java.util.Date; public class Repo { public String name; - public String baseUrl, zipUrl,manifestUrl, logUrl; - public String manifest, version, moduleName, moduleDescription, moduleAuthor, moduleAuthorUrl; - public Boolean usesRoot,usesXposed; + public String baseUrl, zipUrl, manifestUrl, logUrl, manifest, version, moduleName, moduleDescription, moduleAuthor, moduleAuthorUrl; + public Date lastUpdate; + public Boolean usesRoot, usesXposed; private Context appContext; private SharedPreferences prefs; - public Repo(String name, String url, Context context) { + public Repo(String name, String url, Date updated, Context context) { appContext = context; this.name = name; this.baseUrl = url; - prefs = PreferenceManager.getDefaultSharedPreferences(appContext); + this.lastUpdate = updated; + this.fetch(); } - public Repo(String moduleName, String moduleDescription, String zipUrl) { + public Repo(String moduleName, String moduleDescription, String zipUrl, Date lastUpdated, Context context) { + Log.d("Magisk", "Hey, I'm a repo! My name is " + moduleName); + appContext = context; this.zipUrl = zipUrl; this.moduleDescription = moduleDescription; this.moduleName = moduleName; - prefs = PreferenceManager.getDefaultSharedPreferences(appContext); + this.lastUpdate = lastUpdated; + + } public void fetch() { - + prefs = PreferenceManager.getDefaultSharedPreferences(appContext); WebRequest webreq = new WebRequest(); // Construct initial url for contents - Log.d("Magisk","Manifest string is: " + baseUrl + "/contents/"); + Log.d("Magisk", "Manifest string is: " + baseUrl + "/contents/"); String repoString = webreq.makeWebServiceCall(baseUrl + "/contents/", WebRequest.GET); try { @@ -63,13 +68,13 @@ public class Repo { e.printStackTrace(); } - Log.d("Magisk","Inner fetch: " + repoString); + Log.d("Magisk", "Inner fetch: " + repoString); try { WebRequest jsonReq = new WebRequest(); // Construct initial url for contents String manifestString = webreq.makeWebServiceCall(this.manifestUrl, WebRequest.GET); JSONObject manifestObject = new JSONObject(manifestString); - Log.d("Magisk","Object: " +manifestObject.toString()); + Log.d("Magisk", "Object: " + manifestObject.toString()); version = manifestObject.getString("versionCode"); moduleName = manifestObject.getString("moduleName"); moduleDescription = manifestObject.getString("moduleDescription"); @@ -84,9 +89,13 @@ public class Repo { + "\"usesRoot\":\"" + usesRoot + "\"," + "\"usesXposed\":\"" + usesXposed + "\"," + "\"zipUrl\":\"" + zipUrl + "\"," + + "\"lastUpdate\":\"" + lastUpdate + "\"," + "\"logUrl\":\"" + logUrl + "\"}]"; - editor.putString("module_" + moduleName,prefsString); - editor.putBoolean("hasCachedRepos",true); + editor.putString("module_" + moduleName, prefsString); + editor.putBoolean("hasCachedRepos", true); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss"); + editor.putString("updated", sdf.toString()); + Log.d("Magisk", "Storing Preferences: " + prefsString); editor.apply(); } catch (JSONException e) { @@ -116,6 +125,4 @@ public class Repo { } - - } \ 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 3e8c619ba..ebe8a68aa 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -28,6 +28,7 @@ import com.topjohnwu.magisk.module.Module; import com.topjohnwu.magisk.module.RepoAdapter; import com.topjohnwu.magisk.module.Repo; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -37,17 +38,21 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.List; public class Utils { public static int magiskVersion, remoteMagiskVersion = -1, remoteAppVersion = -1; public static String magiskLink, magiskChangelog, appChangelog, appLink, phhLink, supersuLink; + private Context appContext; public static final String MAGISK_PATH = "/magisk"; public static final String MAGISK_CACHE_PATH = "/cache/magisk"; public static final String UPDATE_JSON = "https://raw.githubusercontent.com/topjohnwu/MagiskManager/updates/magisk_update.json"; + public static boolean fileExist(String path) { List ret; ret = Shell.sh("if [ -f " + path + " ]; then echo true; else echo false; fi"); @@ -87,6 +92,10 @@ public class Utils { return ret; } + public Utils(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(); @@ -366,9 +375,14 @@ public class Utils { public static class LoadModules extends AsyncTask { private Context mContext; + private boolean doReload; - public LoadModules(Context context) { + public LoadModules(Context context, boolean reload) { + Log.d("Magisk", "LoadModules created, online is " + reload); mContext = context; + doReload = reload; + + } @Override @@ -377,17 +391,17 @@ public class Utils { ModulesFragment.listModulesCache.clear(); ModulesFragment.listModulesDownload.clear(); List magisk = getModList(MAGISK_PATH); - Log.d("Magisk", String.valueOf(magisk)); + Log.d("Magisk", "Reload called, online mode set to " + doReload); List magiskCache = getModList(MAGISK_CACHE_PATH); RepoAdapter mr = new RepoAdapter(); - List magiskRepos = mr.listRepos(mContext); + + List magiskRepos = mr.listRepos(mContext, doReload); for (String mod : magisk) { - Log.d("Magisk","Utils, listing modules " + mod); - ModulesFragment.listModules.add(new Module(mod)); + ModulesFragment.listModules.add(new Module(mod,mContext)); } for (String mod : magiskCache) { - ModulesFragment.listModulesCache.add(new Module(mod)); + ModulesFragment.listModulesCache.add(new Module(mod,mContext)); } for (Repo repo : magiskRepos) { ModulesFragment.listModulesDownload.add(repo); @@ -395,6 +409,11 @@ public class Utils { return null; } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + } } public static class FlashZIP extends AsyncTask { @@ -402,6 +421,7 @@ public class Utils { private String mPath, mName; private ProgressDialog progress; private Context mContext; + private List ret; public FlashZIP(Context context, String name, String path) { mContext = context; @@ -420,7 +440,7 @@ public class Utils { if (!Shell.rootAccess()) { return false; } else { - List ret = Shell.su( + ret = Shell.su( "rm -rf /data/tmp", "mkdir -p /data/tmp", "cp -af " + mPath + " /data/tmp/install.zip", @@ -428,7 +448,6 @@ public class Utils { "BOOTMODE=true sh /data/tmp/META-INF/com/google/android/update-binary dummy 1 /data/tmp/install.zip", "if [ $? -eq 0 ]; then echo true; else echo false; fi" ); - Log.d("Magisk","ZipResult: " + ret.toString()); return Boolean.parseBoolean(ret.get(ret.size() -1)); } } @@ -441,6 +460,35 @@ public class Utils { if (!result) { Toast.makeText(mContext, mContext.getString(R.string.manual_install, mPath), Toast.LENGTH_LONG).show(); return; + } else { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext); + String jsonString = prefs.getString("module_" + mName,""); + String retSplit[] = ret.toString().split("Using path:"); + String ret2Split[] = retSplit[1].split(","); + String ret3Split[] = ret2Split[0].split("/"); + String finalSplit = "/" + ret3Split[1] + "/" + ret3Split[2]; + Log.d("Magisk","Damn, all that work for one path " + finalSplit); + if (!jsonString.equals("")) { + + JSONArray repoArray = null; + try { + repoArray = new JSONArray(jsonString); + + + for (int f = 0; f < repoArray.length(); f++) { + JSONObject jsonobject = repoArray.getJSONObject(f); + String name = mName; + Boolean installed = true; + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean("isInstalled_" + mName,true); + editor.putString("path_" + mName,finalSplit); + editor.apply(); + + } + } catch (JSONException e) { + e.printStackTrace(); + } + } } done(); } diff --git a/app/src/main/res/layout/single_module_fragment.xml b/app/src/main/res/layout/single_module_fragment.xml index 0b9aa8c9b..42363f378 100644 --- a/app/src/main/res/layout/single_module_fragment.xml +++ b/app/src/main/res/layout/single_module_fragment.xml @@ -1,9 +1,10 @@ - + - \ No newline at end of file + \ No newline at end of file