Merge pull request #824 from zelvalea/main

Чрезмерное создание потоков
This commit is contained in:
Vologhat
2022-10-08 14:23:37 +03:00
committed by GitHub
13 changed files with 154 additions and 115 deletions
@@ -339,7 +339,10 @@ public class AdBlockHook {
return true;
}
var whitelist = AndroidUtils.getDefaultPrefs().getStringSet("whitelisted_filters_groups", Collections.synchronizedSet(new LinkedHashSet<>()));
var whitelist = AndroidUtils.getDefaultPrefs().getStringSet(
"whitelisted_filters_groups",
Collections.emptySet()
);
return whitelist.contains(id);
}
@@ -351,7 +354,10 @@ public class AdBlockHook {
id = String.valueOf(list.optInt("source_id"));
}
var whitelist = AndroidUtils.getDefaultPrefs().getStringSet("whitelisted_ad_groups", Collections.synchronizedSet(new LinkedHashSet<>()));
var whitelist = AndroidUtils.getDefaultPrefs().getStringSet(
"whitelisted_ad_groups",
Collections.emptySet()
);
return whitelist.contains(id);
}
@@ -336,36 +336,34 @@ public class JsonInjectors {
public static JSONArray newsfeedlist(JSONArray items) throws JSONException {
var selectedItems = getDefaultPrefs().getString("news_feed_selected_items", "");
var filtersSet = getDefaultPrefs().getStringSet("news_feed_items_set", null);
var mutableFiltersSet = Collections.synchronizedSet(new LinkedHashSet<String>());
var mutableFiltersSet = new LinkedHashSet<String>();
if (filtersSet != null)
mutableFiltersSet.addAll(filtersSet);
synchronized (mutableFiltersSet) {
for (int i = 0; i < items.length(); i++) {
var item = items.optJSONObject(i);
if (item == null) continue;
for (int i = 0; i < items.length(); i++) {
var item = items.optJSONObject(i);
if (item == null) continue;
var id = item.optString("id");
var title = item.optString("title");
var id = item.optString("id");
var title = item.optString("title");
if (TextUtils.isEmpty(id) || TextUtils.isEmpty(title)
// this items not working
|| id.equals("kpop") || id.equals("foryou")
|| id.equals("qazaqstan") || id.equals("podcasts"))
continue;
if (TextUtils.isEmpty(id) || TextUtils.isEmpty(title)
// this items not working
|| id.equals("kpop") || id.equals("foryou")
|| id.equals("qazaqstan") || id.equals("podcasts"))
continue;
mutableFiltersSet.add(id + "|" + title);
mutableFiltersSet.add(id + "|" + title);
var hide = selectedItems.contains(id);
var hide = selectedItems.contains(id);
Log.d("NewsfeedList", "Added list " + id + " to feed");
item.put("is_hidden", hide)
.put("is_unavailable", hide);
if (dev()) Log.d("NewsfeedListInj", "Unlocked " + id + " in newsfeed list");
}
getDefaultPrefs().edit().putStringSet("news_feed_items_set", mutableFiltersSet)
.apply();
Log.d("NewsfeedList", "Added list " + id + " to feed");
item.put("is_hidden", hide)
.put("is_unavailable", hide);
if (dev()) Log.d("NewsfeedListInj", "Unlocked " + id + " in newsfeed list");
}
getDefaultPrefs().edit().putStringSet("news_feed_items_set", mutableFiltersSet)
.apply();
return items;
}
@@ -70,19 +70,25 @@ public class NewsfeedHook {
}
public static boolean isWhitelistedFilter(ExtendedCommunityProfile eup) {
return getDefaultPrefs().getStringSet("whitelisted_filters_groups", Collections.synchronizedSet(new LinkedHashSet<>())).contains(String.valueOf(AccountManagerUtils.getUserID(eup)));
return getDefaultPrefs().getStringSet(
"whitelisted_filters_groups", Collections.emptySet()
).contains(String.valueOf(AccountManagerUtils.getUserID(eup)));
}
public static boolean isWhitelistedAd(ExtendedCommunityProfile eup) {
return getDefaultPrefs().getStringSet("whitelisted_ad_groups", Collections.synchronizedSet(new LinkedHashSet<>())).contains(String.valueOf(AccountManagerUtils.getUserID(eup)));
return getDefaultPrefs().getStringSet(
"whitelisted_ad_groups",
Collections.emptySet()
).contains(String.valueOf(AccountManagerUtils.getUserID(eup)));
}
public static void setWhitelistedFilter(ExtendedCommunityProfile eup, boolean needWhitelist) {
var mutableAdsSet = Collections.synchronizedSet(new LinkedHashSet<String>());
var id = String.valueOf(AccountManagerUtils.getUserID(eup));
mutableAdsSet.addAll(getDefaultPrefs().getStringSet("whitelisted_filters_groups", mutableAdsSet));
var mutableAdsSet = new LinkedHashSet<>(getDefaultPrefs().getStringSet(
"whitelisted_filters_groups",
Collections.emptySet())
);
if (needWhitelist) {
mutableAdsSet.add(id);
} else {
@@ -93,10 +99,11 @@ public class NewsfeedHook {
}
public static void setWhitelistedAd(ExtendedCommunityProfile eup, boolean needWhitelist) {
var mutableAdsSet = Collections.synchronizedSet(new LinkedHashSet<String>());
var id = String.valueOf(AccountManagerUtils.getUserID(eup));
mutableAdsSet.addAll(getDefaultPrefs().getStringSet("whitelisted_ad_groups", mutableAdsSet));
var mutableAdsSet = new LinkedHashSet<>(getDefaultPrefs().getStringSet(
"whitelisted_ad_groups",
Collections.emptySet()));
if (needWhitelist) {
mutableAdsSet.add(id);
@@ -60,7 +60,7 @@ public class M3UDownloader implements ITrackDownloader {
VKM3UParser parser = new VKM3UParser(payload);
List<TransportStream> tses = parser.getTransportStreams();
AtomicInteger progress = new AtomicInteger(0);
List<CompletableFuture<Void>> futures = new ArrayList<>();
List<CompletableFuture<Void>> futures = new ArrayList<>(tses.size());
var tsesDir = new File(outDir, String.valueOf(track.d));
tsesDir.mkdirs();
@@ -15,24 +15,32 @@ import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public final class NetCall {
private final NetRequest req;
private final NetClient cl;
private final Executor executor;
protected NetCall(NetClient cl, NetRequest req) {
protected NetCall(NetClient cl, NetRequest req, Executor executor) {
this.req = req;
this.cl = cl;
this.executor = executor;
}
private static String constructArgs(Map<String, String> args) throws UnsupportedEncodingException {
args = new TreeMap<>(args);
String str = "";
StringBuilder str = new StringBuilder();
for (Map.Entry<String, String> en : args.entrySet()) {
if (!str.isEmpty()) str += "&";
str += URLEncoder.encode(en.getKey(), "UTF-8") + "=" + URLEncoder.encode(en.getValue(), "UTF-8");
if (str.length() > 0)
str.append("&");
str.append(URLEncoder.encode(en.getKey(), "UTF-8"))
.append("=")
.append(URLEncoder.encode(en.getValue(), "UTF-8"));
}
return str;
return str.toString();
}
public NetRequest request() {
@@ -77,22 +85,13 @@ public final class NetCall {
}
public void enqueue(NetCallback cb) {
new Thread() {
@Override
public void run() {
try {
NetResponse resp = execute();
cb.onResponse(NetCall.this, resp);
} catch (IOException e) {
cb.onFailure(NetCall.this, e);
}
try {
interrupt();
join();
} catch (Exception e) {
Log.e("NetCall", "Failed to interrupt and join thread", e);
}
executor.execute(() -> {
try {
NetResponse resp = execute();
cb.onResponse(NetCall.this, resp);
} catch (IOException e) {
cb.onFailure(NetCall.this, e);
}
}.start();
});
}
}
@@ -2,12 +2,16 @@ package ru.vtosters.lite.net;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class NetClient {
private final long timeout;
private final Proxy proxy;
private final PasswordAuthentication authenticator;
private final Executor executor
= Executors.newSingleThreadExecutor();
protected NetClient(Builder b) {
timeout = b.timeout;
@@ -24,7 +28,7 @@ public class NetClient {
}
public NetCall newCall(NetRequest req) {
return new NetCall(this, req);
return new NetCall(this, req, executor);
}
public PasswordAuthentication getAuthenticator() {
@@ -2,75 +2,77 @@ package ru.vtosters.lite.net;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
import android.os.AsyncTask;
import com.vk.core.network.Network;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class Request {
public static void makeRequest(byte[] bArr, RequestCallback RequestCallback) {
new MakeRequestTask(bArr, RequestCallback).execute();
private static final Executor EXECUTOR =
Executors.newSingleThreadExecutor();
public static void makeRequest(byte[] bArr, RequestCallback callback) {
EXECUTOR.execute(new MakeRequestTask(bArr, callback));
}
public static void makeRequest(String str, RequestCallback RequestCallback) {
new MakeRequestTask(str.getBytes(), RequestCallback).execute();
public static void makeRequest(String str, RequestCallback callback) {
makeRequest(str.getBytes(), callback);
}
public interface RequestCallback {
void onResponse(String str);
}
private static class MakeRequestTask extends AsyncTask<Void, Void, String> {
private static class MakeRequestTask implements Runnable {
private final RequestCallback callback;
private final byte[] url;
private final boolean mIsPut;
private final boolean mIsVTostersRequest;
public MakeRequestTask(byte[] bArr, RequestCallback RequestCallback) {
mIsVTostersRequest = false;
mIsPut = false;
callback = RequestCallback;
url = bArr;
public MakeRequestTask(byte[] bArr, RequestCallback callback) {
this.mIsVTostersRequest = false;
this.mIsPut = false;
this.callback = callback;
this.url = bArr;
}
public String doInBackground(Void... voidArr) {
@Override
public void run() {
try {
HttpURLConnection httpURLConnection = (HttpURLConnection) new URL(new String(url)).openConnection();
httpURLConnection.setRequestMethod(mIsPut ? "PUT" : "GET");
if (mIsVTostersRequest) {
httpURLConnection.setRequestProperty("Token", getUserToken());
}
if (!mIsVTostersRequest) {
} else {
httpURLConnection.setRequestProperty("User-Agent", Network.l.c().a());
}
httpURLConnection.setRequestProperty("Content-Type", mIsVTostersRequest ? "Content-Type" : "application/x-www-form-urlencoded");
httpURLConnection.setRequestProperty("Content-Type", mIsVTostersRequest
? "Content-Type"
: "application/x-www-form-urlencoded");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
StringBuffer stringBuffer = new StringBuffer();
StringBuilder builder = new StringBuilder();
while (true) {
String readLine = bufferedReader.readLine();
if (readLine != null) {
stringBuffer.append(readLine);
builder.append(readLine);
} else {
bufferedReader.close();
return stringBuffer.toString();
callback.onResponse(builder.toString());
break;
}
}
} catch (Exception e) {
return e.getLocalizedMessage();
callback.onResponse(e.getLocalizedMessage());
}
}
public void onPostExecute(String str) {
super.onPostExecute(str);
callback.onResponse(str);
}
}
}
@@ -14,7 +14,12 @@ public abstract class BaseTranslator {
private static final int YANDEX = 0;
private static final int GOOGLE = 1;
private static final int DEEPL = 2;
private final LruCache<String, String> cache = new LruCache<>(200);
private final LruCache<String, String> cache = new LruCache<>(200) {
@Override
protected String create(@NonNull String text) {
return translate(text, getToLanguage());
}
};
public static String getToLanguage() {
var lang = preferences.getString("lang_target", "system");
@@ -43,11 +48,8 @@ public abstract class BaseTranslator {
@NonNull
public final String getTranslation(String text) {
var val = cache.get(text);
if (val != null)
return val;
var translation = translate(text, getToLanguage());
cache.put(text, translation);
return translation;
String v = cache.get(text);
assert v != null;
return v;
}
}
@@ -10,7 +10,6 @@ import org.json.JSONObject;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;
import okhttp3.MediaType;
@@ -49,14 +48,17 @@ public class DeepLTranslator extends BaseTranslator {
private static DeepLTranslator instance;
public static DeepLTranslator getInstance() {
if (instance == null)
instance = new DeepLTranslator();
return instance;
// Race safe when the new object does not contain the state of the previous one
DeepLTranslator translator = instance;
if (translator == null) {
return instance = new DeepLTranslator();
}
return translator;
}
private static Long getTimestamp(int iNumber) {
var now = System.currentTimeMillis();
return Long.valueOf((((long) iNumber) + now) - (now % ((long) iNumber)));
return (((long) iNumber) + now) - (now % ((long) iNumber));
}
@NonNull
@@ -73,16 +75,16 @@ public class DeepLTranslator extends BaseTranslator {
i++;
}
var id = new AtomicLong(ThreadLocalRandom.current().nextLong(Long.parseLong("10000000000")));
var id = ThreadLocalRandom.current().nextLong(1, 10000000000L);
var requestBody = String.format(REQUEST_BODY_FORMAT,
id.incrementAndGet(),
id,
text,
tl,
getTimestamp(i)
);
requestBody = (id.get() + 3) % 13 == 0 || (id.get() + 5) % 29 == 0
requestBody = (id + 3) % 13 == 0 || (id + 5) % 29 == 0
? requestBody.replace("hod\":\"", "hod\" : \"")
: requestBody.replace("hod\":\"", "hod\": \"");
@@ -38,9 +38,11 @@ public class GoogleTranslator extends BaseTranslator {
private static GoogleTranslator instance;
public static GoogleTranslator getInstance() {
if (instance == null)
instance = new GoogleTranslator();
return instance;
// Race safe when the new object does not contain the state of the previous one
GoogleTranslator translator = instance;
if (translator == null)
return instance = new GoogleTranslator();
return translator;
}
@NonNull
@@ -22,9 +22,11 @@ public class YandexTranslator extends BaseTranslator {
private static YandexTranslator instance;
public static YandexTranslator getInstance() {
if (instance == null)
instance = new YandexTranslator();
return instance;
// Race safe when the new object does not contain the state of the previous one
YandexTranslator translator = instance;
if (translator == null)
return instance = new YandexTranslator();
return translator;
}
@NonNull
@@ -9,7 +9,6 @@ import android.app.Activity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import ru.vtosters.lite.ui.vkui.VBottomSheetBuilder;
import ru.vtosters.lite.utils.AndroidUtils;
@@ -18,21 +17,19 @@ public class NewsfeedListManager {
public static void callEditorPopup(Activity activity) {
var selectedItems = getDefaultPrefs().getString("news_feed_selected_items", "");
var filtersSet = getDefaultPrefs().getStringSet("news_feed_items_set", Collections.synchronizedSet(new LinkedHashSet<>()));
var list = new ArrayList<VBListItem>();
var filtersSet = getDefaultPrefs().getStringSet("news_feed_items_set", Collections.emptySet());
var list = new ArrayList<VBListItem>(filtersSet.size());
if (filtersSet.size() == 0) {
if (filtersSet.isEmpty()) {
sendToast(AndroidUtils.getString("newsfeed_list_update_feed"));
return;
}
synchronized (filtersSet) {
for (String item : filtersSet) {
var id = item.substring(0, item.indexOf("|"));
var title = item.substring(item.indexOf("|") + 1);
for (String item : filtersSet) {
var id = item.substring(0, item.indexOf("|"));
var title = item.substring(item.indexOf("|") + 1);
list.add(new VBListItem(id, title, selectedItems.contains(id)));
}
list.add(new VBListItem(id, title, selectedItems.contains(id)));
}
VBottomSheetBuilder.show(activity, new VBottomSheetBuilder.VBSContent(
@@ -11,21 +11,30 @@ import android.util.Log;
import com.vk.core.dialogs.alert.VkAlertDialog;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import ru.vtosters.lite.translators.BaseTranslator;
import ru.vtosters.lite.utils.AndroidUtils;
public class Translate {
private static final Executor ASYNC_EXECUTOR
= Executors.newSingleThreadExecutor();
private static final Executor MAIN_EXECUTOR
= new DelegateExecutor();
public static void showTranslatedText(Context context, String text) {
new Thread(() -> {
BaseTranslator translator = BaseTranslator.getInstance();
if (translator == null) return;
ASYNC_EXECUTOR.execute(() -> {
try {
var translation = BaseTranslator.getInstance().getTranslation(text);
new Handler(Looper.getMainLooper()).post(() -> {
showDialog(context, translation);
});
var translation = translator.getTranslation(text);
MAIN_EXECUTOR.execute(() -> showDialog(context, translation));
} catch (Exception e) {
Log.e("Translate", e + "");
}
}).start();
});
}
private static void showDialog(Context context, String text) {
@@ -42,4 +51,13 @@ public class Translate {
})
.show();
}
private static class DelegateExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable command) {
handler.post(command);
}
}
}