From f404fe05706e08cb7b678b7799d0b38859818b00 Mon Sep 17 00:00:00 2001 From: d8ahazard Date: Tue, 6 Sep 2016 16:54:08 -0500 Subject: [PATCH 1/4] Break/Fix Wheeeeee --- .../topjohnwu/magisk/BaseModuleFragment.java | 53 ++-- .../topjohnwu/magisk/BaseRepoFragment.java | 26 +- .../com/topjohnwu/magisk/ModulesFragment.java | 37 ++- .../com/topjohnwu/magisk/ReposAdapter.java | 91 +++++-- .../com/topjohnwu/magisk/module/Module.java | 125 ++++++--- .../com/topjohnwu/magisk/module/Repo.java | 250 +++++++++++++----- .../topjohnwu/magisk/module/RepoAdapter.java | 52 ++-- .../magisk/utils/AnimationHelper.java | 58 ++++ .../com/topjohnwu/magisk/utils/GitAgent.java | 8 + .../com/topjohnwu/magisk/utils/Utils.java | 8 +- .../topjohnwu/magisk/utils/WebRequest.java | 11 +- app/src/main/res/drawable/ic_done_black.xml | 9 + app/src/main/res/layout/list_item_repo.xml | 24 +- .../res/layout/list_item_repo_expanded.xml | 67 +++++ .../res/layout/single_module_fragment.xml | 7 +- app/src/main/res/values/strings.xml | 3 + 16 files changed, 607 insertions(+), 222 deletions(-) create mode 100644 app/src/main/java/com/topjohnwu/magisk/utils/AnimationHelper.java create mode 100644 app/src/main/java/com/topjohnwu/magisk/utils/GitAgent.java create mode 100644 app/src/main/res/drawable/ic_done_black.xml create mode 100644 app/src/main/res/layout/list_item_repo_expanded.xml diff --git a/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java b/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java index 739ec0463..e41a73df8 100644 --- a/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java @@ -6,9 +6,7 @@ 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; @@ -19,26 +17,24 @@ 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; public abstract class BaseModuleFragment extends Fragment { - @BindView(R.id.recyclerView) RecyclerView recyclerView; - @BindView(R.id.empty_rv) TextView emptyTv; - private SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.recyclerView) + RecyclerView recyclerView; + @BindView(R.id.empty_rv) + TextView emptyTv; private View view; private SharedPreferences prefs; + @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 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()); @@ -59,16 +55,19 @@ public abstract class BaseModuleFragment extends Fragment { return view; } - recyclerView.setAdapter(new ModulesAdapter(listModules(), (chk, position) -> { - // On Checkbox change listener - CheckBox chbox = (CheckBox) chk; + recyclerView.setAdapter(new ModulesAdapter(listModules(), new Utils.ItemClickListener() { + @Override + public void onItemClick(View chk, int 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(); + if (!chbox.isChecked()) { + BaseModuleFragment.this.listModules().get(position).createDisableFile(); + Snackbar.make(chk, R.string.disable_file_created, Snackbar.LENGTH_SHORT).show(); + } else { + BaseModuleFragment.this.listModules().get(position).removeDisableFile(); + Snackbar.make(chk, R.string.disable_file_removed, Snackbar.LENGTH_SHORT).show(); + } } }, (deleteBtn, position) -> { // On delete button click listener @@ -84,22 +83,6 @@ 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 a60bd1043..bc7d49474 100644 --- a/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java @@ -3,17 +3,14 @@ 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.CardView; import android.support.v7.widget.RecyclerView; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; 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; @@ -26,15 +23,14 @@ 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); @@ -51,18 +47,6 @@ 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 3ab89fcc1..0af544180 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java @@ -14,6 +14,7 @@ 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.support.v4.widget.SwipeRefreshLayout; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; @@ -40,7 +41,9 @@ public class ModulesFragment extends Fragment { public static List listModulesCache = new ArrayList<>(); public static List listModulesDownload = new ArrayList<>(); private static final int FILE_SELECT_CODE = 0; + private TabsAdapter ta; private File input; + private SwipeRefreshLayout mSwipeRefreshLayout; @BindView(R.id.progressBar) ProgressBar progressBar; @BindView(R.id.fab) FloatingActionButton fabio; @@ -51,6 +54,7 @@ public class ModulesFragment extends Fragment { @Override 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); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); if (prefs.contains("hasCachedRepos")) { @@ -58,11 +62,18 @@ public class ModulesFragment extends Fragment { } else { new Utils.LoadModules(getActivity(), true).execute(); } + new updateUI().execute(); setHasOptionsMenu(true); return view; } + public void updateThisShit() { + new Utils.LoadModules(getActivity(), true).execute(); + new updateUI().execute(); + setHasOptionsMenu(true); + } + @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); @@ -82,6 +93,8 @@ public class ModulesFragment extends Fragment { } + + public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case FILE_SELECT_CODE: @@ -104,9 +117,10 @@ public class ModulesFragment extends Fragment { listModulesCache.clear(); listModulesDownload.clear(); progressBar.setVisibility(View.VISIBLE); - viewPager.setAdapter(new TabsAdapter(getChildFragmentManager())); + ta = new TabsAdapter(getChildFragmentManager()); + viewPager.setAdapter(ta); tabLayout.setupWithViewPager(viewPager); - new Utils.LoadModules(getActivity(),false).execute(); + new Utils.LoadModules(getActivity(),true).execute(); new updateUI().execute(); break; } @@ -114,6 +128,19 @@ public class ModulesFragment extends Fragment { return super.onOptionsItemSelected(item); } + public void redrawLayout() { + listModules.clear(); + listModulesCache.clear(); + listModulesDownload.clear(); + progressBar.setVisibility(View.VISIBLE); + ta = new TabsAdapter(getChildFragmentManager()); + viewPager.setAdapter(ta); + tabLayout.setupWithViewPager(viewPager); + new Utils.LoadModules(getActivity(),false).execute(); + new updateUI().execute(); + + } + public static class NormalModuleFragment extends BaseModuleFragment { @Override @@ -141,7 +168,7 @@ public class ModulesFragment extends Fragment { } - private class updateUI extends AsyncTask { + public class updateUI extends AsyncTask { @Override protected Void doInBackground(Void... voids) { @@ -153,8 +180,8 @@ public class ModulesFragment extends Fragment { super.onPostExecute(v); progressBar.setVisibility(View.GONE); - - viewPager.setAdapter(new TabsAdapter(getChildFragmentManager())); + ta = new TabsAdapter(getChildFragmentManager()); + viewPager.setAdapter(ta); tabLayout.setupWithViewPager(viewPager); } } diff --git a/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java b/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java index f543e7d29..5d65987a6 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java +++ b/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java @@ -3,22 +3,21 @@ package com.topjohnwu.magisk; import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; +import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.CheckBox; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; -import android.widget.Toast; -import com.topjohnwu.magisk.module.Module; import com.topjohnwu.magisk.module.Repo; -import com.topjohnwu.magisk.utils.Shell; -import com.topjohnwu.magisk.utils.Utils; +import com.topjohnwu.magisk.utils.AnimationHelper; + +import org.w3c.dom.Text; -import java.io.File; import java.util.List; import butterknife.BindView; @@ -27,22 +26,39 @@ import butterknife.ButterKnife; public class ReposAdapter extends RecyclerView.Adapter { private final List mList; - private View view; + private View viewMain; private Context context; + @BindView(R.id.update) + ImageView updateImage; + @BindView(R.id.installed) + ImageView installedImage; + @BindView(R.id.popup_layout) + LinearLayout popupLayout; + @BindView(R.id.author) + TextView authorText; + @BindView(R.id.log) + TextView logText; + @BindView(R.id.updateStatus) TextView updateStatus; + @BindView(R.id.installedStatus) TextView installedStatus; + private boolean isCardExpanded; + public ReposAdapter(List list) { this.mList = list; } + private boolean mIsInstalled; + + @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_repo, parent, false); + viewMain = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_repo, parent, false); + ButterKnife.bind(this, viewMain); context = parent.getContext(); - - return new ViewHolder(view); + return new ViewHolder(viewMain); } @Override @@ -50,26 +66,49 @@ public class ReposAdapter extends RecyclerView.Adapter final Repo repo = mList.get(position); holder.title.setText(repo.getName()); - holder.versionName.setText(repo.getVersion()); + holder.versionName.setText(repo.getmVersion()); holder.description.setText(repo.getDescription()); - view.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - if (!prefs.contains("isInstalled_" + repo.getName())) { + Log.d("Magisk","ReposAdapter: Setting up info " + repo.getId() + " and " + repo.getDescription() + " and " + repo.getmVersion()); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + if (prefs.contains("repo_isInstalled_" + repo.getId())) { + mIsInstalled = prefs.getBoolean("repo_isInstalled_" + repo.getId(),false); + if (mIsInstalled) { + installedImage.setImageResource(R.drawable.ic_done_black); + installedStatus.setText(R.string.module_installed); + } + } - 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); + isCardExpanded = false; + AnimationHelper.collapse(popupLayout); + + viewMain.setOnClickListener(new View.OnClickListener() { + @Override + + public void onClick(View view) { + if (isCardExpanded) { + + AnimationHelper.collapse(popupLayout); + isCardExpanded = false; } else { - Toast.makeText(context,repo.getName() + " is already installed.",Toast.LENGTH_SHORT).show(); + AnimationHelper.expand(popupLayout); + isCardExpanded = true; + } + +// if (!mIsInstalled) { +// +// Utils.DownloadReceiver reciever = new Utils.DownloadReceiver() { +// @Override +// public void task(File file) { +// Log.d("Magisk", "Task firing"); +// new Utils.FlashZIP(context, repo.getId(), file.toString()).execute(); +// } +// }; +// String filename = repo.getId().replace(" ", "") + ".zip"; +// Utils.downloadAndReceive(context, reciever, repo.getmZipUrl(), filename); +// } else { +// Toast.makeText(context,repo.getId() + " is already installed.",Toast.LENGTH_SHORT).show(); +// } } }); 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 c46998f08..0e20a1294 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/Module.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/Module.java @@ -17,58 +17,117 @@ public class Module { private String mName = null; private String mVersion = "(No version provided)"; private String mDescription = "(No description provided)"; - private String mUrl = null; + private String mUrl,mSupportUrl,mDonateUrl,mZipUrl,mBaseUrl,mManifestUrl,mAuthor; + private boolean mEnable, mRemove,mUpdateAvailable,mIsOnline; - private boolean mEnable; - private boolean mRemove; private String mId; private int mVersionCode; 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")) { - String[] parts = line.split("=", 2); - if (parts.length != 2) { + String[] props = line.split("=", 2); + if (props.length != 2) { continue; } - String key = parts[0].trim(); + String key = props[0].trim(); if (key.charAt(0) == '#') { continue; } - String value = parts[1].trim(); - switch (key) { + String value = props[1].trim(); + switch (props[0]) { + case "versionCode": + this.mVersionCode = Integer.valueOf(props[1]); + break; case "name": - mName = value; + this.mName = props[1]; break; - case "version": - mVersion = value; - break; - case "description": - mDescription = value; + case "author": + this.mAuthor = props[1]; break; case "id": - mId = value; + this.mId = props[1]; break; - case "versionCode": - try { - mVersionCode = Integer.parseInt(value); - } catch (NumberFormatException e) { - mVersionCode = 0; + case "version": + this.mVersion = props[1]; + break; + case "description": + this.mDescription = props[1]; + break; + case "donate": + this.mDonateUrl = 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; + default: + Log.d("Magisk", "Manifest string not recognized: " + props[0]); + break; + } + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + if (mId != null) { + Log.d("Magisk", "Module: Checking for preference named repo_" + mId); + if (prefs.contains("repo_" + mId)) { + String entryString = prefs.getString("repo_" + mId, ""); + + + String entryName = "repo" + mId; + + String[] subStrings = entryString.split("\n"); + for (String subKeys : subStrings) { + String[] idEntry = subKeys.split("=", 2); + Log.d("Magisk", "Module: Checking entry strings. Key is " + idEntry[0] + " and value is " + idEntry[1]); + if (idEntry[0].equals("id")) { + if (idEntry.length != 2) { + continue; + } + + if (idEntry[1].equals(mId)) { + Log.d("Magisk", "Module: Hey, I know I'm online..."); + mIsOnline = true; + } else mIsOnline = false; + } + if (idEntry[0].equals("versionCode")) { + if (idEntry.length != 2) { + continue; + } + + if (Integer.valueOf(idEntry[1]) > mVersionCode) { + mUpdateAvailable = true; + Log.d("Magisk", "Module: Hey, I have an update..."); + } else mUpdateAvailable = false; + } } - break; + + + } + + SharedPreferences.Editor editor = prefs.edit(); + if (mIsOnline) { + editor.putBoolean("repo_isInstalled_" + mId, true); + + } else { + editor.putBoolean("repo_isInstalled_" + mId, false); + } + editor.apply(); } } @@ -86,11 +145,11 @@ public class Module { public Module(Repo repo) { mName = repo.getName(); - mVersion = repo.getVersion(); + mVersion = repo.getmVersion(); mDescription = repo.getDescription(); mId = "foo"; mVersionCode = 111; - mUrl = repo.getZipUrl(); + mUrl = repo.getmZipUrl(); mEnable = true; mRemove = false; @@ -134,4 +193,8 @@ public class Module { return mRemove; } + public boolean isOnline() {return mIsOnline; } + + public boolean isUpdateAvailable() { return mUpdateAvailable; }; + } \ No newline at end of file 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 228e7809c..e6944915f 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/Repo.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/Repo.java @@ -15,53 +15,76 @@ import java.text.SimpleDateFormat; import java.util.Date; public class Repo { - public String name; - public String baseUrl, zipUrl, manifestUrl, logUrl, manifest, version, moduleName, moduleDescription, moduleAuthor, moduleAuthorUrl; - public Date lastUpdate; - public Boolean usesRoot, usesXposed; + private String mBaseUrl; + private String mZipUrl; + private String mLogUrl; + private String mManifestUrl; + private String mVersion; + private String mName; + private String mDescription; + private String mAuthor; + public String mAuthorUrl; + private String mId; + private String mVersionCode; + private String mSupportUrl; + private String mDonateUrl; + private Date lastUpdate; private Context appContext; - private SharedPreferences prefs; + private boolean mIsInstalled; + public Repo(String manifestString, Context context) { + ParseProps(manifestString); + appContext = context; + + } public Repo(String name, String url, Date updated, Context context) { appContext = context; - this.name = name; - this.baseUrl = url; + this.mName = name; + this.mBaseUrl = url; this.lastUpdate = updated; this.fetch(); } 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; + this.mZipUrl = zipUrl; + this.mDescription = moduleDescription; + this.mName = moduleName; this.lastUpdate = lastUpdated; - + this.fetch(); } - public void fetch() { - prefs = PreferenceManager.getDefaultSharedPreferences(appContext); + private void fetch() { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext); + if (prefs.contains("repo_" + this.mId)) { + String repoString = prefs.getString("repo_" + this.mId,""); + if (!repoString.equals("")) { + ParseProps(repoString); + } + } + if (prefs.contains("repo_isInstalled_" + this.mId)) { + mIsInstalled = prefs.getBoolean("repo_isInstalled_" + this.mId,false); + + } + WebRequest webreq = new WebRequest(); // Construct initial url for contents - Log.d("Magisk", "Manifest string is: " + baseUrl + "/contents/"); - String repoString = webreq.makeWebServiceCall(baseUrl + "/contents/", WebRequest.GET); - + Log.d("Magisk", "Manifest string is: " + mBaseUrl + "/contents/"); + String repoString = webreq.makeWebServiceCall(mBaseUrl + "/contents/", WebRequest.GET); try { JSONArray repoArray = new JSONArray(repoString); - for (int f = 0; f < repoArray.length(); f++) { JSONObject jsonobject = repoArray.getJSONObject(f); String name = jsonobject.getString("name"); if (name.contains(".zip")) { - this.zipUrl = jsonobject.getString("download_url"); - } else if (name.equals("module.json")) { - this.manifestUrl = jsonobject.getString("download_url"); - } else if (name.equals("Changelog.txt")) { - this.logUrl = jsonobject.getString("download_url"); + this.mZipUrl = jsonobject.getString("download_url"); + } else if (name.equals("module.prop")) { + this.mManifestUrl = jsonobject.getString("download_url"); + } else if (name.equals("changelog.txt")) { + this.mLogUrl = jsonobject.getString("download_url"); } } } catch (JSONException e) { @@ -69,60 +92,159 @@ public class Repo { } 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()); - version = manifestObject.getString("versionCode"); - moduleName = manifestObject.getString("moduleName"); - moduleDescription = manifestObject.getString("moduleDescription"); - moduleAuthor = manifestObject.getString("moduleAuthor"); - usesRoot = Boolean.getBoolean(manifestObject.getString("usesRoot")); - usesXposed = Boolean.getBoolean(manifestObject.getString("usesXposed")); - SharedPreferences.Editor editor = prefs.edit(); - String prefsString = "[{\"moduleDescription\":\"" + moduleDescription + "\"," - + "\"moduleName\":\"" + moduleName + "\"," - + "\"moduleAuthor\":\"" + moduleAuthor + "\"," - + "\"moduleAuthorUrl\":\"" + moduleAuthorUrl + "\"," - + "\"usesRoot\":\"" + usesRoot + "\"," - + "\"usesXposed\":\"" + usesXposed + "\"," - + "\"zipUrl\":\"" + zipUrl + "\"," - + "\"lastUpdate\":\"" + lastUpdate + "\"," - + "\"logUrl\":\"" + logUrl + "\"}]"; - 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) { - e.printStackTrace(); + WebRequest propReq = new WebRequest(); + String manifestString = propReq.makeWebServiceCall(this.mManifestUrl,WebRequest.GET,true); + if (ParseProps(manifestString)) { + PutProps(manifestString); } } - public String getName() { - return moduleName; + private void PutProps(String manifestString) { + manifestString = manifestString + "zipUrl=" + mZipUrl + "\nbaseUrl=" + mBaseUrl + "\nlogUrl=" + mLogUrl + "\nmanifestUrl=" + mManifestUrl; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext); + SharedPreferences.Editor editor = prefs.edit(); + editor.putString("repo_" + mId, manifestString); + editor.putBoolean("hasCachedRepos", true); + editor.putString("updated_" + mId, this.lastUpdate.toString()); + Log.d("Magisk", "Storing Preferences: " + manifestString); + editor.apply(); + } + private boolean ParseProps(String string) { + Log.d("Magisk","Repo: parseprops called for string " + string); + if ((string.length() <= 1) | (!string.contains("id"))) { + return false; + } else { + String lines[] = string.split("\\n"); + for (String line : lines) { + if (line != "") { + String props[] = line.split("="); + Log.d("Magisk", "Repo: Split values are " + props[0] + " and " + props[1]); + switch (props[0]) { + case "versionCode": + this.mVersionCode = 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 "description": + this.mDescription = props[1]; + break; + case "donate": + this.mDonateUrl = 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; + default: + Log.d("Magisk", "Manifest string not recognized: " + props[0]); + break; + } + } + + } + return this.mName != null; + + } } - public String getVersion() { - return version; + public String getStringProperty(String mValue) { + switch (mValue) { + case "author": + return mAuthor; + case "id": + return mId; + case "version": + return mVersion; + case "description": + return mDescription; + case "supportUrl": + return mSupportUrl; + case "donateUrl": + return mDonateUrl; + case "baseeUrl": + return mBaseUrl; + case "zipUrl": + return mZipUrl; + default: + return null; + } + } + + public String getName() { + return mName; + } + + public String getmVersion() { + return mVersion; + } + + public int getmVersionCode() { + return Integer.valueOf(mVersionCode); } public String getDescription() { - return moduleDescription; + return mDescription; } - public String getZipUrl() { - return zipUrl; + public String getId() { + return mId; } - public String getLogUrl() { - return logUrl; + public String getmZipUrl() { + return mZipUrl; + } + + public String getmBaseUrl() { + return mBaseUrl; + } + + public String getmLogUrl() { + return mLogUrl; } -} \ No newline at end of file + public String getmAuthor() { + return mAuthor; + } + + public String getmDonateUrl() { + return mDonateUrl; + } + + public String getmManifestUrl() { + return mManifestUrl; + } + + public String getmSupportUrl() { + return mSupportUrl; + } + + public Date getLastUpdate() { + return lastUpdate; + } + + public boolean isInstalled() { return mIsInstalled; } +} + diff --git a/app/src/main/java/com/topjohnwu/magisk/module/RepoAdapter.java b/app/src/main/java/com/topjohnwu/magisk/module/RepoAdapter.java index a18d77b13..c5e3b9c0d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/RepoAdapter.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/RepoAdapter.java @@ -3,29 +3,39 @@ package com.topjohnwu.magisk.module; import android.content.Context; import android.content.SharedPreferences; import android.os.AsyncTask; +import android.os.Build; import android.preference.PreferenceManager; +import android.support.annotation.NonNull; import android.util.Log; import android.widget.Toast; +import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.WebRequest; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.io.File; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collection; import java.util.Date; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; public class RepoAdapter { private String[] result; private static String url = "https://api.github.com/orgs/Magisk-Modules-Repo/repos"; - private static List repos = new ArrayList(); + private static List repos = new ArrayList() { + + }; private static final String TAG_ID = "id"; private static final String TAG_NAME = "name"; + private static String TAG = "Magisk"; private Context activityContext; private Date updatedDate, currentDate; @@ -36,39 +46,17 @@ public class RepoAdapter { new MyAsyncTask().execute(); List out = null; } else { - Log.d("Magisk", "Building from cache"); + Log.d(TAG, "Building from cache"); Map map = prefs.getAll(); repos.clear(); - for (Map.Entry entry : map.entrySet()) { - if (entry.getKey().contains("module_")) { - String repoString = entry.getValue().toString().replace(""", "\""); - JSONArray repoArray = null; - try { - repoArray = new JSONArray(repoString); - - - for (int f = 0; f < repoArray.length(); f++) { - JSONObject jsonobject = repoArray.getJSONObject(f); - String name = entry.getKey().replace("module_", ""); - name = name.replace(" ", ""); - String moduleName, moduleDescription, zipUrl; - moduleName = jsonobject.getString("moduleName"); - moduleDescription = jsonobject.getString("moduleDescription"); - zipUrl = jsonobject.getString("zipUrl"); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - try { - updatedDate = format.parse(jsonobject.getString("lastUpdate")); - } catch (ParseException e) { - e.printStackTrace(); - } - repos.add(new Repo(name, moduleDescription, zipUrl, updatedDate, activityContext)); - - } - } catch (JSONException e) { - e.printStackTrace(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + map.entrySet().stream().filter(entry -> entry.getKey().contains("repo_")).forEach(entry -> { + String repoString = entry.getValue().toString(); + if (repoString.length() >= 0) { + repos.add(new Repo(repoString,context)); } - } + }); } } @@ -120,8 +108,8 @@ public class RepoAdapter { // TODO Auto-generated catch block e.printStackTrace(); } - - if (!name.contains("Repo.github.io")) { + if ((!name.contains("Repo.github.io"))) { + //if (!name.contains("Repo.github.io") && name.contains("template")) { repos.add(new Repo(name, url, updatedDate, activityContext)); } } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/AnimationHelper.java b/app/src/main/java/com/topjohnwu/magisk/utils/AnimationHelper.java new file mode 100644 index 000000000..ebb1d3301 --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/utils/AnimationHelper.java @@ -0,0 +1,58 @@ +package com.topjohnwu.magisk.utils; + +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.Transformation; +import android.widget.LinearLayout; + +public class AnimationHelper { + public static void expand(final View v) { + v.measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + final int targetHeight = v.getMeasuredHeight(); + + v.getLayoutParams().height = 0; + v.setVisibility(View.VISIBLE); + Animation a = new Animation() { + @Override + protected void applyTransformation(float interpolatedTime, Transformation t) { + v.getLayoutParams().height = interpolatedTime == 1 + ? LinearLayout.LayoutParams.WRAP_CONTENT + : (int) (targetHeight * interpolatedTime); + v.requestLayout(); + } + + @Override + public boolean willChangeBounds() { + return true; + } + }; + + // 1dp/ms + a.setDuration((int) (targetHeight / v.getContext().getResources().getDisplayMetrics().density)); + v.startAnimation(a); + } + + public static void collapse(final View v) { + final int initialHeight = v.getMeasuredHeight(); + + Animation a = new Animation() { + @Override + protected void applyTransformation(float interpolatedTime, Transformation t) { + if (interpolatedTime == 1) { + v.setVisibility(View.GONE); + } else { + v.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime); + v.requestLayout(); + } + } + + @Override + public boolean willChangeBounds() { + return true; + } + }; + // 1dp/ms + a.setDuration((int) (initialHeight / v.getContext().getResources().getDisplayMetrics().density)); + v.startAnimation(a); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/GitAgent.java b/app/src/main/java/com/topjohnwu/magisk/utils/GitAgent.java new file mode 100644 index 000000000..927c4cfb1 --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/utils/GitAgent.java @@ -0,0 +1,8 @@ +package com.topjohnwu.magisk.utils; + + +public class GitAgent { + + + +} 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 ebe8a68aa..8c4322174 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -41,6 +41,7 @@ import java.net.URL; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.List; +import java.util.Set; public class Utils { @@ -394,9 +395,8 @@ public class Utils { 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, doReload); + for (String mod : magisk) { ModulesFragment.listModules.add(new Module(mod,mContext)); } @@ -404,7 +404,9 @@ public class Utils { ModulesFragment.listModulesCache.add(new Module(mod,mContext)); } for (Repo repo : magiskRepos) { - ModulesFragment.listModulesDownload.add(repo); + if (repo.getId() != null){ + ModulesFragment.listModulesDownload.add(repo); + } } return null; 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 1b782a158..171ac5a8a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java @@ -18,6 +18,7 @@ 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() { @@ -31,7 +32,15 @@ public class WebRequest { * @requestmethod - http request method */ public String makeWebServiceCall(String url, int requestmethod) { + addNewLine=false; return this.makeWebServiceCall(url, requestmethod, null); + + } + + public String makeWebServiceCall(String url, int requestmethod, boolean addNewLines) { + addNewLine = addNewLines; + return this.makeWebServiceCall(url, requestmethod, null); + } /** @@ -90,7 +99,7 @@ public class WebRequest { String line; BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); while ((line = br.readLine()) != null) { - response += line; + response += line + "\n"; } } else { response = ""; diff --git a/app/src/main/res/drawable/ic_done_black.xml b/app/src/main/res/drawable/ic_done_black.xml new file mode 100644 index 000000000..7affe9ba9 --- /dev/null +++ b/app/src/main/res/drawable/ic_done_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/list_item_repo.xml b/app/src/main/res/layout/list_item_repo.xml index 353a08fc9..4eea607f8 100644 --- a/app/src/main/res/layout/list_item_repo.xml +++ b/app/src/main/res/layout/list_item_repo.xml @@ -1,4 +1,8 @@ + + + + + + + + - \ No newline at end of file + + \ No newline at end of file diff --git a/app/src/main/res/layout/list_item_repo_expanded.xml b/app/src/main/res/layout/list_item_repo_expanded.xml new file mode 100644 index 000000000..c7303199a --- /dev/null +++ b/app/src/main/res/layout/list_item_repo_expanded.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/single_module_fragment.xml b/app/src/main/res/layout/single_module_fragment.xml index 42363f378..e6ab2c8fc 100644 --- a/app/src/main/res/layout/single_module_fragment.xml +++ b/app/src/main/res/layout/single_module_fragment.xml @@ -1,8 +1,9 @@ - @@ -24,4 +25,4 @@ android:textStyle="italic" android:visibility="gone"/> - \ No newline at end of file + \ 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 983a104e4..6f0fe3a30 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -42,6 +42,9 @@ Cache modules No modules found + Update available + Module is up-to-date + Module is installed Module will be removed at next reboot Module will not be removed at next reboot Module will be disabled at next reboot From e3866eeb29eeccd6f42cd61ea49d25b3acc03c4a Mon Sep 17 00:00:00 2001 From: d8ahazard Date: Thu, 8 Sep 2016 14:47:04 -0500 Subject: [PATCH 2/4] I think it won't break anything? --- .../topjohnwu/magisk/BaseModuleFragment.java | 120 +++++++++-- .../topjohnwu/magisk/BaseRepoFragment.java | 123 ++++++++++- .../com/topjohnwu/magisk/ModulesAdapter.java | 101 --------- .../com/topjohnwu/magisk/ModulesFragment.java | 36 +--- .../com/topjohnwu/magisk/ReposAdapter.java | 140 ------------- .../com/topjohnwu/magisk/WelcomeActivity.java | 12 +- .../com/topjohnwu/magisk/module/Module.java | 106 +++++----- .../com/topjohnwu/magisk/module/Repo.java | 60 +++--- .../topjohnwu/magisk/module/RepoAdapter.java | 135 ------------ .../topjohnwu/magisk/module/RepoHelper.java | 197 ++++++++++++++++++ .../com/topjohnwu/magisk/utils/Utils.java | 65 ++---- .../topjohnwu/magisk/utils/WebRequest.java | 11 +- .../drawable/ic_system_update_alt_black.xml | 9 + app/src/main/res/layout/list_item_repo.xml | 8 +- 14 files changed, 567 insertions(+), 556 deletions(-) delete mode 100644 app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java delete mode 100644 app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java delete mode 100644 app/src/main/java/com/topjohnwu/magisk/module/RepoAdapter.java create mode 100644 app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java create mode 100644 app/src/main/res/drawable/ic_system_update_alt_black.xml diff --git a/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java b/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java index e41a73df8..530ad3e73 100644 --- a/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java @@ -7,13 +7,16 @@ import android.support.annotation.Nullable; import android.support.design.widget.Snackbar; import android.support.v4.app.Fragment; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; +import android.widget.ImageView; import android.widget.TextView; import com.topjohnwu.magisk.module.Module; +import com.topjohnwu.magisk.utils.Shell; import com.topjohnwu.magisk.utils.Utils; import java.util.List; @@ -23,17 +26,16 @@ import butterknife.ButterKnife; public abstract class BaseModuleFragment extends Fragment { - @BindView(R.id.recyclerView) - RecyclerView recyclerView; - @BindView(R.id.empty_rv) - TextView emptyTv; - private View view; + @BindView(R.id.recyclerView) RecyclerView recyclerView; + @BindView(R.id.empty_rv) TextView emptyTv; + + private SharedPreferences prefs; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - view = inflater.inflate(R.layout.single_module_fragment, container, false); + View view = inflater.inflate(R.layout.single_module_fragment, container, false); ButterKnife.bind(this, view); @@ -55,19 +57,16 @@ public abstract class BaseModuleFragment extends Fragment { return view; } - recyclerView.setAdapter(new ModulesAdapter(listModules(), new Utils.ItemClickListener() { - @Override - public void onItemClick(View chk, int position) { - // On Checkbox change listener - CheckBox chbox = (CheckBox) chk; + recyclerView.setAdapter(new ModulesAdapter(listModules(), (chk, position) -> { + // On Checkbox change listener + CheckBox chbox = (CheckBox) chk; - if (!chbox.isChecked()) { - BaseModuleFragment.this.listModules().get(position).createDisableFile(); - Snackbar.make(chk, R.string.disable_file_created, Snackbar.LENGTH_SHORT).show(); - } else { - BaseModuleFragment.this.listModules().get(position).removeDisableFile(); - Snackbar.make(chk, R.string.disable_file_removed, Snackbar.LENGTH_SHORT).show(); - } + 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 @@ -85,4 +84,89 @@ public abstract class BaseModuleFragment extends Fragment { protected abstract List listModules(); + + public class ModulesAdapter extends RecyclerView.Adapter { + + private final List mList; + private final Utils.ItemClickListener chboxListener; + private final Utils.ItemClickListener deleteBtnListener; + private final Utils.ItemClickListener unDeleteBtnListener; + + public ModulesAdapter(List list, Utils.ItemClickListener chboxListener, Utils.ItemClickListener deleteBtnListener, Utils.ItemClickListener undeleteBtnListener) { + this.mList = list; + this.chboxListener = chboxListener; + this.deleteBtnListener = deleteBtnListener; + this.unDeleteBtnListener = undeleteBtnListener; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_module, parent, false); + + return new ViewHolder(view); + } + + @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() ); + + holder.title.setText(module.getName()); + holder.versionName.setText(module.getVersion()); + holder.description.setText(module.getDescription()); + + 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.delete) + ImageView delete; + + public ViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + if (!Shell.rootAccess()) { + checkBox.setEnabled(false); + delete.setEnabled(false); + } + } + } + } } diff --git a/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java b/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java index bc7d49474..082e14878 100644 --- a/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java @@ -1,17 +1,26 @@ package com.topjohnwu.magisk; +import android.content.Context; +import android.content.SharedPreferences; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; -import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; +import android.widget.Toast; import com.topjohnwu.magisk.module.Repo; +import com.topjohnwu.magisk.utils.AnimationHelper; +import com.topjohnwu.magisk.utils.Utils; +import java.io.File; import java.util.List; import butterknife.BindView; @@ -26,6 +35,7 @@ public abstract class BaseRepoFragment extends Fragment { + @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { @@ -40,7 +50,7 @@ public abstract class BaseRepoFragment extends Fragment { return view; } - + Log.d("Magisk","BaseRepoFragment: ListRepos size is " + listRepos().size()); recyclerView.setAdapter(new ReposAdapter(listRepos()) { }); @@ -49,4 +59,113 @@ public abstract class BaseRepoFragment extends Fragment { protected abstract List listRepos(); + + public class ReposAdapter extends RecyclerView.Adapter { + + private final List mList; + private View viewMain; + private Context context; + @BindView(R.id.update) + ImageView updateImage; + @BindView(R.id.installed) + ImageView installedImage; +// @BindView(R.id.popup_layout) +// LinearLayout popupLayout; + + + private boolean isCardExpanded; + private boolean mIsInstalled, mCanUpdate; + + public ReposAdapter(List list) { + this.mList = list; + + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + viewMain = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_repo, parent, false); + ButterKnife.bind(this, viewMain); + context = parent.getContext(); + return new ViewHolder(viewMain); + } + + @Override + public void onBindViewHolder(final ViewHolder holder, int position) { + final Repo repo = mList.get(position); + Log.d("Magisk","ReposAdapter: Trying set up bindview from list pos " + position + " out of a total of " + mList.size() + " and " + repo.getId() ); + if (repo.getId() != null) { + holder.title.setText(repo.getName()); + holder.versionName.setText(repo.getmVersion()); + holder.description.setText(repo.getDescription()); + Log.d("Magisk", "ReposAdapter: Setting up info " + repo.getId() + " and " + repo.getDescription() + " and " + repo.getmVersion()); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + if (prefs.contains("repo-isInstalled_" + repo.getId())) { + mIsInstalled = prefs.getBoolean("repo-isInstalled_" + repo.getId(), false); + if (mIsInstalled) { + installedImage.setImageResource(R.drawable.ic_done_black); + } + mCanUpdate = prefs.getBoolean("repo-isInstalled_" + repo.getId(), false); + if (mCanUpdate) { + updateImage.setImageResource(R.drawable.ic_system_update_alt_black); + } + } + + isCardExpanded = false; +// AnimationHelper.collapse(popupLayout); + + viewMain.setOnClickListener(new View.OnClickListener() { + @Override + + public void onClick(View view) { + if (isCardExpanded) { +// AnimationHelper.expand(popupLayout); + isCardExpanded = false; + } else { +// AnimationHelper.collapse(popupLayout); + isCardExpanded = true; + + } + +// if (!mIsInstalled | mCanUpdate) { +// +// Utils.DownloadReceiver reciever = new Utils.DownloadReceiver() { +// @Override +// public void task(File file) { +// Log.d("Magisk", "Task firing"); +// new Utils.FlashZIP(context, repo.getId(), file.toString()).execute(); +// } +// }; +// String filename = repo.getId().replace(" ", "") + ".zip"; +// Utils.downloadAndReceive(context, reciever, repo.getmZipUrl(), filename); +// } else { +// Toast.makeText(context,repo.getId() + " is already installed.", Toast.LENGTH_SHORT).show(); +// } + } + }); + } + + + } + + + + + @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; + + + public ViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } + } } diff --git a/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java b/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java deleted file mode 100644 index c5b015f4c..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.topjohnwu.magisk; - -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.ImageView; -import android.widget.TextView; - -import com.topjohnwu.magisk.module.Module; -import com.topjohnwu.magisk.utils.Shell; -import com.topjohnwu.magisk.utils.Utils; - -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class ModulesAdapter extends RecyclerView.Adapter { - - private final List mList; - private final Utils.ItemClickListener chboxListener; - private final Utils.ItemClickListener deleteBtnListener; - private final Utils.ItemClickListener unDeleteBtnListener; - - public ModulesAdapter(List list, Utils.ItemClickListener chboxListener, Utils.ItemClickListener deleteBtnListener, Utils.ItemClickListener undeleteBtnListener) { - this.mList = list; - this.chboxListener = chboxListener; - this.deleteBtnListener = deleteBtnListener; - this.unDeleteBtnListener = undeleteBtnListener; - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_module, parent, false); - - return new ViewHolder(view); - } - - @Override - public void onBindViewHolder(final ViewHolder holder, int position) { - final Module module = mList.get(position); - - holder.title.setText(module.getName()); - holder.versionName.setText(module.getVersion()); - holder.description.setText(module.getDescription()); - - 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(); - } - - static 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.delete) ImageView delete; - - public ViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - if (!Shell.rootAccess()) { - checkBox.setEnabled(false); - delete.setEnabled(false); - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java index 0af544180..6a2cc8ea0 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java @@ -56,23 +56,13 @@ public class ModulesFragment extends Fragment { View view = inflater.inflate(R.layout.modules_fragment, container, false); ButterKnife.bind(this, view); + //new Utils.LoadModules(getActivity(),false).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; } - public void updateThisShit() { - new Utils.LoadModules(getActivity(), true).execute(); - new updateUI().execute(); - setHasOptionsMenu(true); - } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { @@ -93,8 +83,6 @@ public class ModulesFragment extends Fragment { } - - public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case FILE_SELECT_CODE: @@ -117,8 +105,7 @@ public class ModulesFragment extends Fragment { listModulesCache.clear(); listModulesDownload.clear(); progressBar.setVisibility(View.VISIBLE); - ta = new TabsAdapter(getChildFragmentManager()); - viewPager.setAdapter(ta); + viewPager.setAdapter(new TabsAdapter(getChildFragmentManager())); tabLayout.setupWithViewPager(viewPager); new Utils.LoadModules(getActivity(),true).execute(); new updateUI().execute(); @@ -128,19 +115,6 @@ public class ModulesFragment extends Fragment { return super.onOptionsItemSelected(item); } - public void redrawLayout() { - listModules.clear(); - listModulesCache.clear(); - listModulesDownload.clear(); - progressBar.setVisibility(View.VISIBLE); - ta = new TabsAdapter(getChildFragmentManager()); - viewPager.setAdapter(ta); - tabLayout.setupWithViewPager(viewPager); - new Utils.LoadModules(getActivity(),false).execute(); - new updateUI().execute(); - - } - public static class NormalModuleFragment extends BaseModuleFragment { @Override @@ -168,7 +142,7 @@ public class ModulesFragment extends Fragment { } - public class updateUI extends AsyncTask { + private class updateUI extends AsyncTask { @Override protected Void doInBackground(Void... voids) { @@ -180,8 +154,8 @@ public class ModulesFragment extends Fragment { super.onPostExecute(v); progressBar.setVisibility(View.GONE); - ta = new TabsAdapter(getChildFragmentManager()); - viewPager.setAdapter(ta); + + viewPager.setAdapter(new TabsAdapter(getChildFragmentManager())); tabLayout.setupWithViewPager(viewPager); } } diff --git a/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java b/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java deleted file mode 100644 index 5d65987a6..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.topjohnwu.magisk; - -import android.content.Context; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import android.support.v7.widget.CardView; -import android.support.v7.widget.RecyclerView; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.topjohnwu.magisk.module.Repo; -import com.topjohnwu.magisk.utils.AnimationHelper; - -import org.w3c.dom.Text; - -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class ReposAdapter extends RecyclerView.Adapter { - - private final List mList; - private View viewMain; - private Context context; - @BindView(R.id.update) - ImageView updateImage; - @BindView(R.id.installed) - ImageView installedImage; - @BindView(R.id.popup_layout) - LinearLayout popupLayout; - @BindView(R.id.author) - TextView authorText; - @BindView(R.id.log) - TextView logText; - @BindView(R.id.updateStatus) TextView updateStatus; - @BindView(R.id.installedStatus) TextView installedStatus; - private boolean isCardExpanded; - - - public ReposAdapter(List list) { - this.mList = list; - - } - - private boolean mIsInstalled; - - - - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - viewMain = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_repo, parent, false); - ButterKnife.bind(this, viewMain); - context = parent.getContext(); - return new ViewHolder(viewMain); - } - - @Override - public void onBindViewHolder(final ViewHolder holder, int position) { - final Repo repo = mList.get(position); - - holder.title.setText(repo.getName()); - holder.versionName.setText(repo.getmVersion()); - holder.description.setText(repo.getDescription()); - Log.d("Magisk","ReposAdapter: Setting up info " + repo.getId() + " and " + repo.getDescription() + " and " + repo.getmVersion()); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - if (prefs.contains("repo_isInstalled_" + repo.getId())) { - mIsInstalled = prefs.getBoolean("repo_isInstalled_" + repo.getId(),false); - if (mIsInstalled) { - installedImage.setImageResource(R.drawable.ic_done_black); - installedStatus.setText(R.string.module_installed); - } - } - - isCardExpanded = false; - AnimationHelper.collapse(popupLayout); - - viewMain.setOnClickListener(new View.OnClickListener() { - @Override - - public void onClick(View view) { - if (isCardExpanded) { - - AnimationHelper.collapse(popupLayout); - isCardExpanded = false; - } else { - AnimationHelper.expand(popupLayout); - isCardExpanded = true; - - } - -// if (!mIsInstalled) { -// -// Utils.DownloadReceiver reciever = new Utils.DownloadReceiver() { -// @Override -// public void task(File file) { -// Log.d("Magisk", "Task firing"); -// new Utils.FlashZIP(context, repo.getId(), file.toString()).execute(); -// } -// }; -// String filename = repo.getId().replace(" ", "") + ".zip"; -// Utils.downloadAndReceive(context, reciever, repo.getmZipUrl(), filename); -// } else { -// Toast.makeText(context,repo.getId() + " is already installed.",Toast.LENGTH_SHORT).show(); -// } - } - }); - - - } - - - - - @Override - public int getItemCount() { - return mList.size(); - } - - static class ViewHolder extends RecyclerView.ViewHolder { - - @BindView(R.id.title) TextView title; - - @BindView(R.id.version_name) TextView versionName; - @BindView(R.id.description) TextView description; - - - - public ViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java b/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java index 6d34d7cfd..cb3c30bde 100644 --- a/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/WelcomeActivity.java @@ -4,10 +4,12 @@ import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.preference.PreferenceManager; import android.support.annotation.IdRes; import android.support.annotation.NonNull; import android.support.design.widget.NavigationView; @@ -58,7 +60,15 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView } new Utils.Initialize(this).execute(); new Utils.CheckUpdates(this).execute(); - new Utils.LoadModules(getApplication(),false).execute(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + if (!prefs.contains("oauth_key")) { + + } + if (!prefs.contains("hasCachedRepos")) { + new Utils.LoadModules(this, true).execute(); + } else { + new Utils.LoadModules(getApplication(),false).execute(); + } setSupportActionBar(toolbar); 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 0e20a1294..f5ab7f1e9 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/Module.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/Module.java @@ -45,90 +45,98 @@ public class Module { this.mVersionCode = Integer.valueOf(props[1]); break; case "name": - this.mName = props[1]; + this.mName = value; break; case "author": - this.mAuthor = props[1]; + this.mAuthor = value; break; case "id": - this.mId = props[1]; + this.mId = value; break; case "version": - this.mVersion = props[1]; + this.mVersion = value; break; case "description": - this.mDescription = props[1]; + this.mDescription = value; break; case "donate": - this.mDonateUrl = props[1]; + this.mDonateUrl = value; break; case "support": - this.mSupportUrl = props[1]; + this.mSupportUrl = value; break; case "donateUrl": - this.mDonateUrl = props[1]; + this.mDonateUrl = value; break; case "zipUrl": - this.mZipUrl = props[1]; + this.mZipUrl = value; break; case "baseUrl": - this.mBaseUrl = props[1]; + this.mBaseUrl = value; break; case "manifestUrl": - this.mManifestUrl = props[1]; + this.mManifestUrl = value; break; default: - Log.d("Magisk", "Manifest string not recognized: " + props[0]); + Log.d("Magisk", "Module: Manifest string not recognized: " + props[0]); break; } - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - if (mId != null) { - Log.d("Magisk", "Module: Checking for preference named repo_" + mId); - if (prefs.contains("repo_" + mId)) { - String entryString = prefs.getString("repo_" + mId, ""); + } - String entryName = "repo" + mId; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - String[] subStrings = entryString.split("\n"); - for (String subKeys : subStrings) { - String[] idEntry = subKeys.split("=", 2); - Log.d("Magisk", "Module: Checking entry strings. Key is " + idEntry[0] + " and value is " + idEntry[1]); - if (idEntry[0].equals("id")) { - if (idEntry.length != 2) { - continue; - } + if (this.mId != null && !this.mId.isEmpty()) { + String preferenceString = "repo_" + this.mId; + String preferenceKey = prefs.getString(preferenceString,"nope"); + Log.d("Magisk", "Module: Checking for preference named " + preferenceString); + if (!preferenceKey.equals("nope")) { + Log.d("Magisk", "Module: repo_" + mId + " found."); + String entryString = prefs.getString("repo_" + mId, ""); - if (idEntry[1].equals(mId)) { - Log.d("Magisk", "Module: Hey, I know I'm online..."); - mIsOnline = true; - } else mIsOnline = false; + String[] subStrings = entryString.split("\n"); + for (String subKeys : subStrings) { + String[] idEntry = subKeys.split("=", 2); + if (idEntry[0].equals("id")) { + if (idEntry.length != 2) { + continue; } - if (idEntry[0].equals("versionCode")) { - if (idEntry.length != 2) { - continue; - } - if (Integer.valueOf(idEntry[1]) > mVersionCode) { - mUpdateAvailable = true; - Log.d("Magisk", "Module: Hey, I have an update..."); - } else mUpdateAvailable = false; - } + if (idEntry[1].equals(mId)) { + Log.d("Magisk", "Module: Hey, I know I'm online..."); + mIsOnline = true; + } else mIsOnline = false; } + if (idEntry[0].equals("versionCode")) { + if (idEntry.length != 2) { + continue; + } - + if (Integer.valueOf(idEntry[1]) > mVersionCode) { + mUpdateAvailable = true; + Log.d("Magisk", "Module: Hey, I have an update..."); + } else mUpdateAvailable = false; + } } - SharedPreferences.Editor editor = prefs.edit(); - if (mIsOnline) { - editor.putBoolean("repo_isInstalled_" + mId, true); - } else { - editor.putBoolean("repo_isInstalled_" + mId, false); - } - editor.apply(); } + + SharedPreferences.Editor editor = prefs.edit(); + if (mIsOnline) { + editor.putBoolean("repo-isInstalled_" + mId, true); + + } else { + editor.putBoolean("repo-isInstalled_" + mId, false); + } + + if (mUpdateAvailable) { + editor.putBoolean("repo-canUpdate_" + mId, true); + } else { + editor.putBoolean("repo-canUpdate_" + mId, false); + } + editor.apply(); } if (mName == null) { @@ -147,8 +155,8 @@ public class Module { mName = repo.getName(); mVersion = repo.getmVersion(); mDescription = repo.getDescription(); - mId = "foo"; - mVersionCode = 111; + mId = repo.getId(); + mVersionCode = repo.getmVersionCode(); mUrl = repo.getmZipUrl(); mEnable = true; mRemove = false; 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 e6944915f..5814ab04c 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/Repo.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/Repo.java @@ -28,21 +28,23 @@ public class Repo { private String mVersionCode; private String mSupportUrl; private String mDonateUrl; - private Date lastUpdate; + private String lastUpdate; private Context appContext; - private boolean mIsInstalled; + private boolean mIsInstalled,mCanUpdate; public Repo(String manifestString, Context context) { - ParseProps(manifestString); appContext = context; + ParseProps(manifestString); } + + public Repo(String name, String url, Date updated, Context context) { appContext = context; this.mName = name; this.mBaseUrl = url; - this.lastUpdate = updated; + this.lastUpdate = updated.toString(); this.fetch(); } @@ -52,28 +54,16 @@ public class Repo { this.mZipUrl = zipUrl; this.mDescription = moduleDescription; this.mName = moduleName; - this.lastUpdate = lastUpdated; + this.lastUpdate = lastUpdated.toString(); this.fetch(); } - private void fetch() { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext); - if (prefs.contains("repo_" + this.mId)) { - String repoString = prefs.getString("repo_" + this.mId,""); - if (!repoString.equals("")) { - ParseProps(repoString); - } - } - if (prefs.contains("repo_isInstalled_" + this.mId)) { - mIsInstalled = prefs.getBoolean("repo_isInstalled_" + this.mId,false); - - } - + public void fetch() { WebRequest webreq = new WebRequest(); // Construct initial url for contents - Log.d("Magisk", "Manifest string is: " + mBaseUrl + "/contents/"); - String repoString = webreq.makeWebServiceCall(mBaseUrl + "/contents/", WebRequest.GET); + Log.d("Magisk", "Repo: Fetch called, Manifest string is: " + mBaseUrl + "/contents?access_token=5c9f47a299d48a6a649af3587bc97200bafcac65"); + String repoString = webreq.makeWebServiceCall(mBaseUrl + "/contents?access_token=5c9f47a299d48a6a649af3587bc97200bafcac65", WebRequest.GET); try { JSONArray repoArray = new JSONArray(repoString); for (int f = 0; f < repoArray.length(); f++) { @@ -91,9 +81,11 @@ public class Repo { e.printStackTrace(); } - Log.d("Magisk", "Inner fetch: " + repoString); + Log.d("Magisk", "Repo: Inner fetch: " + mManifestUrl + "?access_token=5c9f47a299d48a6a649af3587bc97200bafcac65"); WebRequest propReq = new WebRequest(); - String manifestString = propReq.makeWebServiceCall(this.mManifestUrl,WebRequest.GET,true); + String manifestString = propReq.makeWebServiceCall(mManifestUrl,WebRequest.GET,true); + Log.d("Magisk","Repo: parseprops called from fetch for string " + manifestString); + if (ParseProps(manifestString)) { PutProps(manifestString); } @@ -111,7 +103,7 @@ public class Repo { editor.apply(); } private boolean ParseProps(String string) { - Log.d("Magisk","Repo: parseprops called for string " + string); + if ((string.length() <= 1) | (!string.contains("id"))) { return false; } else { @@ -119,7 +111,6 @@ public class Repo { for (String line : lines) { if (line != "") { String props[] = line.split("="); - Log.d("Magisk", "Repo: Split values are " + props[0] + " and " + props[1]); switch (props[0]) { case "versionCode": this.mVersionCode = props[1]; @@ -157,6 +148,9 @@ public class Repo { case "manifestUrl": this.mManifestUrl = props[1]; break; + case "logUrl": + this.mLogUrl = props[1]; + break; default: Log.d("Magisk", "Manifest string not recognized: " + props[0]); break; @@ -164,7 +158,20 @@ public class Repo { } } - return this.mName != null; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext); + if (prefs.contains("repo-isInstalled_" + this.mId)) { + mIsInstalled = prefs.getBoolean("repo-isInstalled_" + this.mId,false); + } + if (prefs.contains("repo-canUpdate_" + this.mId)) { + mCanUpdate = prefs.getBoolean("repo-canUpdate_" + this.mId,false); + } + if (prefs.contains("updated_" + this.mId)) { + lastUpdate = prefs.getString("updated_" + this.mId,""); + } + + + + return this.mId != null; } } @@ -241,10 +248,11 @@ public class Repo { return mSupportUrl; } - public Date getLastUpdate() { + public String getLastUpdate() { return lastUpdate; } public boolean isInstalled() { return mIsInstalled; } + public boolean canUpdate() { return mCanUpdate; } } diff --git a/app/src/main/java/com/topjohnwu/magisk/module/RepoAdapter.java b/app/src/main/java/com/topjohnwu/magisk/module/RepoAdapter.java deleted file mode 100644 index c5e3b9c0d..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/module/RepoAdapter.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.topjohnwu.magisk.module; - -import android.content.Context; -import android.content.SharedPreferences; -import android.os.AsyncTask; -import android.os.Build; -import android.preference.PreferenceManager; -import android.support.annotation.NonNull; -import android.util.Log; -import android.widget.Toast; - -import com.topjohnwu.magisk.utils.Utils; -import com.topjohnwu.magisk.utils.WebRequest; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.File; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public class RepoAdapter { - private String[] result; - private static String url = "https://api.github.com/orgs/Magisk-Modules-Repo/repos"; - private static List repos = new ArrayList() { - - }; - private static final String TAG_ID = "id"; - private static final String TAG_NAME = "name"; - private static String TAG = "Magisk"; - private Context activityContext; - private Date updatedDate, currentDate; - - public List listRepos(Context context, boolean refresh) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - if (!prefs.contains("hasCachedRepos") | refresh) { - activityContext = context; - new MyAsyncTask().execute(); - List out = null; - } else { - Log.d(TAG, "Building from cache"); - Map map = prefs.getAll(); - repos.clear(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - map.entrySet().stream().filter(entry -> entry.getKey().contains("repo_")).forEach(entry -> { - String repoString = entry.getValue().toString(); - if (repoString.length() >= 0) { - repos.add(new Repo(repoString,context)); - } - - }); - } - - } - - - return repos; - } - - - class MyAsyncTask extends AsyncTask { - - @Override - protected void onPreExecute() { - super.onPreExecute(); - - } - - @Override - protected void onProgressUpdate(String... values) { - super.onProgressUpdate(values); - Toast.makeText(activityContext, "Refreshing online modules", Toast.LENGTH_SHORT).show(); - - } - - @Override - protected Void doInBackground(String... params) { - publishProgress(); - // Creating service handler class instance - WebRequest webreq = new WebRequest(); - - // Making a request to url and getting response - String jsonStr = webreq.makeWebServiceCall(url, WebRequest.GET); - Log.d("Magisk", "doInBackground Running, String: " + jsonStr + " Url: " + url); - - - try { - repos.clear(); - JSONArray jsonArray = new JSONArray(jsonStr); - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject jsonobject = jsonArray.getJSONObject(i); - String name = jsonobject.getString("name"); - String url = jsonobject.getString("url"); - String lastUpdate = jsonobject.getString("updated_at"); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - try { - updatedDate = format.parse(lastUpdate); - - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - if ((!name.contains("Repo.github.io"))) { - //if (!name.contains("Repo.github.io") && name.contains("template")) { - repos.add(new Repo(name, url, updatedDate, activityContext)); - } - } - } catch (JSONException e) { - e.printStackTrace(); - } - return null; - - - } - - protected void onPostExecute(Void v) { - - - } // protected void onPostExecute(Void v) - } //class MyAsyncTask extends AsyncTask - - protected void onPreExecute() { - - } - - -} diff --git a/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java b/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java new file mode 100644 index 000000000..d3fdfc0e9 --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java @@ -0,0 +1,197 @@ +package com.topjohnwu.magisk.module; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.AsyncTask; +import android.os.Build; +import android.preference.PreferenceManager; +import android.util.Log; +import android.widget.Toast; + +import com.topjohnwu.magisk.utils.WebRequest; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public class RepoHelper { + private String[] result; + private static String url = "https://api.github.com/orgs/Magisk-Modules-Repo/repos?access_token=5c9f47a299d48a6a649af3587bc97200bafcac65"; + private static List repos = new ArrayList(); + private static final String TAG_ID = "id"; + private static final String TAG_NAME = "name"; + private static String TAG = "Magisk"; + private String mName,mId,mUrl; + private Context activityContext; + private Date updatedDate, currentDate; + private SharedPreferences prefs; + private boolean apiFail; + + public List listRepos(Context context, boolean refresh) { + prefs = PreferenceManager.getDefaultSharedPreferences(context); + activityContext = context; + if (!prefs.contains("hasCachedRepos") | refresh) { + Log.d(TAG, "RepoHelper: Building from web"); + new MyAsyncTask().execute(); + List out = null; + } else { + Log.d(TAG, "RepoHelper: Building from cache"); + repos.clear(); + Map map = prefs.getAll(); + for(Map.Entry entry : map.entrySet()){ + if (entry.getKey().contains("repo_")) { + Log.d("Magisk","RepoHelper: found entry for repo " + entry.getKey()); + String repoString = entry.getValue().toString().replace(""", "\""); + String[] repoStrings = repoString.split("\n"); + for(String string : repoStrings) { + String[] splitStrings = string.split("="); + switch(splitStrings[0]) { + case ("id"): + mId = splitStrings[1]; + break; + case ("baseUrl"): + mUrl = splitStrings[1]; + break; + default: + break; + } + + } + Log.d("Magisk","RepoHelper: adding repo with id of " + mId); + repos.add(new Repo(repoString,activityContext)); + + + } + + } + + + + } + + + return repos; + } + + + class MyAsyncTask extends AsyncTask { + + @Override + protected void onPreExecute() { + super.onPreExecute(); + + } + + @Override + protected void onProgressUpdate(String... values) { + super.onProgressUpdate(values); + Toast.makeText(activityContext, "Refreshing online modules", Toast.LENGTH_SHORT).show(); + + } + + @Override + protected Void doInBackground(String... params) { + publishProgress(); + // Creating service handler class instance + WebRequest webreq = new WebRequest(); + + // Making a request to url and getting response + String jsonStr = webreq.makeWebServiceCall(url, WebRequest.GET); + Log.d("Magisk", "doInBackground Running, String: " + jsonStr + " Url: " + url); + if(jsonStr != null && !jsonStr.isEmpty()) { + + try { + repos.clear(); + JSONArray jsonArray = new JSONArray(jsonStr); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject jsonobject = jsonArray.getJSONObject(i); + String name = jsonobject.getString("name"); + String url = jsonobject.getString("url"); + String lastUpdate = jsonobject.getString("updated_at"); + String mId = ""; + String cacheUpdate = ""; + String manifestString = ""; + boolean doUpdate = true; + boolean hasCachedDate = false; + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + Map map = prefs.getAll(); + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue().toString().contains(url)) { + Log.d("Magisk", "RepoHelper: found matching URL"); + manifestString = entry.getValue().toString(); + String[] entryStrings = entry.getValue().toString().split("\n"); + for (String valueString : entryStrings) { + String[] valueSub = valueString.split("="); + if (valueSub[0].equals("id")) { + mId = valueSub[1]; + Log.d("Magisk", "RepoHelper: Got id for package of " + mId); + if (prefs.contains("updated_" + mId)) { + cacheUpdate = prefs.getString("updated_" + mId, ""); + hasCachedDate = true; + } + } + } + + } + } + try { + updatedDate = format.parse(lastUpdate); + Log.d("Magisk", "RepoHelper: Dates found, online is " + updatedDate + " and cached is " + cacheUpdate); + + if (hasCachedDate) { + + doUpdate = !cacheUpdate.equals(updatedDate.toString()); + Log.d("Magisk", "RepoHelper: DoUpdate is " + doUpdate); + } + + + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if (!name.contains("Repo.github.io")) { + if (doUpdate) { + repos.add(new Repo(name, url, updatedDate, activityContext)); + Log.d(TAG, "RepoHelper: Trying to add new repo for online refresh - " + name); + } else { + repos.add(new Repo(manifestString, activityContext)); + Log.d(TAG, "RepoHelper: Trying to add new repo using manifestString of " + mId); + } + } + for (int f = 0; f < repos.size(); f++) { + repos.get(f).fetch(); + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + apiFail = false; + } else { + apiFail = true; + } + return null; + + + } + + protected void onPostExecute(Void v) { + if (apiFail) { + Toast.makeText(activityContext,"GitHub API Limit reached, please try refreshing again in an hour.",Toast.LENGTH_LONG).show(); + } + + } // protected void onPostExecute(Void v) + } //class MyAsyncTask extends AsyncTask + + protected void onPreExecute() { + + } + + +} 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 8c4322174..c4fdfb4f5 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -25,7 +25,7 @@ import android.widget.Toast; import com.topjohnwu.magisk.ModulesFragment; import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.module.Module; -import com.topjohnwu.magisk.module.RepoAdapter; +import com.topjohnwu.magisk.module.RepoHelper; import com.topjohnwu.magisk.module.Repo; import org.json.JSONArray; @@ -38,16 +38,14 @@ 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; -import java.util.Set; public class Utils { public static int magiskVersion, remoteMagiskVersion = -1, remoteAppVersion = -1; public static String magiskLink, magiskChangelog, appChangelog, appLink, phhLink, supersuLink; private Context appContext; + private static final String TAG = "Magisk"; public static final String MAGISK_PATH = "/magisk"; public static final String MAGISK_CACHE_PATH = "/cache/magisk"; @@ -373,17 +371,25 @@ public class Utils { } } + public static class AuthGithub extends AsyncTask { + private static String mClientToken = "5c9f47a299d48a6a649af3587bc97200bafcac65"; + + public AuthGithub(Context context) {} + + @Override + protected Void doInBackground(Void... voids) { + return null; + } + } + public static class LoadModules extends AsyncTask { private Context mContext; private boolean doReload; public LoadModules(Context context, boolean reload) { - Log.d("Magisk", "LoadModules created, online is " + reload); mContext = context; doReload = reload; - - } @Override @@ -392,30 +398,26 @@ public class Utils { ModulesFragment.listModulesCache.clear(); ModulesFragment.listModulesDownload.clear(); List magisk = getModList(MAGISK_PATH); - Log.d("Magisk", "Reload called, online mode set to " + doReload); + Log.d("Magisk", "Utils: Reload called, loading modules from" + (doReload ? " the internet " : " cache")); List magiskCache = getModList(MAGISK_CACHE_PATH); - RepoAdapter mr = new RepoAdapter(); + RepoHelper mr = new RepoHelper(); List magiskRepos = mr.listRepos(mContext, doReload); for (String mod : magisk) { + Log.d("Magisk","Utils: Adding module from string " + mod); ModulesFragment.listModules.add(new Module(mod,mContext)); } for (String mod : magiskCache) { + Log.d("Magisk","Utils: Adding cache module from string " + mod); ModulesFragment.listModulesCache.add(new Module(mod,mContext)); } for (Repo repo : magiskRepos) { - if (repo.getId() != null){ - ModulesFragment.listModulesDownload.add(repo); - } + Log.d("Magisk","Utils: Adding repo from string " + repo.getId()); + ModulesFragment.listModulesDownload.add(repo); } return null; } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - } } public static class FlashZIP extends AsyncTask { @@ -462,35 +464,6 @@ 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/java/com/topjohnwu/magisk/utils/WebRequest.java b/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java index 171ac5a8a..d01649e97 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java @@ -1,5 +1,7 @@ package com.topjohnwu.magisk.utils; +import android.util.Log; + import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; @@ -33,12 +35,15 @@ public class WebRequest { */ public String makeWebServiceCall(String url, int requestmethod) { addNewLine=false; + Log.d("Magisk","WebRequest: Service call received for URL " + url); return this.makeWebServiceCall(url, requestmethod, null); + } public String makeWebServiceCall(String url, int requestmethod, boolean addNewLines) { addNewLine = addNewLines; + Log.d("Magisk","WebRequest: Service call(bool) received for URL " + url); return this.makeWebServiceCall(url, requestmethod, null); } @@ -99,7 +104,11 @@ public class WebRequest { String line; BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); while ((line = br.readLine()) != null) { - response += line + "\n"; + if (addNewLine) { + response += line + "\n"; + } else { + response += line; + } } } else { response = ""; diff --git a/app/src/main/res/drawable/ic_system_update_alt_black.xml b/app/src/main/res/drawable/ic_system_update_alt_black.xml new file mode 100644 index 000000000..25b07b5b4 --- /dev/null +++ b/app/src/main/res/drawable/ic_system_update_alt_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/list_item_repo.xml b/app/src/main/res/layout/list_item_repo.xml index 4eea607f8..71f9d461e 100644 --- a/app/src/main/res/layout/list_item_repo.xml +++ b/app/src/main/res/layout/list_item_repo.xml @@ -1,8 +1,5 @@ - + - + - \ No newline at end of file From 214649ec20b67285ee40b265d86e9190f6101f43 Mon Sep 17 00:00:00 2001 From: d8ahazard Date: Thu, 8 Sep 2016 15:47:10 -0500 Subject: [PATCH 3/4] Apparently Github is sensitive... --- .../com/topjohnwu/magisk/module/Repo.java | 19 +++++-- .../topjohnwu/magisk/module/RepoHelper.java | 8 +-- .../com/topjohnwu/magisk/utils/Utils.java | 50 ++++++++++++++++--- app/src/main/res/values/strings.xml | 2 + 4 files changed, 66 insertions(+), 13 deletions(-) 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 5814ab04c..d02cedc8e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/Repo.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/Repo.java @@ -5,13 +5,14 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.util.Log; +import com.topjohnwu.magisk.R; +import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.WebRequest; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import java.text.SimpleDateFormat; import java.util.Date; public class Repo { @@ -32,6 +33,7 @@ public class Repo { private Context appContext; private boolean mIsInstalled,mCanUpdate; + public Repo(String manifestString, Context context) { appContext = context; ParseProps(manifestString); @@ -45,6 +47,7 @@ public class Repo { this.mName = name; this.mBaseUrl = url; this.lastUpdate = updated.toString(); + this.fetch(); } @@ -60,10 +63,11 @@ public class Repo { } public void fetch() { + WebRequest webreq = new WebRequest(); // Construct initial url for contents - Log.d("Magisk", "Repo: Fetch called, Manifest string is: " + mBaseUrl + "/contents?access_token=5c9f47a299d48a6a649af3587bc97200bafcac65"); - String repoString = webreq.makeWebServiceCall(mBaseUrl + "/contents?access_token=5c9f47a299d48a6a649af3587bc97200bafcac65", WebRequest.GET); + Log.d("Magisk", "Repo: Fetch called, Manifest string is: " + mBaseUrl + "/contents?access_token=" + Utils.procFile(appContext.getString(R.string.some_string),appContext)); + String repoString = webreq.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++) { @@ -81,7 +85,7 @@ public class Repo { e.printStackTrace(); } - Log.d("Magisk", "Repo: Inner fetch: " + mManifestUrl + "?access_token=5c9f47a299d48a6a649af3587bc97200bafcac65"); + Log.d("Magisk", "Repo: Inner fetch: " + mManifestUrl + "?access_token=" + Utils.procFile(appContext.getString(R.string.some_string),appContext)); WebRequest propReq = new WebRequest(); String manifestString = propReq.makeWebServiceCall(mManifestUrl,WebRequest.GET,true); Log.d("Magisk","Repo: parseprops called from fetch for string " + manifestString); @@ -176,6 +180,13 @@ public class Repo { } } + + + + + + + public String getStringProperty(String mValue) { switch (mValue) { case "author": 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 d3fdfc0e9..40db33fe8 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java @@ -3,11 +3,12 @@ package com.topjohnwu.magisk.module; import android.content.Context; import android.content.SharedPreferences; import android.os.AsyncTask; -import android.os.Build; import android.preference.PreferenceManager; import android.util.Log; import android.widget.Toast; +import com.topjohnwu.magisk.R; +import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.WebRequest; import org.json.JSONArray; @@ -23,7 +24,7 @@ import java.util.Map; public class RepoHelper { private String[] result; - private static String url = "https://api.github.com/orgs/Magisk-Modules-Repo/repos?access_token=5c9f47a299d48a6a649af3587bc97200bafcac65"; + private static String url = "https://api.github.com/orgs/Magisk-Modules-Repo/repos?access_token="; private static List repos = new ArrayList(); private static final String TAG_ID = "id"; private static final String TAG_NAME = "name"; @@ -103,7 +104,8 @@ public class RepoHelper { WebRequest webreq = new WebRequest(); // Making a request to url and getting response - String jsonStr = webreq.makeWebServiceCall(url, WebRequest.GET); + String token = activityContext.getString(R.string.some_string); + String jsonStr = webreq.makeWebServiceCall(url + Utils.procFile(token,activityContext), WebRequest.GET); Log.d("Magisk", "doInBackground Running, String: " + jsonStr + " Url: " + url); if(jsonStr != null && !jsonStr.isEmpty()) { 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 c4fdfb4f5..40340bf3d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -10,6 +10,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; @@ -18,6 +19,7 @@ import android.preference.PreferenceManager; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AlertDialog; +import android.util.Base64; import android.util.Log; import android.view.View; import android.widget.Toast; @@ -36,10 +38,22 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; import java.util.List; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; + public class Utils { public static int magiskVersion, remoteMagiskVersion = -1, remoteAppVersion = -1; @@ -371,15 +385,39 @@ public class Utils { } } - public static class AuthGithub extends AsyncTask { - private static String mClientToken = "5c9f47a299d48a6a649af3587bc97200bafcac65"; + public static String procFile(String value, Context context) { - public AuthGithub(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); - @Override - protected Void doInBackground(Void... voids) { - return null; + 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 { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6f0fe3a30..9be26d621 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -92,4 +92,6 @@ phh\'s superuser SuperSU It seems that you have incompatible root installed\nDo you want to install Magisk compatible root now? + MagiskRox666 + GTYybRBTYf5his9kQ16ZNO7qgkBJ/5MyVe4CGceAOIoXgSnnk8FTd4F1dE9p5Eus From 1a1d37a2d05615846ab2e892daf97d5dc06a952c Mon Sep 17 00:00:00 2001 From: d8ahazard Date: Fri, 9 Sep 2016 16:49:25 -0500 Subject: [PATCH 4/4] Looking good... --- .../topjohnwu/magisk/BaseModuleFragment.java | 124 +++++++++- .../topjohnwu/magisk/BaseRepoFragment.java | 227 +++++++++++++----- .../com/topjohnwu/magisk/ModulesFragment.java | 18 +- .../topjohnwu/magisk/module/RepoHelper.java | 71 +++--- .../drawable/ic_system_update_alt_black.xml | 2 +- app/src/main/res/layout/list_item_module.xml | 22 ++ app/src/main/res/layout/list_item_repo.xml | 48 +++- app/src/main/res/layout/modules_fragment.xml | 97 ++++---- app/src/main/res/values/dimens.xml | 1 + app/src/main/res/values/strings.xml | 6 +- 10 files changed, 464 insertions(+), 152 deletions(-) diff --git a/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java b/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java index 530ad3e73..3becab3a3 100644 --- a/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/BaseModuleFragment.java @@ -1,5 +1,8 @@ package com.topjohnwu.magisk; +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; @@ -7,18 +10,23 @@ import android.support.annotation.Nullable; import android.support.design.widget.Snackbar; import android.support.v4.app.Fragment; 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 java.util.ArrayList; import java.util.List; import butterknife.BindView; @@ -35,17 +43,17 @@ public abstract class BaseModuleFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.single_module_fragment, container, false); + View viewMain = inflater.inflate(R.layout.single_module_fragment, container, false); - ButterKnife.bind(this, view); + ButterKnife.bind(this, viewMain); 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(); + viewMain.invalidate(); + viewMain.requestLayout(); } } @@ -54,7 +62,7 @@ public abstract class BaseModuleFragment extends Fragment { emptyTv.setVisibility(View.VISIBLE); recyclerView.setVisibility(View.GONE); - return view; + return viewMain; } recyclerView.setAdapter(new ModulesAdapter(listModules(), (chk, position) -> { @@ -79,7 +87,7 @@ public abstract class BaseModuleFragment extends Fragment { listModules().get(position).deleteRemoveFile(); Snackbar.make(undeleteBtn, R.string.remove_file_deleted, Snackbar.LENGTH_SHORT).show(); })); - return view; + return viewMain; } @@ -88,12 +96,21 @@ public abstract class BaseModuleFragment extends Fragment { public class ModulesAdapter extends RecyclerView.Adapter { private final List mList; + 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; public ModulesAdapter(List list, Utils.ItemClickListener chboxListener, Utils.ItemClickListener deleteBtnListener, Utils.ItemClickListener undeleteBtnListener) { this.mList = list; + mExpandedList = new ArrayList<>(mList.size()); + for (int i = 0; i < mList.size(); i++) { + mExpandedList.add(false); + } this.chboxListener = chboxListener; this.deleteBtnListener = deleteBtnListener; this.unDeleteBtnListener = undeleteBtnListener; @@ -101,9 +118,10 @@ public abstract class BaseModuleFragment extends Fragment { @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_module, parent, false); - - return new ViewHolder(view); + 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 @@ -158,15 +176,103 @@ public abstract class BaseModuleFragment extends Fragment { @BindView(R.id.checkbox) CheckBox checkBox; @BindView(R.id.delete) ImageView delete; + @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); + final int mHeight = dimension.heightPixels; + 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", "BaseRepoFragment: 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", "BaseRepoFragment: 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", "BaseRepoFragment: 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/BaseRepoFragment.java b/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java index 082e14878..bdf96520d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/BaseRepoFragment.java @@ -1,26 +1,33 @@ package com.topjohnwu.magisk; +import android.animation.Animator; +import android.animation.ValueAnimator; import android.content.Context; import android.content.SharedPreferences; +import android.graphics.Color; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.widget.RecyclerView; +import android.text.util.Linkify; +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.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import com.topjohnwu.magisk.module.Repo; -import com.topjohnwu.magisk.utils.AnimationHelper; import com.topjohnwu.magisk.utils.Utils; import java.io.File; +import java.util.ArrayList; import java.util.List; import butterknife.BindView; @@ -33,15 +40,11 @@ public abstract class BaseRepoFragment extends Fragment { @BindView(R.id.empty_rv) TextView emptyTv; - - - @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); if (listRepos().size() == 0) { @@ -50,7 +53,7 @@ public abstract class BaseRepoFragment extends Fragment { return view; } - Log.d("Magisk","BaseRepoFragment: ListRepos size is " + listRepos().size()); + Log.d("Magisk", "BaseRepoFragment: ListRepos size is " + listRepos().size()); recyclerView.setAdapter(new ReposAdapter(listRepos()) { }); @@ -63,21 +66,23 @@ public abstract class BaseRepoFragment extends Fragment { public class ReposAdapter extends RecyclerView.Adapter { private final List mList; - private View viewMain; - private Context context; + List mExpandedList; @BindView(R.id.update) ImageView updateImage; @BindView(R.id.installed) ImageView installedImage; -// @BindView(R.id.popup_layout) -// LinearLayout popupLayout; - - - private boolean isCardExpanded; + @BindView(R.id.expand_layout) + LinearLayout expandedLayout; + private View viewMain; + private Context context; private boolean mIsInstalled, mCanUpdate; public ReposAdapter(List list) { this.mList = list; + mExpandedList = new ArrayList<>(mList.size()); + for (int i = 0; i < mList.size(); i++) { + mExpandedList.add(false); + } } @@ -92,64 +97,69 @@ public abstract class BaseRepoFragment extends Fragment { @Override public void onBindViewHolder(final ViewHolder holder, int position) { final Repo repo = mList.get(position); - Log.d("Magisk","ReposAdapter: Trying set up bindview from list pos " + position + " out of a total of " + mList.size() + " and " + repo.getId() ); + + Log.d("Magisk", "ReposAdapter: Trying set up bindview from list pos " + position + " out of a total of " + mList.size() + " and " + repo.getId()); if (repo.getId() != null) { + TextView authorView = holder.author; holder.title.setText(repo.getName()); holder.versionName.setText(repo.getmVersion()); holder.description.setText(repo.getDescription()); + String authorString = getResources().getString(R.string.author) + " " + repo.getmAuthor(); + holder.author.setText(authorString); + if ((repo.getmLogUrl() != null) && (repo.getmLogUrl().equals(""))) { + holder.log.setText(repo.getmLogUrl()); + Linkify.addLinks(holder.log, Linkify.WEB_URLS); + } else { + holder.log.setVisibility(View.GONE); + } + holder.installedStatus.setText(repo.isInstalled() ? getResources().getString(R.string.module_installed) : getResources().getString(R.string.module_not_installed)); + if (mExpandedList.get(position)) { + holder.expandLayout.setVisibility(View.VISIBLE); + } else { + holder.expandLayout.setVisibility(View.GONE); + } + if (repo.isInstalled()) { + holder.installedStatus.setTextColor(Color.parseColor("#14AD00")); + holder.updateStatus.setText(repo.canUpdate() ? getResources().getString(R.string.module_update_available) : getResources().getString(R.string.module_up_to_date)); + } Log.d("Magisk", "ReposAdapter: Setting up info " + repo.getId() + " and " + repo.getDescription() + " and " + repo.getmVersion()); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - if (prefs.contains("repo-isInstalled_" + repo.getId())) { - mIsInstalled = prefs.getBoolean("repo-isInstalled_" + repo.getId(), false); - if (mIsInstalled) { - installedImage.setImageResource(R.drawable.ic_done_black); - } - mCanUpdate = prefs.getBoolean("repo-isInstalled_" + repo.getId(), false); - if (mCanUpdate) { - updateImage.setImageResource(R.drawable.ic_system_update_alt_black); - } - } - - isCardExpanded = false; -// AnimationHelper.collapse(popupLayout); - - viewMain.setOnClickListener(new View.OnClickListener() { + updateImage.setImageResource(R.drawable.ic_system_update_alt_black); + mCanUpdate = prefs.getBoolean("repo-isInstalled_" + repo.getId(), false); + updateImage.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View view) { - if (isCardExpanded) { -// AnimationHelper.expand(popupLayout); - isCardExpanded = false; + if (!mIsInstalled | mCanUpdate) { + + Utils.DownloadReceiver reciever = new Utils.DownloadReceiver() { + @Override + public void task(File file) { + Log.d("Magisk", "Task firing"); + new Utils.FlashZIP(context, repo.getId(), file.toString()).execute(); + } + }; + String filename = repo.getId().replace(" ", "") + ".zip"; + Utils.downloadAndReceive(context, reciever, repo.getmZipUrl(), filename); } else { -// AnimationHelper.collapse(popupLayout); - isCardExpanded = true; - + Toast.makeText(context, repo.getId() + " is already installed.", Toast.LENGTH_SHORT).show(); } - -// if (!mIsInstalled | mCanUpdate) { -// -// Utils.DownloadReceiver reciever = new Utils.DownloadReceiver() { -// @Override -// public void task(File file) { -// Log.d("Magisk", "Task firing"); -// new Utils.FlashZIP(context, repo.getId(), file.toString()).execute(); -// } -// }; -// String filename = repo.getId().replace(" ", "") + ".zip"; -// Utils.downloadAndReceive(context, reciever, repo.getmZipUrl(), filename); -// } else { -// Toast.makeText(context,repo.getId() + " is already installed.", Toast.LENGTH_SHORT).show(); -// } } }); + if (prefs.contains("repo-isInstalled_" + repo.getId())) { + mIsInstalled = prefs.getBoolean("repo-isInstalled_" + repo.getId(), false); +// if (mIsInstalled) { +// installedImage.setImageResource(R.drawable.ic_done_black); +// } + + } + + } } - - @Override public int getItemCount() { return mList.size(); @@ -157,15 +167,120 @@ public abstract class BaseRepoFragment extends Fragment { 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.title) + TextView title; + @BindView(R.id.version_name) + TextView versionName; + @BindView(R.id.description) + TextView description; + @BindView(R.id.author) + TextView author; + @BindView(R.id.log) + TextView log; + @BindView(R.id.installedStatus) + TextView installedStatus; + @BindView(R.id.updateStatus) + TextView updateStatus; + @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); + final int mHeight = dimension.heightPixels; + 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", "BaseRepoFragment: CLICK. " + position + " and " + mExpandedList.get(position)); + + if (mExpandedList.get(position)) { + collapse(expandLayout); + } else { + expand(expandLayout); + } + mExpandedList.set(position, !mExpandedList.get(position)); + + }); + } + + private void expand(View view) { + + // set Visible + + + Log.d("Magisk", "BaseRepoFragment: 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", "BaseRepoFragment: 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 6a2cc8ea0..4dd1c2ceb 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/ModulesFragment.java @@ -41,9 +41,7 @@ public class ModulesFragment extends Fragment { public static List listModulesCache = new ArrayList<>(); public static List listModulesDownload = new ArrayList<>(); private static final int FILE_SELECT_CODE = 0; - private TabsAdapter ta; - private File input; - private SwipeRefreshLayout mSwipeRefreshLayout; + private int viewPagePosition; @BindView(R.id.progressBar) ProgressBar progressBar; @BindView(R.id.fab) FloatingActionButton fabio; @@ -56,7 +54,7 @@ public class ModulesFragment extends Fragment { View view = inflater.inflate(R.layout.modules_fragment, container, false); ButterKnife.bind(this, view); - //new Utils.LoadModules(getActivity(),false).execute(); + new Utils.LoadModules(getActivity(),false).execute(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); new updateUI().execute(); setHasOptionsMenu(true); @@ -101,12 +99,14 @@ public class ModulesFragment extends Fragment { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.force_reload: + viewPagePosition = tabLayout.getSelectedTabPosition(); listModules.clear(); listModulesCache.clear(); listModulesDownload.clear(); progressBar.setVisibility(View.VISIBLE); viewPager.setAdapter(new TabsAdapter(getChildFragmentManager())); tabLayout.setupWithViewPager(viewPager); + viewPager.setCurrentItem(viewPagePosition); new Utils.LoadModules(getActivity(),true).execute(); new updateUI().execute(); break; @@ -115,6 +115,11 @@ public class ModulesFragment extends Fragment { return super.onOptionsItemSelected(item); } + void selectPage(int pageIndex){ + tabLayout.setScrollPosition(pageIndex,0f,true); + viewPager.setCurrentItem(pageIndex); + } + public static class NormalModuleFragment extends BaseModuleFragment { @Override @@ -154,9 +159,10 @@ public class ModulesFragment extends Fragment { super.onPostExecute(v); progressBar.setVisibility(View.GONE); - viewPager.setAdapter(new TabsAdapter(getChildFragmentManager())); tabLayout.setupWithViewPager(viewPager); + selectPage(viewPagePosition); + } } @@ -186,7 +192,7 @@ public class ModulesFragment extends Fragment { return new NormalModuleFragment(); } else if (position == 1) { return new CacheModuleFragment(); - } else { + } else { return new DownloadModuleFragment(); } } 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 40db33fe8..1a04c0363 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/RepoHelper.java @@ -29,7 +29,7 @@ public class RepoHelper { private static final String TAG_ID = "id"; private static final String TAG_NAME = "name"; private static String TAG = "Magisk"; - private String mName,mId,mUrl; + private String mName, mId, mUrl; private Context activityContext; private Date updatedDate, currentDate; private SharedPreferences prefs; @@ -44,35 +44,7 @@ public class RepoHelper { List out = null; } else { Log.d(TAG, "RepoHelper: Building from cache"); - repos.clear(); - Map map = prefs.getAll(); - for(Map.Entry entry : map.entrySet()){ - if (entry.getKey().contains("repo_")) { - Log.d("Magisk","RepoHelper: found entry for repo " + entry.getKey()); - String repoString = entry.getValue().toString().replace(""", "\""); - String[] repoStrings = repoString.split("\n"); - for(String string : repoStrings) { - String[] splitStrings = string.split("="); - switch(splitStrings[0]) { - case ("id"): - mId = splitStrings[1]; - break; - case ("baseUrl"): - mUrl = splitStrings[1]; - break; - default: - break; - } - - } - Log.d("Magisk","RepoHelper: adding repo with id of " + mId); - repos.add(new Repo(repoString,activityContext)); - - - } - - } - + BuildFromCache(); } @@ -81,6 +53,37 @@ public class RepoHelper { return repos; } + private void BuildFromCache() { + repos.clear(); + Map map = prefs.getAll(); + for (Map.Entry entry : map.entrySet()) { + if (entry.getKey().contains("repo_")) { + Log.d("Magisk", "RepoHelper: found entry for repo " + entry.getKey()); + String repoString = entry.getValue().toString().replace(""", "\""); + String[] repoStrings = repoString.split("\n"); + for (String string : repoStrings) { + String[] splitStrings = string.split("="); + switch (splitStrings[0]) { + case ("id"): + mId = splitStrings[1]; + break; + case ("baseUrl"): + mUrl = splitStrings[1]; + break; + default: + break; + } + + } + Log.d("Magisk", "RepoHelper: adding repo with id of " + mId); + repos.add(new Repo(repoString, activityContext)); + + + } + + } + } + class MyAsyncTask extends AsyncTask { @@ -105,9 +108,9 @@ public class RepoHelper { // Making a request to url and getting response String token = activityContext.getString(R.string.some_string); - String jsonStr = webreq.makeWebServiceCall(url + Utils.procFile(token,activityContext), WebRequest.GET); + String jsonStr = webreq.makeWebServiceCall(url + Utils.procFile(token, activityContext), WebRequest.GET); Log.d("Magisk", "doInBackground Running, String: " + jsonStr + " Url: " + url); - if(jsonStr != null && !jsonStr.isEmpty()) { + if (jsonStr != null && !jsonStr.isEmpty()) { try { repos.clear(); @@ -185,7 +188,9 @@ public class RepoHelper { protected void onPostExecute(Void v) { if (apiFail) { - Toast.makeText(activityContext,"GitHub API Limit reached, please try refreshing again in an hour.",Toast.LENGTH_LONG).show(); + Toast.makeText(activityContext, "GitHub API Limit reached, please try refreshing again in an hour.", Toast.LENGTH_LONG).show(); + } else { + BuildFromCache(); } } // protected void onPostExecute(Void v) diff --git a/app/src/main/res/drawable/ic_system_update_alt_black.xml b/app/src/main/res/drawable/ic_system_update_alt_black.xml index 25b07b5b4..fb2d85e57 100644 --- a/app/src/main/res/drawable/ic_system_update_alt_black.xml +++ b/app/src/main/res/drawable/ic_system_update_alt_black.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/layout/list_item_module.xml b/app/src/main/res/layout/list_item_module.xml index 6a22df864..00ce343c2 100644 --- a/app/src/main/res/layout/list_item_module.xml +++ b/app/src/main/res/layout/list_item_module.xml @@ -13,6 +13,10 @@ android:minHeight="?android:attr/listPreferredItemHeight" card_view:cardCornerRadius="2dp" card_view:cardElevation="2dp"> + + + + + + + diff --git a/app/src/main/res/layout/list_item_repo.xml b/app/src/main/res/layout/list_item_repo.xml index 71f9d461e..bda43c4fc 100644 --- a/app/src/main/res/layout/list_item_repo.xml +++ b/app/src/main/res/layout/list_item_repo.xml @@ -60,22 +60,64 @@ android:textAppearance="?android:attr/textAppearanceSmall" android:textIsSelectable="false"/> + + + + + + + + + android:layout_height="match_parent" + android:focusable="false" + android:gravity="center" + android:padding="5dp" + /> + android:layout_height="match_parent" + android:focusable="false" + android:gravity="center" + android:padding="5dp" /> - + diff --git a/app/src/main/res/layout/modules_fragment.xml b/app/src/main/res/layout/modules_fragment.xml index 7c954d6a2..ae6bca833 100644 --- a/app/src/main/res/layout/modules_fragment.xml +++ b/app/src/main/res/layout/modules_fragment.xml @@ -1,54 +1,67 @@ - - - + - + - + + + + + - - + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 8eb8263ae..065a40f8a 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -2,4 +2,5 @@ 650dp 500dp + 100dp \ 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 9be26d621..6c927aad8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -42,13 +42,15 @@ Cache modules No modules found - Update available - Module is up-to-date + An update is available + Module is up-to-date Module is installed + Module is not installed Module will be removed at next reboot Module will not be removed at next reboot Module will be disabled at next reboot Module will be enabled at next reboot + Created by Save to SD