mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 10:35:26 +00:00
Small optimization to UpdateRepos
This commit is contained in:
parent
c78896a335
commit
153d0f5505
@ -90,7 +90,6 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
HttpURLConnection conn;
|
HttpURLConnection conn;
|
||||||
do {
|
do {
|
||||||
conn = WebService.request(mLink, null);
|
conn = WebService.request(mLink, null);
|
||||||
if (conn == null) return null;
|
|
||||||
total = conn.getContentLength();
|
total = conn.getContentLength();
|
||||||
if (total < 0)
|
if (total < 0)
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.topjohnwu.magisk.asyncs;
|
package com.topjohnwu.magisk.asyncs;
|
||||||
|
|
||||||
|
import android.database.Cursor;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.ReposFragment;
|
import com.topjohnwu.magisk.ReposFragment;
|
||||||
@ -11,20 +13,22 @@ import com.topjohnwu.magisk.utils.Utils;
|
|||||||
import com.topjohnwu.magisk.utils.WebService;
|
import com.topjohnwu.magisk.utils.WebService;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class UpdateRepos extends ParallelTask<Void, Void, Void> {
|
public class UpdateRepos extends ParallelTask<Void, Void, Void> {
|
||||||
@ -35,7 +39,8 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
|
|||||||
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
|
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
|
||||||
|
|
||||||
private MagiskManager mm;
|
private MagiskManager mm;
|
||||||
private List<String> cached, etags, newEtags = new LinkedList<>();
|
private List<String> etags, newEtags = new LinkedList<>();
|
||||||
|
private Set<String> cached;
|
||||||
private boolean forceUpdate;
|
private boolean forceUpdate;
|
||||||
private AtomicInteger taskCount = new AtomicInteger(0);
|
private AtomicInteger taskCount = new AtomicInteger(0);
|
||||||
final private Object allDone = new Object();
|
final private Object allDone = new Object();
|
||||||
@ -43,13 +48,6 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
|
|||||||
public UpdateRepos(boolean force) {
|
public UpdateRepos(boolean force) {
|
||||||
mm = MagiskManager.get();
|
mm = MagiskManager.get();
|
||||||
mm.repoLoadDone.reset();
|
mm.repoLoadDone.reset();
|
||||||
// Legacy data cleanup
|
|
||||||
File old = new File(mm.getApplicationInfo().dataDir + "/shared_prefs", "RepoMap.xml");
|
|
||||||
if (old.exists() || mm.prefs.getString("repomap", null) != null) {
|
|
||||||
old.delete();
|
|
||||||
mm.prefs.edit().remove("version").remove("repomap").remove(Const.Key.ETAG_KEY).apply();
|
|
||||||
mm.repoDB.clearRepo();
|
|
||||||
}
|
|
||||||
forceUpdate = force;
|
forceUpdate = force;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,75 +80,61 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadJSON(String jsonString) throws Exception {
|
private boolean loadJSON(String jsonString) throws JSONException, ParseException {
|
||||||
JSONArray jsonArray = new JSONArray(jsonString);
|
JSONArray jsonArray = new JSONArray(jsonString);
|
||||||
|
|
||||||
// Empty page, throw error
|
// Empty page, halt
|
||||||
if (jsonArray.length() == 0)
|
if (jsonArray.length() == 0)
|
||||||
throw new Exception();
|
return false;
|
||||||
|
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
JSONObject rawRepo = jsonArray.getJSONObject(i);
|
JSONObject rawRepo = jsonArray.getJSONObject(i);
|
||||||
String id = rawRepo.getString("description");
|
String id = rawRepo.getString("description");
|
||||||
String name = rawRepo.getString("name");
|
String name = rawRepo.getString("name");
|
||||||
Date date = dateFormat.parse(rawRepo.getString("pushed_at"));
|
Date date = dateFormat.parse(rawRepo.getString("pushed_at"));
|
||||||
final List<String> c = cached;
|
Set<String> set = Collections.synchronizedSet(cached);
|
||||||
queueTask(() -> {
|
queueTask(() -> {
|
||||||
Repo repo = mm.repoDB.getRepo(id);
|
Repo repo = mm.repoDB.getRepo(id);
|
||||||
Boolean updated;
|
|
||||||
try {
|
try {
|
||||||
if (repo == null) {
|
if (repo == null)
|
||||||
repo = new Repo(name, date);
|
repo = new Repo(name);
|
||||||
updated = true;
|
else
|
||||||
} else {
|
set.remove(id);
|
||||||
// Popout from cached
|
repo.update(date);
|
||||||
synchronized (c) {
|
mm.repoDB.addRepo(repo);
|
||||||
c.remove(id);
|
publishProgress();
|
||||||
}
|
|
||||||
if (forceUpdate) {
|
|
||||||
repo.update();
|
|
||||||
updated = true;
|
|
||||||
} else {
|
|
||||||
updated = repo.update(date);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (updated) {
|
|
||||||
mm.repoDB.addRepo(repo);
|
|
||||||
publishProgress();
|
|
||||||
}
|
|
||||||
} catch (Repo.IllegalRepoException e) {
|
} catch (Repo.IllegalRepoException e) {
|
||||||
Logger.debug(e.getMessage());
|
Logger.debug(e.getMessage());
|
||||||
mm.repoDB.removeRepo(id);
|
mm.repoDB.removeRepo(id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean loadPage(int page, int mode) {
|
private boolean loadPage(int page, int mode) {
|
||||||
Map<String, String> header = new HashMap<>();
|
Map<String, String> header = new HashMap<>();
|
||||||
String etag = (mode == CHECK_ETAG && page < etags.size()) ? etags.get(page) : "";
|
if (mode == CHECK_ETAG && page < etags.size())
|
||||||
header.put(Const.Key.IF_NONE_MATCH, etag);
|
header.put(Const.Key.IF_NONE_MATCH, etags.get(page));
|
||||||
String url = Utils.fmt(Const.Url.REPO_URL, page + 1);
|
String url = Utils.fmt(Const.Url.REPO_URL, page + 1);
|
||||||
HttpURLConnection conn = WebService.request(url, header);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (conn == null)
|
HttpURLConnection conn = WebService.request(url, header);
|
||||||
throw new Exception();
|
|
||||||
if (conn.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
|
if (conn.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
|
||||||
// Current page is not updated, check the next page
|
// Current page is not updated, check the next page
|
||||||
return page + 1 < etags.size() && loadPage(page + 1, CHECK_ETAG);
|
return loadPage(page + 1, CHECK_ETAG);
|
||||||
}
|
}
|
||||||
loadJSON(WebService.getString(conn));
|
if (!loadJSON(WebService.getString(conn)))
|
||||||
|
return mode != CHECK_ETAG;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
// Don't continue
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If one page is updated, we force update all pages */
|
/* If one page is updated, we force update all pages */
|
||||||
|
|
||||||
// Update ETAG
|
// Update ETAG
|
||||||
etag = header.get(Const.Key.ETAG_KEY);
|
String etag = header.get(Const.Key.ETAG_KEY);
|
||||||
etag = etag.substring(etag.indexOf('\"'), etag.lastIndexOf('\"') + 1);
|
etag = etag.substring(etag.indexOf('\"'), etag.lastIndexOf('\"') + 1);
|
||||||
if (mode == LOAD_PREV) {
|
if (mode == LOAD_PREV) {
|
||||||
// We are loading a previous page, push the new tag to the front
|
// We are loading a previous page, push the new tag to the front
|
||||||
@ -188,40 +172,32 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... voids) {
|
protected Void doInBackground(Void... voids) {
|
||||||
etags = new ArrayList<>(Arrays.asList(mm.prefs.getString(Const.Key.ETAG_KEY, "").split(",")));
|
etags = Arrays.asList(mm.prefs.getString(Const.Key.ETAG_KEY, "").split(","));
|
||||||
cached = mm.repoDB.getRepoIDList();
|
cached = mm.repoDB.getRepoIDSet();
|
||||||
|
|
||||||
if (!loadPage(0, CHECK_ETAG)) {
|
if (loadPage(0, CHECK_ETAG)) {
|
||||||
// Nothing changed online
|
|
||||||
if (forceUpdate) {
|
|
||||||
for (String id : cached) {
|
|
||||||
if (id == null) continue;
|
|
||||||
queueTask(() -> {
|
|
||||||
Repo repo = mm.repoDB.getRepo(id);
|
|
||||||
try {
|
|
||||||
repo.update();
|
|
||||||
mm.repoDB.addRepo(repo);
|
|
||||||
} catch (Repo.IllegalRepoException e) {
|
|
||||||
Logger.debug(e.getMessage());
|
|
||||||
mm.repoDB.removeRepo(repo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
waitTasks();
|
|
||||||
} else {
|
|
||||||
waitTasks();
|
waitTasks();
|
||||||
|
|
||||||
// The leftover cached means they are removed from online repo
|
// The leftover cached means they are removed from online repo
|
||||||
mm.repoDB.removeRepo(cached);
|
mm.repoDB.removeRepo(cached);
|
||||||
|
|
||||||
// Update ETag
|
// Update ETag
|
||||||
StringBuilder etagBuilder = new StringBuilder();
|
mm.prefs.edit().putString(Const.Key.ETAG_KEY, TextUtils.join(",", newEtags)).apply();
|
||||||
for (int i = 0; i < newEtags.size(); ++i) {
|
} else if (forceUpdate) {
|
||||||
if (i != 0) etagBuilder.append(",");
|
Cursor c = mm.repoDB.getRawCursor();
|
||||||
etagBuilder.append(newEtags.get(i));
|
while (c.moveToNext()) {
|
||||||
|
Repo repo = new Repo(c);
|
||||||
|
queueTask(() -> {
|
||||||
|
try {
|
||||||
|
repo.update();
|
||||||
|
mm.repoDB.addRepo(repo);
|
||||||
|
} catch (Repo.IllegalRepoException e) {
|
||||||
|
Logger.debug(e.getMessage());
|
||||||
|
mm.repoDB.removeRepo(repo);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
mm.prefs.edit().putString(Const.Key.ETAG_KEY, etagBuilder.toString()).apply();
|
waitTasks();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,8 @@ public class Repo extends BaseModule {
|
|||||||
private String repoName;
|
private String repoName;
|
||||||
private Date mLastUpdate;
|
private Date mLastUpdate;
|
||||||
|
|
||||||
public Repo(String name, Date lastUpdate) throws IllegalRepoException {
|
public Repo(String name) {
|
||||||
mLastUpdate = lastUpdate;
|
|
||||||
repoName = name;
|
repoName = name;
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Repo(Cursor c) {
|
public Repo(Cursor c) {
|
||||||
@ -48,13 +46,9 @@ public class Repo extends BaseModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean update(Date lastUpdate) throws IllegalRepoException {
|
public void update(Date lastUpdate) throws IllegalRepoException {
|
||||||
if (lastUpdate.after(mLastUpdate)) {
|
mLastUpdate = lastUpdate;
|
||||||
mLastUpdate = lastUpdate;
|
update();
|
||||||
update();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -10,8 +10,8 @@ import com.topjohnwu.magisk.container.Repo;
|
|||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.Set;
|
||||||
|
|
||||||
public class RepoDatabaseHelper extends SQLiteOpenHelper {
|
public class RepoDatabaseHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
|
|||||||
mDb.delete(TABLE_NAME, "repo_name=?", new String[] { repo.getRepoName() });
|
mDb.delete(TABLE_NAME, "repo_name=?", new String[] { repo.getRepoName() });
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeRepo(List<String> list) {
|
public void removeRepo(Iterable<String> list) {
|
||||||
for (String id : list) {
|
for (String id : list) {
|
||||||
if (id == null) continue;
|
if (id == null) continue;
|
||||||
mDb.delete(TABLE_NAME, "id=?", new String[] { id });
|
mDb.delete(TABLE_NAME, "id=?", new String[] { id });
|
||||||
@ -94,6 +94,10 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Cursor getRawCursor() {
|
||||||
|
return mDb.query(TABLE_NAME, null, null, null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public Cursor getRepoCursor() {
|
public Cursor getRepoCursor() {
|
||||||
String orderBy = null;
|
String orderBy = null;
|
||||||
switch (mm.repoOrder) {
|
switch (mm.repoOrder) {
|
||||||
@ -108,13 +112,13 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
|
|||||||
null, null, orderBy);
|
null, null, orderBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getRepoIDList() {
|
public Set<String> getRepoIDSet() {
|
||||||
LinkedList<String> ret = new LinkedList<>();
|
HashSet<String> set = new HashSet<>(300);
|
||||||
try (Cursor c = mDb.query(TABLE_NAME, null, null, null, null, null, null)) {
|
try (Cursor c = mDb.query(TABLE_NAME, null, null, null, null, null, null)) {
|
||||||
while (c.moveToNext()) {
|
while (c.moveToNext()) {
|
||||||
ret.add(c.getString(c.getColumnIndex("id")));
|
set.add(c.getString(c.getColumnIndex("id")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return set;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,13 @@ public class WebService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getString(String url, Map<String, String> header) {
|
public static String getString(String url, Map<String, String> header) {
|
||||||
HttpURLConnection conn = request(url, header);
|
try {
|
||||||
if (conn == null) return "";
|
HttpURLConnection conn = request(url, header);
|
||||||
return getString(conn);
|
return getString(conn);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getString(HttpURLConnection conn) {
|
public static String getString(HttpURLConnection conn) {
|
||||||
@ -40,34 +44,29 @@ public class WebService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HttpURLConnection request(String address, Map<String, String> header) {
|
public static HttpURLConnection request(String address, Map<String, String> header) throws IOException {
|
||||||
try {
|
URL url = new URL(address);
|
||||||
URL url = new URL(address);
|
|
||||||
|
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
conn.setReadTimeout(15000);
|
conn.setReadTimeout(15000);
|
||||||
conn.setConnectTimeout(15000);
|
conn.setConnectTimeout(15000);
|
||||||
|
|
||||||
if (header != null) {
|
if (header != null) {
|
||||||
for (Map.Entry<String, String> entry : header.entrySet()) {
|
for (Map.Entry<String, String> entry : header.entrySet()) {
|
||||||
conn.setRequestProperty(entry.getKey(), entry.getValue());
|
conn.setRequestProperty(entry.getKey(), entry.getValue());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.connect();
|
|
||||||
|
|
||||||
if (header != null) {
|
|
||||||
header.clear();
|
|
||||||
for (Map.Entry<String, List<String>> entry : conn.getHeaderFields().entrySet()) {
|
|
||||||
List<String> l = entry.getValue();
|
|
||||||
header.put(entry.getKey(), l.get(l.size() - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return conn;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conn.connect();
|
||||||
|
|
||||||
|
if (header != null) {
|
||||||
|
header.clear();
|
||||||
|
for (Map.Entry<String, List<String>> entry : conn.getHeaderFields().entrySet()) {
|
||||||
|
List<String> l = entry.getValue();
|
||||||
|
header.put(entry.getKey(), l.get(l.size() - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return conn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user