Project restructure

This commit is contained in:
topjohnwu
2017-01-25 04:27:05 +08:00
parent 478b7eeb65
commit ad16a6fc1b
18 changed files with 200 additions and 180 deletions

View File

@@ -11,12 +11,10 @@ import android.provider.OpenableColumns;
import android.util.Log;
import android.widget.Toast;
import com.topjohnwu.magisk.InstallFragment;
import com.topjohnwu.magisk.Global;
import com.topjohnwu.magisk.MagiskHideFragment;
import com.topjohnwu.magisk.ModulesFragment;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ReposFragment;
import com.topjohnwu.magisk.StatusFragment;
import com.topjohnwu.magisk.module.ModuleHelper;
import org.json.JSONException;
import org.json.JSONObject;
@@ -60,16 +58,16 @@ public class Async {
try {
JSONObject json = new JSONObject(jsonStr);
JSONObject magisk = json.getJSONObject("magisk");
StatusFragment.remoteMagiskVersion = magisk.getDouble("versionCode");
StatusFragment.magiskLink = magisk.getString("link");
StatusFragment.releaseNoteLink = magisk.getString("note");
Global.Info.remoteMagiskVersion = magisk.getDouble("versionCode");
Global.Info.magiskLink = magisk.getString("link");
Global.Info.releaseNoteLink = magisk.getString("note");
} catch (JSONException ignored) {}
return null;
}
@Override
protected void onPostExecute(Void v) {
StatusFragment.updateCheckDone.trigger();
Global.Events.updateCheckDone.trigger();
}
}
@@ -77,8 +75,8 @@ public class Async {
new SafetyNetHelper(context) {
@Override
public void handleResults(int i) {
StatusFragment.SNCheckResult = i;
StatusFragment.safetyNetDone.trigger();
Global.Info.SNCheckResult = i;
Global.Events.safetyNetDone.trigger();
}
}.requestTest();
}
@@ -93,7 +91,7 @@ public class Async {
@Override
protected void onPostExecute(Void v) {
ModulesFragment.moduleLoadDone.trigger();
Global.Events.moduleLoadDone.trigger();
}
}
@@ -113,7 +111,7 @@ public class Async {
@Override
protected void onPostExecute(Void v) {
ReposFragment.repoLoadDone.trigger();
Global.Events.repoLoadDone.trigger();
}
}
@@ -130,7 +128,7 @@ public class Async {
List<ApplicationInfo> listApps = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (Iterator<ApplicationInfo> i = listApps.iterator(); i.hasNext(); ) {
ApplicationInfo info = i.next();
if (MagiskHideFragment.BLACKLIST.contains(info.packageName) || !info.enabled)
if (MagiskHideFragment.HIDEBLACKLIST.contains(info.packageName) || !info.enabled)
i.remove();
}
Collections.sort(listApps, (a, b) -> a.loadLabel(pm).toString().toLowerCase()
@@ -141,7 +139,7 @@ public class Async {
@Override
protected void onPostExecute(Result result) {
MagiskHideFragment.packageLoadDone.trigger(result);
Global.Events.packageLoadDone.trigger(result);
}
public static class Result {
@@ -289,7 +287,7 @@ public class Async {
}
protected void onSuccess() {
StatusFragment.updateCheckDone.trigger();
Global.Events.updateCheckDone.trigger();
new LoadModules().exec();
Utils.getAlertDialogBuilder(mContext)
@@ -324,9 +322,9 @@ public class Async {
@Override
protected Void doInBackground(Void... params) {
if (Shell.rootAccess()) {
InstallFragment.blockList = Shell.su("ls /dev/block | grep mmc");
if (InstallFragment.bootBlock == null) {
InstallFragment.bootBlock = Utils.detectBootImage();
Global.Data.blockList = Shell.su("ls /dev/block | grep mmc");
if (Global.Info.bootBlock == null) {
Global.Info.bootBlock = Utils.detectBootImage();
}
}
return null;
@@ -334,7 +332,7 @@ public class Async {
@Override
protected void onPostExecute(Void aVoid) {
InstallFragment.blockDetectionDone.trigger();
Global.Events.blockDetectionDone.trigger();
}
}
}

View File

@@ -0,0 +1,113 @@
package com.topjohnwu.magisk.utils;
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPropertyAnimatorCompat;
import android.util.AttributeSet;
import android.view.View;
import com.github.clans.fab.FloatingActionMenu;
import java.util.List;
/**
* Created by Matteo on 08/08/2015.
*
* Floating Action Menu Behavior for Clans.FloatingActionButton
* https://github.com/Clans/FloatingActionButton/
*
* Use this behavior as your app:layout_behavior attribute in your Floating Action Menu to use the
* FabMenu in a Coordinator Layout.
*
* Remember to use the correct namespace for the fab:
* xmlns:fab="http://schemas.android.com/apk/res-auto"
*/
public class FABBehavior extends CoordinatorLayout.Behavior {
private float mTranslationY;
public FABBehavior(Context context, AttributeSet attrs) {
super();
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof Snackbar.SnackbarLayout;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
if (dependency instanceof Snackbar.SnackbarLayout) {
updateTranslation(parent, child);
}
return false;
}
@Override
public void onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency) {
if (dependency instanceof Snackbar.SnackbarLayout) {
revertTranslation(child);
}
}
private void updateTranslation(CoordinatorLayout parent, View child) {
float translationY = getTranslationY(parent, child);
if (translationY != mTranslationY) {
ViewPropertyAnimatorCompat anim = ViewCompat.animate(child);
anim.cancel();
anim.translationY(translationY).setDuration(100);
mTranslationY = translationY;
}
}
private void revertTranslation(View child) {
if (mTranslationY != 0) {
ViewPropertyAnimatorCompat anim = ViewCompat.animate(child);
anim.cancel();
anim.translationY(0).setDuration(100);
mTranslationY = 0;
}
}
private float getTranslationY(CoordinatorLayout parent, View child) {
float minOffset = 0.0F;
List dependencies = parent.getDependencies(child);
int i = 0;
for (int z = dependencies.size(); i < z; ++i) {
View view = (View) dependencies.get(i);
if (view instanceof Snackbar.SnackbarLayout && parent.doViewsOverlap(child, view)) {
minOffset = Math.min(minOffset, ViewCompat.getTranslationY(view) - (float) view.getHeight());
}
}
return minOffset;
}
/**
* onStartNestedScroll and onNestedScroll will hide/show the FabMenu when a scroll is detected.
*/
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child,
View directTargetChild, View target, int nestedScrollAxes) {
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL ||
super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target,
nestedScrollAxes);
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target,
int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed,
dyUnconsumed);
FloatingActionMenu fabMenu = (FloatingActionMenu) child;
if (dyConsumed > 0 && !fabMenu.isMenuButtonHidden()) {
fabMenu.hideMenuButton(true);
} else if (dyConsumed < 0 && fabMenu.isMenuButtonHidden()) {
fabMenu.showMenuButton(true);
}
}
}

View File

@@ -1,203 +0,0 @@
package com.topjohnwu.magisk.utils;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.module.BaseModule;
import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.module.Repo;
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.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class ModuleHelper {
private static final String MAGISK_PATH = "/magisk";
public static final String FILE_KEY = "RepoMap";
private static final String REPO_KEY = "repomap";
public static final String VERSION_KEY = "version";
public static final String ETAG_KEY = "ETag";
private static final int DATABASE_VER = 1;
private static ValueSortedMap<String, Repo> repoMap = new ValueSortedMap<>();
private static ValueSortedMap<String, Module> moduleMap = new ValueSortedMap<>();
public static void createModuleMap() {
Logger.dev("ModuleHelper: Loading modules");
moduleMap.clear();
for (String path : Utils.getModList(MAGISK_PATH)) {
Logger.dev("ModuleHelper: Adding modules from " + path);
Module module;
try {
module = new Module(path);
moduleMap.put(module.getId(), module);
} catch (BaseModule.CacheModException ignored) {}
}
Logger.dev("ModuleHelper: Module load done");
}
public static void createRepoMap(Context context) {
Logger.dev("ModuleHelper: Loading repos");
SharedPreferences prefs = context.getSharedPreferences(FILE_KEY, Context.MODE_PRIVATE);
repoMap.clear();
Gson gson = new Gson();
String jsonString;
int cachedVersion = prefs.getInt(VERSION_KEY, 0);
if (cachedVersion != DATABASE_VER) {
// Ignore incompatible cached database
jsonString = null;
} else {
jsonString = prefs.getString(REPO_KEY, null);
}
ValueSortedMap<String, Repo> cached = null;
if (jsonString != null) {
cached = gson.fromJson(jsonString, new TypeToken<ValueSortedMap<String, Repo>>(){}.getType());
}
if (cached == null) {
cached = new ValueSortedMap<>();
}
// Get cached ETag to add in the request header
String etag = prefs.getString(ETAG_KEY, "");
HashMap<String, String> header = new HashMap<>();
header.put("If-None-Match", etag);
// Making a request to main URL for repo info
jsonString = WebService.request(
context.getString(R.string.url_main), WebService.GET, null, header, false);
if (!jsonString.isEmpty()) {
try {
JSONArray jsonArray = new JSONArray(jsonString);
// If it gets to this point, the response is valid, update ETag
etag = WebService.getLastResponseHeader().get(ETAG_KEY).get(0);
// Maybe bug in Android build tools, sometimes the ETag has crap in it...
etag = etag.substring(etag.indexOf('\"'), etag.lastIndexOf('\"') + 1);
// Update repo info
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonobject = jsonArray.getJSONObject(i);
String id = jsonobject.getString("description");
String name = jsonobject.getString("name");
String lastUpdate = jsonobject.getString("pushed_at");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
Date updatedDate;
try {
updatedDate = format.parse(lastUpdate);
} catch (ParseException e) {
continue;
}
Repo repo = cached.get(id);
try {
if (repo == null) {
Logger.dev("ModuleHelper: Create new repo " + id);
repo = new Repo(context, name, updatedDate);
} else {
Logger.dev("ModuleHelper: Update cached repo " + id);
repo.update(updatedDate);
}
if (repo.getId() != null) {
repoMap.put(id, repo);
}
} catch (BaseModule.CacheModException ignored) {}
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
// Use cached if no internet or no updates
Logger.dev("ModuleHelper: No updates, use cached");
repoMap.putAll(cached);
}
prefs.edit()
.putInt(VERSION_KEY, DATABASE_VER)
.putString(REPO_KEY, gson.toJson(repoMap))
.putString(ETAG_KEY, etag)
.apply();
Logger.dev("ModuleHelper: Repo load done");
}
public static void getModuleList(List<Module> moduleList) {
moduleList.clear();
moduleList.addAll(moduleMap.values());
}
public static void getRepoLists(List<Repo> update, List<Repo> installed, List<Repo> others) {
update.clear();
installed.clear();
others.clear();
for (Repo repo : repoMap.values()) {
Module module = moduleMap.get(repo.getId());
if (module != null) {
if (repo.getVersionCode() > module.getVersionCode()) {
update.add(repo);
} else {
installed.add(repo);
}
} else {
others.add(repo);
}
}
}
private static class ValueSortedMap<K, V extends Comparable<? super V>> extends HashMap<K, V> {
private List<V> sorted = new ArrayList<>();
@NonNull
@Override
public Collection<V> values() {
if (sorted.isEmpty()) {
sorted.addAll(super.values());
Collections.sort(sorted);
}
return sorted;
}
@Override
public V put(K key, V value) {
sorted.clear();
return super.put(key, value);
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
sorted.clear();
super.putAll(m);
}
@Override
public V remove(Object key) {
sorted.clear();
return super.remove(key);
}
}
}

View File

@@ -0,0 +1,43 @@
package com.topjohnwu.magisk.utils;
import android.support.annotation.NonNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ValueSortedMap<K, V extends Comparable<? super V>> extends HashMap<K, V> {
private List<V> sorted = new ArrayList<>();
@NonNull
@Override
public Collection<V> values() {
if (sorted.isEmpty()) {
sorted.addAll(super.values());
Collections.sort(sorted);
}
return sorted;
}
@Override
public V put(K key, V value) {
sorted.clear();
return super.put(key, value);
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
sorted.clear();
super.putAll(m);
}
@Override
public V remove(Object key) {
sorted.clear();
return super.remove(key);
}
}