Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
681dd177b8 | ||
|
|
4405b04285 | ||
|
|
3c4e981839 | ||
|
|
e318634e56 | ||
|
|
5ea515f6f4 | ||
|
|
22cd1a8e22 | ||
|
|
ba0169cb4c | ||
|
|
5f0458c587 | ||
|
|
7b840a1721 | ||
|
|
78036bb3db | ||
|
|
da52a7557f | ||
|
|
6eae209d04 | ||
|
|
683f0346e2 | ||
|
|
c95b4e7f86 | ||
|
|
64c55d4b01 |
@@ -11,7 +11,6 @@ import com.vk.api.sdk.exceptions.VKApiExecutionException;
|
||||
import com.vk.common.k.PodcastTimeCodeClickListener;
|
||||
import com.vk.common.links.LinkParser;
|
||||
import com.vk.core.util.ContextExtKt;
|
||||
import com.vk.dto.music.Artist;
|
||||
import com.vk.dto.music.MusicTrack;
|
||||
import com.vk.music.artists.chooser.MusicArtistSelector;
|
||||
import com.vk.music.common.MusicPlaybackLaunchContext;
|
||||
@@ -24,6 +23,8 @@ import com.vtosters.lite.R;
|
||||
import com.vtosters.lite.ViewUtils;
|
||||
import com.vtosters.lite.ui.MusicErrorViewHelper;
|
||||
import com.vtosters.lite.ui.holder.RecyclerHolder;
|
||||
import ru.vtosters.lite.music.Genius;
|
||||
import ru.vtosters.lite.utils.Preferences;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -155,6 +156,14 @@ public class LyricsHolder extends RecyclerHolder<PlayerInfo> implements View.OnC
|
||||
|
||||
@Override // com.vk.api.base.ApiCallback
|
||||
public void a(VKApiExecutionException vKApiExecutionException) {
|
||||
if (Preferences.getBoolValue("useGenius", false)) {
|
||||
var text = Genius.getTextMusic(a);
|
||||
var lyrics = new AudioGetLyrics.a();
|
||||
lyrics.a = text;
|
||||
a(lyrics);
|
||||
return;
|
||||
}
|
||||
|
||||
LyricsHolder.this.B.set(false);
|
||||
LyricsHolder.this.f18328f.a(vKApiExecutionException);
|
||||
LyricsHolder.this.f18328f.b(0);
|
||||
|
||||
@@ -6,12 +6,14 @@ import com.vk.dto.music.MusicTrack;
|
||||
import com.vtosters.lite.R;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
|
||||
import ru.vtosters.lite.utils.AndroidUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
public class Genius {
|
||||
private static final String KEY = "Bearer ZTejoT_ojOEasIkT9WrMBhBQOz6eYKK5QULCMECmOhvwqjRZ6WbpamFe3geHnvp3";
|
||||
@@ -38,10 +40,8 @@ public class Genius {
|
||||
return null;
|
||||
}
|
||||
|
||||
Log.d("Genius", "/search/multi?q=" + artist + "%20" + track + "&from_background=0");
|
||||
|
||||
var request = new Request.a()
|
||||
.b(URL + "/search/multi?q=" + artist + "%20" + track + "&from_background=0")
|
||||
Request request = new Request.a()
|
||||
.b(URL + "/search/multi?q=" + URLEncoder.encode(artist + " " + track) + "&from_background=0")
|
||||
.a("User-Agent", "Genius/5.14.0 (Android; Android 13; Google Pixel 4 XL)")
|
||||
.a("Authorization", KEY)
|
||||
.a("x-genius-app-background-request", "0")
|
||||
@@ -51,26 +51,29 @@ public class Genius {
|
||||
.b()
|
||||
.a();
|
||||
try {
|
||||
var payload = client.a(request).execute().a().g();
|
||||
var sections = new JSONObject(payload).getJSONObject("response").getJSONArray("sections");
|
||||
|
||||
Log.d("Genius", payload);
|
||||
String payload = client.a(request).execute().a().g();
|
||||
JSONArray sections = new JSONObject(payload).getJSONObject("response").getJSONArray("sections");
|
||||
|
||||
for (int i = 0; i < sections.length(); i++) {
|
||||
var json = sections.optJSONObject(i);
|
||||
JSONObject json = sections.optJSONObject(i);
|
||||
|
||||
if (json.optString("type").equals("song")) {
|
||||
var path = json.getJSONArray("hits").getJSONObject(0).getJSONObject("result").getString("api_path");
|
||||
JSONArray hits = json.getJSONArray("hits");
|
||||
|
||||
Log.d("Genius", path);
|
||||
for (int j = 0; j < hits.length(); j++) {
|
||||
JSONObject json2 = hits.optJSONObject(j);
|
||||
JSONObject result = json2.getJSONObject("result");
|
||||
|
||||
return getText(path);
|
||||
if (json2.optString("index").equals("song") && result.optString("path").contains("lyrics")) {
|
||||
return getText(result.getString("api_path"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AndroidUtils.getString("error_no_text");
|
||||
} catch (JSONException | IOException e) {
|
||||
return AndroidUtils.getString("error_no_text") + "\n\n" + AndroidUtils.getString(R.string.error) + ": \n" + e.getLocalizedMessage();
|
||||
return AndroidUtils.getString("error_no_text") + "\n\n" + AndroidUtils.getString(R.string.error) + ": \n" + e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +83,7 @@ public class Genius {
|
||||
return null;
|
||||
}
|
||||
|
||||
var request = new Request.a()
|
||||
Request request = new Request.a()
|
||||
.b(URL + track + "?text_format=plain")
|
||||
.a("User-Agent", "Genius/5.14.0 (Android; Android 13; Google Pixel 4 XL)")
|
||||
.a("Authorization", KEY)
|
||||
@@ -91,16 +94,15 @@ public class Genius {
|
||||
.b()
|
||||
.a();
|
||||
try {
|
||||
var payload = new JSONObject(client.a(request).execute().a().g());
|
||||
Log.d("Genius", String.valueOf(payload));
|
||||
JSONObject payload = new JSONObject(client.a(request).execute().a().g());
|
||||
|
||||
if (!payload.has("response")) {
|
||||
return AndroidUtils.getString("error_no_text");
|
||||
}
|
||||
|
||||
return " " + payload.getJSONObject("response").getJSONObject("song").getJSONObject("lyrics").getString("plain");
|
||||
return payload.getJSONObject("response").getJSONObject("song").getJSONObject("lyrics").getString("plain");
|
||||
} catch (JSONException | IOException e) {
|
||||
return AndroidUtils.getString("error_no_text") + "\n\n" + AndroidUtils.getString(R.string.error) + ": \n" + e.getLocalizedMessage();
|
||||
return AndroidUtils.getString("error_no_text") + "\n\n" + AndroidUtils.getString(R.string.error) + ": \n" + e.getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import java8.util.concurrent.CompletableFuture;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
|
||||
import ru.vtosters.lite.music.cache.CacheDatabaseDelegate;
|
||||
import ru.vtosters.lite.music.converter.ts.FFMpeg;
|
||||
import ru.vtosters.lite.music.converter.ts.TSMerger;
|
||||
import ru.vtosters.lite.music.downloader.ThumbnailDownloader;
|
||||
@@ -18,7 +19,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@@ -53,9 +53,9 @@ public class M3UDownloader implements ITrackDownloader {
|
||||
return;
|
||||
}
|
||||
|
||||
var request = new Request.a().b(track.D).a();
|
||||
try {
|
||||
var response = client.a(request).execute().a().g();
|
||||
Request request = new Request.a().b(track.D).a();
|
||||
String response = client.a(request).execute().a().g();
|
||||
parse(response, outDir, callback, track, cache);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@@ -64,61 +64,91 @@ public class M3UDownloader implements ITrackDownloader {
|
||||
}
|
||||
|
||||
private void parse(String payload, File outDir, Callback callback, MusicTrack track, boolean cache) throws UnsupportedEncodingException {
|
||||
if (cache) try {
|
||||
if (cache) downloadThumbnails(track);
|
||||
|
||||
VKM3UParser parser = new VKM3UParser(track.D.substring(0, track.D.lastIndexOf("/") + 1), payload);
|
||||
AtomicInteger progress = new AtomicInteger(0);
|
||||
List<CompletableFuture<Void>> futures = createFutures(parser, progress, callback, track);
|
||||
|
||||
var resultTs = getResultTsFile(track);
|
||||
var resultMp3 = getResultMp3File(outDir, cache, track);
|
||||
|
||||
callback.onProgress(5);
|
||||
var future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
|
||||
future.join();
|
||||
future.exceptionally(throwable -> {
|
||||
callback.onFailure();
|
||||
return null;
|
||||
}).thenApply(v -> TSMerger.merge(getTsesDir(track), resultTs))
|
||||
.thenApply(mergeResult -> mergeResult && FFMpeg.convert(resultTs, resultMp3.getAbsolutePath(), track))
|
||||
.thenApply(convertResult -> {
|
||||
if (convertResult)
|
||||
callback.onProgress(10 + Math.round(80.0f * progress.addAndGet(1) / parser.mTransportStreams.size()));
|
||||
else callback.onFailure();
|
||||
return convertResult;
|
||||
}).thenRun(() -> IOUtils.deleteRecursive(getTsesDir(track))).thenRun(() -> {
|
||||
callback.onSuccess();
|
||||
if (cache) CacheDatabaseDelegate.insertTrack(track);
|
||||
});
|
||||
}
|
||||
|
||||
private void downloadThumbnails(MusicTrack track) {
|
||||
try {
|
||||
ThumbnailDownloader.downloadThumbnails(track);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
VKM3UParser parser = new VKM3UParser(payload);
|
||||
List<TransportStream> tses = parser.getTransportStreams();
|
||||
AtomicInteger progress = new AtomicInteger(0);
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>(tses.size());
|
||||
private List<CompletableFuture<Void>> createFutures(VKM3UParser parser, AtomicInteger progress, Callback callback, MusicTrack track) {
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>(parser.mTransportStreams.size());
|
||||
|
||||
var tses = parser.mTransportStreams;
|
||||
for (var i = 0; i < tses.size(); ++i) {
|
||||
final var ts = tses.get(i);
|
||||
final var filename = i + ".ts";
|
||||
futures.add(CompletableFuture.runAsync(() -> processTransportStream(parser, ts, filename, progress, tses.size(), callback, track)));
|
||||
}
|
||||
return futures;
|
||||
}
|
||||
|
||||
private void processTransportStream(VKM3UParser parser, TransportStream ts, String filename, AtomicInteger progress, int size, Callback callback, MusicTrack track) {
|
||||
try {
|
||||
InputStream mediaIs = IOUtils.openStream(ts.getMediaSegmentUri());
|
||||
byte[] content;
|
||||
if (ts.needDecoding()) {
|
||||
InputStream keyPubIs = IOUtils.openStream(ts.getKeyURL());
|
||||
content = IOUtils.decodeStream(mediaIs, IOUtils.readFully(keyPubIs));
|
||||
keyPubIs.close();
|
||||
} else {
|
||||
content = IOUtils.readFully(mediaIs);
|
||||
}
|
||||
File tsDump = new File(getTsesDir(track), filename);
|
||||
IOUtils.writeToFile(tsDump, content);
|
||||
callback.onProgress(10 + Math.round(80.0f * progress.addAndGet(1) / size));
|
||||
callback.onSizeReceived((long) content.length * size, parser.mHeapSize);
|
||||
mediaIs.close();
|
||||
} catch (IOException | NoSuchPaddingException | NoSuchAlgorithmException |
|
||||
InvalidAlgorithmParameterException | InvalidKeyException e) {
|
||||
callback.onFailure();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private File getTsesDir(MusicTrack track) {
|
||||
var filesDir = AndroidUtils.getGlobalContext().getFilesDir();
|
||||
var tsesDir = new File(filesDir, String.valueOf(track.d));
|
||||
tsesDir.mkdirs();
|
||||
var resultTs = new File(tsesDir, "result.ts");
|
||||
return tsesDir;
|
||||
}
|
||||
|
||||
private File getResultTsFile(MusicTrack track) {
|
||||
return new File(getTsesDir(track), "result.ts");
|
||||
}
|
||||
|
||||
private File getResultMp3File(File outDir, boolean cache, MusicTrack track) {
|
||||
var fileName = IOUtils.getValidFileName((cache ? "track" : track.C + " - " + getTitle(track)) + ".mp3");
|
||||
var resultMp3 = new File(outDir, fileName);
|
||||
|
||||
callback.onProgress(5);
|
||||
for (TransportStream ts : tses) {
|
||||
String tsURL = parser.getBaseUrl() + URLEncoder.encode(ts.getName(), "UTF-8");
|
||||
|
||||
futures.add(CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
InputStream is = IOUtils.openStream(tsURL);
|
||||
byte[] content;
|
||||
if (TransportStream.METHOD_AES128.equals(ts.getMethod())) {
|
||||
String key = IOUtils.readAllLines(IOUtils.openStream(ts.getKeyURL()));
|
||||
content = IOUtils.decodeStream(is, key);
|
||||
} else {
|
||||
content = IOUtils.readFully(is);
|
||||
}
|
||||
File tsDump = new File(tsesDir, ts.getName());
|
||||
IOUtils.writeToFile(tsDump, content);
|
||||
callback.onProgress(10 + Math.round(80.0f * progress.addAndGet(1) / tses.size()));
|
||||
callback.onSizeReceived((long) content.length * tses.size(), parser.getHeapSize());
|
||||
} catch (IOException | NoSuchPaddingException | NoSuchAlgorithmException |
|
||||
InvalidAlgorithmParameterException | InvalidKeyException e) {
|
||||
callback.onFailure();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
var future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
|
||||
future.join();
|
||||
future.exceptionally(throwable -> {
|
||||
callback.onFailure();
|
||||
return null;
|
||||
}).thenApply(v -> TSMerger.merge(tsesDir, resultTs)).thenApply(mergeResult -> mergeResult && FFMpeg.convert(resultTs, resultMp3.getAbsolutePath(), track)).thenApply(convertResult -> {
|
||||
if (convertResult)
|
||||
callback.onProgress(10 + Math.round(80.0f * progress.addAndGet(1) / tses.size()));
|
||||
else callback.onFailure();
|
||||
return convertResult;
|
||||
}).thenRun(() -> IOUtils.deleteRecursive(tsesDir)).thenRun(callback::onSuccess);
|
||||
return new File(outDir, fileName);
|
||||
}
|
||||
|
||||
// Initialization-on-demand
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
package ru.vtosters.lite.music;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
public class TransportStream {
|
||||
|
||||
public static final String METHOD_NONE = "NONE";
|
||||
public static final String METHOD_AES128 = "AES-128";
|
||||
private String mKeyUri;
|
||||
private final String mMediaSegmentUri;
|
||||
private String mMediaSegmentName;
|
||||
|
||||
private final String mMethod;
|
||||
private String mName;
|
||||
private String mKeyURL;
|
||||
|
||||
public TransportStream() {
|
||||
this.mMethod = METHOD_NONE;
|
||||
public TransportStream(String baseURI, String mediaSegmentName) {
|
||||
this.mMediaSegmentUri = baseURI + mediaSegmentName;
|
||||
}
|
||||
|
||||
public TransportStream(String method, String keyURL) {
|
||||
this.mMethod = method;
|
||||
this.mKeyURL = keyURL;
|
||||
public TransportStream(String keyURI, String baseURI, String mediaSegmentName) {
|
||||
this.mKeyUri = keyURI;
|
||||
this.mMediaSegmentUri = baseURI + mediaSegmentName;
|
||||
this.mMediaSegmentName = mediaSegmentName;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return mMethod;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
mName = name;
|
||||
public boolean needDecoding() {
|
||||
return !TextUtils.isEmpty(mKeyUri);
|
||||
}
|
||||
|
||||
public String getKeyURL() {
|
||||
return mKeyURL;
|
||||
return mKeyUri;
|
||||
}
|
||||
|
||||
public String getMediaSegmentUri() {
|
||||
return this.mMediaSegmentUri;
|
||||
}
|
||||
|
||||
public String getMediaSegmentName() {
|
||||
return this.mMediaSegmentName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +1,127 @@
|
||||
package ru.vtosters.lite.music;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* The parser for extended M3U playlist format used by VK.
|
||||
*
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc8216#ref-M3U">M3U</a>
|
||||
**/
|
||||
public class VKM3UParser {
|
||||
//Playlist types
|
||||
static public int PLAYLIST_TYPE_VOD = 0;
|
||||
static public int PLAYLIST_TYPE_EVENT = 1;
|
||||
|
||||
//region Extended M3U global extensions
|
||||
public List<TransportStream> mTransportStreams = new ArrayList<>();
|
||||
private final String mData;
|
||||
private final List<TransportStream> mTransportStreams = new ArrayList<>();
|
||||
/**
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc8216#section-4.3.1.2">EXT-X-VERSION</a>
|
||||
**/
|
||||
public int mVersion = -1;
|
||||
/**
|
||||
* The EXT-X-ALLOW-CACHE tag is used in protocol version 6 or lower.
|
||||
* If the protocol version is upgraded by VK, we will not support that.
|
||||
**/
|
||||
public boolean mAllowCache = false;
|
||||
/**
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc8216#section-4.3.3.1">EXT-X-TARGETDURATION</a>
|
||||
**/
|
||||
public int mTargetDuration = -1;
|
||||
/**
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc8216#section-4.3.3.2">EXT-X-MEDIA-SEQUENCE</a>
|
||||
**/
|
||||
public int mMediaSequence = -1;
|
||||
/**
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc8216#section-4.3.3.3">EXT-X-DISCONTINUITY-SEQUENCE</a>
|
||||
**/
|
||||
public int mDiscontinuitySequence = -1;
|
||||
//endregion
|
||||
/**
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc8216#section-4.3.3.5">EXT-X-PLAYLIST-TYPE</a>
|
||||
**/
|
||||
public int mPlaylistType = -1;
|
||||
/**
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc8216#section-4.3.3.6">EXT-X-I-FRAMES-ONLY</a>
|
||||
**/
|
||||
public boolean mIFramesOnly = false;
|
||||
public long mHeapSize = 0;
|
||||
|
||||
// maybe will be used
|
||||
private int mDuration;
|
||||
private int mHeapSize = 0;
|
||||
private String mBaseURL;
|
||||
|
||||
public VKM3UParser(String data) {
|
||||
public VKM3UParser(String baseUri, String data) {
|
||||
mData = data;
|
||||
init();
|
||||
init(baseUri);
|
||||
}
|
||||
|
||||
public static boolean isM3U8(String str) {
|
||||
return str.endsWith(".ts") || str.endsWith(".tp") || str.endsWith(".mpeg-ts") || str.endsWith(".m2ts");
|
||||
public static boolean isTS(String str) {
|
||||
return str.matches(".+\\.ts.*");
|
||||
}
|
||||
|
||||
private void init() {
|
||||
int i = 0;
|
||||
private void init(String baseUri) {
|
||||
if (TextUtils.isEmpty(mData)) throw new NullPointerException("mData==null");
|
||||
Scanner scanner = new Scanner(mData);
|
||||
while (scanner.hasNext()) {
|
||||
String line = scanner.nextLine();
|
||||
mHeapSize += line.getBytes().length;
|
||||
if (line.startsWith("#EXT-X-TARGETDURATION")) {
|
||||
mDuration = Integer.parseInt(getDirectiveValue(line));
|
||||
} else if (line.startsWith("#EXT-X-KEY")) {
|
||||
String base = getDirectiveValue(line);
|
||||
final TransportStream ts;
|
||||
if (!base.startsWith("METHOD=NONE")) {
|
||||
String keyURL = base.substring(base.indexOf("\"") + 1, base.lastIndexOf("\""));
|
||||
mBaseURL = keyURL.substring(0, keyURL.lastIndexOf("/") + 1);
|
||||
ts = new TransportStream(TransportStream.METHOD_AES128, keyURL);
|
||||
} else {
|
||||
ts = new TransportStream();
|
||||
String line = scanner.nextLine();
|
||||
if (!"#EXTM3U".equals(line)) throw new IllegalStateException(String.format("Unknown initial M3U tag: %s", line));
|
||||
boolean aes128 = false;
|
||||
String keyUri = "";
|
||||
while (scanner.hasNextLine()) {
|
||||
line = scanner.nextLine();
|
||||
if ('#' == line.charAt(0)) {
|
||||
parseTag(line);
|
||||
if (line.startsWith("#EXT-X-KEY:") && line.contains("METHOD=AES-128")) {
|
||||
aes128 = true;
|
||||
keyUri = getKeyUri(line, baseUri);
|
||||
}
|
||||
mTransportStreams.add(ts);
|
||||
} else if (line.startsWith("#EXTINF")) {
|
||||
if (mTransportStreams.size() == i)
|
||||
mTransportStreams.add(new TransportStream());
|
||||
} else if (isM3U8(line)) {
|
||||
mTransportStreams.get(i).setName(line.substring(line.lastIndexOf("/") + 1));
|
||||
++i;
|
||||
} else if (isTS(line)) {
|
||||
addTransportStream(aes128, keyUri, baseUri, line);
|
||||
aes128 = false;
|
||||
} else {
|
||||
throw new RuntimeException(String.format("Failed to parse: %s", line));
|
||||
}
|
||||
mHeapSize += line.getBytes().length;;
|
||||
}
|
||||
}
|
||||
|
||||
private String getDirectiveValue(String directive) {
|
||||
return directive.substring(directive.indexOf(":") + 1);
|
||||
private void parseTag(String line) {
|
||||
if (line.startsWith("#EXT-X-VERSION:"))
|
||||
mVersion = Integer.parseInt(line.substring(15));
|
||||
else if (line.startsWith("#EXT-X-ALLOW-CACHE:"))
|
||||
mAllowCache = "YES".equalsIgnoreCase(line.substring(19));
|
||||
else if (line.startsWith("#EXT-X-TARGETDURATION:"))
|
||||
mTargetDuration = Integer.parseInt(line.substring(22));
|
||||
else if (line.startsWith("#EXT-X-MEDIA-SEQUENCE:"))
|
||||
mMediaSequence = Integer.parseInt(line.substring(22));
|
||||
else if (line.startsWith("#EXT-X-DISCONTINUITY-SEQUENCE:"))
|
||||
mDiscontinuitySequence = Integer.parseInt(line.substring(30));
|
||||
else if (line.startsWith("#EXT-X-PLAYLIST-TYPE:"))
|
||||
parsePlaylistType(line.substring(21));
|
||||
else if (line.startsWith("#EXT-X-I-FRAMES-ONLY"))
|
||||
mIFramesOnly = true;
|
||||
}
|
||||
|
||||
public int getHeapSize() {
|
||||
return mHeapSize;
|
||||
private void parsePlaylistType(String type) {
|
||||
switch (type) {
|
||||
case "VOD" -> mPlaylistType = PLAYLIST_TYPE_VOD;
|
||||
case "EVENT" -> mPlaylistType = PLAYLIST_TYPE_EVENT;
|
||||
default -> throw new IllegalStateException(String.format("Unknown playlist type: %s", type));
|
||||
}
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return mBaseURL;
|
||||
private String getKeyUri(String line, String baseUri) {
|
||||
String substr = line.substring(11);
|
||||
substr = substr.substring(substr.indexOf('"') + 1, substr.lastIndexOf('"'));
|
||||
//TODO: supposed endpoint
|
||||
return substr.startsWith("http") ? substr : baseUri + substr;
|
||||
}
|
||||
|
||||
public List<TransportStream> getTransportStreams() {
|
||||
return mTransportStreams;
|
||||
private void addTransportStream(boolean aes128, String keyUri, String baseUri, String line) {
|
||||
TransportStream ts = aes128
|
||||
? new TransportStream(keyUri, baseUri, line)
|
||||
: new TransportStream(baseUri, line);
|
||||
mTransportStreams.add(ts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,6 @@ public class PlaylistHelper {
|
||||
}
|
||||
|
||||
public static JSONObject getPlaylist() throws JSONException {
|
||||
|
||||
return new JSONObject()
|
||||
.put("id", -1)
|
||||
.put("owner_id", getUserId())
|
||||
|
||||
@@ -11,9 +11,13 @@ import ru.vtosters.lite.music.cache.FileCacheImplementation;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TracklistHelper {
|
||||
public static List<MusicTrack> getMyCachedMusicTracks() {
|
||||
return getTracksWithThumbnails(TracklistHelper.getTracks());
|
||||
}
|
||||
|
||||
public static List<MusicTrack> getTracks() {
|
||||
return CacheDatabaseDelegate.getTracks();
|
||||
@@ -50,6 +54,21 @@ public class TracklistHelper {
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static List<MusicTrack> getTracksWithThumbnails(List<MusicTrack> list) {
|
||||
List<MusicTrack> tracks = new ArrayList<>();
|
||||
for (MusicTrack track : list) {
|
||||
var json = track.J();
|
||||
var folder = FileCacheImplementation.getThumbnailsFolder(LibVKXClient.asId(track));
|
||||
try {
|
||||
addCachedThumbnails(json, folder);
|
||||
} catch (JSONException | MalformedURLException e) {
|
||||
Log.d("TracklistHelper", e.getMessage());
|
||||
}
|
||||
tracks.add(new MusicTrack(json));
|
||||
}
|
||||
return tracks;
|
||||
}
|
||||
|
||||
private static void addCachedThumbnails(JSONObject target, File thumbnailsDir)
|
||||
throws JSONException, MalformedURLException {
|
||||
var sizes = new JSONArray();
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ public class PlaylistInjector {
|
||||
}
|
||||
|
||||
if (isVirtualPlaylist) {
|
||||
response.c = (ArrayList<MusicTrack>) TracklistHelper.getTracks();
|
||||
response.c = (ArrayList<MusicTrack>) TracklistHelper.getMyCachedMusicTracks();
|
||||
response.b = PlaylistHelper.createCachedPlaylistMetadata();
|
||||
} else {
|
||||
response.c = (ArrayList<MusicTrack>) TracklistHelper.getTracks(requestArgs.get("owner_id"));
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package ru.vtosters.lite.music.cache.injectors;
|
||||
|
||||
import com.vk.dto.music.MusicTrack;
|
||||
import com.vk.music.model.IpcPlayerModelImpl;
|
||||
import com.vk.music.model.PlayerModelImpl;
|
||||
import ru.vtosters.lite.music.cache.helpers.TracklistHelper;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ShuffleInjector {
|
||||
public static void shuffleTracks(IpcPlayerModelImpl ipcPlayerModel) {
|
||||
ipcPlayerModel.a(getShuffledList());
|
||||
}
|
||||
|
||||
public static void shuffleTracks(PlayerModelImpl playerModelImpl) {
|
||||
playerModelImpl.a(getShuffledList());
|
||||
}
|
||||
|
||||
private static List<MusicTrack> getShuffledList() {
|
||||
List<MusicTrack> shuffled = TracklistHelper.getMyCachedMusicTracks();
|
||||
Collections.shuffle(shuffled);
|
||||
return shuffled;
|
||||
}
|
||||
}
|
||||
+136
-84
@@ -12,17 +12,13 @@ import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import ru.vtosters.lite.music.cache.CacheDatabaseDelegate;
|
||||
import ru.vtosters.lite.music.cache.helpers.PlaylistHelper;
|
||||
import ru.vtosters.lite.music.cache.helpers.TracklistHelper;
|
||||
import ru.vtosters.lite.utils.AccountManagerUtils;
|
||||
import ru.vtosters.lite.utils.AndroidUtils;
|
||||
import ru.vtosters.lite.utils.NetworkUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static ru.vtosters.lite.music.cache.CacheDatabaseDelegate.hasTracks;
|
||||
import static ru.vtosters.lite.music.cache.helpers.PlaylistHelper.*;
|
||||
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserId;
|
||||
import java.util.*;
|
||||
|
||||
public class TracklistInjector {
|
||||
|
||||
@@ -58,7 +54,7 @@ public class TracklistInjector {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (!hasTracks()) {
|
||||
if (!CacheDatabaseDelegate.hasTracks()) {
|
||||
observableEmitter.b(parser.c(getEmptyCatalog()));
|
||||
} else {
|
||||
observableEmitter.b(parser.c(createVirtualCatalog(TracklistHelper.getTracks())));
|
||||
@@ -68,66 +64,114 @@ public class TracklistInjector {
|
||||
}
|
||||
|
||||
private static JSONObject getEmptyCatalog() throws JSONException {
|
||||
return new JSONObject("{\"catalog\":{\"default_section\":\"cache\",\"sections\":[{\"id\":\"cache\",\"title\":\"" + AndroidUtils.getString(R.string.cached_content_title) + "\",\"blocks\":[{\"data_type\":\"placeholder\",\"id\":\"0\",\"layout\":{\"name\":\"placeholder_big\"},\"placeholder_ids\":[\"_synth_trackEmpty\"]}]}]},\"audios\":[],\"playlists\":[],\"placeholders\":[{\"id\":\"_synth_trackEmpty\",\"title\":\"" + AndroidUtils.getString(R.string.cached_content_empty) + "\",\"text\":\"" + AndroidUtils.getString(R.string.cached_content_empty_desc) + "\",\"buttons\":[]}]}");
|
||||
JSONObject emptyCatalog = new JSONObject();
|
||||
|
||||
JSONObject catalog = new JSONObject();
|
||||
catalog.put("default_section", "cache");
|
||||
|
||||
JSONArray sections = new JSONArray();
|
||||
JSONObject section = new JSONObject();
|
||||
section.put("id", "cache");
|
||||
section.put("title", AndroidUtils.getString(R.string.cached_content_title));
|
||||
|
||||
JSONArray blocks = new JSONArray();
|
||||
JSONObject block = new JSONObject();
|
||||
block.put("data_type", "placeholder");
|
||||
block.put("id", "0");
|
||||
|
||||
JSONObject layout = new JSONObject();
|
||||
layout.put("name", "placeholder_big");
|
||||
block.put("layout", layout);
|
||||
|
||||
JSONArray placeholderIds = new JSONArray();
|
||||
placeholderIds.put("_synth_trackEmpty");
|
||||
block.put("placeholder_ids", placeholderIds);
|
||||
blocks.put(block);
|
||||
section.put("blocks", blocks);
|
||||
sections.put(section);
|
||||
catalog.put("sections", sections);
|
||||
|
||||
emptyCatalog.put("catalog", catalog);
|
||||
emptyCatalog.put("audios", new JSONArray());
|
||||
emptyCatalog.put("playlists", new JSONArray());
|
||||
|
||||
JSONArray placeholders = new JSONArray();
|
||||
JSONObject placeholder = new JSONObject();
|
||||
placeholder.put("id", "_synth_trackEmpty");
|
||||
placeholder.put("title", AndroidUtils.getString(R.string.cached_content_empty));
|
||||
placeholder.put("text", AndroidUtils.getString(R.string.cached_content_empty_desc));
|
||||
placeholder.put("buttons", new JSONArray());
|
||||
placeholders.put(placeholder);
|
||||
|
||||
emptyCatalog.put("placeholders", placeholders);
|
||||
|
||||
return emptyCatalog;
|
||||
}
|
||||
|
||||
private static JSONObject getShuffleButton() throws JSONException {
|
||||
JSONObject shuffleButton = new JSONObject();
|
||||
shuffleButton.put("id", getRandomId());
|
||||
shuffleButton.put("data_type", "action");
|
||||
|
||||
JSONObject layout = new JSONObject();
|
||||
layout.put("name", "horizontal_buttons");
|
||||
layout.put("owner_id", AccountManagerUtils.getUserId());
|
||||
|
||||
shuffleButton.put("layout", layout);
|
||||
|
||||
JSONArray listenEvents = new JSONArray();
|
||||
listenEvents.put("music_audios_remove");
|
||||
listenEvents.put("music_audios_add");
|
||||
|
||||
shuffleButton.put("listen_events", listenEvents);
|
||||
|
||||
JSONArray buttons = new JSONArray();
|
||||
JSONObject button = new JSONObject();
|
||||
|
||||
JSONObject action = new JSONObject();
|
||||
action.put("type", "play_shuffled_audios_from_block");
|
||||
|
||||
button.put("action", action);
|
||||
button.put("block_id", "shuffle");
|
||||
button.put("ref_items_count", CacheDatabaseDelegate.getTrackCount());
|
||||
button.put("ref_layout_name", "list");
|
||||
button.put("ref_data_type", "music_audios");
|
||||
|
||||
buttons.put(button);
|
||||
|
||||
shuffleButton.put("buttons", buttons);
|
||||
|
||||
return shuffleButton;
|
||||
}
|
||||
|
||||
public static void injectIntoExistingCatalog(JSONObject catalogNode) {
|
||||
Log.d("TracklistInjector", "injectIntoExistingCatalog");
|
||||
|
||||
try {
|
||||
var catalog = catalogNode.getJSONObject("catalog");
|
||||
var sectionsNode = catalog.getJSONArray("sections");
|
||||
var firstSection = sectionsNode.getJSONObject(0);
|
||||
JSONObject catalog = catalogNode.getJSONObject("catalog");
|
||||
JSONArray sectionsNode = catalog.getJSONArray("sections");
|
||||
JSONObject firstSection = sectionsNode.getJSONObject(0);
|
||||
|
||||
if (!firstSection.getString("url").equals("https://vk.com/audios" + getUserId() + "?section=all"))
|
||||
if (!isFirstSectionUrlValid(firstSection)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var blocks = firstSection.getJSONArray("blocks");
|
||||
JSONArray blocks = firstSection.getJSONArray("blocks");
|
||||
|
||||
if (CacheDatabaseDelegate.hasTracks() && !LibVKXClient.isIntegrationEnabled()) { // inj in playlist list
|
||||
var noPlaylists = blocks.optJSONObject(0).optJSONArray("buttons").optJSONObject(0).optJSONObject("action").optString("type").equals("create_playlist");
|
||||
boolean noPlaylists = hasNoPlaylists(blocks);
|
||||
|
||||
if (noPlaylists) {
|
||||
catalogNode.put("playlists", new JSONArray().put(getPlaylist()));
|
||||
Log.d("catalogInjector", "added new pl");
|
||||
catalogNode.put("playlists", new JSONArray().put(PlaylistHelper.getPlaylist()));
|
||||
|
||||
var newBlocks = new JSONArray();
|
||||
|
||||
newBlocks
|
||||
.put(getCatalogHeader())
|
||||
.put(getCatalogPlaylist())
|
||||
.put(getCatalogSeparator());
|
||||
JSONArray newBlocks = createNewBlocks(blocks);
|
||||
|
||||
Log.d("catalogInjector", "added cache catalog playlist");
|
||||
|
||||
for (int i = 0; i < blocks.length(); i++) {
|
||||
newBlocks.put(blocks.optJSONObject(i));
|
||||
}
|
||||
|
||||
firstSection.put("blocks", newBlocks);
|
||||
} else {
|
||||
try {
|
||||
catalogNode.optJSONArray("playlists").put(getPlaylist());
|
||||
Log.d("catalogInjector", "added to exist pl");
|
||||
catalogNode.optJSONArray("playlists").put(PlaylistHelper.getPlaylist());
|
||||
|
||||
for (int i = 0; i < blocks.length(); i++) {
|
||||
var j = blocks.optJSONObject(i);
|
||||
var type = j.optString("data_type");
|
||||
|
||||
if (type.equals("music_playlists") && j.has("playlists_ids")) {
|
||||
var newarr = new JSONArray();
|
||||
var playlists_ids = j.optJSONArray("playlists_ids");
|
||||
|
||||
newarr.put(getUserId() + "_-1");
|
||||
|
||||
for (int n = 0; n < playlists_ids.length(); n++) {
|
||||
newarr.put(playlists_ids.optString(n));
|
||||
}
|
||||
|
||||
j.put("playlists_ids", newarr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
updatePlaylistsIds(blocks);
|
||||
} catch (Exception e) {
|
||||
Log.d("catalogInjector", e.toString());
|
||||
}
|
||||
@@ -138,24 +182,49 @@ public class TracklistInjector {
|
||||
}
|
||||
}
|
||||
|
||||
public static JSONObject createVirtualCatalog(List<MusicTrack> tracks)
|
||||
throws JSONException {
|
||||
Log.d("TracklistInjector", "createVirtualCatalog");
|
||||
private static boolean isFirstSectionUrlValid(JSONObject firstSection) throws JSONException {
|
||||
return firstSection.getString("url").equals("https://vk.com/audios" + AccountManagerUtils.getUserId() + "?section=all");
|
||||
}
|
||||
|
||||
var clickAction = new JSONObject()
|
||||
.put("type", "open_url")
|
||||
.put("target", "internal")
|
||||
.put("url", "https://vkx.app/index.html?app=vt_ctg");
|
||||
private static boolean hasNoPlaylists(JSONArray blocks) throws JSONException {
|
||||
return blocks.optJSONObject(0).optJSONArray("buttons").optJSONObject(0).optJSONObject("action").optString("type").equals("create_playlist");
|
||||
}
|
||||
|
||||
var catalogBanner = new JSONObject()
|
||||
.put("id", 1234)
|
||||
.put("image_mode", "cover")
|
||||
.put("title", AndroidUtils.getString(R.string.vkx_integration_title))
|
||||
.put("text", AndroidUtils.getString(R.string.vkx_integration_desc))
|
||||
.put("click_action", new JSONObject().put("action", clickAction));
|
||||
var catalogBanners = new JSONArray()
|
||||
.put(catalogBanner);
|
||||
private static JSONArray createNewBlocks(JSONArray blocks) throws JSONException {
|
||||
JSONArray newBlocks = new JSONArray();
|
||||
|
||||
newBlocks
|
||||
.put(PlaylistHelper.getCatalogHeader())
|
||||
.put(PlaylistHelper.getCatalogPlaylist())
|
||||
.put(PlaylistHelper.getCatalogSeparator());
|
||||
|
||||
for (int i = 0; i < blocks.length(); i++) {
|
||||
newBlocks.put(blocks.optJSONObject(i));
|
||||
}
|
||||
return newBlocks;
|
||||
}
|
||||
|
||||
private static void updatePlaylistsIds(JSONArray blocks) throws JSONException {
|
||||
for (int i = 0; i < blocks.length(); i++) {
|
||||
JSONObject j = blocks.optJSONObject(i);
|
||||
String type = j.optString("data_type");
|
||||
|
||||
if (type.equals("music_playlists") && j.has("playlists_ids")) {
|
||||
JSONArray newarr = new JSONArray();
|
||||
JSONArray playlists_ids = j.optJSONArray("playlists_ids");
|
||||
|
||||
newarr.put(AccountManagerUtils.getUserId() + "_-1");
|
||||
|
||||
for (int n = 0; n < playlists_ids.length(); n++) {
|
||||
newarr.put(playlists_ids.optString(n));
|
||||
}
|
||||
|
||||
j.put("playlists_ids", newarr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static JSONObject createVirtualCatalog(List<MusicTrack> tracks) throws JSONException {
|
||||
var audiosBlock = new JSONObject()
|
||||
.put("id", getRandomId())
|
||||
.put("data_type", "music_audios")
|
||||
@@ -164,28 +233,12 @@ public class TracklistInjector {
|
||||
|
||||
var layout = new JSONObject()
|
||||
.put("name", "list")
|
||||
.put("owner_id", getUserId());
|
||||
.put("owner_id", AccountManagerUtils.getUserId());
|
||||
|
||||
audiosBlock.put("layout", layout);
|
||||
|
||||
var blocks = new JSONArray()
|
||||
.put(audiosBlock);
|
||||
var blocks = new JSONArray().put(getShuffleButton()).put(audiosBlock);
|
||||
|
||||
// var vkxPostirony = new JSONObject()
|
||||
// .put("id", getRandomId())
|
||||
// .put("data_type", "catalog_banners")
|
||||
// .put("url", "synth:cache:vkx")
|
||||
// .put("catalog_banner_ids", new JSONArray().put(1234));
|
||||
//
|
||||
// var vkxlayout = new JSONObject()
|
||||
// .put("name", "large_list")
|
||||
// .put("owner_id", Globals.getUserId())
|
||||
// .put("infinite_repeat", true);
|
||||
//
|
||||
// vkxPostirony.put("layout", vkxlayout);
|
||||
//
|
||||
// if (eligibleForVkxAd())
|
||||
// blocks.put(vkxPostirony);
|
||||
var randomId = getRandomId();
|
||||
|
||||
var section = new JSONObject()
|
||||
@@ -203,8 +256,7 @@ public class TracklistInjector {
|
||||
|
||||
return new JSONObject()
|
||||
.put("catalog", catalog)
|
||||
.put("audios", TracklistHelper.tracksToJsons(tracks))
|
||||
.put("catalog_banners", catalogBanners);
|
||||
.put("audios", TracklistHelper.tracksToJsons(tracks));
|
||||
}
|
||||
|
||||
private static String getRandomId() {
|
||||
|
||||
@@ -26,11 +26,7 @@ public class TSMerger {
|
||||
|
||||
var mergedByteArrayStream = new ByteArrayOutputStream();
|
||||
|
||||
Arrays.sort(tsesList, (o1, o2) -> {
|
||||
var index1 = Integer.parseInt(o1.getName().split("-")[1]);
|
||||
var index2 = Integer.parseInt(o2.getName().split("-")[1]);
|
||||
return index1 - index2;
|
||||
});
|
||||
sortTsesList(tsesList);
|
||||
|
||||
for (var file : tsesList) {
|
||||
if (file.getName().endsWith(".ts")) {
|
||||
@@ -43,6 +39,20 @@ public class TSMerger {
|
||||
}
|
||||
}
|
||||
|
||||
return writeOutputFile(out, mergedByteArrayStream);
|
||||
}
|
||||
|
||||
private static void sortTsesList(File[] tsesList) {
|
||||
Arrays.sort(tsesList, (ts1, ts2) -> {
|
||||
String ts1Name = ts1.getName();
|
||||
String ts2Name = ts2.getName();
|
||||
int i1 = Integer.parseInt(ts1Name.substring(0, ts1Name.indexOf('.', 1)));
|
||||
int i2 = Integer.parseInt(ts2Name.substring(0, ts2Name.indexOf('.', 1)));
|
||||
return Integer.compare(i1, i2);
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean writeOutputFile(File out, ByteArrayOutputStream mergedByteArrayStream) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
try {
|
||||
Files.write(out.toPath(), mergedByteArrayStream.toByteArray());
|
||||
|
||||
@@ -35,7 +35,6 @@ public class TrackDownloader {
|
||||
|
||||
var path = FileCacheImplementation.getTrackFolder(LibVKXClient.asId(track)).getAbsolutePath();
|
||||
download(track, path, callback, M3UDownloader.getInstance(), true);
|
||||
CacheDatabaseDelegate.insertTrack(track);
|
||||
}
|
||||
|
||||
private static void download(MusicTrack track, String path, Callback callback, ITrackDownloader downloader, boolean cache) {
|
||||
|
||||
@@ -19,11 +19,12 @@ public class ImBanner {
|
||||
var user_id = orig.getJSONObject("peer").getInt("id");
|
||||
|
||||
if (!UsersList.hasBanner(user_id) || user_id == 0) {
|
||||
if (getBoolValue("convBarRecomm", false)) {
|
||||
return null;
|
||||
} else {
|
||||
return orig.optJSONObject("conversation_bar");
|
||||
}
|
||||
// if (getBoolValue("convBarRecomm", false)) {
|
||||
// return null;
|
||||
// } else {
|
||||
// return orig.optJSONObject("conversation_bar");
|
||||
// }
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -18,17 +18,16 @@ import java.util.Arrays;
|
||||
public class IOUtils {
|
||||
public static final int BUFFER_SIZE = 8192;
|
||||
|
||||
public static byte[] decodeStream(InputStream encIs, String keyURL)
|
||||
public static byte[] decodeStream(InputStream encIs,byte[] aesKey)
|
||||
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IOException {
|
||||
CipherInputStream cip = new CipherInputStream(encIs, getCipher(keyURL));
|
||||
CipherInputStream cip = new CipherInputStream(encIs, getCipher(aesKey));
|
||||
return readFully(cip);
|
||||
}
|
||||
|
||||
public static Cipher getCipher(String key)
|
||||
public static Cipher getCipher(byte[] aesKey)
|
||||
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException {
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
Key keySpec = new SecretKeySpec(key.getBytes(), "AES");
|
||||
// bypassing ecb
|
||||
Key keySpec = new SecretKeySpec(aesKey, "AES");
|
||||
byte[] iv = new byte[16];
|
||||
Arrays.fill(iv, (byte) 0x0);
|
||||
IvParameterSpec ivps = new IvParameterSpec(iv);
|
||||
|
||||
@@ -155,6 +155,7 @@
|
||||
android:resizeableActivity="true"
|
||||
android:roundIcon="@mipmap/vt_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:appCategory="social"
|
||||
android:theme="@style/VkLightStyle">
|
||||
<meta-data
|
||||
android:name="com.google.android.geo.API_KEY"
|
||||
@@ -165,9 +166,6 @@
|
||||
<meta-data
|
||||
android:name="com.google.android.geo.API_SECRET"
|
||||
android:value="yu6ZAA0OWO3kmr4es7fGtSmiyfk=" />
|
||||
<meta-data
|
||||
android:name="com.vk.safetynet.API_SECRET"
|
||||
android:value="AIzaSyBf_eM-cgRbg1gOkyEc2Il5gHqgsnFyVug" />
|
||||
<meta-data
|
||||
android:name="com.facebook.sdk.ApplicationId"
|
||||
android:value="@string/fb_app_id" />
|
||||
|
||||
@@ -17,11 +17,6 @@
|
||||
android:entryValues="@array/animations_values"
|
||||
android:key="anim_rtrn_type"
|
||||
android:title="@string/franimation"/>
|
||||
<com.vtosters.lite.ui.MaterialSwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="useGenius"
|
||||
android:summary="@string/useGenius_summ"
|
||||
android:title="@string/useGenius_title"/>
|
||||
<com.vtosters.lite.ui.MaterialSwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="useNewSettings"
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
android:key="autocache"
|
||||
android:summary="@string/autocache_summ"
|
||||
android:title="@string/autocache_title"/>
|
||||
<com.vtosters.lite.ui.MaterialSwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="useGenius"
|
||||
android:summary="@string/useGenius_summ"
|
||||
android:title="@string/useGenius_title"/>
|
||||
<com.vtosters.lite.ui.MaterialSwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="useOldAppVer"
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
android:key="voice"
|
||||
android:summary="@string/vtlvoicesummary"
|
||||
android:title="@string/vtlvoice"/>
|
||||
<com.vtosters.lite.ui.MaterialSwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="convBarRecomm"
|
||||
android:summary="@string/convBarRecomm_summ"
|
||||
android:title="@string/convBarRecomm_title"/>
|
||||
<!-- <com.vtosters.lite.ui.MaterialSwitchPreference-->
|
||||
<!-- android:defaultValue="false"-->
|
||||
<!-- android:key="convBarRecomm"-->
|
||||
<!-- android:summary="@string/convBarRecomm_summ"-->
|
||||
<!-- android:title="@string/convBarRecomm_title"/>-->
|
||||
<com.vtosters.lite.ui.MaterialSwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="wbios"
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
.class final Lcom/vk/common/VKSafetyNet$a;
|
||||
.super Ljava/lang/Object;
|
||||
.source "VKSafetyNet.kt"
|
||||
|
||||
# interfaces
|
||||
.implements Lcom/google/android/gms/tasks/e;
|
||||
|
||||
|
||||
# annotations
|
||||
.annotation system Ldalvik/annotation/EnclosingMethod;
|
||||
value = Lcom/vk/common/VKSafetyNet;->a()Lkotlin/Triple;
|
||||
.end annotation
|
||||
|
||||
.annotation system Ldalvik/annotation/InnerClass;
|
||||
accessFlags = 0x18
|
||||
name = null
|
||||
.end annotation
|
||||
|
||||
.annotation system Ldalvik/annotation/Signature;
|
||||
value = {
|
||||
"<TResult:",
|
||||
"Ljava/lang/Object;",
|
||||
">",
|
||||
"Ljava/lang/Object;",
|
||||
"Lcom/google/android/gms/tasks/e<",
|
||||
"Lcom/google/android/gms/safetynet/c$a;",
|
||||
">;"
|
||||
}
|
||||
.end annotation
|
||||
|
||||
|
||||
# instance fields
|
||||
.field final synthetic a:Ljava/util/concurrent/atomic/AtomicReference;
|
||||
|
||||
.field final synthetic b:Ljava/lang/Object;
|
||||
|
||||
|
||||
# direct methods
|
||||
.method constructor <init>(Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/Object;)V
|
||||
.locals 0
|
||||
|
||||
iput-object p1, p0, Lcom/vk/common/VKSafetyNet$a;->a:Ljava/util/concurrent/atomic/AtomicReference;
|
||||
|
||||
iput-object p2, p0, Lcom/vk/common/VKSafetyNet$a;->b:Ljava/lang/Object;
|
||||
|
||||
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
|
||||
# virtual methods
|
||||
.method public final a(Lcom/google/android/gms/safetynet/c$a;)V
|
||||
.locals 1
|
||||
|
||||
.line 2
|
||||
iget-object v0, p0, Lcom/vk/common/VKSafetyNet$a;->a:Ljava/util/concurrent/atomic/AtomicReference;
|
||||
|
||||
invoke-virtual {v0, p1}, Ljava/util/concurrent/atomic/AtomicReference;->set(Ljava/lang/Object;)V
|
||||
|
||||
.line 3
|
||||
iget-object p1, p0, Lcom/vk/common/VKSafetyNet$a;->b:Ljava/lang/Object;
|
||||
|
||||
monitor-enter p1
|
||||
|
||||
.line 4
|
||||
:try_start_0
|
||||
iget-object v0, p0, Lcom/vk/common/VKSafetyNet$a;->b:Ljava/lang/Object;
|
||||
|
||||
invoke-virtual {v0}, Ljava/lang/Object;->notifyAll()V
|
||||
|
||||
.line 5
|
||||
sget-object v0, Lkotlin/Unit;->a:Lkotlin/Unit;
|
||||
:try_end_0
|
||||
.catchall {:try_start_0 .. :try_end_0} :catchall_0
|
||||
|
||||
.line 6
|
||||
monitor-exit p1
|
||||
|
||||
return-void
|
||||
|
||||
:catchall_0
|
||||
move-exception v0
|
||||
|
||||
monitor-exit p1
|
||||
|
||||
throw v0
|
||||
.end method
|
||||
|
||||
.method public bridge synthetic a(Ljava/lang/Object;)V
|
||||
.locals 0
|
||||
|
||||
.line 1
|
||||
check-cast p1, Lcom/google/android/gms/safetynet/c$a;
|
||||
|
||||
invoke-virtual {p0, p1}, Lcom/vk/common/VKSafetyNet$a;->a(Lcom/google/android/gms/safetynet/c$a;)V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
@@ -1,76 +0,0 @@
|
||||
.class final Lcom/vk/common/VKSafetyNet$b;
|
||||
.super Ljava/lang/Object;
|
||||
.source "VKSafetyNet.kt"
|
||||
|
||||
# interfaces
|
||||
.implements Lcom/google/android/gms/tasks/d;
|
||||
|
||||
|
||||
# annotations
|
||||
.annotation system Ldalvik/annotation/EnclosingMethod;
|
||||
value = Lcom/vk/common/VKSafetyNet;->a()Lkotlin/Triple;
|
||||
.end annotation
|
||||
|
||||
.annotation system Ldalvik/annotation/InnerClass;
|
||||
accessFlags = 0x18
|
||||
name = null
|
||||
.end annotation
|
||||
|
||||
|
||||
# instance fields
|
||||
.field final synthetic a:Ljava/util/concurrent/atomic/AtomicReference;
|
||||
|
||||
.field final synthetic b:Ljava/lang/Object;
|
||||
|
||||
|
||||
# direct methods
|
||||
.method constructor <init>(Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/Object;)V
|
||||
.locals 0
|
||||
|
||||
iput-object p1, p0, Lcom/vk/common/VKSafetyNet$b;->a:Ljava/util/concurrent/atomic/AtomicReference;
|
||||
|
||||
iput-object p2, p0, Lcom/vk/common/VKSafetyNet$b;->b:Ljava/lang/Object;
|
||||
|
||||
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
|
||||
# virtual methods
|
||||
.method public final onFailure(Ljava/lang/Exception;)V
|
||||
.locals 1
|
||||
|
||||
.line 1
|
||||
iget-object v0, p0, Lcom/vk/common/VKSafetyNet$b;->a:Ljava/util/concurrent/atomic/AtomicReference;
|
||||
|
||||
invoke-virtual {v0, p1}, Ljava/util/concurrent/atomic/AtomicReference;->set(Ljava/lang/Object;)V
|
||||
|
||||
.line 2
|
||||
iget-object p1, p0, Lcom/vk/common/VKSafetyNet$b;->b:Ljava/lang/Object;
|
||||
|
||||
monitor-enter p1
|
||||
|
||||
.line 3
|
||||
:try_start_0
|
||||
iget-object v0, p0, Lcom/vk/common/VKSafetyNet$b;->b:Ljava/lang/Object;
|
||||
|
||||
invoke-virtual {v0}, Ljava/lang/Object;->notifyAll()V
|
||||
|
||||
.line 4
|
||||
sget-object v0, Lkotlin/Unit;->a:Lkotlin/Unit;
|
||||
:try_end_0
|
||||
.catchall {:try_start_0 .. :try_end_0} :catchall_0
|
||||
|
||||
.line 5
|
||||
monitor-exit p1
|
||||
|
||||
return-void
|
||||
|
||||
:catchall_0
|
||||
move-exception v0
|
||||
|
||||
monitor-exit p1
|
||||
|
||||
throw v0
|
||||
.end method
|
||||
@@ -1,316 +0,0 @@
|
||||
.class public final Lcom/vk/common/VKSafetyNet;
|
||||
.super Ljava/lang/Object;
|
||||
.source "VKSafetyNet.kt"
|
||||
|
||||
|
||||
# static fields
|
||||
.field public static final a:Lcom/vk/common/VKSafetyNet;
|
||||
|
||||
|
||||
# direct methods
|
||||
.method static constructor <clinit>()V
|
||||
.locals 1
|
||||
|
||||
.line 1
|
||||
new-instance v0, Lcom/vk/common/VKSafetyNet;
|
||||
|
||||
invoke-direct {v0}, Lcom/vk/common/VKSafetyNet;-><init>()V
|
||||
|
||||
sput-object v0, Lcom/vk/common/VKSafetyNet;->a:Lcom/vk/common/VKSafetyNet;
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method private constructor <init>()V
|
||||
.locals 0
|
||||
|
||||
.line 1
|
||||
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
|
||||
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method private final a(Landroid/content/Context;)Ljava/lang/String;
|
||||
.locals 5
|
||||
|
||||
const/4 v0, 0x0
|
||||
|
||||
.line 21
|
||||
:try_start_0
|
||||
invoke-virtual {p1}, Landroid/content/Context;->getPackageManager()Landroid/content/pm/PackageManager;
|
||||
|
||||
move-result-object v1
|
||||
|
||||
invoke-virtual {p1}, Landroid/content/Context;->getPackageName()Ljava/lang/String;
|
||||
|
||||
move-result-object p1
|
||||
|
||||
const/16 v2, 0x80
|
||||
|
||||
invoke-virtual {v1, p1, v2}, Landroid/content/pm/PackageManager;->getApplicationInfo(Ljava/lang/String;I)Landroid/content/pm/ApplicationInfo;
|
||||
|
||||
move-result-object p1
|
||||
|
||||
iget-object p1, p1, Landroid/content/pm/ApplicationInfo;->metaData:Landroid/os/Bundle;
|
||||
|
||||
const-string v1, "com.vk.safetynet.API_SECRET"
|
||||
|
||||
.line 22
|
||||
invoke-virtual {p1, v1, v0}, Landroid/os/Bundle;->getString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
|
||||
:try_end_0
|
||||
.catch Landroid/content/pm/PackageManager$NameNotFoundException; {:try_start_0 .. :try_end_0} :catch_0
|
||||
|
||||
goto :goto_0
|
||||
|
||||
:catch_0
|
||||
move-exception p1
|
||||
|
||||
const/4 v1, 0x1
|
||||
|
||||
new-array v1, v1, [Ljava/lang/Object;
|
||||
|
||||
const/4 v2, 0x0
|
||||
|
||||
.line 23
|
||||
new-instance v3, Ljava/lang/StringBuilder;
|
||||
|
||||
invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V
|
||||
|
||||
const-string v4, "can\'t get key "
|
||||
|
||||
invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||
|
||||
invoke-virtual {v3, p1}, Ljava/lang/StringBuilder;->append(Ljava/lang/Object;)Ljava/lang/StringBuilder;
|
||||
|
||||
invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||
|
||||
move-result-object p1
|
||||
|
||||
aput-object p1, v1, v2
|
||||
|
||||
invoke-static {v1}, Lcom/vk/log/L;->e([Ljava/lang/Object;)V
|
||||
|
||||
:goto_0
|
||||
return-object v0
|
||||
.end method
|
||||
|
||||
.method private final b()[B
|
||||
.locals 4
|
||||
|
||||
const/16 v0, 0x10
|
||||
|
||||
new-array v0, v0, [B
|
||||
|
||||
.line 1
|
||||
new-instance v1, Ljava/util/Random;
|
||||
|
||||
invoke-static {}, Landroid/os/SystemClock;->currentThreadTimeMillis()J
|
||||
|
||||
move-result-wide v2
|
||||
|
||||
invoke-direct {v1, v2, v3}, Ljava/util/Random;-><init>(J)V
|
||||
|
||||
invoke-virtual {v1, v0}, Ljava/util/Random;->nextBytes([B)V
|
||||
|
||||
return-object v0
|
||||
.end method
|
||||
|
||||
|
||||
# virtual methods
|
||||
.method public final a()Lkotlin/Triple;
|
||||
.locals 7
|
||||
.annotation system Ldalvik/annotation/Signature;
|
||||
value = {
|
||||
"()",
|
||||
"Lkotlin/Triple<",
|
||||
"Ljava/lang/String;",
|
||||
"[B",
|
||||
"Ljava/lang/Long;",
|
||||
">;"
|
||||
}
|
||||
.end annotation
|
||||
|
||||
.line 1
|
||||
invoke-static {}, Lcom/google/android/gms/common/c;->a()Lcom/google/android/gms/common/c;
|
||||
|
||||
move-result-object v0
|
||||
|
||||
.line 2
|
||||
sget-object v1, Lcom/vk/core/util/AppContextHolder;->a:Landroid/content/Context;
|
||||
|
||||
invoke-virtual {v0, v1}, Lcom/google/android/gms/common/c;->c(Landroid/content/Context;)I
|
||||
|
||||
move-result v0
|
||||
|
||||
if-nez v0, :cond_3
|
||||
|
||||
.line 3
|
||||
sget-object v0, Lcom/vk/core/util/AppContextHolder;->a:Landroid/content/Context;
|
||||
|
||||
const-string v1, "AppContextHolder.context"
|
||||
|
||||
invoke-static {v0, v1}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
|
||||
|
||||
invoke-direct {p0, v0}, Lcom/vk/common/VKSafetyNet;->a(Landroid/content/Context;)Ljava/lang/String;
|
||||
|
||||
move-result-object v0
|
||||
|
||||
if-eqz v0, :cond_2
|
||||
|
||||
.line 4
|
||||
new-instance v1, Ljava/util/concurrent/atomic/AtomicReference;
|
||||
|
||||
invoke-direct {v1}, Ljava/util/concurrent/atomic/AtomicReference;-><init>()V
|
||||
|
||||
.line 5
|
||||
new-instance v2, Ljava/util/concurrent/atomic/AtomicReference;
|
||||
|
||||
invoke-direct {v2}, Ljava/util/concurrent/atomic/AtomicReference;-><init>()V
|
||||
|
||||
.line 6
|
||||
new-instance v3, Ljava/lang/Object;
|
||||
|
||||
invoke-direct {v3}, Ljava/lang/Object;-><init>()V
|
||||
|
||||
.line 7
|
||||
invoke-direct {p0}, Lcom/vk/common/VKSafetyNet;->b()[B
|
||||
|
||||
move-result-object v4
|
||||
|
||||
.line 8
|
||||
sget-object v5, Lcom/vk/core/util/AppContextHolder;->a:Landroid/content/Context;
|
||||
|
||||
invoke-static {v5}, Lcom/google/android/gms/safetynet/b;->a(Landroid/content/Context;)Lcom/google/android/gms/safetynet/d;
|
||||
|
||||
move-result-object v5
|
||||
|
||||
invoke-virtual {v5, v4, v0}, Lcom/google/android/gms/safetynet/d;->a([BLjava/lang/String;)Lcom/google/android/gms/tasks/g;
|
||||
|
||||
move-result-object v0
|
||||
|
||||
.line 9
|
||||
new-instance v5, Lcom/vk/common/VKSafetyNet$a;
|
||||
|
||||
invoke-direct {v5, v1, v3}, Lcom/vk/common/VKSafetyNet$a;-><init>(Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/Object;)V
|
||||
|
||||
invoke-virtual {v0, v5}, Lcom/google/android/gms/tasks/g;->a(Lcom/google/android/gms/tasks/e;)Lcom/google/android/gms/tasks/g;
|
||||
|
||||
.line 10
|
||||
new-instance v5, Lcom/vk/common/VKSafetyNet$b;
|
||||
|
||||
invoke-direct {v5, v2, v3}, Lcom/vk/common/VKSafetyNet$b;-><init>(Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/Object;)V
|
||||
|
||||
invoke-virtual {v0, v5}, Lcom/google/android/gms/tasks/g;->a(Lcom/google/android/gms/tasks/d;)Lcom/google/android/gms/tasks/g;
|
||||
|
||||
.line 11
|
||||
monitor-enter v3
|
||||
|
||||
const-wide/16 v5, 0x2710
|
||||
|
||||
.line 12
|
||||
:try_start_0
|
||||
invoke-virtual {v3, v5, v6}, Ljava/lang/Object;->wait(J)V
|
||||
|
||||
.line 13
|
||||
sget-object v0, Lkotlin/Unit;->a:Lkotlin/Unit;
|
||||
:try_end_0
|
||||
.catchall {:try_start_0 .. :try_end_0} :catchall_0
|
||||
|
||||
.line 14
|
||||
monitor-exit v3
|
||||
|
||||
.line 15
|
||||
invoke-virtual {v1}, Ljava/util/concurrent/atomic/AtomicReference;->get()Ljava/lang/Object;
|
||||
|
||||
move-result-object v0
|
||||
|
||||
if-eqz v0, :cond_0
|
||||
|
||||
new-instance v0, Lkotlin/Triple;
|
||||
|
||||
invoke-virtual {v1}, Ljava/util/concurrent/atomic/AtomicReference;->get()Ljava/lang/Object;
|
||||
|
||||
move-result-object v1
|
||||
|
||||
const-string v2, "resultRef.get()"
|
||||
|
||||
invoke-static {v1, v2}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
|
||||
|
||||
check-cast v1, Lcom/google/android/gms/safetynet/c$a;
|
||||
|
||||
invoke-virtual {v1}, Lcom/google/android/gms/safetynet/c$a;->b()Ljava/lang/String;
|
||||
|
||||
move-result-object v1
|
||||
|
||||
sget-object v2, Lcom/vk/core/network/TimeProvider;->f:Lcom/vk/core/network/TimeProvider;
|
||||
|
||||
invoke-virtual {v2}, Lcom/vk/core/network/TimeProvider;->b()J
|
||||
|
||||
move-result-wide v2
|
||||
|
||||
invoke-static {v2, v3}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
|
||||
|
||||
move-result-object v2
|
||||
|
||||
invoke-direct {v0, v1, v4, v2}, Lkotlin/Triple;-><init>(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
|
||||
|
||||
return-object v0
|
||||
|
||||
.line 16
|
||||
:cond_0
|
||||
invoke-virtual {v2}, Ljava/util/concurrent/atomic/AtomicReference;->get()Ljava/lang/Object;
|
||||
|
||||
move-result-object v0
|
||||
|
||||
if-eqz v0, :cond_1
|
||||
|
||||
invoke-virtual {v2}, Ljava/util/concurrent/atomic/AtomicReference;->get()Ljava/lang/Object;
|
||||
|
||||
move-result-object v0
|
||||
|
||||
const-string v1, "errorRef.get()"
|
||||
|
||||
invoke-static {v0, v1}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
|
||||
|
||||
check-cast v0, Ljava/lang/Throwable;
|
||||
|
||||
throw v0
|
||||
|
||||
.line 17
|
||||
:cond_1
|
||||
new-instance v0, Ljava/io/IOException;
|
||||
|
||||
const-string v1, "Can\'t cat result from SafetyNet"
|
||||
|
||||
invoke-direct {v0, v1}, Ljava/io/IOException;-><init>(Ljava/lang/String;)V
|
||||
|
||||
throw v0
|
||||
|
||||
:catchall_0
|
||||
move-exception v0
|
||||
|
||||
.line 18
|
||||
monitor-exit v3
|
||||
|
||||
throw v0
|
||||
|
||||
.line 19
|
||||
:cond_2
|
||||
new-instance v0, Ljava/io/IOException;
|
||||
|
||||
const-string v1, "SafetyNet unavailable"
|
||||
|
||||
invoke-direct {v0, v1}, Ljava/io/IOException;-><init>(Ljava/lang/String;)V
|
||||
|
||||
throw v0
|
||||
|
||||
.line 20
|
||||
:cond_3
|
||||
new-instance v0, Ljava/io/IOException;
|
||||
|
||||
const-string v1, "SafetyNet unavailable"
|
||||
|
||||
invoke-direct {v0, v1}, Ljava/io/IOException;-><init>(Ljava/lang/String;)V
|
||||
|
||||
throw v0
|
||||
.end method
|
||||
@@ -2983,7 +2983,26 @@
|
||||
invoke-virtual {v0, v2}, Lorg/json/JSONObject;->optInt(Ljava/lang/String;)I
|
||||
|
||||
move-result v14
|
||||
###
|
||||
const-string v2, "useGenius"
|
||||
|
||||
const/4 v3, 0x0
|
||||
|
||||
invoke-static {v3}, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;
|
||||
|
||||
move-result-object v3
|
||||
|
||||
invoke-static {v2, v3}, Lru/vtosters/lite/utils/Preferences;->getBoolValue(Ljava/lang/String;Ljava/lang/Boolean;)Z
|
||||
|
||||
move-result v3
|
||||
|
||||
if-eqz v3, :cond_37
|
||||
|
||||
invoke-static {}, Lru/vtosters/lite/utils/NetworkUtils;->isNetworkConnected()Z
|
||||
|
||||
move-result v14
|
||||
###
|
||||
:cond_37
|
||||
const-string v2, "album"
|
||||
|
||||
.line 44
|
||||
|
||||
@@ -1780,6 +1780,18 @@
|
||||
|
||||
.line 90
|
||||
:cond_3
|
||||
invoke-static {}, Lru/vtosters/lite/music/cache/injectors/TracklistInjector;->eligibleForOfflineCaching()Z
|
||||
|
||||
move-result v0
|
||||
|
||||
if-eqz v0, :cond_4
|
||||
|
||||
invoke-static {p0}, Lru/vtosters/lite/music/cache/injectors/ShuffleInjector;->shuffleTracks(Lcom/vk/music/model/IpcPlayerModelImpl;)V
|
||||
|
||||
return-void
|
||||
|
||||
.line 90
|
||||
:cond_4
|
||||
new-instance v0, Lcom/vk/api/audio/AudioGetButtonTracks;
|
||||
|
||||
const/16 v1, 0x64
|
||||
|
||||
@@ -1362,6 +1362,18 @@
|
||||
|
||||
.line 44
|
||||
:cond_0
|
||||
invoke-static {}, Lru/vtosters/lite/music/cache/injectors/TracklistInjector;->eligibleForOfflineCaching()Z
|
||||
|
||||
move-result v0
|
||||
|
||||
if-eqz v0, :cond_1
|
||||
|
||||
invoke-static {p0}, Lru/vtosters/lite/music/cache/injectors/ShuffleInjector;->shuffleTracks(Lcom/vk/music/model/PlayerModelImpl;)V
|
||||
|
||||
return-void
|
||||
|
||||
.line 90
|
||||
:cond_1
|
||||
new-instance v0, Lcom/vk/api/audio/AudioGetButtonTracks;
|
||||
|
||||
const/16 v1, 0x64
|
||||
|
||||
@@ -31,20 +31,6 @@
|
||||
}
|
||||
.end annotation
|
||||
|
||||
.line 1
|
||||
:try_start_0
|
||||
sget-object v0, Lcom/vk/common/VKSafetyNet;->a:Lcom/vk/common/VKSafetyNet;
|
||||
|
||||
invoke-virtual {v0}, Lcom/vk/common/VKSafetyNet;->a()Lkotlin/Triple;
|
||||
|
||||
move-result-object v0
|
||||
:try_end_0
|
||||
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0
|
||||
|
||||
goto :goto_0
|
||||
|
||||
.line 2
|
||||
:catch_0
|
||||
new-instance v0, Lkotlin/Triple;
|
||||
|
||||
const/4 v1, 0x0
|
||||
@@ -61,7 +47,6 @@
|
||||
|
||||
invoke-direct {v0, v3, v1, v2}, Lkotlin/Triple;-><init>(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
|
||||
|
||||
:goto_0
|
||||
return-object v0
|
||||
.end method
|
||||
|
||||
|
||||
Reference in New Issue
Block a user