Compare commits

...
39 Commits
Author SHA1 Message Date
Artur Skubei 7dd646e72b Update build.yml 2024-09-06 15:55:34 +03:00
Artur Skubei c0b9c1dab0 fixed workflow compile 2024-09-06 15:42:04 +03:00
Artur Skubei 0fd631adfb Portuguese language support via MLT (#1466) 2024-07-23 02:48:01 +03:00
gdlbo 93edbf2d3d Revert "Update ProxyHostChecker.smali"
This reverts commit 5932d6f9dc.
2024-07-06 12:47:28 +03:00
gdlbo f39463f782 fixes 2024-06-22 01:09:54 +03:00
gdlbo 27b07719d9 fix music catalog 2024-06-21 20:59:46 +03:00
Vologhat c6cff1a585 fix #1619 (#1620) 2024-06-21 20:34:37 +03:00
gdlbo 5932d6f9dc Update ProxyHostChecker.smali 2024-04-15 01:42:06 +03:00
gdlbo 15bb5fa469 fixes 2024-04-15 01:39:13 +03:00
gdlbo fd17e2bc8c fixed groups load 2024-04-12 10:24:02 +03:00
gdlbo 4cd94d811c fix #1607 2024-04-12 10:08:57 +03:00
gdlbo f1ea800336 fixed profiles loading 2024-04-12 09:58:44 +03:00
Artur Skubei b20230848b Speedup cache injection (#1597) 2024-03-30 05:54:56 +03:00
gdlbo adc5bb2b8c some more global renames 2024-03-29 15:16:33 +03:00
gdlbo 34f49a9b42 fixed rename in wall 2024-03-29 15:12:56 +03:00
gdlbo 84ad75e948 fixed disabler for playlist catalog 2024-03-29 13:45:28 +03:00
gdlbo e049b5f989 Update OEMDetector.java 2024-03-29 13:41:55 +03:00
Artur Skubei 5de52ed6b5 Rename Profiles/Groups v2 (#1596) 2024-03-29 13:38:30 +03:00
gdlbo 46c4f1c6dc hyperos support + gms refactored 2024-03-29 13:37:25 +03:00
gdlbo 126f5259d1 fixes 2024-03-29 10:47:18 +03:00
gdlbo 2d1867197f fixes of sponsorpost sdk
also added force update of filters
2024-03-28 22:20:07 +03:00
gdlbo c1d4216416 music stats catalog disabler 2024-03-28 20:16:39 +03:00
gdlbo 0f45a8d175 Update strings.xml 2024-03-28 20:10:08 +03:00
gdlbo 15ed01b4d3 fixed cache playlist shuffle 2024-03-28 20:05:10 +03:00
aliveoutside 41763a4b54 master.m3u8 fix 2024-03-26 22:59:32 +03:00
gdlbo d98d81f105 fixed autocache text dialog with dark theme 2024-03-26 17:47:10 +03:00
Artur Skubei 899554a571 Music autocaching v2 (#1591) 2024-03-26 17:36:34 +03:00
Artur Skubei 87b1a89bd8 Video metrics impl (#1590) 2024-03-25 23:45:42 +03:00
gdlbo c2b51338e8 Update MusicFragment.java 2024-03-24 22:55:58 +03:00
gdlbo 1d03182a1f fixed pause for music track stats 2024-03-24 22:40:01 +03:00
Artur Skubei bbad64c0aa Music metrics impl for recommendations (#1587) 2024-03-24 22:00:26 +03:00
Artur Skubei 53081115cc Fixed bypass online in profiles and messages (#1584) 2024-03-21 21:40:49 +03:00
gdlbo af4f069eb4 fixed sony crash on android 14
https://t.me/vtosterschat/3499552/3563197
2024-03-21 08:41:42 +03:00
gdlbo 904814e5cb fixed batchmessages applying 2024-03-19 22:49:06 +03:00
gdlbo c240db520d fixed tabs text color in vkid 2024-03-19 22:33:34 +03:00
gdlbo 8f9235e6db added test feature of alter load msgs 2024-03-19 22:16:00 +03:00
gdlbo 10b27566c0 fix #1350 #1178 #1045
also fixed webview coloring after theme change
2024-03-19 21:43:59 +03:00
Artur Skubei 16b67cf6c6 Music Caching v2 (#1283)
* Playlist caching
* Playlist gzip support
* Many catalog fixes
2024-03-19 19:33:05 +03:00
gdlbo 23436f1026 some sponsorpost fixes 2024-03-19 19:29:29 +03:00
90 changed files with 4746 additions and 4467 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
uses: nttld/setup-ndk@v1 uses: nttld/setup-ndk@v1
with: with:
ndk-version: r25c ndk-version: r25c
add-to-path: false add-to-path: true
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v3 uses: actions/setup-java@v3
+2 -2
View File
@@ -4,7 +4,7 @@ import java.util.zip.ZipFile
plugins { plugins {
id 'com.android.application' id 'com.android.application'
id 'net.nemerosa.versioning' version '2.15.1' id 'net.nemerosa.versioning' version '3.1.0'
id 'org.mozilla.rust-android-gradle.rust-android' id 'org.mozilla.rust-android-gradle.rust-android'
} }
@@ -95,7 +95,7 @@ dependencies {
implementation 'com.microsoft.appcenter:appcenter-crashes:5.0.4' implementation 'com.microsoft.appcenter:appcenter-crashes:5.0.4'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
implementation 'net.sourceforge.streamsupport:streamsupport-minifuture:1.7.4' implementation 'net.sourceforge.streamsupport:streamsupport-minifuture:1.7.4'
implementation 'com.google.guava:guava:32.0.0-android' implementation 'com.google.guava:guava:33.2.1-android'
implementation 'com.mpatric:mp3agic:0.9.1' implementation 'com.mpatric:mp3agic:0.9.1'
@@ -0,0 +1,336 @@
package com.vk.libvideo;
import android.os.Bundle;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import com.vk.bridges.StatisticsBridge1;
import com.vk.dto.common.VideoFile;
import com.vk.media.player.PlayerTypes;
import com.vk.navigation.NavigatorKeys;
import com.vk.statistic.Statistic;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.utils.Metrics;
import java.util.Locale;
import java.util.Objects;
/* loaded from: classes3.dex */
public class VideoTracker {
private final VideoFile a;
/* renamed from: b reason: collision with root package name */
private Statistic f15638b;
/* renamed from: c reason: collision with root package name */
private String f15639c;
/* renamed from: d reason: collision with root package name */
private String f15640d;
/* renamed from: e reason: collision with root package name */
private final boolean f15641e;
/* renamed from: f reason: collision with root package name */
private int f15642f = -1;
private final int g;
private final int h;
private final int i;
private final int j;
private final int k;
private int l;
private PlayerType m;
private Screen n;
/* loaded from: classes3.dex */
public enum FullscreenTransition {
TAP,
SCREEN_ROTATION
}
/* loaded from: classes3.dex */
public enum PlayerType {
INLINE,
CAROUSEL,
FULLSCREEN
}
/* loaded from: classes3.dex */
public enum ResizeAction {
BUTTON,
GESTURE
}
/* loaded from: classes3.dex */
public enum RewindType {
SLIDER,
DOUBLE_TAP
}
/* loaded from: classes3.dex */
public enum Screen {
INLINE,
CAROUSEL,
PORTRAIT,
LANDSCAPE
}
public VideoTracker(VideoFile videoFile, @Nullable Statistic statistic, String str, boolean z, @Nullable String str2) {
this.a = videoFile;
this.f15638b = statistic;
int i = videoFile.d;
this.g = (int) (i * 0.25f);
this.h = (int) (i * 0.5f);
this.i = (int) (i * 0.75f);
this.j = (int) (i * 0.95f);
this.k = i - 1;
this.f15639c = str;
this.f15641e = z;
this.f15640d = str2;
}
private static boolean a(int i, int i2, int i3) {
return i3 > i && i3 <= i2;
}
public void a(String str) {
this.f15640d = str;
}
public boolean b() {
return this.f15638b != null;
}
public void c() {
this.f15642f = -1;
}
public void d() {
c("video_fullscreen_off");
}
public void e() {
c("video_fullscreen_on");
}
public void f() {
c("video_pause");
c("pause", "pause");
}
public void g() {
c("video_resume");
c("pause", "resume");
}
public void h() {
c("video_volume_off");
c("volume", "off");
}
public void i() {
c("video_volume_on");
c("volume", "on");
}
private void c(String str, String str2) {
a(b(str, str2));
}
public String a() {
return this.f15640d;
}
public void b(String str) {
if (Objects.equals(this.f15639c, str)) {
return;
}
this.f15639c = str;
}
private void c(String str) {
if (this.f15638b != null) {
StatisticsBridge1.a().a(this.f15638b, str);
}
}
public void a(@Nullable Statistic statistic) {
this.f15638b = statistic;
}
private Bundle b(String str, String str2) {
Bundle bundle = new Bundle();
bundle.putString(NotificationCompat.CATEGORY_EVENT, str);
bundle.putString("value", str2);
bundle.putInt("position", this.f15642f);
return bundle;
}
public void a(PlayerType playerType) {
if (this.m != playerType) {
this.m = playerType;
}
}
public void a(int i, int i2) {
int i3 = this.f15642f;
if (i == i3) {
return;
}
if (a(i3, i, 0)) {
a("start", i2);
c("video_start");
}
// if (this.a.d > 0) {
// if (a(this.f15642f, i, 3)) {
// a("3s", i2);
// c("video_play_3s");
// }
// if (a(this.f15642f, i, 10)) {
// a("10s", i2);
// c("video_play_10s");
// }
// if (a(this.f15642f, i, this.g)) {
// a("25", i2);
// c("video_play_25");
// }
// if (a(this.f15642f, i, this.h)) {
// a("50", i2);
// c("video_play_50");
// }
// if (a(this.f15642f, i, this.i)) {
// a("75", i2);
// c("video_play_75");
// }
// if (a(this.f15642f, i, this.j)) {
// a("95", i2);
// c("video_play_95");
// }
// if (a(this.f15642f, i, this.k)) {
// a("100", i2);
// c("video_play_100");
// }
// }
this.f15642f = i;
}
public void a(int i) {
a("continue", i);
c("video_start");
}
public void a(@NonNull Screen screen) {
if (this.n != screen) {
this.n = screen;
c("screen", screen.toString().toLowerCase());
}
}
public void a(@NonNull FullscreenTransition fullscreenTransition) {
c("full_screen_transition", fullscreenTransition.toString().toLowerCase());
}
public void a(int i, boolean z) {
if (this.l != i) {
this.l = i;
c(z ? "auto_quality" : "quality", PlayerTypes.c(i));
}
}
public void a(@Nullable String str, boolean z) {
String str2 = z ? "auto_subtitles" : "subtitles";
if (str == null) {
str = "off";
}
c(str2, str);
}
public void a(int i, int i2, @NonNull RewindType rewindType) {
Bundle b2 = b("rewind", i <= i2 ? "forward" : "backward");
b2.putString("rewind_type", rewindType.toString().toLowerCase());
b2.putInt("rewind_start", i);
b2.putInt("rewind_end", i2);
a(b2);
}
public void a(float f2) {
String format;
if (f2 == 1.0f) {
format = "normal";
} else {
int i = (int) f2;
format = f2 == ((float) i) ? String.format(Locale.US, "%s", i) : String.format(Locale.US, "%.2f", f2);
}
c("speed", format);
}
public void a(boolean z, @NonNull ResizeAction resizeAction) {
Bundle b2 = b("resize", z ? "widen" : "narrow");
b2.putString("resize_action", resizeAction.toString().toLowerCase());
a(b2);
}
public void a(String str, String str2) {
Bundle bundle = new Bundle();
bundle.putString("link_type", str);
bundle.putString("value", str2);
bundle.putString(NotificationCompat.CATEGORY_EVENT, "show_link");
a(bundle);
}
private void a(String str, int i) {
Bundle bundle = new Bundle();
bundle.putString("autoplay", this.f15641e ? "1" : "0");
bundle.putString("position", str);
if (i >= 0) {
bundle.putInt("quality", i - 2);
}
PlayerType playerType = this.m;
if (playerType != null) {
bundle.putString("player_type", playerType.toString().toLowerCase());
}
a("video_play", bundle);
}
private void a(Bundle bundle) {
a("video_event", bundle);
}
private void a(String str, Bundle bundle) {
bundle.putString("video_id", this.a.a + "_" + this.a.b);
bundle.putString(NavigatorKeys.V, this.f15639c);
bundle.putString(NavigatorKeys.Z, this.f15639c);
if (!TextUtils.isEmpty(this.f15640d)) {
bundle.putString("context", this.f15640d);
}
if (!TextUtils.isEmpty(this.a.l0)) {
bundle.putString(NavigatorKeys.l0, this.a.l0);
}
bundle.putLong("ts", System.currentTimeMillis());
StatisticsBridge1.a().a(str, bundle);
if (Preferences.getBoolValue("sendVideoMetrics", true) && str.equals("video_play")) {
try {
sendMetrics(str);
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
}
public void sendMetrics(String event) throws JSONException {
JSONObject jsonObject = new JSONObject();
jsonObject.put("e", event);
jsonObject.put("source", this.f15639c);
jsonObject.put("ref", this.f15639c);
jsonObject.put("video_id", this.a.a + "_" + this.a.b);
jsonObject.put("position", "start");
jsonObject.put("position_sec", 0);
jsonObject.put("cur_quality", "auto");
Metrics.trackEvents(jsonObject, false);
}
}
@@ -0,0 +1,256 @@
package com.vk.music.stats;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.core.app.NotificationCompat;
import com.vk.core.extensions.StringExt;
import com.vk.music.common.MusicPlaybackLaunchContext;
import com.vk.music.logger.MusicLogger;
import com.vk.music.stats.i.MusicPlaybackParams;
import com.vk.navigation.NavigatorKeys;
import com.vtosters.lite.data.Analytics;
import kotlin.jvm.b.Functions2;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.utils.Metrics;
import java.util.Objects;
import java.util.UUID;
public final class VKMusicStatsTracker implements MusicStatsTracker {
private String a;
private final Functions2<String, Analytics.l> b;
private static final a c = new a();
public VKMusicStatsTracker(Functions2<String, Analytics.l> functions2) {
this.b = functions2;
}
private String e(MusicPlaybackParams musicPlaybackParams) {
String g = musicPlaybackParams.g();
if (g == null) {
g = this.a;
}
if (g == null) {
g = "auto";
}
this.a = g;
return g;
}
@Override
public void a(boolean z) {
MusicStatsTracker.a.a(this, z);
}
@Override
public void b(MusicPlaybackParams musicPlaybackParams) {
c.a(a(musicPlaybackParams, "music_start_playback"));
if (Preferences.sendMusicMetrics()) {
try {
makeMetricsRequest(musicPlaybackParams, "music_start_playback");
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
}
@Override
public void b(boolean z) {
}
@Override
public void c(MusicPlaybackParams musicPlaybackParams) {
MusicStatsTracker.a.b(this, musicPlaybackParams);
}
@Override
public void d() {
MusicStatsTracker.a.a(this);
}
@Override
public void a(Intent intent, String str) {
MusicStatsTracker.a.a(this, intent, str);
}
@Override
public void b(String str, @NonNull String str2) {
Analytics.l invoke = this.b.invoke("music_subscription_action");
invoke.a("popup", str);
invoke.a("action", str2);
c.a(invoke);
}
@Override
public void c(boolean z) {
MusicStatsTracker.a.b(this, z);
}
@Override
public void d(MusicPlaybackParams musicPlaybackParams) {
if (Objects.equals("pause", this.a)) {
a(musicPlaybackParams);
}
}
@Override
public void a(long j) {
MusicStatsTracker.a.a(this, j);
}
@Override
public void c() {
Analytics.l invoke = this.b.invoke("music_subscription_push");
invoke.a("action", "open");
c.a(invoke);
}
@Override
public void a(String str, MusicStatsRefer musicStatsRefer) {
Analytics.l invoke = this.b.invoke("music_subscription_show");
invoke.a("popup", str);
c.a(invoke);
}
@Override
public void b() {
Analytics.l invoke = this.b.invoke("music_subscription_push");
invoke.a("action", "send");
c.a(invoke);
}
@Override
public void a(MusicPlaybackParams musicPlaybackParams) {
c.a(a(musicPlaybackParams, "music_stop_playback"));
if (Preferences.sendMusicMetrics()) {
try {
makeMetricsRequest(musicPlaybackParams, "music_stop_playback");
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
}
@Override
public void a(PlayerStateChangedParams playerStateChangedParams) {
Analytics.l invoke = this.b.invoke("audio_player");
invoke.a(NavigatorKeys.t0, playerStateChangedParams.a());
invoke.a("prev_state", playerStateChangedParams.c());
invoke.a("duration", playerStateChangedParams.b());
c.a(invoke);
}
@Override
public void b(String str) {
Analytics.l invoke = this.b.invoke("music_subscription_free_displayed");
invoke.a("popup", str);
c.a(invoke);
}
@Override
public void a(String str) {
Analytics.l invoke = this.b.invoke("playlist_start");
invoke.a(NavigatorKeys.e, str);
c.a(invoke);
}
private void makeMetricsRequest(MusicPlaybackParams musicPlaybackParams, String str) throws JSONException {
JSONObject event = new JSONObject();
if (str.equals("music_stop_playback")) {
event.put("e", str);
event.put("audio_id", musicPlaybackParams.c());
event.put("duration", musicPlaybackParams.a());
event.put("start_time", musicPlaybackParams.i());
event.put("shuffle", "false");
event.put("reason", "new");
event.put("state", "app");
event.put("duration", musicPlaybackParams.a());
} else {
event.put("e", str);
event.put("audio_id", musicPlaybackParams.c());
event.put("start_time", musicPlaybackParams.i());
event.put("shuffle", "false");
event.put("reason", "auto");
event.put("state", "app");
if (StringExt.a((CharSequence) musicPlaybackParams.e())) {
event.put("prev_audio_id", musicPlaybackParams.e());
}
}
Metrics.trackEvents(event, true);
}
private Analytics.l a(MusicPlaybackParams musicPlaybackParams, String str) {
Analytics.l invoke = this.b.invoke(str);
invoke.a("audio_id", musicPlaybackParams.c());
invoke.a("uuid", UUID.randomUUID().hashCode());
invoke.a("shuffle", musicPlaybackParams.l());
invoke.a("reason", e(musicPlaybackParams));
invoke.a("start_time", musicPlaybackParams.i());
invoke.a("playback_started_at", musicPlaybackParams.d());
invoke.a(NavigatorKeys.l0, musicPlaybackParams.j());
if (!Objects.equals("music_start_playback", str)) {
invoke.a("duration", musicPlaybackParams.a());
}
int i = h.$EnumSwitchMapping$0[musicPlaybackParams.b().ordinal()];
if (i == 1) {
invoke.a("repeat", "one");
} else if (i == 2) {
invoke.a("repeat", "all");
}
invoke.a(NavigatorKeys.t0, musicPlaybackParams.m());
MusicPlaybackLaunchContext h = musicPlaybackParams.h();
invoke.a(NavigatorKeys.V, h.v0());
if (h.v1()) {
invoke.a("playlist_id", h.u1());
}
if (h.i(4) || h.i(8)) {
invoke.a("expanded", h.i(4));
}
if (StringExt.a((CharSequence) musicPlaybackParams.e())) {
invoke.a("prev_audio_id", musicPlaybackParams.e());
}
if (StringExt.a((CharSequence) musicPlaybackParams.f())) {
invoke.a("prev_playlist_id", musicPlaybackParams.f());
}
return invoke;
}
@Override
public void a(String str, String str2) {
boolean a2 = Objects.equals("success", str2);
Analytics.l builder = this.b.invoke("music_subscription_purchase_result");
builder.a("popup", str);
builder.a(NotificationCompat.CATEGORY_STATUS, a2 ? "success" : "fail");
if (!a2) {
builder.a("reason", str2);
}
c.a(builder);
}
@Override
public void a() {
Analytics.l invoke = this.b.invoke("music_subscription");
invoke.a("popup", "background_v2");
invoke.a("action", "link");
c.a(invoke);
}
public static final class a {
private a() {
}
@VisibleForTesting
public void a(Analytics.l lVar) {
MusicLogger.a("MusicStats", "[VK_TRACKER]", lVar);
lVar.b();
}
}
}
@@ -11,37 +11,37 @@ import com.vtosters.lite.R;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
public class GmsHook { public class GmsHook {
private static final boolean needToSpoof = !isGmsInstalled() && (isFakeGmsInstalled() || isFakeGms2Installed()); private static final String[] spoofPackages = {"com.mgoogle", "app.revanced"};
private static final String currentGms;
static {
currentGms = getSpoofPackagePrefix();
}
private static boolean isPackageInstalled(String packageName) {
try {
AndroidUtils.getGlobalContext().getPackageManager().getPackageInfo(packageName, 0);
return true;
} catch (Exception unused) {
return false;
}
}
public static boolean isGmsInstalled() { public static boolean isGmsInstalled() {
try { return isPackageInstalled("com.google.android.gms");
AndroidUtils.getGlobalContext().getPackageManager().getPackageInfo("com.google.android.gms", 0);
return true;
} catch (Exception unused) {
return false;
} }
} // Google Market Services check
public static boolean isFakeGmsInstalled() { public static boolean isSpoofPackageInstalled(String packageName) {
try { return isPackageInstalled(packageName + ".android.gms");
AndroidUtils.getGlobalContext().getPackageManager().getPackageInfo("com.mgoogle.android.gms", 0);
return true;
} catch (Exception unused) {
return false;
} }
} // Microg Google Market Services check
public static boolean isFakeGms2Installed() {
try {
AndroidUtils.getGlobalContext().getPackageManager().getPackageInfo("app.revanced.android.gms", 0);
return true;
} catch (Exception unused) {
return false;
}
} // Microg Google Market Services check
public static boolean isAnyServicesInstalled() { public static boolean isAnyServicesInstalled() {
return isGmsInstalled() || isFakeGmsInstalled() || isFakeGms2Installed(); for (String packageName : spoofPackages) {
if (isSpoofPackageInstalled(packageName)) {
return true;
}
}
return false;
} }
public static void fixGapps() { public static void fixGapps() {
@@ -52,10 +52,10 @@ public class GmsHook {
notificationManager.createNotificationChannel(new NotificationChannel("audio_playback_channel", AndroidUtils.getResources().getString(R.string.audio_message_play_error), NotificationManager.IMPORTANCE_LOW)); notificationManager.createNotificationChannel(new NotificationChannel("audio_playback_channel", AndroidUtils.getResources().getString(R.string.audio_message_play_error), NotificationManager.IMPORTANCE_LOW));
} }
} }
} // Music channels fix }
public static String replaceGMSPackage(String str) { public static String replaceGMSPackage(String str) {
return needToSpoof ? str.replaceAll("com.google", (isFakeGms2Installed() ? "app.revanced" : "com.mgoogle")) : str; return shouldSpoof() ? str.replaceAll("com.google", currentGms) : str;
} }
public static String getFirebaseInstanceIdReceiver() { public static String getFirebaseInstanceIdReceiver() {
@@ -63,6 +63,37 @@ public class GmsHook {
} }
public static Class getFirebaseInstanceIdReceiverClass() { public static Class getFirebaseInstanceIdReceiverClass() {
return needToSpoof ? (isFakeGms2Installed() ? FirebaseInstanceIdReceiver3.class : FirebaseInstanceIdReceiver2.class) : FirebaseInstanceIdReceiver.class; return getSpoofFirebaseInstanceIdReceiverClass();
}
public static String getCurrentGms() {
return currentGms;
}
private static boolean shouldSpoof() {
return !isGmsInstalled() && (isSpoofPackageInstalled("com.mgoogle") || isSpoofPackageInstalled("app.revanced"));
}
private static String getSpoofPackagePrefix() {
for (String packageName : spoofPackages) {
if (isSpoofPackageInstalled(packageName)) {
return packageName;
}
}
return "com.google";
}
private static Class getSpoofFirebaseInstanceIdReceiverClass() {
switch (currentGms) {
case "com.mgoogle" -> {
return FirebaseInstanceIdReceiver2.class;
}
case "app.revanced" -> {
return FirebaseInstanceIdReceiver3.class;
}
default -> {
return FirebaseInstanceIdReceiver.class;
}
}
} }
} }
@@ -66,7 +66,8 @@ public class MainActivityInjector {
// VKIDProtection.alert(activity); // VKIDProtection.alert(activity);
//needs to show selected tgs pack count in settings after cold launch //needs to show selected tgs pack count in settings after cold launch
TelegramStickersService.getInstance(activity); TelegramStickersService.getInstance(activity);
if (AccountManagerUtils.isLogin()) {
if (AccountManagerUtils.isLogin() && !Preferences.serverFeaturesDisable() && Preferences.isValidSignature()) {
Native.canVote = NativeLibLoader.loadLibrary("sponsorpost"); Native.canVote = NativeLibLoader.loadLibrary("sponsorpost");
} }
} }
@@ -82,7 +83,7 @@ public class MainActivityInjector {
ThemesManager.generateModApk(ThemesUtils.getReservedAccent()); ThemesManager.generateModApk(ThemesUtils.getReservedAccent());
activity.runOnUiThread(LifecycleUtils::restartApplication); activity.runOnUiThread(LifecycleUtils::restartApplication);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.fillInStackTrace();
activity.runOnUiThread(() -> { activity.runOnUiThread(() -> {
dialog.cancel(); dialog.cancel();
new VkAlertDialog.Builder(activity) new VkAlertDialog.Builder(activity)
@@ -1,7 +1,10 @@
package ru.vtosters.hooks; package ru.vtosters.hooks;
import android.util.Log; import android.util.Log;
import android.util.SparseArray;
import com.vk.core.network.Network; import com.vk.core.network.Network;
import com.vk.im.engine.internal.api_parsers.UserApiParser;
import com.vk.im.engine.models.users.User;
import com.vtosters.lite.R; import com.vtosters.lite.R;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
@@ -10,8 +13,6 @@ import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences; import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.proxy.ProxyUtils;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import java.io.IOException; import java.io.IOException;
@@ -146,16 +147,36 @@ public class OnlineFormatterHook {
return json; return json;
} }
public static JSONArray onlineHookList(JSONArray jsonArr) { public static SparseArray<User> onlineHookList(String str) {
if (!getBoolValue("onlinefix", false) || Preferences.serverFeaturesDisable()) return jsonArr; JSONArray jSONArray;
try { try {
JsonInjectors.setOnlineInfoUsers(jsonArr); jSONArray = new JSONObject(str).getJSONArray("response");
} catch (Exception e) { } catch (JSONException e) {
Log.e("onlineHookProfiles", e.getMessage()); throw new RuntimeException(e);
}
SparseArray<User> sparseArray = new SparseArray<>(jSONArray.length());
int length = jSONArray.length();
if (getBoolValue("onlinefix", false) || !Preferences.serverFeaturesDisable()) {
try {
jSONArray = JsonInjectors.setOnlineInfoUsers(jSONArray);
} catch (JSONException e) {
throw new RuntimeException(e);
}
} }
return jsonArr; for (int i = 0; i < length; i++) {
JSONObject jSONObject;
try {
jSONObject = jSONArray.getJSONObject(i);
} catch (JSONException e) {
throw new RuntimeException(e);
}
User b = UserApiParser.b(jSONObject);
sparseArray.put(b.getId(), b);
}
return sparseArray;
} }
public static JSONObject onlineHookProfiles(JSONObject json) { public static JSONObject onlineHookProfiles(JSONObject json) {
@@ -188,19 +209,19 @@ public class OnlineFormatterHook {
try { try {
JsonInjectors.setOnlineInfoUsers(json.optJSONObject("read_requests").optJSONArray("items")); JsonInjectors.setOnlineInfoUsers(json.optJSONObject("read_requests").optJSONArray("items"));
} catch (Exception e) { } catch (Exception e) {
Log.e("onlineHookItems", e.getMessage()); Log.e("onlineHookItemsRec", e.getMessage());
} }
try { try {
JsonInjectors.setOnlineInfoUsers(json.optJSONObject("recommendations").optJSONArray("items")); JsonInjectors.setOnlineInfoUsers(json.optJSONObject("recommendations").optJSONArray("items"));
} catch (Exception e) { } catch (Exception e) {
Log.e("onlineHookItems", e.getMessage()); Log.e("onlineHookItemsRec", e.getMessage());
} }
try { try {
JsonInjectors.setOnlineInfoUsers(json.optJSONArray("profiles")); JsonInjectors.setOnlineInfoUsers(json.optJSONArray("profiles"));
} catch (Exception e) { } catch (Exception e) {
Log.e("onlineHookItems", e.getMessage()); Log.e("onlineHookItemsRec", e.getMessage());
} }
return json; return json;
@@ -0,0 +1,16 @@
package ru.vtosters.hooks;
import com.vtosters.lite.api.execute.GetWallInfo;
import java.util.ArrayList;
/**
* Since June 12, 2024, there are troubles with API method "execute.getUserInfo" in the old versions of VK Client (<6.16),
* to fix that issue we need to upgrade "execute.getUserInfo" for new API versions
* and implement the new API method "newsfeed.getPostTopics" (TODO)*/
@SuppressWarnings("unused")
public class PostTopicsHook {
public static void hook(final GetWallInfo.a model) throws Exception {
model.f = new ArrayList<>();
}
}
@@ -1,29 +1,40 @@
package ru.vtosters.hooks; package ru.vtosters.hooks;
import androidx.core.util.Pair;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.utils.RenameTool;
public class RenameHook { public class RenameHook {
public static void injectIntoJson(JSONObject obj) throws JSONException { public static void injectIntoJson(JSONObject obj) throws JSONException {
// int i = obj.getInt("id"); if (isEnabled()) {
// if (RenameTool.updateRequested) { int i = obj.getInt("id");
// RenameTool.reloadDB(); if (RenameTool.updateRequested) {
// } RenameTool.reloadDB();
// }
// Pair<String, String> user = RenameTool.renamedUsers.get(i);
// if (user == null) return; Pair<String, String> user = RenameTool.renamedUsers.get(i);
// obj.put(RenameTool.COLUMN_FIRSTNAME, user.first).put(RenameTool.COLUMN_LASTNAME, user.second); if (user == null) return;
obj.put(RenameTool.COLUMN_FIRSTNAME, user.first).put(RenameTool.COLUMN_LASTNAME, user.second);
}
}
public static boolean isEnabled() {
return Preferences.getBoolValue("unstableNameChanger", true);
} }
public static void injectIntoJsonGroup(JSONObject obj) throws JSONException { public static void injectIntoJsonGroup(JSONObject obj) throws JSONException {
// int i = obj.getInt("id"); if (isEnabled()) {
// int i = obj.getInt("id");
// if (RenameTool.updateRequested) {
// RenameTool.reloadDB(); if (RenameTool.updateRequested) {
// } RenameTool.reloadDB();
// }
// String user = RenameTool.renamedGroups.get(i);
// if (user == null) return; String user = RenameTool.renamedGroups.get(i);
// obj.put("name", user); if (user == null) return;
obj.put("name", user);
}
} }
} }
@@ -0,0 +1,29 @@
package ru.vtosters.hooks;
import android.os.Build;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.impl.*;
import java.util.List;
public class ShortcutBadgerHook {
public static void init(List<Class<? extends Badger>> list) {
list.add(AdwHomeBadger.class);
list.add(ApexHomeBadger.class);
list.add(DefaultBadger.class);
list.add(NewHtcHomeBadger.class);
list.add(NovaHomeBadger.class);
list.add(AsusHomeBadger.class);
list.add(HuaweiHomeBadger.class);
list.add(OPPOHomeBader.class);
list.add(SamsungHomeBadger.class);
list.add(ZukHomeBadger.class);
list.add(VivoHomeBadger.class);
list.add(ZTEHomeBadger.class);
list.add(EverythingMeHomeBadger.class);
if (Build.VERSION.SDK_INT < 34) {
list.add(SonyHomeBadger.class);
}
}
}
@@ -3,15 +3,17 @@ package ru.vtosters.hooks;
import com.vk.medianative.MediaImageEncoder; import com.vk.medianative.MediaImageEncoder;
import com.vk.toggle.FeatureManager; import com.vk.toggle.FeatureManager;
import com.vk.toggle.Features; import com.vk.toggle.Features;
import ru.vtosters.hooks.other.Preferences;
import static ru.vtosters.hooks.other.Preferences.*; import static ru.vtosters.hooks.other.Preferences.*;
public class TogglesHook { public class TogglesHook {
public static boolean shouldPatch(Features.Type feature) { public static boolean shouldPatch(Features.Type feature) {
return switch (feature) { return switch (feature) {
case AB_MULTI_GIFTS, AB_NEWS_VIDEO_LAYOUT_TEXT, AB_STICKERS_DISCOVER, AB_GIFTS_FROM_KEYBOARD, EXPERIMENT_NEWS_VIDEO_LAYOUT_TEXT, FEATURE_DISCOVER_CATEGORIES, FEATURE_FAVE_PERF_IMPROVE, FEATURE_GROUP_ADMIN_MESSAGES, FEATURE_GROUP_MSG_PUSH_PARAM, FEATURE_IMAGE_QUALITY_UPGRADE, FEATURE_IM_AUDIO_MSG_TRANSCRIPT, FEATURE_IM_CASPER_MSGS, FEATURE_IM_DISABLE_FORCE_OPEN_VK_ME, FEATURE_IM_GIF_AUTOPLAY, FEATURE_IM_MR_IN_VKAPP, FEATURE_MEMORIES_ENABLED, FEATURE_MENU_GAMES_CAROUSEL, FEATURE_MILKSHAKE, FEATURE_MILKSHAKE_NEWS_SCROLL_ON_BACK, FEATURE_MILKSHAKE_SWITCH_THEME_ON_TAP, FEATURE_ML_BRANDS, FEATURE_ML_FEATURES, FEATURE_ML_MODELS_LOADING, FEATURE_MONEY_TRANSFERS_VKPAY, FEATURE_MUSIC_ARTIST_CATALOG, FEATURE_MUSIC_NEW_CATALOG, FEATURE_NARRATIVE_SNIPPET_TYPE, FEATURE_NEWS_GAMES_IN_DISCOVER, FEATURE_NEWS_HEADER_SCROLL, FEATURE_NEW_FORMAT_SHOW_WPB, FEATURE_PODCASTS_PAGE, FEATURE_QR_CREATE_QR, FEATURE_QR_DYNAMIC_FRAME, FEATURE_QR_SCAN_FROM_PHOTO, FEATURE_QR_VISION_DECODER, FEATURE_QUEUE_COUNTERS, FEATURE_REEF, FEATURE_ROAMING_AUTOPLAY, FEATURE_SHARE_MSGS_ON_INVITE, FEATURE_STICKERS_BOT_LINK, FEATURE_STICKERS_NEW_CATALOG, FEATURE_STORIES_AVATAR, FEATURE_STORIES_FEED_TYPE, FEATURE_STORIES_SHOW_ALWAYS, FEATURE_STORY_ANSWER_PUBLIC, FEATURE_STORY_APP_STICKER, FEATURE_STORY_ARCHIVE, FEATURE_STORY_ARCHIVE_POST, FEATURE_STORY_BAKGROUND_ALL, FEATURE_STORY_BOX, FEATURE_STORY_CADRE, FEATURE_STORY_CAMERA_TOOLTIP, FEATURE_STORY_EDITOR_GALLERY, FEATURE_STORY_EDITOR_TYPE, FEATURE_STORY_ENDLESS_VIDEO, FEATURE_STORY_FAST_REACTIONS, FEATURE_STORY_GIF, FEATURE_STORY_GROUPED, FEATURE_STORY_HIGH_QUALITY, FEATURE_STORY_MASKS_FRONTAL, FEATURE_STORY_MENTION_ICON, FEATURE_STORY_MODERN_PUBLISH, FEATURE_STORY_MUSIC_EDITOR, FEATURE_STORY_MUSIC_REPLIES, FEATURE_STORY_MUSIC_REPLIES_2, FEATURE_STORY_NEW_FRAME, FEATURE_STORY_ONE_TIME, FEATURE_STORY_PHOTO_SHARING, FEATURE_STORY_PHOTO_STICKER, FEATURE_STORY_POLLS, FEATURE_STORY_POST_REPOST, FEATURE_STORY_PRELOADING, FEATURE_STORY_QUESTION, FEATURE_STORY_QUESTION_STYLE, FEATURE_STORY_RLOTTIE, FEATURE_STORY_RLOTTIE_CACHE, FEATURE_STORY_SAVE_DEFAULT_ON, FEATURE_STORY_SEND_DIALOG_LIST, FEATURE_STORY_STICKER_PACK, FEATURE_STORY_TIME, FEATURE_STORY_VIEWER_CAMERA, FEATURE_STORY_VOICE_ANSWER, FEATURE_STORY_WITH_CONTEXT, FEATURE_SUPERAPP_MENU, FEATURE_TRAFFIC_SAVER, FEATURE_VKPAY_WIDGET, FEATURE_VKUI_INTERNAL_TO_MINI_APPS, FEATURE_VKUI_TOKEN_CACHE, FEATURE_VK_APPS_SEARCH, FEATURE_VOTES_BALANCE, FEATURE_WEBVIEW_TOKEN_ACTIVE, FEATURE_MILKSHAKE_FORCE_DISABLED, FEATURE_MILKSHAKE_ACTIVATION_DISABLED, EXPERIMENT_NEWS_DISABLE_CACHE -> case AB_IM_LONGPOLL_MSG_BATCHING, AB_IM_VIEW_POOL, AB_MULTI_GIFTS, AB_NEWS_VIDEO_LAYOUT_TEXT, AB_STICKERS_DISCOVER, AB_GIFTS_FROM_KEYBOARD, EXPERIMENT_NEWS_VIDEO_LAYOUT_TEXT, FEATURE_DISCOVER_CATEGORIES, FEATURE_FAVE_PERF_IMPROVE, FEATURE_GROUP_ADMIN_MESSAGES, FEATURE_GROUP_MSG_PUSH_PARAM, FEATURE_IMAGE_QUALITY_UPGRADE, FEATURE_IM_AUDIO_MSG_TRANSCRIPT, FEATURE_IM_CASPER_MSGS, FEATURE_IM_DISABLE_FORCE_OPEN_VK_ME, FEATURE_IM_GIF_AUTOPLAY, FEATURE_IM_MR_IN_VKAPP, FEATURE_MEMORIES_ENABLED, FEATURE_MENU_GAMES_CAROUSEL, FEATURE_MILKSHAKE, FEATURE_MILKSHAKE_NEWS_SCROLL_ON_BACK, FEATURE_MILKSHAKE_SWITCH_THEME_ON_TAP, FEATURE_ML_BRANDS, FEATURE_ML_FEATURES, FEATURE_ML_MODELS_LOADING, FEATURE_MONEY_TRANSFERS_VKPAY, FEATURE_MUSIC_ARTIST_CATALOG, FEATURE_MUSIC_NEW_CATALOG, FEATURE_NARRATIVE_SNIPPET_TYPE, FEATURE_NEWS_GAMES_IN_DISCOVER, FEATURE_NEWS_HEADER_SCROLL, FEATURE_NEW_FORMAT_SHOW_WPB, FEATURE_PODCASTS_PAGE, FEATURE_QR_CREATE_QR, FEATURE_QR_DYNAMIC_FRAME, FEATURE_QR_SCAN_FROM_PHOTO, FEATURE_QR_VISION_DECODER, FEATURE_QUEUE_COUNTERS, FEATURE_REEF, FEATURE_ROAMING_AUTOPLAY, FEATURE_SHARE_MSGS_ON_INVITE, FEATURE_STICKERS_BOT_LINK, FEATURE_STICKERS_NEW_CATALOG, FEATURE_STORIES_AVATAR, FEATURE_STORIES_FEED_TYPE, FEATURE_STORIES_SHOW_ALWAYS, FEATURE_STORY_ANSWER_PUBLIC, FEATURE_STORY_APP_STICKER, FEATURE_STORY_ARCHIVE, FEATURE_STORY_ARCHIVE_POST, FEATURE_STORY_BAKGROUND_ALL, FEATURE_STORY_BOX, FEATURE_STORY_CADRE, FEATURE_STORY_CAMERA_TOOLTIP, FEATURE_STORY_EDITOR_GALLERY, FEATURE_STORY_EDITOR_TYPE, FEATURE_STORY_ENDLESS_VIDEO, FEATURE_STORY_FAST_REACTIONS, FEATURE_STORY_GIF, FEATURE_STORY_GROUPED, FEATURE_STORY_HIGH_QUALITY, FEATURE_STORY_MASKS_FRONTAL, FEATURE_STORY_MENTION_ICON, FEATURE_STORY_MODERN_PUBLISH, FEATURE_STORY_MUSIC_EDITOR, FEATURE_STORY_MUSIC_REPLIES, FEATURE_STORY_MUSIC_REPLIES_2, FEATURE_STORY_NEW_FRAME, FEATURE_STORY_ONE_TIME, FEATURE_STORY_PHOTO_SHARING, FEATURE_STORY_PHOTO_STICKER, FEATURE_STORY_POLLS, FEATURE_STORY_POST_REPOST, FEATURE_STORY_PRELOADING, FEATURE_STORY_QUESTION, FEATURE_STORY_QUESTION_STYLE, FEATURE_STORY_RLOTTIE, FEATURE_STORY_RLOTTIE_CACHE, FEATURE_STORY_SAVE_DEFAULT_ON, FEATURE_STORY_SEND_DIALOG_LIST, FEATURE_STORY_STICKER_PACK, FEATURE_STORY_TIME, FEATURE_STORY_VIEWER_CAMERA, FEATURE_STORY_VOICE_ANSWER, FEATURE_STORY_WITH_CONTEXT, FEATURE_SUPERAPP_MENU, FEATURE_TRAFFIC_SAVER, FEATURE_VKPAY_WIDGET, FEATURE_VKUI_INTERNAL_TO_MINI_APPS, FEATURE_VKUI_TOKEN_CACHE, FEATURE_VK_APPS_SEARCH, FEATURE_VOTES_BALANCE, FEATURE_WEBVIEW_TOKEN_ACTIVE, FEATURE_MILKSHAKE_FORCE_DISABLED, FEATURE_MILKSHAKE_ACTIVATION_DISABLED, EXPERIMENT_NEWS_DISABLE_CACHE ->
true; true;
default -> false; default ->
false;
}; };
} }
@@ -26,6 +28,7 @@ public class TogglesHook {
case FEATURE_IMAGE_QUALITY_UPGRADE -> !MediaImageEncoder.needToCompress(); case FEATURE_IMAGE_QUALITY_UPGRADE -> !MediaImageEncoder.needToCompress();
case FEATURE_MENU_GAMES_CAROUSEL -> miniapps(); case FEATURE_MENU_GAMES_CAROUSEL -> miniapps();
case FEATURE_TRAFFIC_SAVER -> !disableForceTrafficSaver(); case FEATURE_TRAFFIC_SAVER -> !disableForceTrafficSaver();
case AB_IM_LONGPOLL_MSG_BATCHING, AB_IM_VIEW_POOL -> Preferences.getBoolValue("batchmessages", false);
default -> true; default -> true;
}; };
} }
@@ -24,9 +24,7 @@ public class VKUIHook {
private static void applyVKUIStyles(WebView webView) { private static void applyVKUIStyles(WebView webView) {
if (getBoolValue("VKUI_INJ", true) && webView != null && webView.getUrl() != null && !webView.getUrl().contains("static.vk.com/memories")) { if (getBoolValue("VKUI_INJ", true) && webView != null && webView.getUrl() != null && !webView.getUrl().contains("static.vk.com/memories")) {
if (!WebViewColoringUtils.isLoaded) {
WebViewColoringUtils.load(); WebViewColoringUtils.load();
}
loadAndApplyCSS(webView); loadAndApplyCSS(webView);
} }
} }
@@ -9,6 +9,7 @@ import com.vk.music.common.MusicPlaybackLaunchContext;
import com.vtosters.lite.R; import com.vtosters.lite.R;
import ru.vtosters.lite.downloaders.AudioDownloader; import ru.vtosters.lite.downloaders.AudioDownloader;
import ru.vtosters.lite.music.cache.MusicCacheImpl; import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.music.cache.delegate.PlaylistCacheDbDelegate;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.music.VKXUtils; import ru.vtosters.lite.utils.music.VKXUtils;
@@ -19,18 +20,29 @@ import static ru.vtosters.hooks.other.Preferences.milkshake;
import static ru.vtosters.lite.utils.NetworkUtils.isNetworkConnected; import static ru.vtosters.lite.utils.NetworkUtils.isNetworkConnected;
public class MusicBottomSheetHook { public class MusicBottomSheetHook {
public static ArrayList<MusicAction> hook(final ArrayList<MusicAction> actions, final MusicTrack musicTrack) { public static ArrayList<MusicAction> hook(ArrayList<MusicAction> actions, MusicTrack musicTrack) {
if (musicTrack.F1()) return actions; if (musicTrack.F1()) return actions;
final var trackId = asId(musicTrack);
String trackId = asId(musicTrack);
if (isVkxInstalled()) actions.add(getPlayInVKXAction()); if (isVkxInstalled()) actions.add(getPlayInVKXAction());
if (isIntegrationEnabled()) { if (isIntegrationEnabled()) {
if (VKXUtils.isVkxCached(trackId)) actions.add(getRemoveCacheTrackVkxAction()); if (VKXUtils.isVkxCached(trackId)) {
else if (isNetworkConnected()) actions.add(addToCacheTrackVkxAction()); actions.add(getRemoveCacheTrackVkxAction());
} else { } else if (isNetworkConnected()) {
if (MusicCacheImpl.isCachedTrack(trackId)) actions.add(getRemoveCacheTrackAction()); actions.add(addToCacheTrackVkxAction());
else if (isNetworkConnected()) actions.add(addToCacheTrackAction());
} }
} else {
if (MusicCacheImpl.isCachedTrack(trackId)) {
actions.add(getRemoveCacheTrackAction());
} else if (isNetworkConnected()) {
actions.add(addToCacheTrackAction());
}
}
if (isNetworkConnected()) actions.add(downloadAsMp3Action()); if (isNetworkConnected()) actions.add(downloadAsMp3Action());
return actions; return actions;
} }
@@ -72,9 +84,13 @@ public class MusicBottomSheetHook {
} else if (isNetworkConnected()) { } else if (isNetworkConnected()) {
actions.add(addToCacheTrackVkxAction()); actions.add(addToCacheTrackVkxAction());
} }
} else {
if (PlaylistCacheDbDelegate.isCachedPlaylist(AndroidUtils.getGlobalContext(), playlist.v1())) {
actions.add(getRemoveCacheTrackAction());
} else if (isNetworkConnected()) { } else if (isNetworkConnected()) {
actions.add(addToCacheTrackAction()); actions.add(addToCacheTrackAction());
} }
}
if (isNetworkConnected()) actions.add(downloadAsMp3Action()); if (isNetworkConnected()) actions.add(downloadAsMp3Action());
@@ -134,10 +150,14 @@ public class MusicBottomSheetHook {
} }
public static boolean injectOnClick(int actionId, Playlist playlist) { // playlist inj public static boolean injectOnClick(int actionId, Playlist playlist) { // playlist inj
if (actionId == R.id.play_in_vkx) if (actionId == R.id.play_in_vkx) {
return tryPlayInVKX(null, null, playlist); return tryPlayInVKX(null, null, playlist);
}
if (actionId == R.id.add_to_cache) { if (actionId == R.id.remove_from_cache) {
PlaylistCacheDbDelegate.deletePlaylist(AndroidUtils.getGlobalContext(), playlist.v1());
return true;
} else if (actionId == R.id.add_to_cache) {
AudioDownloader.cachePlaylist(playlist); AudioDownloader.cachePlaylist(playlist);
return true; return true;
} }
@@ -147,7 +167,7 @@ public class MusicBottomSheetHook {
try { try {
service.deletePlaylistFromCache(playlist.a, playlist.b); service.deletePlaylistFromCache(playlist.a, playlist.b);
} catch (RemoteException e) { } catch (RemoteException e) {
e.printStackTrace(); e.fillInStackTrace();
} }
}); });
return true; return true;
@@ -156,7 +176,7 @@ public class MusicBottomSheetHook {
try { try {
service.addPlaylistToCache(playlist.a, playlist.b, (playlist.Q != null) ? playlist.Q : ""); service.addPlaylistToCache(playlist.a, playlist.b, (playlist.Q != null) ? playlist.Q : "");
} catch (RemoteException e) { } catch (RemoteException e) {
e.printStackTrace(); e.fillInStackTrace();
} }
}); });
return true; return true;
@@ -168,7 +188,7 @@ public class MusicBottomSheetHook {
try { try {
service.downloadPlaylist(playlist.a, playlist.b, (playlist.Q != null) ? playlist.Q : ""); service.downloadPlaylist(playlist.a, playlist.b, (playlist.Q != null) ? playlist.Q : "");
} catch (RemoteException e) { } catch (RemoteException e) {
e.printStackTrace(); e.fillInStackTrace();
} }
}); });
} else { } else {
@@ -4,13 +4,13 @@ import android.util.Log;
import bruhcollective.itaysonlab.libvkx.client.LibVKXClient; import bruhcollective.itaysonlab.libvkx.client.LibVKXClient;
import com.vk.core.network.Network; import com.vk.core.network.Network;
import com.vk.core.util.DeviceIdProvider; import com.vk.core.util.DeviceIdProvider;
import okhttp3.Headers;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences; import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.music.cache.helpers.PlaylistHelper;
import ru.vtosters.lite.music.cache.MusicCacheImpl; import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.utils.AccountManagerUtils; import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
@@ -41,9 +41,15 @@ public class CatalogJsonInjector {
removeUnsupportedLayouts(blocks); removeUnsupportedLayouts(blocks);
if (Preferences.getBoolValue("playlistsCatalogs", true)) {
fetchCatalogId("https://vk.com/audio?section=my_playlists", oldItems); fetchCatalogId("https://vk.com/audio?section=my_playlists", oldItems);
fetchCatalogId("https://vk.com/audio?section=albums", oldItems); fetchCatalogId("https://vk.com/audio?section=albums", oldItems);
}
if (Preferences.sendMusicMetrics() && Preferences.getBoolValue("playStatCatalog", false)) {
fetchCatalogId("https://vk.com/audio?section=recent", oldItems);
}
setDefaultAudioPage(oldItems, catalog); setDefaultAudioPage(oldItems, catalog);
} }
@@ -52,18 +58,16 @@ public class CatalogJsonInjector {
var noPlaylists = !json.has("playlists"); var noPlaylists = !json.has("playlists");
if (noPlaylists) { if (noPlaylists) {
json.put("playlists", new JSONArray().put(getPlaylist())); PlaylistHelper.addCachedPlaylists(new JSONArray());
Log.d("catalogInjector", "added new pl");
} else { } else {
json.optJSONArray("playlists").put(getPlaylist()); PlaylistHelper.addCachedPlaylists(json.optJSONArray("playlists"));
Log.d("catalogInjector", "added to exist pl");
} }
if (!useOldAppVer || noPlaylists) { if (!useOldAppVer || noPlaylists) {
var newBlocks = new JSONArray(); var newBlocks = new JSONArray();
newBlocks newBlocks
.put(getCatalogHeader()) .put(getCatalogHeader("Кешированные плейлисты"))
.put(getCatalogPlaylist()) .put(getCatalogPlaylist())
.put(getCatalogSeparator()); .put(getCatalogSeparator());
@@ -99,22 +103,16 @@ public class CatalogJsonInjector {
var noPlaylists = !json.has("playlists"); var noPlaylists = !json.has("playlists");
if (noPlaylists) { if (noPlaylists) {
json.put("playlists", new JSONArray().put(getPlaylist())); PlaylistHelper.addCachedPlaylists(new JSONArray());
Log.d("catalogInjector", "added new pl");
} else { } else {
try { PlaylistHelper.addCachedPlaylists(json.optJSONArray("playlists"));
json.optJSONArray("playlists").put(getPlaylist());
Log.d("catalogInjector", "added to exist pl");
} catch (Exception e) {
Log.d("catalogInjector", e.toString());
}
} }
if (!useOldAppVer && !noPlaylists) { if (!useOldAppVer && !noPlaylists) {
var newBlocks = new JSONArray(); var newBlocks = new JSONArray();
newBlocks newBlocks
.put(getCatalogHeader()) .put(getCatalogHeader("Кешированные плейлисты"))
.put(getCatalogPlaylist()) .put(getCatalogPlaylist())
.put(getCatalogSeparator()); .put(getCatalogSeparator());
@@ -132,12 +130,15 @@ public class CatalogJsonInjector {
if (type.equals("music_playlists") && j.has("playlists_ids")) { if (type.equals("music_playlists") && j.has("playlists_ids")) {
var newarr = new JSONArray(); var newarr = new JSONArray();
var playlists_ids = j.optJSONArray("playlists_ids"); var playlists_ids = j.getJSONArray("playlists_ids");
var savedPlaylists = PlaylistHelper.getCachedPlaylistsIds();
newarr.put(getUserId() + "_-1"); for (int n = 0; n < savedPlaylists.length(); n++) {
newarr.put(savedPlaylists.getString(n));
}
for (int n = 0; n < playlists_ids.length(); n++) { for (int n = 0; n < playlists_ids.length(); n++) {
newarr.put(playlists_ids.optString(n)); newarr.put(playlists_ids.getString(n));
} }
Log.d("catalogInjector", "added to pl ids"); Log.d("catalogInjector", "added to pl ids");
@@ -219,24 +220,35 @@ public class CatalogJsonInjector {
} }
} }
private static void removeUnsupportedLayouts(JSONArray blocks) throws JSONException { private static void removeUnsupportedLayouts(JSONArray blocks) {
for (int i = 0; i < blocks.length(); i++) { for (int i = blocks.length() - 1; i >= 0; i--) {
var block = blocks.optJSONObject(i); JSONObject block = blocks.optJSONObject(i);
var layout = block.optJSONObject("layout"); if (block == null) continue;
var data_type = block.optString("data_type");
if (Objects.equals(data_type, "music_recommended_playlists")) { JSONObject layout = block.optJSONObject("layout");
if (layout == null) continue;
String data_type = block.optString("data_type");
if (Objects.equals(data_type, "music_recommended_playlists") || Objects.equals(data_type, "radiostations")) {
blocks.remove(i); // block
if (i - 1 >= 0) blocks.remove(i - 1); // text
if (i - 2 >= 0) blocks.remove(i - 2); // divider
continue; // Skip to the next iteration after removing
}
String name = layout.optString("name");
if (!name.equals("header_extended")) {
continue; // Skip to the next iteration if not header_extended
}
if (layout.has("top_title")) {
blocks.remove(i); blocks.remove(i);
blocks.remove(i - 1);
blocks.remove(i - 2);
} }
try {
if (layout != null) {
var name = layout.optString("name");
if (name.equals("header_extended")) {
if (layout.has("top_title")) blocks.remove(i);
layout.put("name", "header"); layout.put("name", "header");
} } catch (JSONException e) {
e.fillInStackTrace();
} }
} }
} }
@@ -273,7 +285,9 @@ public class CatalogJsonInjector {
+ "&access_token=" + "&access_token="
+ AccountManagerUtils.getUserToken()) + AccountManagerUtils.getUserToken())
.a("Accept-Encoding", "gzip") .a("Accept-Encoding", "gzip")
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8")).a(); .a("User-Agent", Network.l.c().a())
.a("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
.a();
try (Response resp = Network.b(CLIENT_API).a(request).execute()) { try (Response resp = Network.b(CLIENT_API).a(request).execute()) {
var json = new JSONObject(GzipDecompressor.decompressResponse(resp)).getJSONObject("response"); var json = new JSONObject(GzipDecompressor.decompressResponse(resp)).getJSONObject("response");
var catalogarr = json.optJSONObject("catalog").optJSONArray("sections").optJSONObject(0); var catalogarr = json.optJSONObject("catalog").optJSONArray("sections").optJSONObject(0);
@@ -15,11 +15,16 @@ import ru.vtosters.lite.downloaders.AudioDownloader;
import ru.vtosters.lite.music.cache.MusicCacheImpl; import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.music.cache.helpers.PlaylistHelper; import ru.vtosters.lite.music.cache.helpers.PlaylistHelper;
import ru.vtosters.lite.music.cache.helpers.TracklistHelper; import ru.vtosters.lite.music.cache.helpers.TracklistHelper;
import ru.vtosters.lite.utils.AccountManagerUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class PlaylistInjector { public class PlaylistInjector {
private static final ExecutorService executor = Executors.newCachedThreadPool();
public final static String CHANNEL_NAME = "VTCH"; public final static String CHANNEL_NAME = "VTCH";
public static void injectDownloadPlaylist(Playlist playlist) { public static void injectDownloadPlaylist(Playlist playlist) {
@@ -32,8 +37,10 @@ public class PlaylistInjector {
public static Observable<AudioGetPlaylist.c> injectGetPlaylist(AudioGetPlaylist audioGetPlaylist) { public static Observable<AudioGetPlaylist.c> injectGetPlaylist(AudioGetPlaylist audioGetPlaylist) {
try { try {
if (!eligibleForOfflineCaching()) if (MusicCacheImpl.isEmpty()) {
return null; return null;
}
var requestArgs = audioGetPlaylist.b(); var requestArgs = audioGetPlaylist.b();
var id = requestArgs.get("id"); var id = requestArgs.get("id");
@@ -41,11 +48,11 @@ public class PlaylistInjector {
var accessKey = requestArgs.get("access_key"); var accessKey = requestArgs.get("access_key");
boolean isVirtualPlaylist = accessKey != null && (accessKey.equals("cache")); boolean isVirtualPlaylist = accessKey != null && (accessKey.equals("cache"));
boolean isAlbumVirtualPlaylist = accessKey != null && (accessKey.equals("cacheAlbum")); boolean isAlbumVirtualPlaylist = accessKey != null && (accessKey.equals("cacheAlbum"));
boolean isOwnCachePlaylist = Objects.equals(ownerId, String.valueOf(AccountManagerUtils.getUserId())) && Objects.equals(id, "-1");
Log.d("PlaylistInjector", "id = " + id + " / owner = " + ownerId + " / access = " + accessKey + " / " + isVirtualPlaylist + " + " + isAlbumVirtualPlaylist); if (TextUtils.isEmpty(id) || (!isVirtualPlaylist && !isAlbumVirtualPlaylist)) {
if (TextUtils.isEmpty(id) || (!isVirtualPlaylist && !isAlbumVirtualPlaylist))
return null; return null;
}
return Observable.a((ObservableOnSubscribe<AudioGetPlaylist.c>) observableEmitter -> { return Observable.a((ObservableOnSubscribe<AudioGetPlaylist.c>) observableEmitter -> {
AudioGetPlaylist.c response = new AudioGetPlaylist.c(); AudioGetPlaylist.c response = new AudioGetPlaylist.c();
@@ -70,7 +77,7 @@ public class PlaylistInjector {
response.c = tracks; response.c = tracks;
} catch (RemoteException | JSONException e) { } catch (RemoteException | JSONException e) {
e.printStackTrace(); e.fillInStackTrace();
response.c = new ArrayList<>(); response.c = new ArrayList<>();
} }
observableEmitter.b(response); observableEmitter.b(response);
@@ -79,18 +86,18 @@ public class PlaylistInjector {
return; return;
} }
if (isVirtualPlaylist) { if (isOwnCachePlaylist) {
response.c = (ArrayList<MusicTrack>) TracklistHelper.getMyCachedMusicTracks(); response.c = (ArrayList<MusicTrack>) TracklistHelper.getMyCachedMusicTracks();
response.b = PlaylistHelper.createCachedPlaylistMetadata(); response.b = PlaylistHelper.createCachedPlaylistMetadata();
} else { } else {
response.c = (ArrayList<MusicTrack>) TracklistHelper.getTracks(requestArgs.get("owner_id")); response.c = (ArrayList<MusicTrack>) MusicCacheImpl.getPlaylistSongs(ownerId, id);
response.b = PlaylistHelper.createCachedPlaylistMetadata(requestArgs.get("owner_id")); response.b = MusicCacheImpl.getPlaylist(id, ownerId);
} }
observableEmitter.b(response); observableEmitter.b(response);
}); });
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.fillInStackTrace();
} }
return null; return null;
} }
@@ -12,6 +12,7 @@ import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import ru.vtosters.lite.music.cache.MusicCacheImpl; import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.music.cache.delegate.PlaylistCacheDbDelegate;
import ru.vtosters.lite.music.cache.helpers.PlaylistHelper; import ru.vtosters.lite.music.cache.helpers.PlaylistHelper;
import ru.vtosters.lite.music.cache.helpers.TracklistHelper; import ru.vtosters.lite.music.cache.helpers.TracklistHelper;
import ru.vtosters.lite.utils.AccountManagerUtils; import ru.vtosters.lite.utils.AccountManagerUtils;
@@ -22,6 +23,8 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import static ru.vtosters.lite.music.cache.helpers.PlaylistHelper.*;
public class TracklistInjector { public class TracklistInjector {
public static boolean eligibleForOfflineCaching() { public static boolean eligibleForOfflineCaching() {
@@ -39,7 +42,7 @@ public class TracklistInjector {
Log.d("TracklistInjector", "Using vkx cache catalog"); Log.d("TracklistInjector", "Using vkx cache catalog");
observableEmitter.b(parser.c(new JSONObject(service.getCacheCatalog()))); observableEmitter.b(parser.c(new JSONObject(service.getCacheCatalog())));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.fillInStackTrace();
List<MusicTrack> tracks = new ArrayList<>(); List<MusicTrack> tracks = new ArrayList<>();
List<String> cache = service.getCache(); List<String> cache = service.getCache();
@@ -52,14 +55,14 @@ public class TracklistInjector {
observableEmitter.b(parser.c(createVirtualCatalog(tracks))); observableEmitter.b(parser.c(createVirtualCatalog(tracks)));
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.fillInStackTrace();
} }
}); });
} else { } else {
if (MusicCacheImpl.isEmpty()) { if (MusicCacheImpl.isEmpty()) {
observableEmitter.b(parser.c(getEmptyCatalog())); observableEmitter.b(parser.c(getEmptyCatalog()));
} else { } else {
observableEmitter.b(parser.c(createVirtualCatalog(TracklistHelper.getTracks()))); observableEmitter.b(parser.c(createVirtualCatalog(TracklistHelper.getMyCachedMusicTracks())));
} }
} }
}); });
@@ -162,16 +165,12 @@ public class TracklistInjector {
boolean noPlaylists = hasNoPlaylists(blocks); boolean noPlaylists = hasNoPlaylists(blocks);
if (noPlaylists) { if (noPlaylists) {
catalogNode.put("playlists", new JSONArray().put(PlaylistHelper.getPlaylist())); PlaylistHelper.addCachedPlaylists(new JSONArray());
JSONArray newBlocks = createNewBlocks(blocks); firstSection.put("blocks", createNewBlocks(blocks));
Log.d("catalogInjector", "added cache catalog playlist");
firstSection.put("blocks", newBlocks);
} else { } else {
try { try {
catalogNode.optJSONArray("playlists").put(PlaylistHelper.getPlaylist()); PlaylistHelper.addCachedPlaylists(catalogNode.optJSONArray("playlists"));
updatePlaylistsIds(blocks); updatePlaylistsIds(blocks);
} catch (Exception e) { } catch (Exception e) {
@@ -188,7 +187,7 @@ public class TracklistInjector {
return firstSection.getString("url").equals("https://vk.com/audios" + AccountManagerUtils.getUserId() + "?section=all"); return firstSection.getString("url").equals("https://vk.com/audios" + AccountManagerUtils.getUserId() + "?section=all");
} }
private static boolean hasNoPlaylists(JSONArray blocks) throws JSONException { private static boolean hasNoPlaylists(JSONArray blocks) {
return blocks.optJSONObject(0).optJSONArray("buttons").optJSONObject(0).optJSONObject("action").optString("type").equals("create_playlist"); return blocks.optJSONObject(0).optJSONArray("buttons").optJSONObject(0).optJSONObject("action").optString("type").equals("create_playlist");
} }
@@ -196,13 +195,14 @@ public class TracklistInjector {
JSONArray newBlocks = new JSONArray(); JSONArray newBlocks = new JSONArray();
newBlocks newBlocks
.put(PlaylistHelper.getCatalogHeader()) .put(PlaylistHelper.getCatalogHeader(AndroidUtils.getString(R.string.cached_tracks_title)))
.put(PlaylistHelper.getCatalogPlaylist()) .put(PlaylistHelper.getCatalogPlaylist())
.put(PlaylistHelper.getCatalogSeparator()); .put(PlaylistHelper.getCatalogSeparator());
for (int i = 0; i < blocks.length(); i++) { for (int i = 0; i < blocks.length(); i++) {
newBlocks.put(blocks.optJSONObject(i)); newBlocks.put(blocks.optJSONObject(i));
} }
return newBlocks; return newBlocks;
} }
@@ -212,16 +212,15 @@ public class TracklistInjector {
String type = j.optString("data_type"); String type = j.optString("data_type");
if (type.equals("music_playlists") && j.has("playlists_ids")) { if (type.equals("music_playlists") && j.has("playlists_ids")) {
JSONArray newarr = new JSONArray(); JSONArray newarr = PlaylistHelper.getCachedPlaylistsIds();
JSONArray playlists_ids = j.optJSONArray("playlists_ids"); JSONArray playlists_ids = j.optJSONArray("playlists_ids");
newarr.put(AccountManagerUtils.getUserId() + "_-1");
for (int n = 0; n < playlists_ids.length(); n++) { for (int n = 0; n < playlists_ids.length(); n++) {
newarr.put(playlists_ids.optString(n)); newarr.put(playlists_ids.optString(n));
} }
j.put("playlists_ids", newarr); j.put("playlists_ids", newarr);
break; break;
} }
} }
@@ -240,7 +239,19 @@ public class TracklistInjector {
audiosBlock.put("layout", layout); audiosBlock.put("layout", layout);
var blocks = new JSONArray().put(getShuffleButton()).put(audiosBlock); var blocks = new JSONArray();
if (MusicCacheImpl.hasPlaylist()) {
blocks.put(getCatalogHeader("Кешированные плейлисты"))
.put(getCatalogPlaylist());
}
if (!PlaylistCacheDbDelegate.isPlaylistEmpty(AndroidUtils.getGlobalContext(), AccountManagerUtils.getUserId() + "_-1")) {
if (MusicCacheImpl.hasPlaylist()) blocks.put(getCatalogSeparator());
blocks.put(getCatalogHeader(AndroidUtils.getString(R.string.cached_tracks_title)))
.put(getShuffleButton())
.put(audiosBlock);
}
var randomId = getRandomId(); var randomId = getRandomId();
@@ -259,6 +270,7 @@ public class TracklistInjector {
return new JSONObject() return new JSONObject()
.put("catalog", catalog) .put("catalog", catalog)
.put("playlists", addCachedPlaylists(new JSONArray()))
.put("audios", TracklistHelper.tracksToJsons(tracks)); .put("audios", TracklistHelper.tracksToJsons(tracks));
} }
@@ -100,8 +100,8 @@ public class Preferences {
return getBoolValue("vkme", false); return getBoolValue("vkme", false);
} }
public static boolean autocache() { public static int autocache() {
return getBoolValue("autocache", false); return Preferences.getPreferences().getInt("autocaching", 0);
} }
public static boolean adsstories() { public static boolean adsstories() {
@@ -292,6 +292,10 @@ public class Preferences {
return getBoolValue("vkme_notifs", false); return getBoolValue("vkme_notifs", false);
} }
public static boolean sendMusicMetrics() {
return getBoolValue("sendMusicMetrics", true);
}
public static boolean screenshotdetect() { public static boolean screenshotdetect() {
return getBoolValue("screenshotdetect", true); return getBoolValue("screenshotdetect", true);
} }
@@ -24,6 +24,8 @@ import com.vk.core.drawable.RecoloredDrawable;
import com.vk.core.ui.themes.MilkshakeHelper; import com.vk.core.ui.themes.MilkshakeHelper;
import com.vk.core.ui.themes.VKTheme; import com.vk.core.ui.themes.VKTheme;
import com.vk.core.ui.themes.VKThemeHelper; import com.vk.core.ui.themes.VKThemeHelper;
import com.vk.im.engine.models.dialogs.DialogTheme;
import com.vk.im.ui.themes.DefaultThemeProvider;
import com.vtosters.lite.R; import com.vtosters.lite.R;
import com.vtosters.lite.data.ThemeTracker; import com.vtosters.lite.data.ThemeTracker;
import ru.vtosters.lite.deviceinfo.OEMDetector; import ru.vtosters.lite.deviceinfo.OEMDetector;
@@ -31,9 +33,7 @@ import ru.vtosters.lite.themes.ThemesCore;
import ru.vtosters.lite.themes.ThemesHacks; import ru.vtosters.lite.themes.ThemesHacks;
import ru.vtosters.lite.themes.ThemesManager; import ru.vtosters.lite.themes.ThemesManager;
import ru.vtosters.lite.ui.wallpapers.WallpapersHooks; import ru.vtosters.lite.ui.wallpapers.WallpapersHooks;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.LifecycleUtils; import ru.vtosters.lite.utils.LifecycleUtils;
import ru.vtosters.lite.utils.WebViewColoringUtils;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@@ -45,7 +45,7 @@ public class ThemesUtils {
try { try {
setTheme(theme, LifecycleUtils.getCurrentActivity(), restartActivity); setTheme(theme, LifecycleUtils.getCurrentActivity(), restartActivity);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.fillInStackTrace();
} }
} // Apply VKTheme and ImTheme (hard applying without dynamic theme changing) } // Apply VKTheme and ImTheme (hard applying without dynamic theme changing)
@@ -62,14 +62,27 @@ public class ThemesUtils {
activity = LifecycleUtils.getCurrentActivity(); activity = LifecycleUtils.getCurrentActivity();
} }
VKThemeHelper.theme(theme, activity, fl); VKThemeHelper.theme(theme, activity, fl);
if (isMonetTheme() || ThemesManager.canApplyCustomAccent()) ThemesCore.clear(); if (isMonetTheme() || ThemesManager.canApplyCustomAccent()) {
if (restartActivity) activity.recreate(); ThemesCore.clear();
ThemesCore.init();
DialogTheme.d.a(new DefaultThemeProvider(VKThemeHelper.k).b()); // reset dialog attrs cache
}
ThemeTracker.a(); ThemeTracker.a();
WebViewColoringUtils.isLoaded = false; if (restartActivity) {
activity.recreate();
}
new WebView(activity).clearCache(true); new WebView(activity).clearCache(true);
WebCachePreloader.e(); WebCachePreloader.e();
} }
public static DialogTheme getDialogTheme() {
if (isMonetTheme()) {
return new DefaultThemeProvider(VKThemeHelper.k).b(); // get directly from theme cuz monet issue
} else {
return DialogTheme.d.a(); // get cached theme
}
}
public static boolean isDarkTheme() { public static boolean isDarkTheme() {
return VKThemeHelper.r(); return VKThemeHelper.r();
} }
@@ -115,7 +115,7 @@ public class Device {
+ "- Manufacturer: " + this.manufacturerName + "\n" + "- Manufacturer: " + this.manufacturerName + "\n"
+ "- Brand: " + this.brandName + "\n" + "- Brand: " + this.brandName + "\n"
+ "- Model: " + this.modelName + "\n" + "- Model: " + this.modelName + "\n"
+ (isMIUI() ? "- Miui Version Code: " + this.MiuiUiVersionCode + "\n" + "- Miui Version Name: " + this.MiuiUiVersionName + "\n" : "") + (isMIUI() || isHyperOs() ? "- Miui/HyperOS Version Code: " + this.MiuiUiVersionCode + "\n" + "- Miui/HyperOS Version Name: " + this.MiuiUiVersionName + "\n" : "")
+ (isSamsung() ? "- OneUi Major Version: " + this.OneUiMajorVersion + "\n" + "- OneUi Minor Version: " + this.OneUiMinorVersion + "\n" : "") + (isSamsung() ? "- OneUi Major Version: " + this.OneUiMajorVersion + "\n" + "- OneUi Minor Version: " + this.OneUiMinorVersion + "\n" : "")
+ (hasMiuiIncrCode() ? "- Miui Version Incremental Code: " + this.MiuiIncrementalCode + "\n" : "") + (hasMiuiIncrCode() ? "- Miui Version Incremental Code: " + this.MiuiIncrementalCode + "\n" : "")
+ (isEMUI() ? "- Emui Version: " + this.EmuiVersion : ""); + (isEMUI() ? "- Emui Version: " + this.EmuiVersion : "");
@@ -56,7 +56,7 @@ public class OEMDetector {
} }
public static boolean isOEM() { public static boolean isOEM() {
return isMIUI() || isEMUI() || isFlyme() || isZenUI() || isSamsung() || isVivo() || isOneUi(); return isMIUI() || isEMUI() || isFlyme() || isZenUI() || isSamsung() || isVivo() || isOneUi() || isHyperOs();
} }
public static boolean isMIUI() { public static boolean isMIUI() {
@@ -68,6 +68,15 @@ public class OEMDetector {
} }
} }
public static boolean isHyperOs() {
try {
int miuiVer = Integer.parseInt(getMiuiUiVersionCode()); // cuz hyperos gives 816 and etc
return miuiVer > 14 && isMIUI();
} catch (Exception unused) {
return false;
}
}
public static boolean isIntentResolved(Context ctx, Intent intent) { public static boolean isIntentResolved(Context ctx, Intent intent) {
return (intent != null && ctx.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null); return (intent != null && ctx.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null);
} }
@@ -124,7 +133,6 @@ public class OEMDetector {
try { try {
return (String) getPropMtd.invoke(null, prop); return (String) getPropMtd.invoke(null, prop);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace();
return null; return null;
} }
} }
@@ -1,27 +1,35 @@
package ru.vtosters.lite.downloaders; package ru.vtosters.lite.downloaders;
import android.os.Environment; import android.os.Environment;
import android.util.Log;
import androidx.core.app.NotificationCompat;
import bruhcollective.itaysonlab.libvkx.client.LibVKXClient; import bruhcollective.itaysonlab.libvkx.client.LibVKXClient;
import com.vk.core.util.ToastUtils; import com.vk.core.util.ToastUtils;
import com.vk.dto.music.MusicTrack; import com.vk.dto.music.MusicTrack;
import com.vk.dto.music.Playlist; import com.vk.dto.music.Playlist;
import com.vtosters.lite.R; import com.vtosters.lite.R;
import java8.util.concurrent.CompletableFuture; import org.json.JSONObject;
import ru.vtosters.hooks.music.MusicCacheFilesHook; import ru.vtosters.hooks.music.MusicCacheFilesHook;
import ru.vtosters.hooks.other.Preferences; import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.music.cache.MusicCacheImpl; import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.music.cache.delegate.PlaylistCacheDbDelegate;
import ru.vtosters.lite.music.cache.helpers.PlaylistHelper;
import ru.vtosters.lite.music.callback.MusicCallbackBuilder; import ru.vtosters.lite.music.callback.MusicCallbackBuilder;
import ru.vtosters.lite.music.converter.playlist.PlaylistConverter; import ru.vtosters.lite.music.converter.playlist.PlaylistConverter;
import ru.vtosters.lite.music.downloader.AudioGet; import ru.vtosters.lite.music.downloader.AudioGet;
import ru.vtosters.lite.music.downloader.PlaylistDownloader; import ru.vtosters.lite.music.downloader.PlaylistDownloader;
import ru.vtosters.lite.music.downloader.ThumbnailPlaylistDownloader;
import ru.vtosters.lite.music.downloader.TrackDownloader; import ru.vtosters.lite.music.downloader.TrackDownloader;
import ru.vtosters.lite.music.interfaces.Callback;
import ru.vtosters.lite.music.notification.MusicNotificationBuilder; import ru.vtosters.lite.music.notification.MusicNotificationBuilder;
import ru.vtosters.lite.utils.AccountManagerUtils; import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.IOUtils; import ru.vtosters.lite.utils.IOUtils;
import ru.vtosters.lite.utils.music.PlaylistUtils;
import java.io.File; import java.io.File;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import static ru.vtosters.lite.utils.AndroidUtils.getString; import static ru.vtosters.lite.utils.AndroidUtils.getString;
@@ -35,18 +43,18 @@ import static ru.vtosters.lite.utils.AndroidUtils.getString;
public class AudioDownloader { public class AudioDownloader {
public static final String dlpath = Preferences.getBoolValue("dldir", false) ? Environment.DIRECTORY_DOWNLOADS : Environment.DIRECTORY_MUSIC; public static final String dlpath = Preferences.getBoolValue("dldir", false) ? Environment.DIRECTORY_DOWNLOADS : Environment.DIRECTORY_MUSIC;
public static CompletableFuture<Void> downloadPlaylist(Playlist playlist) { public static void downloadPlaylist(Playlist playlist) {
var tracks = PlaylistConverter.getPlaylist(playlist); List<MusicTrack> tracks = PlaylistConverter.getPlaylist(playlist);
var playlistName = IOUtils.getValidFileName(playlist.g); String playlistName = IOUtils.getValidFileName(playlist.g);
var musicPath = Environment.getExternalStoragePublicDirectory(dlpath).getAbsolutePath(); String musicPath = Environment.getExternalStoragePublicDirectory(dlpath).getAbsolutePath();
var downloadPath = musicPath + File.separator + playlistName; String downloadPath = musicPath + File.separator + playlistName;
var notificationId = playlistName.hashCode(); int notificationId = playlistName.hashCode();
var notification = MusicNotificationBuilder.buildPlaylistDownloadNotification(playlistName, notificationId); NotificationCompat.Builder notification = MusicNotificationBuilder.buildPlaylistDownloadNotification(playlistName, notificationId);
return PlaylistDownloader.downloadPlaylist( PlaylistDownloader.downloadPlaylist(
tracks, tracks,
IOUtils.getValidFileName(playlist.g), IOUtils.getValidFileName(playlist.g),
downloadPath, downloadPath,
@@ -60,53 +68,96 @@ public class AudioDownloader {
} }
public static void cacheTrack(MusicTrack track) { public static void cacheTrack(MusicTrack track) {
var trackId = LibVKXClient.asId(track); String trackId = LibVKXClient.asId(track);
if (MusicCacheImpl.isCachedTrack(trackId)) { if (MusicCacheImpl.isCachedTrack(trackId)) {
MusicCacheImpl.removeTrack(trackId); MusicCacheImpl.removeTrack(trackId);
AndroidUtils.sendToast(AndroidUtils.getString("audio_deleted_from_cache")); AndroidUtils.sendToast(AndroidUtils.getString("audio_deleted_from_cache"));
} else { } else {
var trackFile = MusicCacheFilesHook.getTrackFile(trackId); File trackFile = MusicCacheFilesHook.getTrackFile(trackId);
if (!trackFile.exists()) if (!trackFile.exists()) {
trackFile.getParentFile().mkdirs(); trackFile.getParentFile().mkdirs();
}
downloadM3U8(track, true); downloadM3U8(track, true);
} }
} }
public static CompletableFuture<Void> cachePlaylist(Playlist playlist) { public static void cachePlaylist(Playlist playlist) {
var tracks = PlaylistConverter.getPlaylist(playlist); List<MusicTrack> tracks = PlaylistConverter.getPlaylist(playlist);
var notificationId = playlist.g.hashCode(); int notificationId = playlist.g.hashCode();
var notification = MusicNotificationBuilder.buildPlaylistDownloadNotification(playlist.g, notificationId); NotificationCompat.Builder notification = MusicNotificationBuilder.buildPlaylistDownloadNotification(playlist.g, notificationId);
return PlaylistDownloader.cachePlaylist( JSONObject thumbs = PlaylistUtils.getThumb(playlist);
if (thumbs != null) {
new ThumbnailPlaylistDownloader().download(null, new Callback() {
@Override
public void onProgress(int progress) {
}
@Override
public void onSuccess() {
PlaylistCacheDbDelegate.addPlaylist(AndroidUtils.getGlobalContext(), playlist);
Log.d("Playlist", "adding to cache with thumbs " + playlist.v1());
}
@Override
public void onFailure(Throwable e) {
throw new RuntimeException(e);
}
@Override
public void onSizeReceived(long size, long header) {
}
}, playlist);
} else {
PlaylistCacheDbDelegate.addPlaylist(AndroidUtils.getGlobalContext(), playlist);
Log.d("Playlist", "adding to cache without thumbs " + playlist.a);
}
PlaylistDownloader.cachePlaylist(
tracks, tracks,
MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId) MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId),
playlist
); );
} }
public static void cacheAllAudios() { public static void cacheAllAudios() {
var tracks = AudioGet.getAudios(); List<MusicTrack> tracks = AudioGet.getAudios();
var notificationId = AccountManagerUtils.getUserId(); int notificationId = AccountManagerUtils.getUserId();
var notification = MusicNotificationBuilder.buildAllAudiosDownloadNotification(notificationId); NotificationCompat.Builder notification = MusicNotificationBuilder.buildAllAudiosDownloadNotification(notificationId);
if (tracks == null || tracks.isEmpty()) {
return;
}
PlaylistDownloader.cachePlaylist( PlaylistDownloader.cachePlaylist(
tracks, tracks,
MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId) MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId),
PlaylistHelper.createCachedPlaylistMetadata()
); );
} }
public static void downloadAllAudios() { public static void downloadAllAudios() {
var tracks = AudioGet.getAudios(); List<MusicTrack> tracks = AudioGet.getAudios();
var notificationId = AccountManagerUtils.getUserId(); int notificationId = AccountManagerUtils.getUserId();
var notification = MusicNotificationBuilder.buildAllAudiosDownloadNotification(notificationId); NotificationCompat.Builder notification = MusicNotificationBuilder.buildAllAudiosDownloadNotification(notificationId);
var playlistName = "Audios of " + AccountManagerUtils.getUserId(); String playlistName = "Audios of " + AccountManagerUtils.getUserId();
var musicPath = Environment.getExternalStoragePublicDirectory(dlpath).getAbsolutePath(); String musicPath = Environment.getExternalStoragePublicDirectory(dlpath).getAbsolutePath();
var downloadPath = musicPath + File.separator + playlistName; String downloadPath = musicPath + File.separator + playlistName;
if (tracks == null || tracks.isEmpty()) {
return;
}
PlaylistDownloader.downloadPlaylist( PlaylistDownloader.downloadPlaylist(
tracks, tracks,
@@ -116,21 +167,21 @@ public class AudioDownloader {
); );
} }
private static void private static void downloadM3U8(MusicTrack track, boolean cache) {
downloadM3U8(MusicTrack track, boolean cache) {
Objects.requireNonNull(track.D, () -> { Objects.requireNonNull(track.D, () -> {
ToastUtils.a(getString(R.string.link_audio_error)); ToastUtils.a(getString(R.string.link_audio_error));
return "link must not be null"; return "link must not be null";
}); });
var musicPath = Environment.getExternalStoragePublicDirectory(dlpath).getAbsolutePath(); String musicPath = Environment.getExternalStoragePublicDirectory(dlpath).getAbsolutePath();
var tempId = track.d; int tempId = track.d;
var downloadPath = musicPath + File.separator; String downloadPath = musicPath + File.separator;
var notification = MusicNotificationBuilder.buildDownloadNotification(track, tempId); NotificationCompat.Builder notification = MusicNotificationBuilder.buildDownloadNotification(track, tempId);
var cb = MusicCallbackBuilder.buildOneTrackCallback(tempId, notification); Callback cb = MusicCallbackBuilder.buildOneTrackCallback(tempId, notification);
if (cache) if (cache) {
TrackDownloader.cacheTrack(track, cb); TrackDownloader.cacheTrack(track, cb, PlaylistHelper.createCachedPlaylistMetadata());
else } else {
TrackDownloader.downloadTrack(track, downloadPath, cb); TrackDownloader.downloadTrack(track, downloadPath, cb);
} }
} }
}
@@ -30,6 +30,7 @@ import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.di.singleton.VtOkHttpClient; import ru.vtosters.lite.di.singleton.VtOkHttpClient;
import ru.vtosters.lite.downloaders.AudioDownloader; import ru.vtosters.lite.downloaders.AudioDownloader;
import ru.vtosters.lite.music.cache.MusicCacheImpl; import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.music.MusicTrackUtils; import ru.vtosters.lite.utils.music.MusicTrackUtils;
@@ -50,13 +51,14 @@ public class LastFMScrobbler {
var access_key = !TextUtils.isEmpty(musictrack.J) ? musictrack.J : ""; var access_key = !TextUtils.isEmpty(musictrack.J) ? musictrack.J : "";
var album_id = musictrack.I; var album_id = musictrack.I;
var album = album_id != null ? album_id.getTitle() : null; var album = album_id != null ? album_id.getTitle() : null;
var isOwnTrack = musictrack.e == AccountManagerUtils.getUserId();
if (TextUtils.isEmpty(uid) || TextUtils.isEmpty(artist) || TextUtils.isEmpty(title) || duration == 0) { if (TextUtils.isEmpty(uid) || TextUtils.isEmpty(artist) || TextUtils.isEmpty(title) || duration == 0) {
Log.d("Scrobbler", "grabTrackInfo: " + "Empty track, info: " + artist + " - " + title + " - " + duration + " - " + uid); Log.d("Scrobbler", "grabTrackInfo: " + "Empty track, info: " + artist + " - " + title + " - " + duration + " - " + uid);
return; return;
} }
if (Preferences.autocache() && !MusicCacheImpl.isCachedTrack(uid)) { if (needToCache(isOwnTrack) && !MusicCacheImpl.isCachedTrack(uid)) {
if (LibVKXClient.isIntegrationEnabled()) { if (LibVKXClient.isIntegrationEnabled()) {
LibVKXClient.getInstance().runOnService(service -> { LibVKXClient.getInstance().runOnService(service -> {
try { try {
@@ -73,6 +75,12 @@ public class LastFMScrobbler {
scrobbleTrack(duration, artist, title, uid, album); scrobbleTrack(duration, artist, title, uid, album);
} }
private static boolean needToCache(boolean isOwnTrack) {
int autocache = Preferences.autocache();
return autocache == 2 || (autocache == 1 && isOwnTrack);
}
public static void scrobbleTrack( public static void scrobbleTrack(
long duration, long duration,
String artist, String artist,
@@ -10,6 +10,10 @@ import java.util.List;
import bruhcollective.itaysonlab.libvkx.ILibVkxService; import bruhcollective.itaysonlab.libvkx.ILibVkxService;
import bruhcollective.itaysonlab.libvkx.client.LibVKXClient; import bruhcollective.itaysonlab.libvkx.client.LibVKXClient;
import bruhcollective.itaysonlab.libvkx.client.LibVKXClientImpl; import bruhcollective.itaysonlab.libvkx.client.LibVKXClientImpl;
import com.vk.dto.music.Playlist;
import ru.vtosters.lite.music.cache.delegate.MusicCacheDbDelegate;
import ru.vtosters.lite.music.cache.delegate.PlaylistCacheDbDelegate;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.music.MusicCacheStorageUtils; import ru.vtosters.lite.utils.music.MusicCacheStorageUtils;
import ru.vtosters.lite.utils.music.MusicTrackUtils; import ru.vtosters.lite.utils.music.MusicTrackUtils;
@@ -34,25 +38,33 @@ public class MusicCacheImpl {
MusicCacheStorageUtils.removeTrackDirById(trackId); MusicCacheStorageUtils.removeTrackDirById(trackId);
} }
public static List<MusicTrack> getAllTracks() { public static List<MusicTrack> getAllOwnTracks() {
return MusicCacheDbDelegate.getAllTracks(AndroidUtils.getGlobalContext()); return PlaylistCacheDbDelegate.getTracksInPlaylist(AndroidUtils.getGlobalContext(), AccountManagerUtils.getUserId() + "_-1");
} }
public static List<MusicTrack> getAlbumById(String albumId) { public static List<MusicTrack> getPlaylistSongs(String owner_id, String playlist_id) {
return MusicCacheDbDelegate.getAlbumById(AndroidUtils.getGlobalContext(), albumId); return PlaylistCacheDbDelegate.getTracksInPlaylist(AndroidUtils.getGlobalContext(), owner_id + "_" + playlist_id); // get songs from playlist
} }
public static List<MusicTrack> getFirstAlbumTrack(String albumId) { public static Playlist getPlaylist(String playlist_id, String owner_id) {
return MusicCacheDbDelegate.getFirstAlbumTrack(AndroidUtils.getGlobalContext(), albumId); return getPlaylistById(owner_id + "_" + playlist_id); // get playlist from db
} }
public static List<MusicTrack> getPlaylist() { public static List<Playlist> getPlaylists() {
return MusicCacheDbDelegate.getPlaylist(AndroidUtils.getGlobalContext()); return PlaylistCacheDbDelegate.getAllPlaylists(AndroidUtils.getGlobalContext()); // get all cached playlists
}
public static Playlist getPlaylistById(String query) {
return PlaylistCacheDbDelegate.getPlaylistById(AndroidUtils.getGlobalContext(), query); // get playlist from db
}
public static boolean hasPlaylist() {
return !PlaylistCacheDbDelegate.isPlaylistsDbEmpty(AndroidUtils.getGlobalContext()); // has playlists or not
} }
public static long getTracksCount() { public static long getTracksCount() {
return !LibVKXClient.isIntegrationEnabled() return !LibVKXClient.isIntegrationEnabled()
? MusicCacheDbDelegate.getTracksCount(AndroidUtils.getGlobalContext()) ? PlaylistCacheDbDelegate.getTracksCountInPlaylist(AndroidUtils.getGlobalContext(),AccountManagerUtils.getUserId() + "_-1")
: LibVKXClient.getInstance().runOnServiceSync( : LibVKXClient.getInstance().runOnServiceSync(
new LibVKXClientImpl.LibVKXActionGeneric<Long>() { new LibVKXClientImpl.LibVKXActionGeneric<Long>() {
@Override @Override
@@ -60,7 +72,7 @@ public class MusicCacheImpl {
try { try {
return (long) service.getCache().size(); return (long) service.getCache().size();
} catch (RemoteException e) { } catch (RemoteException e) {
e.printStackTrace(); e.fillInStackTrace();
return defaultValue(); return defaultValue();
} }
} }
@@ -77,11 +89,12 @@ public class MusicCacheImpl {
} }
public static boolean isEmpty() { public static boolean isEmpty() {
return !LibVKXClient.isIntegrationEnabled() && getTracksCount() == 0L; return !LibVKXClient.isIntegrationEnabled() && MusicCacheDbDelegate.isEmpty(AndroidUtils.getGlobalContext());
} }
public static void clear() { public static void clear() {
MusicCacheDbDelegate.drop(AndroidUtils.getGlobalContext()); MusicCacheDbDelegate.drop(AndroidUtils.getGlobalContext());
PlaylistCacheDbDelegate.drop(AndroidUtils.getGlobalContext());
MusicCacheStorageUtils.clear(); MusicCacheStorageUtils.clear();
} }
} }
@@ -24,6 +24,8 @@ import java.net.URLDecoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import ru.vtosters.lite.music.cache.delegate.PlaylistCacheDbDelegate;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.music.MusicCacheStorageUtils; import ru.vtosters.lite.utils.music.MusicCacheStorageUtils;
import ru.vtosters.lite.utils.music.MusicTrackUtils; import ru.vtosters.lite.utils.music.MusicTrackUtils;
@@ -127,6 +129,8 @@ public class MusicCacheDb extends SQLiteOpenHelper implements AutoCloseable { //
vals.put(Constants.COLUMN_DURATION, track.h); vals.put(Constants.COLUMN_DURATION, track.h);
vals.put(Constants.COLUMN_HAS_ARTWORK, track.I != null && track.I.u1() != null); vals.put(Constants.COLUMN_HAS_ARTWORK, track.I != null && track.I.u1() != null);
db.insert(Constants.TABLE_NAME, null, vals); db.insert(Constants.TABLE_NAME, null, vals);
PlaylistCacheDbDelegate.addTrackToPlaylist(AndroidUtils.getGlobalContext(), AccountManagerUtils.getUserId() + "_-1", track.y1());
} }
} }
} }
@@ -170,18 +174,30 @@ public class MusicCacheDb extends SQLiteOpenHelper implements AutoCloseable { //
return DatabaseUtils.queryNumEntries(getReadableDatabase(), Constants.TABLE_NAME); return DatabaseUtils.queryNumEntries(getReadableDatabase(), Constants.TABLE_NAME);
} }
public boolean isDatabaseEmpty() {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT EXISTS(SELECT 1 FROM " + Constants.TABLE_NAME + " LIMIT 1)", null);
cursor.moveToFirst();
boolean isEmpty = cursor.getInt(0) == 0;
cursor.close();
return isEmpty;
}
public MusicTrack getTrackById(String trackId) {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.query(Constants.TABLE_NAME, null, Constants.COLUMN_TRACK_ID + " = ?", new String[]{trackId}, null, null, null);
MusicTrack track = null;
if (cursor.moveToFirst()) {
track = fromCursor(cursor);
}
cursor.close();
return track;
}
public List<MusicTrack> getAllTracks() { public List<MusicTrack> getAllTracks() {
return getTracksWithCursor(getReadableDatabase().query(Constants.TABLE_NAME, null, null, null, null, null, null)); return getTracksWithCursor(getReadableDatabase().query(Constants.TABLE_NAME, null, null, null, null, null, null));
} }
public List<MusicTrack> getAlbum(String albumId) {
return getAlbumTracks(albumId, null);
}
public List<MusicTrack> getFirstAlbumTrack(String albumId) {
return getAlbumTracks(albumId, "0,1");
}
private List<MusicTrack> getAlbumTracks(String albumId, @Nullable String limit) { private List<MusicTrack> getAlbumTracks(String albumId, @Nullable String limit) {
return getTracksWithCursor(getReadableDatabase().query( return getTracksWithCursor(getReadableDatabase().query(
Constants.TABLE_NAME, Constants.TABLE_NAME,
@@ -220,7 +236,7 @@ public class MusicCacheDb extends SQLiteOpenHelper implements AutoCloseable { //
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface Constants { public @interface Constants {
int DV_VERSION = 0x2; int DV_VERSION = 0x3;
String DB_NAME = "vt_lite_cache.db"; String DB_NAME = "vt_lite_cache.db";
String TABLE_NAME = "tracks"; String TABLE_NAME = "tracks";
//columns //columns
@@ -0,0 +1,306 @@
package ru.vtosters.lite.music.cache.db;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.vk.dto.music.MusicTrack;
import com.vk.dto.music.Playlist;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.music.cache.helpers.PlaylistHelper;
import ru.vtosters.lite.music.cache.helpers.TracklistHelper;
import ru.vtosters.lite.utils.music.MusicCacheStorageUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import static ru.vtosters.lite.utils.music.MusicCacheStorageUtils.*;
public class PlaylistCacheDb extends SQLiteOpenHelper implements AutoCloseable {
public PlaylistCacheDb(Context context) {
super(context, Constants.DB_NAME, null, Constants.DV_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(Constants.CREATE_QUERY);
db.execSQL(Constants.CREATE_PLAYLIST_TRACKS_QUERY);
}
private static Playlist fromCursor(Cursor cur) throws JSONException {
@SuppressLint("Range")
String photoString = cur.getString(cur.getColumnIndex(Constants.COLUMN_PHOTO));
JSONObject photo = null;
try {
photo = new JSONObject(photoString);
} catch (JSONException e) {
// ok and
}
@SuppressLint("Range")
JSONObject playlist = PlaylistHelper.generatePlaylist(
cur.getInt(cur.getColumnIndex(Constants.COLUMN_ID)),
cur.getInt(cur.getColumnIndex(Constants.COLUMN_OWNER_ID)),
Boolean.parseBoolean(cur.getString(cur.getColumnIndex(Constants.COLUMN_IS_EXPLICIT))),
cur.getString(cur.getColumnIndex(Constants.COLUMN_TITLE)),
cur.getString(cur.getColumnIndex(Constants.COLUMN_DESCRIPTION)),
photo);
Log.d("Playlist", "generated " + Playlist.U.a(playlist).v1());
return Playlist.U.a(playlist);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(Constants.DROP_QUERY);
onCreate(db);
}
public void addPlaylist(int id, int ownerId, boolean isExplicit, String title, String description, JSONObject photo) {
ContentValues values = new ContentValues();
values.put(Constants.COLUMN_ID, id);
values.put(Constants.COLUMN_OWNER_ID, ownerId);
values.put(Constants.COLUMN_IS_EXPLICIT, isExplicit);
values.put(Constants.COLUMN_TITLE, title);
values.put(Constants.COLUMN_DESCRIPTION, description);
values.put(Constants.COLUMN_PHOTO, String.valueOf(photo));
getWritableDatabase().insert(Constants.TABLE_NAME, null, values);
}
private void deletePlaylist(int id, int ownerId) {
getWritableDatabase().delete(Constants.TABLE_NAME, Constants.COLUMN_ID + " = ? AND " + Constants.COLUMN_OWNER_ID + " = ?", new String[]{String.valueOf(id), String.valueOf(ownerId)});
}
public boolean isCachedPlaylist(int id, int ownerId) {
Cursor cursor = getReadableDatabase().query(Constants.TABLE_NAME, new String[]{Constants.COLUMN_ID}, Constants.COLUMN_ID + " = ? AND " + Constants.COLUMN_OWNER_ID + " = ?", new String[]{String.valueOf(id), String.valueOf(ownerId)}, null, null, null);
boolean exists = cursor.getCount() > 0;
cursor.close();
return exists;
}
public long getPlaylistsCount() {
return DatabaseUtils.queryNumEntries(getReadableDatabase(), Constants.TABLE_NAME);
}
public void deletePlaylistWithTracks(String playlistId) {
SQLiteDatabase db = getWritableDatabase();
String[] parts = playlistId.split("_");
int id = Integer.parseInt(parts[1]);
int ownerId = Integer.parseInt(parts[0]);
// Get all tracks in the playlist
List<MusicTrack> tracks = getTracksInPlaylist(playlistId);
// Delete the playlist
deletePlaylist(id, ownerId);
// Delete each track from the playlist_tracks table
for (MusicTrack track : tracks) {
String trackId = track.y1();
removeTrackFromPlaylist(playlistId, trackId);
removePlaylistThumb(playlistId);
if (!isTrackInAnyOtherPlaylist(trackId, playlistId)) {
MusicCacheImpl.removeTrack(trackId);
Log.d("Playlist", "removed " + trackId);
}
}
// Delete all entries from the playlist_tracks table for this playlist
db.delete(Constants.TABLE_PLAYLIST_TRACKS, Constants.COLUMN_PLAYLIST_ID + " = ?", new String[]{playlistId});
}
private boolean isTrackInAnyOtherPlaylist(String trackId, String playlistId) {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.query(
Constants.TABLE_PLAYLIST_TRACKS,
null,
Constants.COLUMN_TRACK_ID + " = ? AND " + Constants.COLUMN_PLAYLIST_ID + " != ?",
new String[]{trackId, playlistId},
null, null, null
);
boolean exists = cursor.getCount() > 0;
cursor.close();
return exists;
}
public List<Playlist> getAllPlaylists() {
Cursor cursor = getReadableDatabase().query(Constants.TABLE_NAME, null, null, null, null, null, null);
List<Playlist> playlists = getPlaylistsWithCursor(cursor);
cursor.close();
return playlists;
}
public Playlist getPlaylistById(int id, int ownerId) {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.query(Constants.TABLE_NAME, null, Constants.COLUMN_ID + " = ? AND " + Constants.COLUMN_OWNER_ID + " = ?", new String[]{String.valueOf(id), String.valueOf(ownerId)}, null, null, null);
Playlist playlist = null;
if (cursor.moveToFirst()) {
try {
playlist = fromCursor(cursor);
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
cursor.close();
return playlist;
}
private List<Playlist> getPlaylistsWithCursor(Cursor cur) {
List<Playlist> playlists = new ArrayList<>();
while (cur.moveToNext()) {
try {
playlists.add(fromCursor(cur));
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
return playlists;
}
public long getTracksCountInPlaylist(String playlistId) {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.query(
Constants.TABLE_PLAYLIST_TRACKS,
new String[]{Constants.COLUMN_TRACK_ID},
Constants.COLUMN_PLAYLIST_ID + " = ?",
new String[]{playlistId},
null, null, null
);
long count = cursor.getCount();
cursor.close();
return count;
}
public List<String> getAllPlaylistIds() {
SQLiteDatabase db = getReadableDatabase();
List<String> playlistIds = new ArrayList<>();
Cursor cursor = db.query(
Constants.TABLE_NAME,
new String[]{Constants.COLUMN_ID, Constants.COLUMN_OWNER_ID},
null, null, null, null, null
);
if (cursor.moveToFirst()) {
do {
String playlistId = cursor.getString(cursor.getColumnIndexOrThrow(Constants.COLUMN_OWNER_ID)) + "_" + cursor.getString(cursor.getColumnIndexOrThrow(Constants.COLUMN_ID));
playlistIds.add(playlistId);
} while (cursor.moveToNext());
}
cursor.close();
return playlistIds;
}
public boolean isPlaylistsDbEmpty() {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT EXISTS(SELECT 1 FROM " + Constants.TABLE_NAME + " LIMIT 1)", null);
cursor.moveToFirst();
boolean isEmpty = cursor.getInt(0) == 0;
cursor.close();
return isEmpty;
}
public void addTrackToPlaylist(String playlistId, String trackId) {
ContentValues values = new ContentValues();
values.put(Constants.COLUMN_PLAYLIST_ID, playlistId);
values.put(Constants.COLUMN_TRACK_ID, trackId);
getWritableDatabase().insert(Constants.TABLE_PLAYLIST_TRACKS, null, values);
}
public void removeTrackFromPlaylist(String playlistId, String trackId) {
getWritableDatabase().delete(Constants.TABLE_PLAYLIST_TRACKS, Constants.COLUMN_PLAYLIST_ID + " = ? AND " + Constants.COLUMN_TRACK_ID + " = ?", new String[]{playlistId, trackId});
}
public boolean isPlaylistEmpty(String playlistId) {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT EXISTS(SELECT 1 FROM " + Constants.TABLE_PLAYLIST_TRACKS + " WHERE " + Constants.COLUMN_PLAYLIST_ID + " = ? LIMIT 1)", new String[]{playlistId});
cursor.moveToFirst();
boolean isEmpty = cursor.getInt(0) == 0;
cursor.close();
return isEmpty;
}
public List<MusicTrack> getTracksInPlaylist(String playlistId) {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.query(
Constants.TABLE_PLAYLIST_TRACKS,
new String[]{Constants.COLUMN_TRACK_ID},
Constants.COLUMN_PLAYLIST_ID + " = ?",
new String[]{playlistId},
null, null, null
);
List<MusicTrack> tracks = new ArrayList<>();
while (cursor.moveToNext()) {
@SuppressLint("Range")
String trackId = cursor.getString(cursor.getColumnIndex(Constants.COLUMN_TRACK_ID));
MusicTrack track = TracklistHelper.getTrack(trackId);
Log.d("Playlist", "add " + trackId + " to playlist " + playlistId);
if (track != null) {
tracks.add(track);
}
}
cursor.close();
return tracks;
}
@Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
db.setForeignKeyConstraintsEnabled(true);
}
@Retention(RetentionPolicy.SOURCE)
public @interface Constants {
int DV_VERSION = 0x2;
String DB_NAME = "vt_lite_cache_playlists.db";
String TABLE_NAME = "playlists";
//columns
String COLUMN_ID = "id";
String COLUMN_OWNER_ID = "owner_id";
String COLUMN_IS_EXPLICIT = "is_explicit";
String COLUMN_TITLE = "title";
String COLUMN_DESCRIPTION = "description";
String COLUMN_PHOTO = "photo";
// tracks
String COLUMN_TRACK_ID = "track_id";
String TABLE_PLAYLIST_TRACKS = "playlist_tracks";
String COLUMN_PLAYLIST_ID = "playlist_id";
//queries
String CREATE_QUERY = "create table " + TABLE_NAME
+ "("
+ COLUMN_ID + " INTEGER PRIMARY KEY autoincrement,"
+ COLUMN_OWNER_ID + " INTEGER not null,"
+ COLUMN_IS_EXPLICIT + " TEXT not null,"
+ COLUMN_TITLE + " TEXT not null,"
+ COLUMN_DESCRIPTION + " TEXT not null,"
+ COLUMN_PHOTO + " TEXT not null"
+ ")";
String CREATE_PLAYLIST_TRACKS_QUERY = "create table " + TABLE_PLAYLIST_TRACKS + "("
+ COLUMN_PLAYLIST_ID + " TEXT not null,"
+ COLUMN_TRACK_ID + " TEXT not null"
+ ")";
String DROP_QUERY = "drop table if exists " + TABLE_NAME;
}
}
@@ -1,4 +1,4 @@
package ru.vtosters.lite.music.cache; package ru.vtosters.lite.music.cache.delegate;
import android.content.Context; import android.content.Context;
@@ -43,27 +43,9 @@ public class MusicCacheDbDelegate {
} }
} }
public static List<MusicTrack> getAllTracks(Context context) { public static MusicTrack getTrackById(Context context, String trackId) {
try (var db = connectToDb(context)) { try (var db = connectToDb(context)) {
return db.getAllTracks(); return db.getTrackById(trackId);
}
}
public static List<MusicTrack> getAlbumById(Context context, String albumId) {
try (var db = connectToDb(context)) {
return db.getAlbum(albumId);
}
}
public static List<MusicTrack> getFirstAlbumTrack(Context context, String albumId) {
try (var db = connectToDb(context)) {
return db.getFirstAlbumTrack(albumId);
}
}
public static List<MusicTrack> getPlaylist(Context context) {
try (var db = connectToDb(context)) {
return db.getPlaylist();
} }
} }
@@ -73,6 +55,12 @@ public class MusicCacheDbDelegate {
} }
} }
public static boolean isEmpty(Context context) {
try (var db = connectToDb(context)) {
return db.isDatabaseEmpty();
}
}
public static boolean isCachedTrack(Context context, String trackId) { public static boolean isCachedTrack(Context context, String trackId) {
try (var db = connectToDb(context)) { try (var db = connectToDb(context)) {
return db.isCachedTrack(trackId); return db.isCachedTrack(trackId);
@@ -0,0 +1,149 @@
package ru.vtosters.lite.music.cache.delegate;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import com.vk.dto.music.MusicTrack;
import com.vk.dto.music.Playlist;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.lite.music.cache.db.PlaylistCacheDb;
import ru.vtosters.lite.utils.music.MusicCacheStorageUtils;
import ru.vtosters.lite.utils.music.PlaylistUtils;
import java.util.List;
public class PlaylistCacheDbDelegate {
static synchronized private PlaylistCacheDb connectToDb(Context context) {
synchronized (PlaylistCacheDb.class) {
return new PlaylistCacheDb(context);
}
}
public static void addPlaylist(Context context, Playlist playlist) {
try (var db = connectToDb(context)) {
db.addPlaylist(playlist.a, playlist.b, playlist.C, playlist.g, playlist.B, generatePhotoJSON(playlist));
}
}
public static JSONObject generatePhotoJSON(Playlist playlist) {
if (PlaylistUtils.getThumb(playlist) != null) {
JSONObject photo = new JSONObject();
String playlistId = playlist.v1();
try {
photo.put("height", 300);
photo.put("width", 300);
addPhotoSizeToJSON(photo, playlistId, 600, "photo_600");
addPhotoSizeToJSON(photo, playlistId, 34, "photo_34");
addPhotoSizeToJSON(photo, playlistId, 1200, "photo_1200");
addPhotoSizeToJSON(photo, playlistId, 68, "photo_68");
addPhotoSizeToJSON(photo, playlistId, 135, "photo_135");
addPhotoSizeToJSON(photo, playlistId, 300, "photo_300");
addPhotoSizeToJSON(photo, playlistId, 270, "photo_270");
return photo;
} catch (JSONException e) {
throw new RuntimeException(e);
}
} else {
return null;
}
}
private static void addPhotoSizeToJSON(JSONObject photo, String playlistId, int size, String key) throws JSONException {
photo.put(key, Uri.fromFile(MusicCacheStorageUtils.getPlaylistThumb(playlistId, size)).toString());
Log.d("Playlist", "thumb link " + Uri.fromFile(MusicCacheStorageUtils.getPlaylistThumb(playlistId, size)).toString());
}
public static void deletePlaylist(Context context, String playlistId) {
try (var db = connectToDb(context)) {
db.deletePlaylistWithTracks(playlistId);
}
}
public static long getTracksCountInPlaylist(Context context, String playlistId) {
try (var db = connectToDb(context)) {
return db.getTracksCountInPlaylist(playlistId);
}
}
public static boolean isPlaylistsDbEmpty(Context context) {
try (var db = connectToDb(context)) {
return db.isPlaylistsDbEmpty();
}
}
public static void removeAllPlaylists(Context context) {
List<String> playlistIds = getAllPlaylistIds(context);
for (String playlistId : playlistIds) {
deletePlaylist(context, playlistId);
}
}
public static List<String> getAllPlaylistIds(Context context) {
try (var db = connectToDb(context)) {
return db.getAllPlaylistIds();
}
}
public static boolean isCachedPlaylist(Context context, String id) {
try (var db = connectToDb(context)) {
String[] parts = id.split("_");
int playlistId = Integer.parseInt(parts[1]);
int ownerId = Integer.parseInt(parts[0]);
return db.isCachedPlaylist(playlistId, ownerId);
}
}
public static long getPlaylistsCount(Context context) {
try (var db = connectToDb(context)) {
return db.getPlaylistsCount();
}
}
public static List<Playlist> getAllPlaylists(Context context) {
try (var db = connectToDb(context)) {
return db.getAllPlaylists();
}
}
public static Playlist getPlaylistById(Context context, String playlistId) {
try (var db = connectToDb(context)) {
String[] parts = playlistId.split("_");
int id = Integer.parseInt(parts[1]);
int ownerId = Integer.parseInt(parts[0]);
return db.getPlaylistById(id, ownerId);
}
}
public static void addTrackToPlaylist(Context context, String playlistId, String trackId) {
try (var db = connectToDb(context)) {
db.addTrackToPlaylist(playlistId, trackId);
}
}
public static void removeTrackFromPlaylist(Context context, String playlistId, String trackId) {
try (var db = connectToDb(context)) {
db.removeTrackFromPlaylist(playlistId, trackId);
}
}
public static List<MusicTrack> getTracksInPlaylist(Context context, String playlistId) {
try (var db = connectToDb(context)) {
return db.getTracksInPlaylist(playlistId);
}
}
public static boolean isPlaylistEmpty(Context context, String playlistId) {
try (var db = connectToDb(context)) {
return db.isPlaylistEmpty(playlistId);
}
}
public static void drop(Context context) {
context.deleteDatabase(PlaylistCacheDb.Constants.DB_NAME);
}
}
@@ -1,96 +1,79 @@
package ru.vtosters.lite.music.cache.helpers; package ru.vtosters.lite.music.cache.helpers;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserId; import android.util.Log;
import android.net.Uri;
import com.vk.dto.music.Playlist; import com.vk.dto.music.Playlist;
import com.vtosters.lite.R; import com.vtosters.lite.R;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import ru.vtosters.lite.music.cache.MusicCacheImpl; import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.music.cache.delegate.PlaylistCacheDbDelegate;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.music.MusicCacheStorageUtils; import ru.vtosters.lite.utils.NetworkUtils;
import ru.vtosters.lite.utils.music.MusicTrackUtils; import ru.vtosters.lite.utils.music.PlaylistUtils;
public class PlaylistHelper { public class PlaylistHelper {
public static Playlist createCachedPlaylistMetadata() { public static Playlist createCachedPlaylistMetadata() {
try { try {
return new Playlist(getPlaylist()); return new Playlist(getCachedSongsPlaylist());
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace();
return null; return null;
} }
} }
public static Playlist createCachedPlaylistMetadata(String id) { public static JSONArray addCachedPlaylists(JSONArray jsonArray) {
var track = TracklistHelper.getTracksOne(id).get(0);
var albumLink = track.I;
var thumb = albumLink.u1();
return createAlbum(
thumb != null ? thumb.h(600) : "",
albumLink.getTitle(),
MusicTrackUtils.getArtists(track),
track.y1(),
albumLink.getId()
);
}
public static Playlist createAlbum(String photo, String title, String artist, String trackId, int albumId) {
try { try {
var jPhoto = new JSONObject(); if (!PlaylistCacheDbDelegate.isPlaylistEmpty(AndroidUtils.getGlobalContext(), AccountManagerUtils.getUserId() + "_-1")) {
if (!photo.isEmpty()) jsonArray.put(getCachedSongsPlaylist());
jPhoto.put("height", 600) }
.put("width", 600)
.putOpt("photo_300", Uri.fromFile(MusicCacheStorageUtils.getTrackThumb(trackId, 300)).toString()) if (MusicCacheImpl.hasPlaylist()) {
.putOpt("photo_600", Uri.fromFile(MusicCacheStorageUtils.getTrackThumb(trackId, 600)).toString()); for (Playlist playlist : MusicCacheImpl.getPlaylists()) {
var obj = new JSONObject() jsonArray.put(generatePlaylist(playlist.a, playlist.b, playlist.C, playlist.g, playlist.B, PlaylistUtils.getThumb(playlist)));
.put("id", -2)
.put("owner_id", albumId) Log.d("PlaylistHelper", "Playlist cache added: " + playlist.a + " " + playlist.b + " " + playlist.C + " " + playlist.g + " " + playlist.B);
.put("type", 1) }
.put("album_type", "main_only") }
.put("title", title)
.put("description", albumId + "/ " + AndroidUtils.getString(R.string.cached_album_warning))
.put("main_artists", new JSONArray()
.put(new JSONObject().put("name", artist)
.put("id", "-1")
.put("domain", "-1")))
.putOpt("photo", jPhoto)
.put("count", 0);
return new Playlist(obj);
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.fillInStackTrace();
return null;
} }
return jsonArray;
} }
public static List<Playlist> getAlbumPlaylists() { public static JSONObject generatePlaylist(int id, int owner_id, boolean is_explicit, String title, String description, JSONObject photo) throws JSONException {
List<Playlist> list = new ArrayList<>(); JSONObject playlist = new JSONObject()
for (var track : MusicCacheImpl.getPlaylist()) { .put("id", id)
var albumLink = track.I; .put("owner_id", owner_id)
var thumb = albumLink.u1(); .put("type", 0)
list.add(createAlbum( .put("album_type", "playlist")
thumb != null ? thumb.h(600) : "", .put("is_explicit", is_explicit)
albumLink.getTitle(), .put("title", title)
MusicTrackUtils.getArtists(track), .put("description", description)
track.y1(), .put("access_key", "cache")
albumLink.getId() .put("genres", new JSONArray())
)); .put("is_following", false)
} .put("followers", 0)
return list; .put("plays", 0)
.put("create_time", 0)
.put("update_time", 0)
.put("subtitle", "")
.put("meta", new JSONObject()
.put("view", "compact"))
.put("count", 0);
if (photo != null) {
playlist.put("photo", photo);
} }
public static JSONObject getPlaylist() throws JSONException { return playlist;
}
public static JSONObject getCachedSongsPlaylist() throws JSONException {
return new JSONObject() return new JSONObject()
.put("id", -1) .put("id", -1)
.put("owner_id", getUserId()) .put("owner_id", AccountManagerUtils.getUserId())
.put("type", 0) .put("type", 0)
.put("album_type", "playlist") .put("album_type", "playlist")
.put("title", AndroidUtils.getString(R.string.cached_tracks_title)) .put("title", AndroidUtils.getString(R.string.cached_tracks_title))
@@ -118,6 +101,20 @@ public class PlaylistHelper {
.put("count", 0); .put("count", 0);
} }
public static JSONArray getCachedPlaylistsIds() {
JSONArray arr = new JSONArray();
if (NetworkUtils.isNetworkConnected() && !PlaylistCacheDbDelegate.isPlaylistEmpty(AndroidUtils.getGlobalContext(), AccountManagerUtils.getUserId() + "_-1")) {
arr.put(AccountManagerUtils.getUserId() + "_-1");
}
for (String playlist : PlaylistCacheDbDelegate.getAllPlaylistIds(AndroidUtils.getGlobalContext())) {
arr.put(playlist);
}
return arr;
}
public static JSONObject getCatalogPlaylist() throws JSONException { public static JSONObject getCatalogPlaylist() throws JSONException {
return new JSONObject() return new JSONObject()
.put("id", "cache") .put("id", "cache")
@@ -125,18 +122,17 @@ public class PlaylistHelper {
.put("layout", new JSONObject() .put("layout", new JSONObject()
.put("name", "large_slider") .put("name", "large_slider")
.put("is_editable", 0) .put("is_editable", 0)
.put("owner_id", getUserId())) .put("owner_id", AccountManagerUtils.getUserId()))
.put("playlists_ids", new JSONArray() .put("playlists_ids", getCachedPlaylistsIds());
.put(getUserId() + "_-1"));
} }
public static JSONObject getCatalogHeader() throws JSONException { public static JSONObject getCatalogHeader(String text) throws JSONException {
return new JSONObject() return new JSONObject()
.put("id", "cache") .put("id", "cache")
.put("data_type", "none") .put("data_type", "none")
.put("layout", new JSONObject() .put("layout", new JSONObject()
.put("name", "header") .put("name", "header")
.put("title", AndroidUtils.getString(R.string.cached_tracks_title))); .put("title", text));
} }
public static JSONObject getCatalogSeparator() throws JSONException { public static JSONObject getCatalogSeparator() throws JSONException {
@@ -8,6 +8,8 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import ru.vtosters.hooks.other.Preferences; import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.music.cache.MusicCacheImpl; import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.music.cache.delegate.MusicCacheDbDelegate;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.music.MusicCacheStorageUtils; import ru.vtosters.lite.utils.music.MusicCacheStorageUtils;
import java.io.File; import java.io.File;
@@ -22,24 +24,19 @@ public class TracklistHelper {
} }
public static List<MusicTrack> getTracks() { public static List<MusicTrack> getTracks() {
List<MusicTrack> tracks = MusicCacheImpl.getAllTracks(); List<MusicTrack> tracks = MusicCacheImpl.getAllOwnTracks();
boolean doNotinvertOrder = Preferences.getBoolValue("invertCachedTracks", false); boolean doNotinvertOrder = Preferences.getBoolValue("invertCachedTracks", false);
if (!doNotinvertOrder) { if (doNotinvertOrder) {
Collections.reverse(tracks); Collections.reverse(tracks);
} }
return tracks; return tracks;
} }
public static MusicTrack getTrack(String id) {
public static List<MusicTrack> getTracks(String id) { return MusicCacheDbDelegate.getTrackById(AndroidUtils.getGlobalContext(), id);
return MusicCacheImpl.getAlbumById(id);
}
public static List<MusicTrack> getTracksOne(String id) {
return MusicCacheImpl.getFirstAlbumTrack(id);
} }
public static JSONArray tracksToIds(List<MusicTrack> tracks) { public static JSONArray tracksToIds(List<MusicTrack> tracks) {
@@ -53,7 +53,9 @@ public class PlaylistConverter {
var request = new Request.a() var request = new Request.a()
.b(requestUrl) .b(requestUrl)
.a("Accept-Encoding", "gzip") .a("Accept-Encoding", "gzip")
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8")).a(); .a("User-Agent", Network.l.c().a())
.a("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
.a();
try { try {
var response = CompletableFuture.supplyAsync(() -> { var response = CompletableFuture.supplyAsync(() -> {
@@ -47,8 +47,9 @@ public class AudioGet {
var request = new Request.a() var request = new Request.a()
.b(requestUrl) .b(requestUrl)
.a("Accept-Encoding", "gzip") .a("Accept-Encoding", "gzip")
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8")).a(); .a("User-Agent", Network.l.c().a())
.a("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
.a();
try { try {
var response = CompletableFuture.supplyAsync(() -> { var response = CompletableFuture.supplyAsync(() -> {
try (Response resp = Network.b(CLIENT_API).a(request).execute()) { try (Response resp = Network.b(CLIENT_API).a(request).execute()) {
@@ -2,9 +2,12 @@ package ru.vtosters.lite.music.downloader;
import com.vk.dto.music.MusicTrack; import com.vk.dto.music.MusicTrack;
import com.vk.dto.music.Playlist;
import ru.vtosters.lite.music.cache.MusicCacheImpl; import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.music.cache.delegate.PlaylistCacheDbDelegate;
import ru.vtosters.lite.music.interfaces.Callback; import ru.vtosters.lite.music.interfaces.Callback;
import ru.vtosters.lite.music.interfaces.ITrackDownloader; import ru.vtosters.lite.music.interfaces.ITrackDownloader;
import ru.vtosters.lite.utils.AndroidUtils;
public final class CachedDownloader implements ITrackDownloader { public final class CachedDownloader implements ITrackDownloader {
@@ -14,9 +17,8 @@ public final class CachedDownloader implements ITrackDownloader {
this.origin = origin; this.origin = origin;
} }
@Override @Override
public void download(MusicTrack track, Callback callback) { public void download(MusicTrack track, Callback callback, Playlist playlist) {
origin.download(track, new Callback() { origin.download(track, new Callback() {
@Override @Override
public void onProgress(int progress) { public void onProgress(int progress) {
@@ -25,18 +27,26 @@ public final class CachedDownloader implements ITrackDownloader {
@Override @Override
public void onSuccess() { public void onSuccess() {
new ThumbnailDownloader().download(track, new Callback() { new ThumbnailTrackDownloader().download(track, new Callback() {
@Override public void onProgress(int progress) {} @Override public void onProgress(int progress) {
@Override public void onSuccess() {} }
@Override public void onSuccess() {
}
@Override @Override
public void onFailure(Throwable e) { public void onFailure(Throwable e) {
callback.onFailure(e); callback.onFailure(e);
} }
@Override public void onSizeReceived(long size, long header) {} @Override public void onSizeReceived(long size, long header) {
});
}
}, null);
PlaylistCacheDbDelegate.addTrackToPlaylist(AndroidUtils.getGlobalContext(), playlist.v1(), track.y1());
MusicCacheImpl.addTrack(track); MusicCacheImpl.addTrack(track);
callback.onSuccess(); callback.onSuccess();
} }
@@ -50,6 +60,6 @@ public final class CachedDownloader implements ITrackDownloader {
public void onSizeReceived(long size, long header) { public void onSizeReceived(long size, long header) {
callback.onSizeReceived(size, header); callback.onSizeReceived(size, header);
} }
}); }, playlist);
} }
} }
@@ -8,9 +8,11 @@ import com.google.android.exoplayer2.source.hls.playlist.e;
import com.google.android.exoplayer2.source.hls.playlist.f; import com.google.android.exoplayer2.source.hls.playlist.f;
import com.google.android.exoplayer2.source.hls.playlist.f.a; import com.google.android.exoplayer2.source.hls.playlist.f.a;
import com.vk.dto.music.MusicTrack; import com.vk.dto.music.MusicTrack;
import com.vk.dto.music.Playlist;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URL;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -34,19 +36,31 @@ public final class Mp3Downloader implements ITrackDownloader {
} }
@Override @Override
public void download(MusicTrack track, Callback callback) { public void download(MusicTrack track, Callback callback, Playlist playlist) {
String uri = track.D; String uri = track.D;
if (Objects.requireNonNull(uri).isEmpty()) { if (Objects.requireNonNull(uri).isEmpty()) {
String msg = "link error: " + track.y1() + ", title: " + Mp3Downloader.getTitle(track); String msg = "link error: " + track.y1() + ", title: " + Mp3Downloader.getTitle(track);
Log.d("Mp3Downloader", msg); Log.d("Mp3Downloader", msg);
throw new RuntimeException(msg); throw new RuntimeException(msg);
} }
var tsParser = new com.google.android.exoplayer2.source.hls.playlist.h(e.a(track.D)); if (Objects.requireNonNull(uri).contains("master.m3u8?siren=1")) {
var baseUri = track.D.substring(0, track.D.lastIndexOf("/") + 1); try {
String content = IOUtils.readAllLines(new URL(uri).openStream());
String replacement = content.split("\n")[2].trim();
uri = uri.replace("master.m3u8?siren=1", replacement);
} catch (IOException e) {
callback.onFailure(e);
return;
}
}
var tsParser = new com.google.android.exoplayer2.source.hls.playlist.h(e.a(uri));
var baseUri = uri.substring(0, uri.lastIndexOf("/") + 1);
try { try {
var segments = ((f) tsParser.a(Uri.parse(baseUri), IOUtils.openStream(track.D))).o; var segments = ((f) tsParser.a(Uri.parse(baseUri), IOUtils.openStream(uri))).o;
byte[] buff = getMergedTs(baseUri, segments, callback); byte[] buff = getMergedTs(baseUri, segments, callback);
MpegDemuxer.convert(buff, outputFile.getAbsolutePath()); MpegDemuxer.convert(buff, outputFile.getAbsolutePath());
@@ -3,23 +3,23 @@ package ru.vtosters.lite.music.downloader;
import android.util.Log; import android.util.Log;
import com.vk.dto.music.MusicTrack; import com.vk.dto.music.MusicTrack;
import com.vk.dto.music.Playlist;
import ru.vtosters.lite.music.interfaces.Callback;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java8.util.concurrent.CompletableFuture; import java8.util.concurrent.CompletableFuture;
import ru.vtosters.lite.music.interfaces.Callback;
public class PlaylistDownloader { public class PlaylistDownloader {
public static CompletableFuture<Void> public static void downloadPlaylist(List<MusicTrack> playlist, String playlistName, String path, Callback callback) {
downloadPlaylist(List<MusicTrack> playlist, String playlistName, String path, Callback callback) {
var outDir = new File(path); var outDir = new File(path);
if (!outDir.exists()) if (!outDir.exists())
if (outDir.mkdirs()) Log.v("PlaylistDownloader", "Directory created"); if (outDir.mkdirs()) Log.v("PlaylistDownloader", "Directory created");
else Log.e("PlaylistDownloader", "Directory creation failed"); else Log.e("PlaylistDownloader", "Directory creation failed");
Callback delegate = new ProgressCallback(callback); Callback delegate = new ProgressCallback(callback);
return CompletableFuture.allOf(playlist CompletableFuture.allOf(playlist
.stream() .stream()
.map(x -> { .map(x -> {
Callback.CompletableFutureCallback d = new Callback.CompletableFutureCallback d = new
@@ -30,14 +30,13 @@ public class PlaylistDownloader {
.toArray(CompletableFuture[]::new)); .toArray(CompletableFuture[]::new));
} }
public static CompletableFuture<Void> cachePlaylist(List<MusicTrack> playlist, Callback callback) { public static void cachePlaylist(List<MusicTrack> playlist, Callback callback, Playlist playlistId) {
Callback delegate = new ProgressCallback(callback); Callback delegate = new ProgressCallback(callback);
return CompletableFuture.allOf(playlist CompletableFuture.allOf(playlist
.stream() .stream()
.map(x -> { .map(x -> {
Callback.CompletableFutureCallback d = new Callback.CompletableFutureCallback d = new Callback.CompletableFutureCallback(delegate);
Callback.CompletableFutureCallback(delegate); TrackDownloader.cacheTrack(x, d, playlistId);
TrackDownloader.cacheTrack(x, d);
return d; return d;
}) })
.toArray(CompletableFuture[]::new)); .toArray(CompletableFuture[]::new));
@@ -0,0 +1,57 @@
package ru.vtosters.lite.music.downloader;
import android.util.Log;
import com.vk.dto.music.MusicTrack;
import com.vk.dto.music.Playlist;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import ru.vtosters.lite.music.interfaces.Callback;
import ru.vtosters.lite.music.interfaces.ITrackDownloader;
import ru.vtosters.lite.utils.IOUtils;
import ru.vtosters.lite.utils.music.MusicCacheStorageUtils;
import ru.vtosters.lite.utils.music.PlaylistUtils;
import java.io.IOException;
import java.net.URL;
import java.util.List;
public class ThumbnailPlaylistDownloader implements ITrackDownloader {
@Override
public void download(MusicTrack track, Callback callback, Playlist playlist) {
JSONObject json = PlaylistUtils.getThumb(playlist); // get thumbnail photo
if (json == null) {
callback.onFailure(new IOException("No thumbnail found"));
return;
}
try {
List<String> sizes = List.of("600", "1200", "68", "135", "300", "270"); // define the order of sizes to download
JSONArray sizesArray = json.getJSONArray("sizes");
for (String size : sizes) {
for (int i = 0; i < sizesArray.length(); i++) {
JSONObject sizeObj = sizesArray.getJSONObject(i);
if (sizeObj.getInt("width") == Integer.parseInt(size)) {
String url = sizeObj.getString("src");
if (url.isEmpty()) continue;
Log.d("Playlist", "downloading thumb " + url);
downloadThumbnailPlaylist(url, Integer.parseInt(size), playlist.v1());
}
}
}
callback.onSuccess();
} catch (IOException | JSONException e) {
callback.onFailure(e);
throw new RuntimeException(e);
}
}
private static void downloadThumbnailPlaylist(String url, int res, String playlistId) throws IOException {
IOUtils.writeToFile(MusicCacheStorageUtils.getPlaylistThumb(playlistId, res), IOUtils.readFully(new URL(url).openStream()));
}
}
@@ -2,6 +2,7 @@ package ru.vtosters.lite.music.downloader;
import com.vk.dto.music.MusicTrack; import com.vk.dto.music.MusicTrack;
import com.vk.dto.music.Playlist;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
@@ -14,10 +15,10 @@ import ru.vtosters.lite.music.interfaces.ITrackDownloader;
import ru.vtosters.lite.utils.IOUtils; import ru.vtosters.lite.utils.IOUtils;
import ru.vtosters.lite.utils.music.MusicCacheStorageUtils; import ru.vtosters.lite.utils.music.MusicCacheStorageUtils;
public final class ThumbnailDownloader implements ITrackDownloader { public final class ThumbnailTrackDownloader implements ITrackDownloader {
@Override @Override
public void download(MusicTrack track, Callback callback) { public void download(MusicTrack track, Callback callback, Playlist playlist) {
JSONObject json = track.J(); JSONObject json = track.J();
JSONObject album = json.optJSONObject("album"); JSONObject album = json.optJSONObject("album");
if (album == null) return; if (album == null) return;
@@ -50,5 +51,4 @@ public final class ThumbnailDownloader implements ITrackDownloader {
private static void downloadThumbnail(String url, int res, String trackId) throws IOException { private static void downloadThumbnail(String url, int res, String trackId) throws IOException {
IOUtils.writeToFile(MusicCacheStorageUtils.getTrackThumb(trackId, res), IOUtils.readFully(new URL(url).openStream())); IOUtils.writeToFile(MusicCacheStorageUtils.getTrackThumb(trackId, res), IOUtils.readFully(new URL(url).openStream()));
} }
} }
@@ -7,6 +7,7 @@ import com.vk.dto.music.MusicTrack;
import java.io.File; import java.io.File;
import bruhcollective.itaysonlab.libvkx.client.LibVKXClient; import bruhcollective.itaysonlab.libvkx.client.LibVKXClient;
import com.vk.dto.music.Playlist;
import ru.vtosters.lite.concurrent.VTExecutors; import ru.vtosters.lite.concurrent.VTExecutors;
import ru.vtosters.lite.music.cache.MusicCacheImpl; import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.music.interfaces.Callback; import ru.vtosters.lite.music.interfaces.Callback;
@@ -21,25 +22,24 @@ public final class TrackDownloader {
public static void downloadTrack(MusicTrack track, String path, Callback callback) { public static void downloadTrack(MusicTrack track, String path, Callback callback) {
File outDir = new File(path); File outDir = new File(path);
if (!outDir.exists()) { if (!outDir.exists()) {
if (outDir.mkdir()) if (outDir.mkdir()) {
Log.v("TrackDownloader", "Directory created"); Log.v("TrackDownloader", "Directory created");
else } else {
Log.e("TrackDownloader", "Directory creation failed"); Log.e("TrackDownloader", "Directory creation failed");
} }
var outputFile = new File(outDir, IOUtils.getValidFileName( }
MusicTrackUtils.getArtists(track) + " - " + Mp3Downloader.getTitle(track)) + ".mp3"); File outputFile = new File(outDir, IOUtils.getValidFileName(MusicTrackUtils.getArtists(track) + " - " + Mp3Downloader.getTitle(track)) + ".mp3");
VTExecutors.getMusicDownloadExecutor().submit(() -> new Mp3Downloader(outputFile).download(track, callback)); VTExecutors.getMusicDownloadExecutor().submit(() -> new Mp3Downloader(outputFile).download(track, callback, null));
} }
public static void cacheTrack(MusicTrack track, Callback callback) { public static void cacheTrack(MusicTrack track, Callback callback, Playlist playlist) {
if (MusicCacheImpl.isCachedTrack(LibVKXClient.asId(track))) if (MusicCacheImpl.isCachedTrack(LibVKXClient.asId(track))) {
return; return;
var outputFile = MusicCacheStorageUtils }
.getTrackFile(LibVKXClient.asId(track));
VTExecutors.getMusicDownloadExecutor().submit(() -> new CachedDownloader( File outputFile = MusicCacheStorageUtils.getTrackFile(LibVKXClient.asId(track));
new Mp3Downloader(outputFile)
).download(track, callback)); VTExecutors.getMusicDownloadExecutor().submit(() -> new CachedDownloader(new Mp3Downloader(outputFile)).download(track, callback, playlist));
} }
} }
@@ -1,6 +1,7 @@
package ru.vtosters.lite.music.interfaces; package ru.vtosters.lite.music.interfaces;
import com.vk.dto.music.MusicTrack; import com.vk.dto.music.MusicTrack;
import com.vk.dto.music.Playlist;
/** /**
* Interface for track downloaders * Interface for track downloaders
@@ -11,6 +12,7 @@ public interface ITrackDownloader {
* *
* @param track Music track * @param track Music track
* @param callback Callback to call when download status changes * @param callback Callback to call when download status changes
* @param playlist
*/ */
void download(MusicTrack track, Callback callback); void download(MusicTrack track, Callback callback, Playlist playlist);
} }
@@ -28,8 +28,7 @@ public class ThemesCore {
private static int darken_color; private static int darken_color;
static { static {
setExceptions(); init();
setThemedColors(ThemesUtils.getAccentColor());
} }
public static void setExceptions() { public static void setExceptions() {
@@ -201,4 +200,9 @@ public class ThemesCore {
public static boolean isCachedAccents() { public static boolean isCachedAccents() {
return cachedAccents; return cachedAccents;
} }
public static void init() {
setExceptions();
setThemedColors(ThemesUtils.getAccentColor());
}
} }
@@ -10,7 +10,7 @@ import ru.vtosters.lite.utils.NavigatorUtils;
public class InstallGMS { public class InstallGMS {
public static void alert(final Activity activity) { public static void alert(final Activity activity) {
if (!GmsHook.isAnyServicesInstalled() && Preferences.getBoolValue("showAlertGms", true)) { if (!GmsHook.isAnyServicesInstalled() && !GmsHook.isGmsInstalled() && Preferences.getBoolValue("showAlertGms", true)) {
new VkAlertDialog.Builder(activity) new VkAlertDialog.Builder(activity)
.setTitle(activity.getString(R.string.warning)) .setTitle(activity.getString(R.string.warning))
.setMessage(activity.getString(R.string.gmsissuesumm)) .setMessage(activity.getString(R.string.gmsissuesumm))
@@ -1,29 +1,41 @@
package ru.vtosters.lite.ui.fragments; package ru.vtosters.lite.ui.fragments;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText; import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import androidx.preference.Preference; import android.widget.TextView;
import bruhcollective.itaysonlab.libvkx.client.LibVKXClient; import bruhcollective.itaysonlab.libvkx.client.LibVKXClient;
import com.vk.core.dialogs.alert.VkAlertDialog; import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.dto.music.Playlist;
import com.vtosters.lite.ui.SummaryListPreference; import com.vtosters.lite.ui.SummaryListPreference;
import ru.vtosters.hooks.other.Preferences; import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.hooks.other.ThemesUtils; import ru.vtosters.hooks.other.ThemesUtils;
import ru.vtosters.lite.downloaders.AudioDownloader; import ru.vtosters.lite.downloaders.AudioDownloader;
import ru.vtosters.lite.music.LastFMScrobbler; import ru.vtosters.lite.music.LastFMScrobbler;
import ru.vtosters.lite.music.cache.MusicCacheImpl; import ru.vtosters.lite.music.cache.MusicCacheImpl;
import ru.vtosters.lite.music.cache.delegate.PlaylistCacheDbDelegate;
import ru.vtosters.lite.ui.PreferenceFragmentUtils; import ru.vtosters.lite.ui.PreferenceFragmentUtils;
import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.LifecycleUtils; import ru.vtosters.lite.utils.LifecycleUtils;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import static ru.vtosters.hooks.other.Preferences.getBoolValue;
import static ru.vtosters.hooks.other.ThemesUtils.getTextAttr;
public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment { public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
private static final ExecutorService executor = Executors.newCachedThreadPool(); private static final ExecutorService executor = Executors.newCachedThreadPool();
@SuppressLint("DefaultLocale")
@Override @Override
public void onCreate(Bundle bundle) { public void onCreate(Bundle bundle) {
super.onCreate(bundle); super.onCreate(bundle);
@@ -44,12 +56,38 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
if (MusicCacheImpl.isEmpty()) { if (MusicCacheImpl.isEmpty()) {
AndroidUtils.sendToast(requireContext().getString(com.vtosters.lite.R.string.no_cache_error)); AndroidUtils.sendToast(requireContext().getString(com.vtosters.lite.R.string.no_cache_error));
} else { } else {
delcache(requireContext()); delcache(requireContext(), false);
} }
return true; return true;
} }
); );
if (MusicCacheImpl.hasPlaylist()) {
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"cached_playlists",
"Кешированные плейлисты",
String.format("Скачано плейлистов: %d", MusicCacheImpl.getPlaylists().size()),
null,
preference -> {
cachedPlaylistsDialog(requireContext());
return true;
}
);
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"cached_playlists",
"Удалить все скачанные плейлисты",
null,
null,
preference -> {
delcache(requireContext(), true);
return true;
}
);
}
PreferenceFragmentUtils.addPreference( PreferenceFragmentUtils.addPreference(
getPreferenceScreen(), getPreferenceScreen(),
"audio_download", "audio_download",
@@ -75,15 +113,38 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
} }
).setEnabled(!MusicCacheImpl.isEmpty()); ).setEnabled(!MusicCacheImpl.isEmpty());
PreferenceFragmentUtils.addMaterialSwitchPreference( PreferenceFragmentUtils.addPreference(
getPreferenceScreen(), getPreferenceScreen(),
"autocache", "autocache_params",
getString(com.vtosters.lite.R.string.autocache_title), getString(com.vtosters.lite.R.string.autocache_title),
getString(com.vtosters.lite.R.string.autocache_summ), getAutocacheSumm(),
null, null,
false, preference -> {
(preference, o) -> { List<String> items = Arrays.asList("Не кешировать", "Только свои", "Все");
Preferences.getPreferences().edit().putBoolean("autocache", (boolean) o).apply();
ArrayAdapter<String> adapter = new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, items) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = (TextView) super.getView(position, convertView, parent);
textView.setTextColor(getTextAttr());
return textView;
}
};
int selectedItem = Preferences.getPreferences().getInt("autocaching", 0);
if (selectedItem >= 0 && selectedItem < items.size()) {
adapter.getItem(selectedItem);
}
new VkAlertDialog.Builder(getActivity())
.setAdapter(adapter, (dialog, which) -> {
adapter.getItem(which);
Preferences.getPreferences().edit().putInt("autocaching", which).apply();
findPreference("autocache_params").setSummary(getAutocacheSumm());
dialog.cancel();
})
.show();
return true; return true;
} }
); );
@@ -99,6 +160,7 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
false, false,
(preference, o) -> { (preference, o) -> {
Preferences.getPreferences().edit().putBoolean("dldir", (boolean) o).apply(); Preferences.getPreferences().edit().putBoolean("dldir", (boolean) o).apply();
LifecycleUtils.restartApplicationWithTimer();
return true; return true;
} }
); );
@@ -147,6 +209,7 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
return; return;
} }
Preferences.setMetadataSeparator(separator.getText().toString()); Preferences.setMetadataSeparator(separator.getText().toString());
findPreference("metadataSeparator").setSummary(separator.getText().toString());
}) })
.setNegativeButton("Отмена", (dialog, which) -> dialog.cancel()) .setNegativeButton("Отмена", (dialog, which) -> dialog.cancel())
.show(); .show();
@@ -155,6 +218,33 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
} }
); );
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), "Рекомендации музыки");
PreferenceFragmentUtils.addMaterialSwitchPreference(
getPreferenceScreen(),
"sendMusicMetrics",
"Отправлять статистику",
"Статистика прослушиваний необходима для работы рекомендаций и истории прослушивания музыки",
null,
true,
(preference, o) -> {
Preferences.getPreferences().edit().putBoolean("sendMusicMetrics", (boolean) o).apply();
return true;
}
);
PreferenceFragmentUtils.addMaterialSwitchPreference(
getPreferenceScreen(),
"playStatCatalog",
"Список истории прослушиваний",
"Показывать вкладку истории прослушиваний в музыкальном разделе\n\nОтключение ускорит открытие музыкального раздела при медленном интернете",
null,
false,
(preference, o) -> {
Preferences.getPreferences().edit().putBoolean("playStatCatalog", (boolean) o).apply();
return true;
}
).setVisible(Preferences.sendMusicMetrics() && !getBoolValue("useOldAppVer", false));
if (!Preferences.serverFeaturesDisable()) { if (!Preferences.serverFeaturesDisable()) {
PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), "Интеграция Genius"); PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), "Интеграция Genius");
PreferenceFragmentUtils.addMaterialSwitchPreference( PreferenceFragmentUtils.addMaterialSwitchPreference(
@@ -262,6 +352,19 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
list.setVisible(!Preferences.getBoolValue("useOldAppVer", false)); list.setVisible(!Preferences.getBoolValue("useOldAppVer", false));
getPreferenceScreen().addPreference(list); getPreferenceScreen().addPreference(list);
PreferenceFragmentUtils.addMaterialSwitchPreference(
getPreferenceScreen(),
"playlistsCatalogs",
"Списки плейлистов",
"Показывать вкладку плейлистов и альбомов прослушиваний в музыкальном разделе\n\nОтключение ускорит открытие музыкального раздела при медленном интернете",
null,
true,
(preference, o) -> {
Preferences.getPreferences().edit().putBoolean("playlistsCatalogs", (boolean) o).apply();
return true;
}
).setVisible(!getBoolValue("useOldAppVer", false));
} }
private void lastfmAuth(Context ctx) { private void lastfmAuth(Context ctx) {
@@ -301,6 +404,15 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
.show(); .show();
} }
private static String getAutocacheSumm() {
int autocache = Preferences.autocache();
return switch (autocache) {
case 1 -> "Только для своих";
case 2 -> "Кешировать всё";
default -> "Отключено";
};
}
public void updateLastFmPref() { public void updateLastFmPref() {
if (LastFMScrobbler.isLoggedIn()) { if (LastFMScrobbler.isLoggedIn()) {
findPreference("lastfm_auth").setSummary(getString(com.vtosters.lite.R.string.lastfm_authorized_as) + " " + LastFMScrobbler.getUserName()); findPreference("lastfm_auth").setSummary(getString(com.vtosters.lite.R.string.lastfm_authorized_as) + " " + LastFMScrobbler.getUserName());
@@ -322,14 +434,43 @@ public class MusicFragment extends TrackedMaterialPreferenceToolbarFragment {
.show(); .show();
} }
private void delcache(Context ctx) { @SuppressLint("DefaultLocale")
private void cachedPlaylistsDialog(Context ctx) {
List<Playlist> playlists = PlaylistCacheDbDelegate.getAllPlaylists(ctx);
String[] playlistNames = new String[playlists.size()];
for (int i = 0; i < playlists.size(); i++) {
playlistNames[i] = playlists.get(i).g; // Assuming Playlist class has a getTitle() method
}
VkAlertDialog.Builder builder = new VkAlertDialog.Builder(ctx);
builder.setTitle("Скачанные плейлисты");
builder.setItems(playlistNames, (dialog, which) -> {
Playlist selectedPlaylist = playlists.get(which);
String playlistId = selectedPlaylist.v1();
PlaylistCacheDbDelegate.deletePlaylist(ctx, playlistId);
AndroidUtils.sendToast("Плейлист удален");
findPreference("cached_playlists").setSummary(String.format("Скачано плейлистов: %d", MusicCacheImpl.getPlaylists().size()));
});
builder.show();
}
private void delcache(Context ctx, boolean isPlaylists) {
new VkAlertDialog.Builder(ctx) new VkAlertDialog.Builder(ctx)
.setTitle(com.vtosters.lite.R.string.warning) .setTitle(com.vtosters.lite.R.string.warning)
.setMessage(com.vtosters.lite.R.string.cached_tracks_remove_confirm) .setMessage(com.vtosters.lite.R.string.cached_tracks_remove_confirm)
.setPositiveButton(com.vtosters.lite.R.string.yes, .setPositiveButton(com.vtosters.lite.R.string.yes, (dialog, which) -> {
(dialog, which) -> executor.submit(MusicCacheImpl::clear)) executor.submit(() -> {
.setNeutralButton(com.vtosters.lite.R.string.no, if (isPlaylists) {
(dialog, which) -> dialog.cancel()) PlaylistCacheDbDelegate.removeAllPlaylists(ctx);
} else {
PlaylistCacheDbDelegate.deletePlaylist(ctx, AccountManagerUtils.getUserId() + "_-1");
}
});
findPreference("cached_tracks").setSummary(String.format(requireContext().getString(com.vtosters.lite.R.string.cached_tracks_counter), MusicCacheImpl.getTracksCount()));
})
.setNeutralButton(com.vtosters.lite.R.string.no, (dialog, which) -> dialog.cancel())
.show(); .show();
} }
@@ -60,12 +60,12 @@ public class OtherFragment extends TrackedMaterialPreferenceToolbarFragment {
return true; return true;
}); });
findPreference("microgsettings").setVisible(GmsHook.isFakeGmsInstalled() && !GmsHook.isGmsInstalled()); findPreference("microgsettings").setVisible(GmsHook.isAnyServicesInstalled() && !GmsHook.isGmsInstalled());
findPreference("microgsettings").setOnPreferenceClickListener(preference -> { findPreference("microgsettings").setOnPreferenceClickListener(preference -> {
try { try {
Intent intent = new Intent(Intent.ACTION_MAIN); Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName((GmsHook.isFakeGms2Installed() ? "app.revanced.android.gms" : "com.mgoogle.android.gms"), "org.microg.gms.ui.SettingsActivity")); intent.setComponent(new ComponentName(GmsHook.getCurrentGms() + ".android.gms", "org.microg.gms.ui.SettingsActivity"));
startActivity(intent); startActivity(intent);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -81,6 +81,17 @@ public class OtherFragment extends TrackedMaterialPreferenceToolbarFragment {
return true; return true;
}); });
findPreference("unstableNameChangerDrop").setOnPreferenceClickListener(preference -> {
RenameTool.clearDatabase();
LifecycleUtils.restartApplicationWithTimer();
return true;
});
findPreference("unstableNameChanger").setOnPreferenceChangeListener((preference, o) -> {
LifecycleUtils.restartApplicationWithTimer();
return true;
});
findPreference("copydebuginfo").setOnPreferenceClickListener(preference -> { findPreference("copydebuginfo").setOnPreferenceClickListener(preference -> {
copyText(new DeviceInfoCollector().collect().forLogging()); copyText(new DeviceInfoCollector().collect().forLogging());
Toast.makeText(requireContext(), AndroidUtils.getString("device_info_copied"), Toast.LENGTH_SHORT).show(); Toast.makeText(requireContext(), AndroidUtils.getString("device_info_copied"), Toast.LENGTH_SHORT).show();
@@ -92,6 +103,11 @@ public class OtherFragment extends TrackedMaterialPreferenceToolbarFragment {
return true; return true;
}); });
findPreference("batchmessages").setOnPreferenceChangeListener((preference, o) -> {
LifecycleUtils.restartApplicationWithTimer();
return true;
});
findPreference("copyownlink").setOnPreferenceClickListener(preference -> { findPreference("copyownlink").setOnPreferenceClickListener(preference -> {
copyText("https://vk.com/id" + AccountManagerUtils.getUserId()); copyText("https://vk.com/id" + AccountManagerUtils.getUserId());
ToastUtils.a(requireContext().getString(R.string.link_copied)); ToastUtils.a(requireContext().getString(R.string.link_copied));
@@ -227,6 +227,23 @@ public class SponsorPostFragment extends TrackedMaterialPreferenceToolbarFragmen
} }
); );
if (NetworkUtils.isNetworkConnected()) {
PreferenceFragmentUtils.addPreference(
getPreferenceScreen(),
"",
"Обновить списки фильтров",
null,
null,
preference -> {
this.requireActivity().runOnUiThread(() -> {
FiltersPreferences.forceUpdateFilters();
AndroidUtils.sendToast("Обновлено");
});
return false;
}
);
}
PreferenceFragmentUtils.addPreference( PreferenceFragmentUtils.addPreference(
getPreferenceScreen(), getPreferenceScreen(),
"", "",
@@ -13,6 +13,8 @@ import ru.vtosters.lite.ui.PreferenceFragmentUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.VersionReader; import ru.vtosters.lite.utils.VersionReader;
import static ru.vtosters.hooks.GmsHook.isSpoofPackageInstalled;
public class SystemInfo extends TrackedMaterialPreferenceToolbarFragment { public class SystemInfo extends TrackedMaterialPreferenceToolbarFragment {
@Override @Override
@@ -46,11 +48,11 @@ public class SystemInfo extends TrackedMaterialPreferenceToolbarFragment {
boolean isZenUI = OEMDetector.isZenUI(); boolean isZenUI = OEMDetector.isZenUI();
boolean isEMUI = OEMDetector.isEMUI(); boolean isEMUI = OEMDetector.isEMUI();
boolean hasMiuiIncrCode = OEMDetector.hasMiuiIncrCode(); boolean hasMiuiIncrCode = OEMDetector.hasMiuiIncrCode();
boolean isHyperOS = OEMDetector.isHyperOs();
boolean hasGMS = GmsHook.isGmsInstalled(); boolean hasGMS = GmsHook.isGmsInstalled();
boolean hasVancedMicroG = GmsHook.isFakeGmsInstalled(); boolean hasVancedMicroG = GmsHook.isAnyServicesInstalled();
boolean hasReVancedMicroG = GmsHook.isFakeGms2Installed(); String GMSPackageName = hasGMS ? "com.google.android.gms" : hasVancedMicroG ? GmsHook.getCurrentGms() + ".android.gms" : "no gms or microg";
String GMSPackageName = hasGMS ? "com.google.android.gms" : hasVancedMicroG ? "com.mgoogle.android.gms" : hasReVancedMicroG ? "app.revanced.android.gms" : "no gms or microg";
boolean isValidSignature = Preferences.isValidSignature(); boolean isValidSignature = Preferences.isValidSignature();
boolean isTablet = AndroidUtils.isTablet(); boolean isTablet = AndroidUtils.isTablet();
@@ -104,9 +106,7 @@ public class SystemInfo extends TrackedMaterialPreferenceToolbarFragment {
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isInstalledGoogleGMS", "Value: " + hasGMS, 0, null); PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isInstalledGoogleGMS", "Value: " + hasGMS, 0, null);
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isInstalledVancedMicroG", "Value: " + hasVancedMicroG, 0, null); PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isInstalledMicroG", "Value: " + hasVancedMicroG, 0, null);
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isInstalledReVancedMicroG", "Value: " + hasReVancedMicroG, 0, null);
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "Product Name", productName, 0, preference -> { PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "Product Name", productName, 0, preference -> {
((ClipboardManager) requireActivity().getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText("MBH-ST", productName)); ((ClipboardManager) requireActivity().getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText("MBH-ST", productName));
@@ -194,6 +194,8 @@ public class SystemInfo extends TrackedMaterialPreferenceToolbarFragment {
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isMiui", "Value: " + isMiui, 0, null); PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isMiui", "Value: " + isMiui, 0, null);
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isHyperOS", "Value: " + isHyperOS, 0, null);
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isEMUI", "Value: " + isEMUI, 0, null); PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isEMUI", "Value: " + isEMUI, 0, null);
PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isFlyme", "Value: " + isFlyme, 0, null); PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isFlyme", "Value: " + isFlyme, 0, null);
@@ -108,7 +108,7 @@ public class VTSettings extends TrackedMaterialPreferenceToolbarFragment {
boolean isLinksUnverified = AndroidUtils.isLinksUnverified(requireActivity()); boolean isLinksUnverified = AndroidUtils.isLinksUnverified(requireActivity());
boolean isDozingAvailable = Build.VERSION.SDK_INT >= 23 && !manager.isIgnoringBatteryOptimizations(AndroidUtils.getPackageName()); boolean isDozingAvailable = Build.VERSION.SDK_INT >= 23 && !manager.isIgnoringBatteryOptimizations(AndroidUtils.getPackageName());
boolean areNotificationsDisabled = !AndroidUtils.areNotificationsEnabled() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; boolean areNotificationsDisabled = !AndroidUtils.areNotificationsEnabled() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
boolean isGMSNotInstalled = !GmsHook.isAnyServicesInstalled(); boolean isGMSNotInstalled = !GmsHook.isAnyServicesInstalled() && !GmsHook.isGmsInstalled();
if (AccountManagerUtils.isLogin()) { if (AccountManagerUtils.isLogin()) {
Preference accountSwitcher = PreferenceFragmentUtils.addPreference( Preference accountSwitcher = PreferenceFragmentUtils.addPreference(
@@ -584,7 +584,7 @@ public class VTSettings extends TrackedMaterialPreferenceToolbarFragment {
} }
); );
if (Build.VERSION.SDK_INT >= 33 && !OEMDetector.isMIUI()) { if (Build.VERSION.SDK_INT >= 33 && (!OEMDetector.isMIUI() || OEMDetector.isHyperOs())) {
PreferenceFragmentUtils.addPreference( PreferenceFragmentUtils.addPreference(
getPreferenceScreen(), getPreferenceScreen(),
"", "",
@@ -14,10 +14,12 @@ import com.vtosters.lite.api.ExtendedCommunityProfile;
import com.vtosters.lite.api.ExtendedUserProfile; import com.vtosters.lite.api.ExtendedUserProfile;
import kotlin.Unit; import kotlin.Unit;
import kotlin.jvm.b.Functions; import kotlin.jvm.b.Functions;
import ru.vtosters.hooks.RenameHook;
import ru.vtosters.hooks.other.Preferences; import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.foaf.FoafBase; import ru.vtosters.lite.foaf.FoafBase;
import ru.vtosters.lite.utils.AccountManagerUtils; import ru.vtosters.lite.utils.AccountManagerUtils;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.RenameTool;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@@ -66,10 +68,12 @@ public class MenuBuilder {
return Unit.a; return Unit.a;
}); });
// addItem(builder, AndroidUtils.getString(R.string.menu_change_name), () -> { if (RenameHook.isEnabled()) {
// RenameTool.createDialog(eup, ctx); addItem(builder, AndroidUtils.getString(R.string.menu_change_name), () -> {
// return Unit.a; RenameTool.createDialog(eup, ctx);
// }); return Unit.a;
});
}
addItem(builder, AndroidUtils.getString(isPageWhitelistedFilter ? R.string.remove_from_filter_whitelist : R.string.add_to_filter_whitelist), () -> { addItem(builder, AndroidUtils.getString(isPageWhitelistedFilter ? R.string.remove_from_filter_whitelist : R.string.add_to_filter_whitelist), () -> {
setWhitelistedFilter(eup, !isPageWhitelistedFilter); setWhitelistedFilter(eup, !isPageWhitelistedFilter);
@@ -83,7 +87,7 @@ public class MenuBuilder {
return Unit.a; return Unit.a;
}); });
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace(); e.fillInStackTrace();
} }
} }
@@ -100,10 +104,12 @@ public class MenuBuilder {
return Unit.a; return Unit.a;
}); });
// addItem(builder, AndroidUtils.getString(R.string.menu_change_name), () -> { if (RenameHook.isEnabled()) {
// RenameTool.createDialogGroup(ecp, ctx); addItem(builder, AndroidUtils.getString(R.string.menu_change_name), () -> {
// return Unit.a; RenameTool.createDialogGroup(ecp, ctx);
// }); return Unit.a;
});
}
addItem(builder, AndroidUtils.getString(isPageWhitelistedFilter ? R.string.remove_from_filter_whitelist : R.string.add_to_filter_whitelist), () -> { addItem(builder, AndroidUtils.getString(isPageWhitelistedFilter ? R.string.remove_from_filter_whitelist : R.string.add_to_filter_whitelist), () -> {
setWhitelistedFilter(ecp, !isPageWhitelistedFilter); setWhitelistedFilter(ecp, !isPageWhitelistedFilter);
@@ -123,7 +129,7 @@ public class MenuBuilder {
return Unit.a; return Unit.a;
}); });
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace(); e.fillInStackTrace();
} }
} }
@@ -0,0 +1,107 @@
package ru.vtosters.lite.utils;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.os.Build;
import android.util.Log;
import com.vk.core.network.Network;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Request;
import okhttp3.Response;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import static com.vk.core.network.Network.ClientType.CLIENT_API;
import static ru.vtosters.hooks.other.Preferences.getBoolValue;
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
public class Metrics {
private static JSONArray events = new JSONArray();
public static void trackEvents(JSONObject object, boolean isMusic) {
if (NetworkUtils.isNetworkConnected()) {
handleNetworkConnected(object, isMusic);
} else {
handleNetworkDisconnected(object, isMusic);
}
}
private static void handleNetworkConnected(JSONObject object, boolean isMusic) {
if (isMusic || shouldSaveUserTraffic() || events.length() > 0) {
trackEventsImmediately(object);
} else {
trackEventList(object);
}
}
private static void handleNetworkDisconnected(JSONObject object, boolean isMusic) {
if (!isMusic) {
events.put(object);
}
}
private static boolean shouldSaveUserTraffic() {
return getBoolValue("isRoamingState", false) || isMobileNetwork();
}
private static void trackEventList(JSONObject object) {
events.put(object);
if (events.length() > 2) {
trackEventsRequest(events);
resetEvents();
}
}
private static void trackEventsImmediately(JSONObject object) {
JSONArray eventsToTrack = new JSONArray();
eventsToTrack.put(object);
trackEventsRequest(eventsToTrack);
}
private static void resetEvents() {
events = new JSONArray();
}
@SuppressWarnings("deprecation")
private static boolean isMobileNetwork() {
ConnectivityManager connectivityManager = (ConnectivityManager) AndroidUtils.getGlobalContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
android.net.Network network = connectivityManager.getActiveNetwork();
if (network != null) {
NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
return networkCapabilities != null && networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
}
} else {
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
return networkInfo != null && networkInfo.isConnected();
}
return false;
}
private static void trackEventsRequest(JSONArray object) {
Request req = new Request.a()
.b("https://" + getApi() + "/method/stats.trackEvents?events=" + object.toString() + "&v=5.119&access_token=" + getUserToken())
.a();
Network.b(CLIENT_API).a(req).a(new Callback() {
@Override
public void a(Call call, IOException e) {
e.fillInStackTrace();
}
@Override
public void a(Call call, Response response) throws IOException {
Log.d("Metrics", response.a().g());
}
});
}
}
@@ -9,24 +9,24 @@ import static ru.vtosters.lite.foaf.FoafBase.getBypassedOnlineInfo;
public class OnlineBypass { public class OnlineBypass {
public static JSONObject setOnlineInfo(JSONObject json) throws JSONException { public static JSONObject setOnlineInfo(JSONObject json) throws JSONException {
var id = json.optInt("id"); int id = json.optInt("id");
if (id == AccountManagerUtils.getUserId()) { if (id == AccountManagerUtils.getUserId()) {
return json; return json;
} }
var onlineinfo = json.optJSONObject("online_info"); JSONObject onlineinfo = json.optJSONObject("online_info");
if (onlineinfo != null && !onlineinfo.optBoolean("visible") && !Preferences.serverFeaturesDisable()) { if (onlineinfo != null && !onlineinfo.optBoolean("visible") && !Preferences.serverFeaturesDisable()) {
var bypassed = getBypassedOnlineInfo(id); var bypassed = getBypassedOnlineInfo(id);
if (bypassed.optInt("last_seen", 0) != 0) { if (bypassed.optInt("last_seen", 0) != 0) {
json.remove("online_info"); json.remove("online_info");
var online_info = new JSONObject() JSONObject online_info = new JSONObject()
.put("visible", true) .put("visible", true)
.put("last_seen", bypassed.optInt("last_seen")) .put("last_seen", bypassed.optInt("last_seen"))
.put("is_online", bypassed.optBoolean("is_online")) .put("is_online", bypassed.optBoolean("is_online"))
.put("app_id", bypassed.optInt("app_id")) .put("app_id", bypassed.optInt("app_id"))
.put("is_mobile", bypassed.optBoolean("is_mobile")); .put("is_mobile", bypassed.optBoolean("is_mobile"));
var last_seen = new JSONObject() JSONObject last_seen = new JSONObject()
.put("platform", bypassed.optInt("platform")) .put("platform", bypassed.optInt("platform"))
.put("time", bypassed.optInt("last_seen")); .put("time", bypassed.optInt("last_seen"));
@@ -37,51 +37,95 @@ public class OnlineBypass {
return json; return json;
} }
public static JSONArray setOnlineInfoUsers(JSONArray profiles) throws JSONException { public static JSONArray setOnlineInfoUsers(JSONArray profiles) {
if (profiles == null || profiles.length() == 0 || Preferences.serverFeaturesDisable()) return profiles; if (shouldReturnProfiles(profiles)) return profiles;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
var curVkId = AccountManagerUtils.getUserId(); int curVkId = AccountManagerUtils.getUserId();
for (int i = 0; i < profiles.length(); i++) { for (int i = 0; i < profiles.length(); i++) {
JSONObject profile = profiles.getJSONObject(i); JSONObject profile = getProfile(profiles, i);
int id = profile.optInt("id", -1); int id = profile.optInt("id", -1);
JSONObject onlinfo = profile.optJSONObject("online_info"); JSONObject onlinfo = profile.optJSONObject("online_info");
if (id == curVkId || id < 0 || onlinfo == null || onlinfo.optBoolean("visible")) {
continue; if (shouldSkipProfile(id, curVkId, onlinfo)) continue;
}
sb.append(id); sb.append(id).append(",");
sb.append(",");
}
var ids = sb.toString();
if (!ids.isEmpty()) {
ids = ids.substring(0, ids.length() - 1);
} else {
return profiles;
} }
String ids = prepareIds(sb);
if (ids.isEmpty()) return profiles;
JSONObject bypassedObj = getBypassedOnlineInfo(ids); JSONObject bypassedObj = getBypassedOnlineInfo(ids);
for (int i = 0; i < profiles.length(); i++) { for (int i = 0; i < profiles.length(); i++) {
JSONObject profile = profiles.getJSONObject(i); JSONObject profile = getProfile(profiles, i);
int id = profile.optInt("id"); int id = profile.optInt("id");
JSONObject bypassed = bypassedObj.optJSONObject(Integer.toString(id)); JSONObject bypassed = bypassedObj.optJSONObject(Integer.toString(id));
if (bypassed == null) {
continue;
}
profile.remove("online_info");
var online_info = new JSONObject() if (bypassed == null) continue;
JSONObject online_info = createOnlineInfo(bypassed);
JSONObject last_seen = createLastSeen(bypassed);
updateProfile(profile, online_info, last_seen);
}
return profiles;
}
private static boolean shouldReturnProfiles(JSONArray profiles) {
return profiles == null || profiles.length() == 0 || Preferences.serverFeaturesDisable();
}
private static JSONObject getProfile(JSONArray profiles, int i) {
try {
return profiles.getJSONObject(i);
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
private static boolean shouldSkipProfile(int id, int curVkId, JSONObject onlinfo) {
return id == curVkId || id < 0 || onlinfo == null || onlinfo.optBoolean("visible");
}
private static String prepareIds(StringBuilder sb) {
String ids = sb.toString();
if (!ids.isEmpty()) {
ids = ids.substring(0, ids.length() - 1);
}
return ids;
}
private static JSONObject createOnlineInfo(JSONObject bypassed) {
try {
return new JSONObject()
.put("visible", true) .put("visible", true)
.put("last_seen", bypassed.optInt("last_seen")) .put("last_seen", bypassed.optInt("last_seen"))
.put("is_online", bypassed.optBoolean("is_online")) .put("is_online", bypassed.optBoolean("is_online"))
.put("app_id", bypassed.optInt("app_id")) .put("app_id", bypassed.optInt("app_id"))
.put("is_mobile", bypassed.optBoolean("is_mobile")); .put("is_mobile", bypassed.optBoolean("is_mobile"));
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
var last_seen = new JSONObject() private static JSONObject createLastSeen(JSONObject bypassed) {
try {
return new JSONObject()
.put("platform", bypassed.optInt("platform")) .put("platform", bypassed.optInt("platform"))
.put("time", bypassed.optInt("last_seen")); .put("time", bypassed.optInt("last_seen"));
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
private static void updateProfile(JSONObject profile, JSONObject online_info, JSONObject last_seen) {
try {
profile.remove("online_info");
profile.put("last_seen", last_seen).put("online_info", online_info); profile.put("last_seen", last_seen).put("online_info", online_info);
} catch (JSONException e) {
throw new RuntimeException(e);
} }
return profiles;
} }
} }
@@ -1,5 +1,6 @@
package ru.vtosters.lite.utils; package ru.vtosters.lite.utils;
import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
@@ -12,15 +13,15 @@ import android.widget.LinearLayout;
import androidx.core.util.Pair; import androidx.core.util.Pair;
import com.vk.core.dialogs.alert.VkAlertDialog; import com.vk.core.dialogs.alert.VkAlertDialog;
import com.vk.dto.user.UserProfile; import com.vk.dto.user.UserProfile;
import com.vk.im.engine.models.users.User;
import com.vtosters.lite.R; import com.vtosters.lite.R;
import com.vtosters.lite.api.ExtendedCommunityProfile; import com.vtosters.lite.api.ExtendedCommunityProfile;
import com.vtosters.lite.api.ExtendedUserProfile; import com.vtosters.lite.api.ExtendedUserProfile;
import ru.vtosters.hooks.other.ThemesUtils; import ru.vtosters.hooks.other.ThemesUtils;
import java.lang.reflect.Field; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.function.BiConsumer;
import static ru.vtosters.hooks.other.ThemesUtils.getSTextAttr; import static ru.vtosters.hooks.other.ThemesUtils.getSTextAttr;
import static ru.vtosters.hooks.other.ThemesUtils.getTextAttr; import static ru.vtosters.hooks.other.ThemesUtils.getTextAttr;
@@ -47,69 +48,40 @@ public class RenameTool {
return helperInstance; return helperInstance;
} }
public static String getCurrentModifiedUser() {
Cursor rawQuery = getHelper().getReadableDatabase().rawQuery(String.format("SELECT * FROM %s WHERE %s=%s", TABLE_NAME, COLUMN_VKID, AccountManagerUtils.getUserId()), new String[0]);
if (rawQuery.moveToFirst()) {
try {
String decode = URLDecoder.decode(rawQuery.getString(rawQuery.getColumnIndexOrThrow(COLUMN_FIRSTNAME)), "UTF-8");
return decode + " " + URLDecoder.decode(rawQuery.getString(rawQuery.getColumnIndexOrThrow(COLUMN_LASTNAME)), "UTF-8");
} catch (java.io.UnsupportedEncodingException | java.lang.IllegalArgumentException e) {
e.printStackTrace();
} finally {
rawQuery.close();
}
} else rawQuery.close();
return null;
}
// Reload all values from DB
public static void reloadDB() { public static void reloadDB() {
renamedGroups.clear(); renamedGroups.clear();
renamedUsers.clear(); renamedUsers.clear();
updateRequested = false; updateRequested = false;
try (Cursor cursor = getHelper().getReadableDatabase().rawQuery(String.format("SELECT * FROM %s", TABLE_NAME), new String[0])) { loadData(TABLE_NAME, (cursor, vkID) -> {
while (cursor.moveToNext()) { String firstName = decode(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_FIRSTNAME)));
String firstName = URLDecoder.decode(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_FIRSTNAME)), "UTF-8"); String lastName = decode(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_LASTNAME)));
String lastName = URLDecoder.decode(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_LASTNAME)), "UTF-8");
int vkID = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_VKID));
renamedUsers.put(vkID, new Pair<>(firstName, lastName)); renamedUsers.put(vkID, new Pair<>(firstName, lastName));
} });
} catch (Exception e) {
e.printStackTrace();
}
try (Cursor cursor = getHelper().getReadableDatabase().rawQuery(String.format("SELECT * FROM %s", TABLE_NAME_GROUP), new String[0])) { loadData(TABLE_NAME_GROUP, (cursor, vkID) -> {
while (cursor.moveToNext()) { String name = decode(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME)));
String name = URLDecoder.decode(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME)), "UTF-8");
int vkID = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_VKID));
renamedGroups.put(vkID, name); renamedGroups.put(vkID, name);
});
}
// Generic method to load data from the database
private static void loadData(String tableName, BiConsumer<Cursor, Integer> consumer) {
try (Cursor cursor = getHelper().getReadableDatabase().rawQuery("SELECT * FROM " + tableName, null)) {
while (cursor.moveToNext()) {
int vkID = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_VKID));
consumer.accept(cursor, vkID);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); throw new RuntimeException("Failed to load data from " + tableName, e);
} }
} }
public static void injectIntoChat(User u) { private static String decode(String value) {
int id = u.getId();
if (updateRequested) {
reloadDB();
}
Pair<String, String> user = renamedUsers.get(id);
if (user == null) return;
setObject(u, "I", user.first);
setObject(u, "J", user.second);
}
public static void setObject(User instance, String name, Object obj) {
try { try {
Field f = User.class.getDeclaredField(name); return URLDecoder.decode(value, "UTF-8");
f.setAccessible(true); } catch (UnsupportedEncodingException e) {
f.set(instance, obj); throw new RuntimeException("UTF-8 encoding not supported", e);
} catch (Exception e) {
e.printStackTrace();
} }
} }
@@ -117,7 +89,7 @@ public class RenameTool {
LinearLayout linearLayout = new LinearLayout(ctx); LinearLayout linearLayout = new LinearLayout(ctx);
linearLayout.setOrientation(LinearLayout.VERTICAL); linearLayout.setOrientation(LinearLayout.VERTICAL);
final EditText fn = new EditText(ctx); EditText fn = new EditText(ctx);
fn.setHint(R.string.vk_auth_sign_up_first_name); fn.setHint(R.string.vk_auth_sign_up_first_name);
fn.setTextColor(getTextAttr()); fn.setTextColor(getTextAttr());
fn.setHintTextColor(getSTextAttr()); fn.setHintTextColor(getSTextAttr());
@@ -128,7 +100,7 @@ public class RenameTool {
margin.setMargins(dp2px(20f), 0, dp2px(20f), 0); margin.setMargins(dp2px(20f), 0, dp2px(20f), 0);
fn.setLayoutParams(margin); fn.setLayoutParams(margin);
final EditText ln = new EditText(ctx); EditText ln = new EditText(ctx);
ln.setHint(R.string.vk_auth_sign_up_last_name); ln.setHint(R.string.vk_auth_sign_up_last_name);
ln.setTextColor(getTextAttr()); ln.setTextColor(getTextAttr());
ln.setHintTextColor(getSTextAttr()); ln.setHintTextColor(getSTextAttr());
@@ -137,69 +109,93 @@ public class RenameTool {
ln.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT; ln.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
ln.setLayoutParams(margin); ln.setLayoutParams(margin);
final UserProfile profile = AccountManagerUtils.fromEup(eup); UserProfile profile = AccountManagerUtils.fromEup(eup);
fn.setText(AccountManagerUtils.getUserFirstName(profile)); fn.setText(AccountManagerUtils.getUserFirstName(profile));
ln.setText(AccountManagerUtils.getUserLastName(profile)); ln.setText(AccountManagerUtils.getUserLastName(profile));
int id = AccountManagerUtils.getUserID(profile); int id = AccountManagerUtils.getUserID(profile);
var builder = new VkAlertDialog.Builder(ctx) VkAlertDialog.Builder builder = new VkAlertDialog.Builder(ctx)
.setTitle(R.string.rename_title) .setTitle(R.string.rename_title)
.setMessage(R.string.rename_message) .setMessage(R.string.rename_message)
.setView(linearLayout) .setView(linearLayout)
.setPositiveButton("OK", (dialog, which) -> { .setPositiveButton("OK", (dialog, which) -> updateName(ctx, fn.getText().toString(), ln.getText().toString(), id));
String firstName = fn.getText().toString();
String lastName = ln.getText().toString();
SQLiteDatabase writableDatabase = getHelper().getWritableDatabase();
try {
if (isChangedName(id)) { if (isChangedName(id)) {
writableDatabase.execSQL( builder.setNeutralButton(R.string.rename_reset, (dialog, which) -> deleteUser(ctx, id));
String.format("UPDATE %s SET %s='%s', %s='%s' WHERE %s='%s'",
TABLE_NAME,
COLUMN_FIRSTNAME, URLEncoder.encode(firstName, "UTF-8"),
COLUMN_LASTNAME, URLEncoder.encode(lastName, "UTF-8"),
COLUMN_VKID, id));
} else {
writableDatabase.execSQL(
String.format("INSERT INTO %s (%s, %s, %s) VALUES (%s, '%s', '%s')",
TABLE_NAME,
COLUMN_VKID, COLUMN_FIRSTNAME, COLUMN_LASTNAME,
id, URLEncoder.encode(firstName, "UTF-8"), URLEncoder.encode(lastName, "UTF-8")));
} }
builder.show();
}
public static void deleteUser(Context ctx, int id) {
SQLiteDatabase writableDatabase = getHelper().getWritableDatabase();
writableDatabase.delete(TABLE_NAME, COLUMN_VKID + "=?", new String[]{String.valueOf(id)});
updateRequested = true; updateRequested = true;
if (id == AccountManagerUtils.getUserId()) { notifyUser(ctx, id);
ctx.sendBroadcast(new Intent("com.vkontakte.android.USER_NAME_CHANGED"));
sendToast(ctx.getString(R.string.rename_remove_from_bd_success));
} }
ctx.sendBroadcast(new Intent("com.vkontakte.android.ACTION_PROFILE_UPDATED").putExtra("uid", id));
public static void clearDatabase() {
SQLiteDatabase writableDatabase = getHelper().getWritableDatabase();
writableDatabase.delete(TABLE_NAME, null, null);
writableDatabase.delete(TABLE_NAME_GROUP, null, null);
renamedGroups.clear();
renamedUsers.clear();
updateRequested = true;
}
public static void updateName(Context ctx, String firstName, String lastName, int id) {
SQLiteDatabase writableDatabase = getHelper().getWritableDatabase();
try {
ContentValues values = new ContentValues();
values.put(COLUMN_FIRSTNAME, encode(firstName));
values.put(COLUMN_LASTNAME, encode(lastName));
if (isChangedName(id)) {
// Update existing record
writableDatabase.update(TABLE_NAME, values, COLUMN_VKID + "=?", new String[]{String.valueOf(id)});
} else {
// Insert new record
values.put(COLUMN_VKID, id);
writableDatabase.insert(TABLE_NAME, null, values);
}
updateRequested = true;
notifyUser(ctx, id);
sendToast(ctx.getString(R.string.rename_success)); sendToast(ctx.getString(R.string.rename_success));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); throw new RuntimeException("Database operation failed", e);
sendToast(ctx.getString(R.string.rename_error));
} }
}); }
if (isChangedName(id))
builder.setNeutralButton(R.string.rename_reset, (dialog, which) -> { private static String encode(String value) {
getHelper().getWritableDatabase().execSQL( try {
String.format( return URLEncoder.encode(value, "UTF-8");
"DELETE FROM %s WHERE %s='%s'", } catch (UnsupportedEncodingException e) {
TABLE_NAME, throw new RuntimeException("UTF-8 encoding not supported", e);
COLUMN_VKID, id)); }
}
private static void notifyUser(Context ctx, int id) {
if (id == AccountManagerUtils.getUserId()) { if (id == AccountManagerUtils.getUserId()) {
ctx.sendBroadcast(new Intent("com.vkontakte.android.USER_NAME_CHANGED")); ctx.sendBroadcast(new Intent("com.vkontakte.android.USER_NAME_CHANGED"));
} }
updateRequested = true;
ctx.sendBroadcast(new Intent("com.vkontakte.android.ACTION_PROFILE_UPDATED").putExtra("uid", id)); ctx.sendBroadcast(new Intent("com.vkontakte.android.ACTION_PROFILE_UPDATED").putExtra("uid", id));
sendToast(ctx.getString(R.string.rename_remove_from_bd_success));
});
builder.show();
} }
public static void createDialogGroup(ExtendedCommunityProfile eup, final Context ctx) { public static void createDialogGroup(ExtendedCommunityProfile eup, final Context ctx) {
LinearLayout linearLayout = new LinearLayout(ctx); LinearLayout linearLayout = new LinearLayout(ctx);
linearLayout.setOrientation(LinearLayout.VERTICAL); linearLayout.setOrientation(LinearLayout.VERTICAL);
final EditText fn = new EditText(ctx); EditText fn = new EditText(ctx);
fn.setHint(R.string.vk_auth_sign_up_first_name); fn.setHint(R.string.vk_auth_sign_up_first_name);
fn.setHintTextColor(getSTextAttr()); fn.setHintTextColor(getSTextAttr());
fn.setTextColor(getTextAttr()); fn.setTextColor(getTextAttr());
@@ -210,50 +206,59 @@ public class RenameTool {
margin.setMargins(dp2px(20f), 0, dp2px(20f), 0); margin.setMargins(dp2px(20f), 0, dp2px(20f), 0);
fn.setLayoutParams(margin); fn.setLayoutParams(margin);
final UserProfile profile = AccountManagerUtils.fromEup(eup); UserProfile profile = AccountManagerUtils.fromEup(eup);
fn.setText(AccountManagerUtils.getGroupName(profile)); fn.setText(AccountManagerUtils.getGroupName(profile));
int fid = AccountManagerUtils.getUserID(profile); int fid = AccountManagerUtils.getUserID(profile);
if (fid < 0) fid = -fid; if (fid < 0) fid = -fid;
final int id = fid; int id = fid;
var builder = new VkAlertDialog.Builder(ctx) VkAlertDialog.Builder builder = new VkAlertDialog.Builder(ctx)
.setTitle(R.string.rename_title) .setTitle(R.string.rename_title)
.setMessage(R.string.rename_message) .setMessage(R.string.rename_message)
.setView(linearLayout) .setView(linearLayout)
.setPositiveButton("OK", (dialog, which) -> { .setPositiveButton("OK", (dialog, which) -> updateGroupName(ctx, fn.getText().toString(), id));
String firstName = fn.getText().toString();
SQLiteDatabase writableDatabase = getHelper().getWritableDatabase();
try {
if (isChangedNameGroup(id)) { if (isChangedNameGroup(id)) {
writableDatabase.execSQL( builder.setNeutralButton(R.string.rename_reset, (dialog, which) -> deleteGroupName(ctx, id));
String.format(
"UPDATE %s SET %s='%s' WHERE %s='%s'",
TABLE_NAME_GROUP,
COLUMN_NAME, URLEncoder.encode(firstName, "UTF-8"),
COLUMN_VKID, id));
} else {
writableDatabase.execSQL(
String.format(
"INSERT INTO %s (%s, %s) VALUES (%s, '%s')",
TABLE_NAME_GROUP,
COLUMN_VKID, COLUMN_NAME,
id, URLEncoder.encode(firstName, "UTF-8")));
} }
builder.show();
}
public static void deleteGroupName(Context ctx, int id) {
SQLiteDatabase writableDatabase = getHelper().getWritableDatabase();
writableDatabase.delete(TABLE_NAME_GROUP, COLUMN_VKID + "=?", new String[]{String.valueOf(id)});
updateRequested = true;
sendToast(ctx.getString(R.string.rename_remove_group_from_bd_success));
}
public static void updateGroupName(Context ctx, String groupName, int id) {
SQLiteDatabase writableDatabase = getHelper().getWritableDatabase();
try {
ContentValues values = new ContentValues();
values.put(COLUMN_NAME, encode(groupName));
if (isChangedNameGroup(id)) {
// Update existing record
writableDatabase.update(TABLE_NAME_GROUP, values, COLUMN_VKID + "=?", new String[]{String.valueOf(id)});
} else {
// Insert new record
values.put(COLUMN_VKID, id);
writableDatabase.insert(TABLE_NAME_GROUP, null, values);
}
updateRequested = true; updateRequested = true;
sendToast(AndroidUtils.getString(R.string.rename_group_success)); sendToast(AndroidUtils.getString(R.string.rename_group_success));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); throw new RuntimeException("Database operation failed", e);
} }
});
if (isChangedNameGroup(id))
builder.setNeutralButton(R.string.rename_reset, (dialog, which) -> {
getHelper().getWritableDatabase().execSQL(String.format("DELETE FROM %s WHERE %s='%s'", TABLE_NAME_GROUP, COLUMN_VKID, id));
updateRequested = true;
sendToast(ctx.getString(R.string.rename_remove_group_from_bd_success));
});
builder.show();
} }
public static boolean isChangedName(int uid) { public static boolean isChangedName(int uid) {
@@ -264,10 +269,6 @@ public class RenameTool {
return renamedGroups.get(uid) != null; return renamedGroups.get(uid) != null;
} }
public static boolean isIdInList(UserProfile profile) {
return true;
}
private static class DbHelper extends SQLiteOpenHelper { private static class DbHelper extends SQLiteOpenHelper {
public DbHelper(Context context) { public DbHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION); super(context, DB_NAME, null, DB_VERSION);
@@ -9,7 +9,6 @@ import static ru.vtosters.hooks.other.ThemesUtils.*;
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext; import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
public class WebViewColoringUtils { public class WebViewColoringUtils {
public static boolean isLoaded = false;
public static String loadedCSS = ""; public static String loadedCSS = "";
public static String loadedCSSAmoled = ""; public static String loadedCSSAmoled = "";
@@ -53,7 +52,6 @@ public class WebViewColoringUtils {
public static void load() { public static void load() {
loadedCSS = readCSS("vt_ui_accent.css"); loadedCSS = readCSS("vt_ui_accent.css");
loadedCSSAmoled = readCSS("vt_ui_oled.css"); loadedCSSAmoled = readCSS("vt_ui_oled.css");
isLoaded = true;
} }
public static void inject(WebView webView, String str) { public static void inject(WebView webView, String str) {
@@ -11,28 +11,36 @@ public class MusicCacheStorageUtils {
} }
@SuppressWarnings("ResultOfMethodCallIgnored") @SuppressWarnings("ResultOfMethodCallIgnored")
public static File getTrackDirById(final String trackId) { public static File getTrackDirById(String trackId) {
final var res = new File(getCacheStorageDir(), trackId); File res = new File(getCacheStorageDir(), trackId);
res.mkdirs(); res.mkdirs();
return res; return res;
} }
public static File getTrackFile(final String trackId) { public static File getTrackFile(String trackId) {
return new File(getTrackDirById(trackId), "track.mp3"); return new File(getTrackDirById(trackId), "track.mp3");
} }
@SuppressWarnings("ResultOfMethodCallIgnored") @SuppressWarnings("ResultOfMethodCallIgnored")
public static File getThumbDirById(final String trackId) { public static File getThumbDirById(String trackId) {
final var res = new File(getTrackDirById(trackId), "thumbs"); File res = new File(getTrackDirById(trackId), "thumbs");
res.mkdirs(); res.mkdirs();
return res; return res;
} }
public static File getTrackThumb(final String trackId, final int factor) { public static File getTrackThumb(String trackId, int factor) {
return new File(getThumbDirById(trackId), "thumb_" + factor + ".png"); return new File(getThumbDirById(trackId), "thumb_" + factor + ".png");
} }
public static void removeTrackDirById(final String trackId) { public static File getPlaylistThumb(String playlistId, int factor) {
return new File(getThumbDirById(playlistId), "thumb_playlist_" + factor + ".png");
}
public static void removePlaylistThumb(String playlistId) {
IOUtils.deleteRecursive(getThumbDirById(playlistId));
}
public static void removeTrackDirById(String trackId) {
IOUtils.deleteRecursive(getTrackDirById(trackId)); IOUtils.deleteRecursive(getTrackDirById(trackId));
} }
@@ -0,0 +1,17 @@
package ru.vtosters.lite.utils.music;
import android.util.Log;
import com.vk.dto.music.Playlist;
import org.json.JSONObject;
public class PlaylistUtils {
public static JSONObject getThumb(Playlist playlist) {
try {
Log.d("Playlist", "thumb is not null");
return playlist.F.J();
} catch (Exception e) {
Log.d("Playlist", "thumb is null");
return null;
}
}
}
@@ -3,6 +3,7 @@ package ru.vtosters.sponsorpost.internal;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.util.Log; import android.util.Log;
import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import java.util.HashSet; import java.util.HashSet;
@@ -22,7 +23,7 @@ public class VotesPreferences {
} }
public static boolean isEnabled() { public static boolean isEnabled() {
return preferences.getBoolean("sponsortesting", false); return preferences.getBoolean("sponsortesting", false) && !Preferences.serverFeaturesDisable();
} }
public static void setEnabled(boolean status) { public static void setEnabled(boolean status) {
@@ -61,6 +61,18 @@ public class FiltersPreferences {
editor.apply(); editor.apply();
} }
public static void forceUpdateFilters() {
SharedPreferences.Editor editor = preferences.edit();
preferences.getAll().keySet().stream()
.filter(key -> key.endsWith(":" + PREF_KEY_VERSION))
.forEach(key -> editor.putString(key, "0"));
editor.apply();
Updates.updateFilters();
}
public static boolean getSavedKeyValue(int id) { public static boolean getSavedKeyValue(int id) {
return getFilter(id) != null; return getFilter(id) != null;
} }
@@ -3,6 +3,7 @@ package ru.vtosters.sponsorpost.utils;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.util.Log; import android.util.Log;
import ru.vtosters.hooks.other.Preferences;
import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.sponsorpost.data.Post; import ru.vtosters.sponsorpost.data.Post;
@@ -23,7 +24,7 @@ public class PostsPreferences {
} }
public static boolean isEnabled() { public static boolean isEnabled() {
return preferences.getBoolean("sponsorpost", true); return preferences.getBoolean("sponsorpost", true) && !Preferences.serverFeaturesDisable();
} }
public static void setEnabled(boolean status) { public static void setEnabled(boolean status) {
@@ -1,5 +1,6 @@
package ru.vtosters.sponsorpost.utils; package ru.vtosters.sponsorpost.utils;
import android.util.Log;
import ru.vtosters.lite.utils.NetworkUtils; import ru.vtosters.lite.utils.NetworkUtils;
import ru.vtosters.lite.utils.newsfeed.NewsFeedFiltersUtils; import ru.vtosters.lite.utils.newsfeed.NewsFeedFiltersUtils;
import ru.vtosters.sponsorpost.data.Filter; import ru.vtosters.sponsorpost.data.Filter;
@@ -31,14 +32,17 @@ public class Updates {
for (Filter filter : filters) { for (Filter filter : filters) {
Filter localFilter = findLocalFilterById(localFilters, filter.getId()); Filter localFilter = findLocalFilterById(localFilters, filter.getId());
if (localFilter == null) { if (localFilter == null) {
Log.d("Updates", "local filter is not exist, adding new: " + filter.getId());
FiltersPreferences.saveFilter(filter); FiltersPreferences.saveFilter(filter);
} else { } else {
String remoteVersion = filter.getVersion(); String remoteVersion = filter.getVersion();
String localVersion = localFilter.getVersion(); String localVersion = localFilter.getVersion();
if (Objects.equals(remoteVersion, localVersion)) { if (Objects.equals(remoteVersion, localVersion)) {
FiltersPreferences.saveFilter(filter); Log.d("Updates", "saved local filter: " + localFilter.getId());
} else {
FiltersPreferences.saveFilter(localFilter); FiltersPreferences.saveFilter(localFilter);
} else {
Log.d("Updates", "saved remote filter: " + filter.getId());
FiltersPreferences.saveFilter(filter);
} }
} }
} }
+2
View File
@@ -75,6 +75,7 @@
--header_tint: %header_text% !important; --header_tint: %header_text% !important;
--header_tint_alternate: %header_text% !important; --header_tint_alternate: %header_text% !important;
--vkui--color_icon_accent_themed: %header_text% !important; --vkui--color_icon_accent_themed: %header_text% !important;
--vkui--color_text_accent_themed: %header_text% !important;
} }
@@ -139,6 +140,7 @@
--header_tint: %header_text% !important; --header_tint: %header_text% !important;
--header_tint_alternate: %header_text% !important; --header_tint_alternate: %header_text% !important;
--vkui--color_icon_accent_themed: %header_text% !important; --vkui--color_icon_accent_themed: %header_text% !important;
--vkui--color_text_accent_themed: %header_text% !important;
--color_field_border: %field_border% !important; --color_field_border: %field_border% !important;
--vkui--color_field_border: %field_border% !important; --vkui--color_field_border: %field_border% !important;
--color_field_background: %field_background% !important; --color_field_background: %field_background% !important;
View File
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -6437,7 +6437,7 @@
<string name="update_latest">У вас установлена последняя версия приложения</string> <string name="update_latest">У вас установлена последняя версия приложения</string>
<string name="update_err">Ошибка проверки обновления</string> <string name="update_err">Ошибка проверки обновления</string>
<string name="serverFeaturesDisable">Отключить все внешние подключения</string> <string name="serverFeaturesDisable">Отключить все внешние подключения</string>
<string name="serverFeaturesDisable_summ">Отключает галочки и все дополнительные функции связанные с получением данных с сервера ВТостерс.\n\nАктульно для тех у кого безлимитный интернет на ВКонтакте</string> <string name="serverFeaturesDisable_summ">Отключает галочки и все дополнительные функции связанные с получением данных с сервера ВТостерс.\n\nАктуально для тех у кого безлимитный интернет на ВКонтакте</string>
<string name="tgs_token_missing">Токен отсутствует</string> <string name="tgs_token_missing">Токен отсутствует</string>
<string name="tgs_token_reset_dialog">Сбросить токен бота?</string> <string name="tgs_token_reset_dialog">Сбросить токен бота?</string>
+5
View File
@@ -31,6 +31,11 @@
android:key="__dbg_disable_video_feed" android:key="__dbg_disable_video_feed"
android:summary="@string/interfacevideorecsum" android:summary="@string/interfacevideorecsum"
android:title="@string/interfacevideorec"/> android:title="@string/interfacevideorec"/>
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="true"
android:key="sendVideoMetrics"
android:summary="Статистика необходима для работы рекомендаций и истории видео"
android:title="Отправлять статистику"/>
<Preference <Preference
android:key="clearvideohistory" android:key="clearvideohistory"
android:summary="@string/clearvideohistory_summ" android:summary="@string/clearvideohistory_summ"
+15
View File
@@ -9,6 +9,21 @@
android:key="microgsettings" android:key="microgsettings"
android:title="@string/microgsett"/> android:title="@string/microgsett"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="Экспериментальные функции">
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="false"
android:key="batchmessages"
android:summary="Поможет исправить скорость загрузки сообщений, но работает нестабильно"
android:title="Альтернативная загрузка сообщений"/>
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="true"
android:key="unstableNameChanger"
android:title="Редактор имен"
android:summary="Редактор имен групп и профилей людей\n\nПри проблемах с работой сообщений лучше отключить данную функцию"/>
<Preference
android:key="unstableNameChangerDrop"
android:title="Сбросить информацию о переименованиях"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/vtverify"> <PreferenceCategory android:title="@string/vtverify">
<Preference <Preference
android:key="updateverifdata" android:key="updateverifdata"
@@ -474,7 +474,7 @@
invoke-virtual {p1, v1, v0}, Ljava/net/HttpURLConnection;->setRequestProperty(Ljava/lang/String;Ljava/lang/String;)V invoke-virtual {p1, v1, v0}, Ljava/net/HttpURLConnection;->setRequestProperty(Ljava/lang/String;Ljava/lang/String;)V
.line 15 .line 15
const-string v0, "C8EAB7342DA62B4A229E1BFDEB27B029DD6788A1" const-string v0, "48761EEF50EE53AFC4CC9C5F10E6BDE7F8F5B82F"
const-string v1, "X-Android-Cert" const-string v1, "X-Android-Cert"
@@ -82,10 +82,6 @@
move-result-object p1 move-result-object p1
invoke-static {p1}, Lru/vtosters/hooks/OnlineFormatterHook;->onlineHookProfiles(Lorg/json/JSONObject;)Lorg/json/JSONObject;
move-result-object p1
const-string v0, "items" const-string v0, "items"
.line 3 .line 3
@@ -40,31 +40,33 @@
.method public a(Lorg/json/JSONObject;)Lcom/vk/dto/music/CurrentAccountInformation; .method public a(Lorg/json/JSONObject;)Lcom/vk/dto/music/CurrentAccountInformation;
.locals 1 .locals 1
const-string v0, "response" # const-string v0, "response"
.line 2 # .line 2
invoke-virtual {p1, v0}, Lorg/json/JSONObject;->getJSONObject(Ljava/lang/String;)Lorg/json/JSONObject; # invoke-virtual {p1, v0}, Lorg/json/JSONObject;->getJSONObject(Ljava/lang/String;)Lorg/json/JSONObject;
move-result-object p1 # move-result-object p1
const-string v0, "has_music_subscription" # const-string v0, "has_music_subscription"
.line 3 # .line 3
invoke-virtual {p1, v0}, Lorg/json/JSONObject;->optInt(Ljava/lang/String;)I # invoke-virtual {p1, v0}, Lorg/json/JSONObject;->optInt(Ljava/lang/String;)I
move-result p1 # move-result p1
# const/4 v0, 0x1
# if-ne p1, v0, :cond_0
# goto :goto_0
# :cond_0
# const/4 v0, 0x1
# .line 4
# :goto_0
const/4 v0, 0x1 const/4 v0, 0x1
if-ne p1, v0, :cond_0
goto :goto_0
:cond_0
const/4 v0, 0x1
.line 4
:goto_0
new-instance p1, Lcom/vk/dto/music/CurrentAccountInformation; new-instance p1, Lcom/vk/dto/music/CurrentAccountInformation;
invoke-direct {p1, v0}, Lcom/vk/dto/music/CurrentAccountInformation;-><init>(Z)V invoke-direct {p1, v0}, Lcom/vk/dto/music/CurrentAccountInformation;-><init>(Z)V
@@ -390,6 +390,8 @@
.method public static final b(Lorg/json/JSONObject;)Lcom/vk/dto/newsfeed/Owner; .method public static final b(Lorg/json/JSONObject;)Lcom/vk/dto/newsfeed/Owner;
.locals 1 .locals 1
invoke-static {p0}, Lru/vtosters/hooks/RenameHook;->injectIntoJsonGroup(Lorg/json/JSONObject;)V
sget-object v0, Lcom/vk/dto/newsfeed/Owner;->h:Lcom/vk/dto/newsfeed/Owner$b; sget-object v0, Lcom/vk/dto/newsfeed/Owner;->h:Lcom/vk/dto/newsfeed/Owner$b;
invoke-virtual {v0, p0}, Lcom/vk/dto/newsfeed/Owner$b;->b(Lorg/json/JSONObject;)Lcom/vk/dto/newsfeed/Owner; invoke-virtual {v0, p0}, Lcom/vk/dto/newsfeed/Owner$b;->b(Lorg/json/JSONObject;)Lcom/vk/dto/newsfeed/Owner;
@@ -402,6 +404,8 @@
.method public static final c(Lorg/json/JSONObject;)Lcom/vk/dto/newsfeed/Owner; .method public static final c(Lorg/json/JSONObject;)Lcom/vk/dto/newsfeed/Owner;
.locals 1 .locals 1
invoke-static {p0}, Lru/vtosters/hooks/RenameHook;->injectIntoJson(Lorg/json/JSONObject;)V
sget-object v0, Lcom/vk/dto/newsfeed/Owner;->h:Lcom/vk/dto/newsfeed/Owner$b; sget-object v0, Lcom/vk/dto/newsfeed/Owner;->h:Lcom/vk/dto/newsfeed/Owner$b;
invoke-virtual {v0, p0}, Lcom/vk/dto/newsfeed/Owner$b;->c(Lorg/json/JSONObject;)Lcom/vk/dto/newsfeed/Owner; invoke-virtual {v0, p0}, Lcom/vk/dto/newsfeed/Owner$b;->c(Lorg/json/JSONObject;)Lcom/vk/dto/newsfeed/Owner;
@@ -194,6 +194,8 @@
move-result v0 move-result v0
const v0, 0x0
if-eqz v0, :cond_2 if-eqz v0, :cond_2
const/4 v0, 0x1 const/4 v0, 0x1
@@ -50,10 +50,6 @@
move-result-object p1 move-result-object p1
invoke-static {p1}, Lru/vtosters/hooks/OnlineFormatterHook;->onlineHookProfiles(Lorg/json/JSONObject;)Lorg/json/JSONObject;
move-result-object p1
const-string v0, "items" const-string v0, "items"
.line 2 .line 2
@@ -50,9 +50,6 @@
move-result-object p1 move-result-object p1
invoke-static {p1}, Lru/vtosters/hooks/OnlineFormatterHook;->onlineHookProfiles(Lorg/json/JSONObject;)Lorg/json/JSONObject;
move-result-object p1
const-string v0, "items" const-string v0, "items"
.line 2 .line 2
@@ -50,10 +50,6 @@
move-result-object p1 move-result-object p1
invoke-static {p1}, Lru/vtosters/hooks/OnlineFormatterHook;->onlineHookProfiles(Lorg/json/JSONObject;)Lorg/json/JSONObject;
move-result-object p1
const-string v0, "items" const-string v0, "items"
.line 2 .line 2
@@ -60,6 +60,10 @@
move-result-object p1 move-result-object p1
invoke-static {p1}, Lru/vtosters/hooks/OnlineFormatterHook;->onlineHookProfiles(Lorg/json/JSONObject;)Lorg/json/JSONObject;
move-result-object p1
const-string v0, "JSONObject(response).getJSONObject(\"response\")" const-string v0, "JSONObject(response).getJSONObject(\"response\")"
invoke-static {p1, v0}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V invoke-static {p1, v0}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
@@ -76,6 +80,10 @@
move-object/from16 v0, p1 move-object/from16 v0, p1
invoke-static {v0}, Lru/vtosters/hooks/OnlineFormatterHook;->onlineHookProfiles(Lorg/json/JSONObject;)Lorg/json/JSONObject;
move-result-object v0
.line 3 .line 3
new-instance v1, Lcom/vk/im/engine/models/ProfilesSimpleInfo; new-instance v1, Lcom/vk/im/engine/models/ProfilesSimpleInfo;
@@ -164,6 +164,10 @@
invoke-static {v0}, Lru/vtosters/hooks/RenameHook;->injectIntoJson(Lorg/json/JSONObject;)V invoke-static {v0}, Lru/vtosters/hooks/RenameHook;->injectIntoJson(Lorg/json/JSONObject;)V
invoke-static {v0}, Lru/vtosters/hooks/OnlineFormatterHook;->onlineHook(Lorg/json/JSONObject;)Lorg/json/JSONObject;
move-result-object v0
const-string v2, "" const-string v2, ""
.line 1 .line 1
@@ -52,79 +52,11 @@
} }
.end annotation .end annotation
.line 2 invoke-static {p1}, Lru/vtosters/hooks/OnlineFormatterHook;->onlineHookList(Ljava/lang/String;)Landroid/util/SparseArray;
:try_start_0
new-instance v0, Lorg/json/JSONObject;
invoke-direct {v0, p1}, Lorg/json/JSONObject;-><init>(Ljava/lang/String;)V move-result-object v0
const-string p1, "response"
invoke-virtual {v0, p1}, Lorg/json/JSONObject;->getJSONArray(Ljava/lang/String;)Lorg/json/JSONArray;
move-result-object p1
invoke-static {p1}, Lru/vtosters/hooks/OnlineFormatterHook;->onlineHookList(Lorg/json/JSONArray;)Lorg/json/JSONArray;
move-result-object p1
.line 3
new-instance v0, Landroid/util/SparseArray;
invoke-virtual {p1}, Lorg/json/JSONArray;->length()I
move-result v1
invoke-direct {v0, v1}, Landroid/util/SparseArray;-><init>(I)V
const/4 v1, 0x0
.line 4
invoke-virtual {p1}, Lorg/json/JSONArray;->length()I
move-result v2
:goto_0
if-ge v1, v2, :cond_0
.line 5
invoke-virtual {p1, v1}, Lorg/json/JSONArray;->getJSONObject(I)Lorg/json/JSONObject;
move-result-object v3
const-string v4, "ja.getJSONObject(i)"
invoke-static {v3, v4}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
invoke-static {v3}, Lcom/vk/im/engine/internal/api_parsers/UserApiParser;->b(Lorg/json/JSONObject;)Lcom/vk/im/engine/models/users/User;
move-result-object v3
.line 6
invoke-virtual {v3}, Lcom/vk/im/engine/models/users/User;->getId()I
move-result v4
invoke-virtual {v0, v4, v3}, Landroid/util/SparseArray;->put(ILjava/lang/Object;)V
:try_end_0
.catch Lorg/json/JSONException; {:try_start_0 .. :try_end_0} :catch_0
add-int/lit8 v1, v1, 0x1
goto :goto_0
:cond_0
return-object v0 return-object v0
:catch_0
move-exception p1
.line 7
new-instance v0, Lcom/vk/api/sdk/exceptions/VKApiIllegalResponseException;
invoke-direct {v0, p1}, Lcom/vk/api/sdk/exceptions/VKApiIllegalResponseException;-><init>(Ljava/lang/Throwable;)V
throw v0
.end method .end method
.method public bridge synthetic a(Ljava/lang/String;)Ljava/lang/Object; .method public bridge synthetic a(Ljava/lang/String;)Ljava/lang/Object;
@@ -1196,7 +1196,9 @@
.locals 1 .locals 1
.line 1 .line 1
iget-object v0, p0, Lcom/vk/im/engine/models/dialogs/Dialog;->theme:Lcom/vk/im/engine/models/dialogs/DialogTheme; invoke-static {}, Lru/vtosters/hooks/other/ThemesUtils;->getDialogTheme()Lcom/vk/im/engine/models/dialogs/DialogTheme;
move-result-object v0
return-object v0 return-object v0
.end method .end method
@@ -1,118 +0,0 @@
.class public final enum Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
.super Ljava/lang/Enum;
.source "VideoTracker.java"
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Lcom/vk/libvideo/VideoTracker;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x4019
name = "FullscreenTransition"
.end annotation
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/lang/Enum<",
"Lcom/vk/libvideo/VideoTracker$FullscreenTransition;",
">;"
}
.end annotation
# static fields
.field private static final synthetic $VALUES:[Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
.field public static final enum SCREEN_ROTATION:Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
.field public static final enum TAP:Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
# direct methods
.method static constructor <clinit>()V
.locals 4
.line 1
new-instance v0, Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
const/4 v1, 0x0
const-string v2, "TAP"
invoke-direct {v0, v2, v1}, Lcom/vk/libvideo/VideoTracker$FullscreenTransition;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$FullscreenTransition;->TAP:Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
new-instance v0, Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
const/4 v2, 0x1
const-string v3, "SCREEN_ROTATION"
invoke-direct {v0, v3, v2}, Lcom/vk/libvideo/VideoTracker$FullscreenTransition;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$FullscreenTransition;->SCREEN_ROTATION:Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
const/4 v0, 0x2
new-array v0, v0, [Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
.line 2
sget-object v3, Lcom/vk/libvideo/VideoTracker$FullscreenTransition;->TAP:Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
aput-object v3, v0, v1
sget-object v1, Lcom/vk/libvideo/VideoTracker$FullscreenTransition;->SCREEN_ROTATION:Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
aput-object v1, v0, v2
sput-object v0, Lcom/vk/libvideo/VideoTracker$FullscreenTransition;->$VALUES:[Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
return-void
.end method
.method private constructor <init>(Ljava/lang/String;I)V
.locals 0
.annotation system Ldalvik/annotation/Signature;
value = {
"()V"
}
.end annotation
.line 1
invoke-direct {p0, p1, p2}, Ljava/lang/Enum;-><init>(Ljava/lang/String;I)V
return-void
.end method
.method public static valueOf(Ljava/lang/String;)Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
.locals 1
.line 1
const-class v0, Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
invoke-static {v0, p0}, Ljava/lang/Enum;->valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
move-result-object p0
check-cast p0, Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
return-object p0
.end method
.method public static values()[Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
.locals 1
.line 1
sget-object v0, Lcom/vk/libvideo/VideoTracker$FullscreenTransition;->$VALUES:[Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
invoke-virtual {v0}, [Lcom/vk/libvideo/VideoTracker$FullscreenTransition;->clone()Ljava/lang/Object;
move-result-object v0
check-cast v0, [Lcom/vk/libvideo/VideoTracker$FullscreenTransition;
return-object v0
.end method
@@ -1,134 +0,0 @@
.class public final enum Lcom/vk/libvideo/VideoTracker$PlayerType;
.super Ljava/lang/Enum;
.source "VideoTracker.java"
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Lcom/vk/libvideo/VideoTracker;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x4019
name = "PlayerType"
.end annotation
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/lang/Enum<",
"Lcom/vk/libvideo/VideoTracker$PlayerType;",
">;"
}
.end annotation
# static fields
.field private static final synthetic $VALUES:[Lcom/vk/libvideo/VideoTracker$PlayerType;
.field public static final enum CAROUSEL:Lcom/vk/libvideo/VideoTracker$PlayerType;
.field public static final enum FULLSCREEN:Lcom/vk/libvideo/VideoTracker$PlayerType;
.field public static final enum INLINE:Lcom/vk/libvideo/VideoTracker$PlayerType;
# direct methods
.method static constructor <clinit>()V
.locals 5
.line 1
new-instance v0, Lcom/vk/libvideo/VideoTracker$PlayerType;
const/4 v1, 0x0
const-string v2, "INLINE"
invoke-direct {v0, v2, v1}, Lcom/vk/libvideo/VideoTracker$PlayerType;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$PlayerType;->INLINE:Lcom/vk/libvideo/VideoTracker$PlayerType;
new-instance v0, Lcom/vk/libvideo/VideoTracker$PlayerType;
const/4 v2, 0x1
const-string v3, "CAROUSEL"
invoke-direct {v0, v3, v2}, Lcom/vk/libvideo/VideoTracker$PlayerType;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$PlayerType;->CAROUSEL:Lcom/vk/libvideo/VideoTracker$PlayerType;
new-instance v0, Lcom/vk/libvideo/VideoTracker$PlayerType;
const/4 v3, 0x2
const-string v4, "FULLSCREEN"
invoke-direct {v0, v4, v3}, Lcom/vk/libvideo/VideoTracker$PlayerType;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$PlayerType;->FULLSCREEN:Lcom/vk/libvideo/VideoTracker$PlayerType;
const/4 v0, 0x3
new-array v0, v0, [Lcom/vk/libvideo/VideoTracker$PlayerType;
.line 2
sget-object v4, Lcom/vk/libvideo/VideoTracker$PlayerType;->INLINE:Lcom/vk/libvideo/VideoTracker$PlayerType;
aput-object v4, v0, v1
sget-object v1, Lcom/vk/libvideo/VideoTracker$PlayerType;->CAROUSEL:Lcom/vk/libvideo/VideoTracker$PlayerType;
aput-object v1, v0, v2
sget-object v1, Lcom/vk/libvideo/VideoTracker$PlayerType;->FULLSCREEN:Lcom/vk/libvideo/VideoTracker$PlayerType;
aput-object v1, v0, v3
sput-object v0, Lcom/vk/libvideo/VideoTracker$PlayerType;->$VALUES:[Lcom/vk/libvideo/VideoTracker$PlayerType;
return-void
.end method
.method private constructor <init>(Ljava/lang/String;I)V
.locals 0
.annotation system Ldalvik/annotation/Signature;
value = {
"()V"
}
.end annotation
.line 1
invoke-direct {p0, p1, p2}, Ljava/lang/Enum;-><init>(Ljava/lang/String;I)V
return-void
.end method
.method public static valueOf(Ljava/lang/String;)Lcom/vk/libvideo/VideoTracker$PlayerType;
.locals 1
.line 1
const-class v0, Lcom/vk/libvideo/VideoTracker$PlayerType;
invoke-static {v0, p0}, Ljava/lang/Enum;->valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
move-result-object p0
check-cast p0, Lcom/vk/libvideo/VideoTracker$PlayerType;
return-object p0
.end method
.method public static values()[Lcom/vk/libvideo/VideoTracker$PlayerType;
.locals 1
.line 1
sget-object v0, Lcom/vk/libvideo/VideoTracker$PlayerType;->$VALUES:[Lcom/vk/libvideo/VideoTracker$PlayerType;
invoke-virtual {v0}, [Lcom/vk/libvideo/VideoTracker$PlayerType;->clone()Ljava/lang/Object;
move-result-object v0
check-cast v0, [Lcom/vk/libvideo/VideoTracker$PlayerType;
return-object v0
.end method
@@ -1,118 +0,0 @@
.class public final enum Lcom/vk/libvideo/VideoTracker$ResizeAction;
.super Ljava/lang/Enum;
.source "VideoTracker.java"
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Lcom/vk/libvideo/VideoTracker;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x4019
name = "ResizeAction"
.end annotation
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/lang/Enum<",
"Lcom/vk/libvideo/VideoTracker$ResizeAction;",
">;"
}
.end annotation
# static fields
.field private static final synthetic $VALUES:[Lcom/vk/libvideo/VideoTracker$ResizeAction;
.field public static final enum BUTTON:Lcom/vk/libvideo/VideoTracker$ResizeAction;
.field public static final enum GESTURE:Lcom/vk/libvideo/VideoTracker$ResizeAction;
# direct methods
.method static constructor <clinit>()V
.locals 4
.line 1
new-instance v0, Lcom/vk/libvideo/VideoTracker$ResizeAction;
const/4 v1, 0x0
const-string v2, "BUTTON"
invoke-direct {v0, v2, v1}, Lcom/vk/libvideo/VideoTracker$ResizeAction;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$ResizeAction;->BUTTON:Lcom/vk/libvideo/VideoTracker$ResizeAction;
new-instance v0, Lcom/vk/libvideo/VideoTracker$ResizeAction;
const/4 v2, 0x1
const-string v3, "GESTURE"
invoke-direct {v0, v3, v2}, Lcom/vk/libvideo/VideoTracker$ResizeAction;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$ResizeAction;->GESTURE:Lcom/vk/libvideo/VideoTracker$ResizeAction;
const/4 v0, 0x2
new-array v0, v0, [Lcom/vk/libvideo/VideoTracker$ResizeAction;
.line 2
sget-object v3, Lcom/vk/libvideo/VideoTracker$ResizeAction;->BUTTON:Lcom/vk/libvideo/VideoTracker$ResizeAction;
aput-object v3, v0, v1
sget-object v1, Lcom/vk/libvideo/VideoTracker$ResizeAction;->GESTURE:Lcom/vk/libvideo/VideoTracker$ResizeAction;
aput-object v1, v0, v2
sput-object v0, Lcom/vk/libvideo/VideoTracker$ResizeAction;->$VALUES:[Lcom/vk/libvideo/VideoTracker$ResizeAction;
return-void
.end method
.method private constructor <init>(Ljava/lang/String;I)V
.locals 0
.annotation system Ldalvik/annotation/Signature;
value = {
"()V"
}
.end annotation
.line 1
invoke-direct {p0, p1, p2}, Ljava/lang/Enum;-><init>(Ljava/lang/String;I)V
return-void
.end method
.method public static valueOf(Ljava/lang/String;)Lcom/vk/libvideo/VideoTracker$ResizeAction;
.locals 1
.line 1
const-class v0, Lcom/vk/libvideo/VideoTracker$ResizeAction;
invoke-static {v0, p0}, Ljava/lang/Enum;->valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
move-result-object p0
check-cast p0, Lcom/vk/libvideo/VideoTracker$ResizeAction;
return-object p0
.end method
.method public static values()[Lcom/vk/libvideo/VideoTracker$ResizeAction;
.locals 1
.line 1
sget-object v0, Lcom/vk/libvideo/VideoTracker$ResizeAction;->$VALUES:[Lcom/vk/libvideo/VideoTracker$ResizeAction;
invoke-virtual {v0}, [Lcom/vk/libvideo/VideoTracker$ResizeAction;->clone()Ljava/lang/Object;
move-result-object v0
check-cast v0, [Lcom/vk/libvideo/VideoTracker$ResizeAction;
return-object v0
.end method
@@ -1,118 +0,0 @@
.class public final enum Lcom/vk/libvideo/VideoTracker$RewindType;
.super Ljava/lang/Enum;
.source "VideoTracker.java"
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Lcom/vk/libvideo/VideoTracker;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x4019
name = "RewindType"
.end annotation
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/lang/Enum<",
"Lcom/vk/libvideo/VideoTracker$RewindType;",
">;"
}
.end annotation
# static fields
.field private static final synthetic $VALUES:[Lcom/vk/libvideo/VideoTracker$RewindType;
.field public static final enum DOUBLE_TAP:Lcom/vk/libvideo/VideoTracker$RewindType;
.field public static final enum SLIDER:Lcom/vk/libvideo/VideoTracker$RewindType;
# direct methods
.method static constructor <clinit>()V
.locals 4
.line 1
new-instance v0, Lcom/vk/libvideo/VideoTracker$RewindType;
const/4 v1, 0x0
const-string v2, "SLIDER"
invoke-direct {v0, v2, v1}, Lcom/vk/libvideo/VideoTracker$RewindType;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$RewindType;->SLIDER:Lcom/vk/libvideo/VideoTracker$RewindType;
new-instance v0, Lcom/vk/libvideo/VideoTracker$RewindType;
const/4 v2, 0x1
const-string v3, "DOUBLE_TAP"
invoke-direct {v0, v3, v2}, Lcom/vk/libvideo/VideoTracker$RewindType;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$RewindType;->DOUBLE_TAP:Lcom/vk/libvideo/VideoTracker$RewindType;
const/4 v0, 0x2
new-array v0, v0, [Lcom/vk/libvideo/VideoTracker$RewindType;
.line 2
sget-object v3, Lcom/vk/libvideo/VideoTracker$RewindType;->SLIDER:Lcom/vk/libvideo/VideoTracker$RewindType;
aput-object v3, v0, v1
sget-object v1, Lcom/vk/libvideo/VideoTracker$RewindType;->DOUBLE_TAP:Lcom/vk/libvideo/VideoTracker$RewindType;
aput-object v1, v0, v2
sput-object v0, Lcom/vk/libvideo/VideoTracker$RewindType;->$VALUES:[Lcom/vk/libvideo/VideoTracker$RewindType;
return-void
.end method
.method private constructor <init>(Ljava/lang/String;I)V
.locals 0
.annotation system Ldalvik/annotation/Signature;
value = {
"()V"
}
.end annotation
.line 1
invoke-direct {p0, p1, p2}, Ljava/lang/Enum;-><init>(Ljava/lang/String;I)V
return-void
.end method
.method public static valueOf(Ljava/lang/String;)Lcom/vk/libvideo/VideoTracker$RewindType;
.locals 1
.line 1
const-class v0, Lcom/vk/libvideo/VideoTracker$RewindType;
invoke-static {v0, p0}, Ljava/lang/Enum;->valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
move-result-object p0
check-cast p0, Lcom/vk/libvideo/VideoTracker$RewindType;
return-object p0
.end method
.method public static values()[Lcom/vk/libvideo/VideoTracker$RewindType;
.locals 1
.line 1
sget-object v0, Lcom/vk/libvideo/VideoTracker$RewindType;->$VALUES:[Lcom/vk/libvideo/VideoTracker$RewindType;
invoke-virtual {v0}, [Lcom/vk/libvideo/VideoTracker$RewindType;->clone()Ljava/lang/Object;
move-result-object v0
check-cast v0, [Lcom/vk/libvideo/VideoTracker$RewindType;
return-object v0
.end method
@@ -1,150 +0,0 @@
.class public final enum Lcom/vk/libvideo/VideoTracker$Screen;
.super Ljava/lang/Enum;
.source "VideoTracker.java"
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Lcom/vk/libvideo/VideoTracker;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x4019
name = "Screen"
.end annotation
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/lang/Enum<",
"Lcom/vk/libvideo/VideoTracker$Screen;",
">;"
}
.end annotation
# static fields
.field private static final synthetic $VALUES:[Lcom/vk/libvideo/VideoTracker$Screen;
.field public static final enum CAROUSEL:Lcom/vk/libvideo/VideoTracker$Screen;
.field public static final enum INLINE:Lcom/vk/libvideo/VideoTracker$Screen;
.field public static final enum LANDSCAPE:Lcom/vk/libvideo/VideoTracker$Screen;
.field public static final enum PORTRAIT:Lcom/vk/libvideo/VideoTracker$Screen;
# direct methods
.method static constructor <clinit>()V
.locals 6
.line 1
new-instance v0, Lcom/vk/libvideo/VideoTracker$Screen;
const/4 v1, 0x0
const-string v2, "INLINE"
invoke-direct {v0, v2, v1}, Lcom/vk/libvideo/VideoTracker$Screen;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$Screen;->INLINE:Lcom/vk/libvideo/VideoTracker$Screen;
new-instance v0, Lcom/vk/libvideo/VideoTracker$Screen;
const/4 v2, 0x1
const-string v3, "CAROUSEL"
invoke-direct {v0, v3, v2}, Lcom/vk/libvideo/VideoTracker$Screen;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$Screen;->CAROUSEL:Lcom/vk/libvideo/VideoTracker$Screen;
new-instance v0, Lcom/vk/libvideo/VideoTracker$Screen;
const/4 v3, 0x2
const-string v4, "PORTRAIT"
invoke-direct {v0, v4, v3}, Lcom/vk/libvideo/VideoTracker$Screen;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$Screen;->PORTRAIT:Lcom/vk/libvideo/VideoTracker$Screen;
new-instance v0, Lcom/vk/libvideo/VideoTracker$Screen;
const/4 v4, 0x3
const-string v5, "LANDSCAPE"
invoke-direct {v0, v5, v4}, Lcom/vk/libvideo/VideoTracker$Screen;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/vk/libvideo/VideoTracker$Screen;->LANDSCAPE:Lcom/vk/libvideo/VideoTracker$Screen;
const/4 v0, 0x4
new-array v0, v0, [Lcom/vk/libvideo/VideoTracker$Screen;
.line 2
sget-object v5, Lcom/vk/libvideo/VideoTracker$Screen;->INLINE:Lcom/vk/libvideo/VideoTracker$Screen;
aput-object v5, v0, v1
sget-object v1, Lcom/vk/libvideo/VideoTracker$Screen;->CAROUSEL:Lcom/vk/libvideo/VideoTracker$Screen;
aput-object v1, v0, v2
sget-object v1, Lcom/vk/libvideo/VideoTracker$Screen;->PORTRAIT:Lcom/vk/libvideo/VideoTracker$Screen;
aput-object v1, v0, v3
sget-object v1, Lcom/vk/libvideo/VideoTracker$Screen;->LANDSCAPE:Lcom/vk/libvideo/VideoTracker$Screen;
aput-object v1, v0, v4
sput-object v0, Lcom/vk/libvideo/VideoTracker$Screen;->$VALUES:[Lcom/vk/libvideo/VideoTracker$Screen;
return-void
.end method
.method private constructor <init>(Ljava/lang/String;I)V
.locals 0
.annotation system Ldalvik/annotation/Signature;
value = {
"()V"
}
.end annotation
.line 1
invoke-direct {p0, p1, p2}, Ljava/lang/Enum;-><init>(Ljava/lang/String;I)V
return-void
.end method
.method public static valueOf(Ljava/lang/String;)Lcom/vk/libvideo/VideoTracker$Screen;
.locals 1
.line 1
const-class v0, Lcom/vk/libvideo/VideoTracker$Screen;
invoke-static {v0, p0}, Ljava/lang/Enum;->valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
move-result-object p0
check-cast p0, Lcom/vk/libvideo/VideoTracker$Screen;
return-object p0
.end method
.method public static values()[Lcom/vk/libvideo/VideoTracker$Screen;
.locals 1
.line 1
sget-object v0, Lcom/vk/libvideo/VideoTracker$Screen;->$VALUES:[Lcom/vk/libvideo/VideoTracker$Screen;
invoke-virtual {v0}, [Lcom/vk/libvideo/VideoTracker$Screen;->clone()Ljava/lang/Object;
move-result-object v0
check-cast v0, [Lcom/vk/libvideo/VideoTracker$Screen;
return-object v0
.end method
File diff suppressed because it is too large Load Diff
@@ -196,6 +196,21 @@
.method public a(Lcom/vk/dto/music/MusicTrack;)V .method public a(Lcom/vk/dto/music/MusicTrack;)V
.locals 3 .locals 3
invoke-static {}, Lru/vtosters/hooks/other/Preferences;->sendMusicMetrics()Z
move-result v1
if-nez v1, :cond_228
const/4 v0, 0x1
new-instance p1, Lcom/vk/dto/music/CurrentAccountInformation;
invoke-direct {p1, v0}, Lcom/vk/dto/music/CurrentAccountInformation;-><init>(Z)V
return-void
:cond_228
const/4 v0, 0x2 const/4 v0, 0x2
new-array v0, v0, [Ljava/lang/Object; new-array v0, v0, [Ljava/lang/Object;
@@ -224,41 +239,41 @@
.line 14 .line 14
:cond_0 :cond_0
# new-instance v0, Lcom/vk/api/audio/AudioSendStartEvent; new-instance v0, Lcom/vk/api/audio/AudioSendStartEvent;
# invoke-virtual {p1}, Lcom/vk/dto/music/MusicTrack;->y1()Ljava/lang/String; invoke-virtual {p1}, Lcom/vk/dto/music/MusicTrack;->y1()Ljava/lang/String;
# move-result-object p1 move-result-object p1
# sget-object v2, Lcom/vk/api/base/ApiConfig;->d:Lcom/vk/api/base/ApiConfig$a; sget-object v2, Lcom/vk/api/base/ApiConfig;->d:Lcom/vk/api/base/ApiConfig$a;
# invoke-interface {v2}, Lcom/vk/api/base/ApiConfig$a;->O1()Ljava/lang/String; invoke-interface {v2}, Lcom/vk/api/base/ApiConfig$a;->O1()Ljava/lang/String;
# move-result-object v2 move-result-object v2
# invoke-direct {v0, p1, v2}, Lcom/vk/api/audio/AudioSendStartEvent;-><init>(Ljava/lang/String;Ljava/lang/String;)V invoke-direct {v0, p1, v2}, Lcom/vk/api/audio/AudioSendStartEvent;-><init>(Ljava/lang/String;Ljava/lang/String;)V
# const/4 p1, 0x0 const/4 p1, 0x0
# .line 15 .line 15
# invoke-static {v0, p1, v1, p1}, Lcom/vk/api/base/ApiRequest;->d(Lcom/vk/api/base/ApiRequest;Lcom/vk/api/base/ApiThreadHolder;ILjava/lang/Object;)Lio/reactivex/Observable; invoke-static {v0, p1, v1, p1}, Lcom/vk/api/base/ApiRequest;->d(Lcom/vk/api/base/ApiRequest;Lcom/vk/api/base/ApiThreadHolder;ILjava/lang/Object;)Lio/reactivex/Observable;
# move-result-object p1 move-result-object p1
# .line 16 .line 16
# new-instance v0, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$d; new-instance v0, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$d;
# invoke-direct {v0, p0}, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$d;-><init>(Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl;)V invoke-direct {v0, p0}, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$d;-><init>(Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl;)V
# .line 17 .line 17
# sget-object v1, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$e;->a:Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$e; sget-object v1, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$e;->a:Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl$e;
# .line 18 .line 18
# invoke-virtual {p1, v0, v1}, Lio/reactivex/Observable;->a(Lio/reactivex/functions/Consumer;Lio/reactivex/functions/Consumer;)Lio/reactivex/disposables/Disposable; invoke-virtual {p1, v0, v1}, Lio/reactivex/Observable;->a(Lio/reactivex/functions/Consumer;Lio/reactivex/functions/Consumer;)Lio/reactivex/disposables/Disposable;
# move-result-object p1 move-result-object p1
# iput-object p1, p0, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl;->a:Lio/reactivex/disposables/Disposable; iput-object p1, p0, Lcom/vk/music/notifications/restriction/MusicRestrictionModelImpl;->a:Lio/reactivex/disposables/Disposable;
return-void return-void
.end method .end method
@@ -1,70 +0,0 @@
.class public final Lcom/vk/music/stats/VKMusicStatsTracker$a;
.super Ljava/lang/Object;
.source "VKMusicStatsTracker.kt"
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Lcom/vk/music/stats/VKMusicStatsTracker;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x19
name = "a"
.end annotation
# direct methods
.method private constructor <init>()V
.locals 0
.line 1
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public synthetic constructor <init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
.locals 0
.line 2
invoke-direct {p0}, Lcom/vk/music/stats/VKMusicStatsTracker$a;-><init>()V
return-void
.end method
# virtual methods
.method public final a(Lcom/vtosters/lite/data/Analytics$l;)V
.locals 3
.annotation build Landroidx/annotation/VisibleForTesting;
.end annotation
const/4 v0, 0x3
new-array v0, v0, [Ljava/lang/Object;
const/4 v1, 0x0
const-string v2, "MusicStats"
aput-object v2, v0, v1
const/4 v1, 0x1
const-string v2, "[VK_TRACKER]"
aput-object v2, v0, v1
const/4 v1, 0x2
aput-object p1, v0, v1
.line 1
invoke-static {v0}, Lcom/vk/music/logger/MusicLogger;->a([Ljava/lang/Object;)V
.line 2
invoke-virtual {p1}, Lcom/vtosters/lite/data/Analytics$l;->b()Lcom/vtosters/lite/data/Analytics$l;
return-void
.end method
@@ -1,841 +0,0 @@
.class public final Lcom/vk/music/stats/VKMusicStatsTracker;
.super Ljava/lang/Object;
.source "VKMusicStatsTracker.kt"
# interfaces
.implements Lcom/vk/music/stats/MusicStatsTracker;
# annotations
.annotation system Ldalvik/annotation/MemberClasses;
value = {
Lcom/vk/music/stats/VKMusicStatsTracker$a;
}
.end annotation
# static fields
.field public static final c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
# instance fields
.field private a:Ljava/lang/String;
.field private final b:Lkotlin/jvm/b/Functions2;
.annotation system Ldalvik/annotation/Signature;
value = {
"Lkotlin/jvm/b/Functions2<",
"Ljava/lang/String;",
"Lcom/vtosters/lite/data/Analytics$l;",
">;"
}
.end annotation
.end field
# direct methods
.method static constructor <clinit>()V
.locals 2
new-instance v0, Lcom/vk/music/stats/VKMusicStatsTracker$a;
const/4 v1, 0x0
invoke-direct {v0, v1}, Lcom/vk/music/stats/VKMusicStatsTracker$a;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
sput-object v0, Lcom/vk/music/stats/VKMusicStatsTracker;->c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
return-void
.end method
.method public constructor <init>(Lkotlin/jvm/b/Functions2;)V
.locals 0
.annotation system Ldalvik/annotation/Signature;
value = {
"(",
"Lkotlin/jvm/b/Functions2<",
"-",
"Ljava/lang/String;",
"+",
"Lcom/vtosters/lite/data/Analytics$l;",
">;)V"
}
.end annotation
.line 1
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
iput-object p1, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->b:Lkotlin/jvm/b/Functions2;
return-void
.end method
.method private final a(Lcom/vk/music/stats/i/MusicPlaybackParams;Ljava/lang/String;)Lcom/vtosters/lite/data/Analytics$l;
.locals 4
.line 16
iget-object v0, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->b:Lkotlin/jvm/b/Functions2;
invoke-interface {v0, p2}, Lkotlin/jvm/b/Functions2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
move-result-object v0
check-cast v0, Lcom/vtosters/lite/data/Analytics$l;
.line 17
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->c()Ljava/lang/String;
move-result-object v1
const-string v2, "audio_id"
invoke-virtual {v0, v2, v1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 18
invoke-static {}, Ljava/util/UUID;->randomUUID()Ljava/util/UUID;
move-result-object v1
invoke-virtual {v1}, Ljava/util/UUID;->hashCode()I
move-result v1
invoke-static {v1}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result-object v1
const-string v2, "uuid"
invoke-virtual {v0, v2, v1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 19
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->l()Z
move-result v1
invoke-static {v1}, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;
move-result-object v1
const-string v2, "shuffle"
invoke-virtual {v0, v2, v1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 20
invoke-direct {p0, p1}, Lcom/vk/music/stats/VKMusicStatsTracker;->e(Lcom/vk/music/stats/i/MusicPlaybackParams;)Ljava/lang/String;
move-result-object v1
const-string v2, "reason"
invoke-virtual {v0, v2, v1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 21
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->i()J
move-result-wide v1
invoke-static {v1, v2}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
move-result-object v1
const-string v2, "start_time"
invoke-virtual {v0, v2, v1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 22
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->d()J
move-result-wide v1
invoke-static {v1, v2}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
move-result-object v1
const-string v2, "playback_started_at"
invoke-virtual {v0, v2, v1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 23
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->j()Ljava/lang/String;
move-result-object v1
const-string v2, "track_code"
invoke-virtual {v0, v2, v1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
const-string v1, "music_start_playback"
.line 24
invoke-static {v1, p2}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/Object;)Z
move-result p2
const/4 v1, 0x1
xor-int/2addr p2, v1
if-eqz p2, :cond_0
.line 25
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->a()J
move-result-wide v2
invoke-static {v2, v3}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
move-result-object p2
const-string v2, "duration"
invoke-virtual {v0, v2, p2}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 26
:cond_0
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->b()Lcom/vk/music/player/LoopMode;
move-result-object p2
sget-object v2, Lcom/vk/music/stats/h;->$EnumSwitchMapping$0:[I
invoke-virtual {p2}, Ljava/lang/Enum;->ordinal()I
move-result p2
aget p2, v2, p2
const-string v2, "repeat"
if-eq p2, v1, :cond_2
const/4 v1, 0x2
if-eq p2, v1, :cond_1
goto :goto_0
:cond_1
const-string p2, "all"
.line 27
invoke-virtual {v0, v2, p2}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
goto :goto_0
:cond_2
const-string p2, "one"
.line 28
invoke-virtual {v0, v2, p2}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 29
:goto_0
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->m()Ljava/lang/String;
move-result-object p2
const-string v1, "state"
invoke-virtual {v0, v1, p2}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 30
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->h()Lcom/vk/music/common/MusicPlaybackLaunchContext;
move-result-object p2
.line 31
invoke-virtual {p2}, Lcom/vk/music/common/MusicPlaybackLaunchContext;->v0()Ljava/lang/String;
move-result-object v1
const-string v2, "source"
invoke-virtual {v0, v2, v1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 32
invoke-virtual {p2}, Lcom/vk/music/common/MusicPlaybackLaunchContext;->v1()Z
move-result v1
if-eqz v1, :cond_3
.line 33
invoke-virtual {p2}, Lcom/vk/music/common/MusicPlaybackLaunchContext;->u1()Ljava/lang/String;
move-result-object v1
const-string v2, "playlist_id"
invoke-virtual {v0, v2, v1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
:cond_3
const/4 v1, 0x4
.line 34
invoke-virtual {p2, v1}, Lcom/vk/music/common/MusicPlaybackLaunchContext;->i(I)Z
move-result v2
if-nez v2, :cond_4
const/16 v2, 0x8
invoke-virtual {p2, v2}, Lcom/vk/music/common/MusicPlaybackLaunchContext;->i(I)Z
move-result v2
if-eqz v2, :cond_5
.line 35
:cond_4
invoke-virtual {p2, v1}, Lcom/vk/music/common/MusicPlaybackLaunchContext;->i(I)Z
move-result p2
invoke-static {p2}, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;
move-result-object p2
const-string v1, "expanded"
invoke-virtual {v0, v1, p2}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 36
:cond_5
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->e()Ljava/lang/String;
move-result-object p2
invoke-static {p2}, Lcom/vk/core/extensions/StringExt;->a(Ljava/lang/CharSequence;)Z
move-result p2
if-eqz p2, :cond_6
.line 37
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->e()Ljava/lang/String;
move-result-object p2
const-string v1, "prev_audio_id"
invoke-virtual {v0, v1, p2}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 38
:cond_6
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->f()Ljava/lang/String;
move-result-object p2
invoke-static {p2}, Lcom/vk/core/extensions/StringExt;->a(Ljava/lang/CharSequence;)Z
move-result p2
if-eqz p2, :cond_7
.line 39
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->f()Ljava/lang/String;
move-result-object p1
const-string p2, "prev_playlist_id"
invoke-virtual {v0, p2, p1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
:cond_7
return-object v0
.end method
.method private final e(Lcom/vk/music/stats/i/MusicPlaybackParams;)Ljava/lang/String;
.locals 0
.line 1
invoke-virtual {p1}, Lcom/vk/music/stats/i/MusicPlaybackParams;->g()Ljava/lang/String;
move-result-object p1
if-nez p1, :cond_0
.line 2
iget-object p1, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->a:Ljava/lang/String;
:cond_0
if-nez p1, :cond_1
const-string p1, "auto"
.line 3
:cond_1
iput-object p1, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->a:Ljava/lang/String;
return-object p1
.end method
# virtual methods
.method public a()V
.locals 4
.line 46
sget-object v0, Lcom/vk/music/stats/VKMusicStatsTracker;->c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
iget-object v1, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->b:Lkotlin/jvm/b/Functions2;
const-string v2, "music_subscription"
invoke-interface {v1, v2}, Lkotlin/jvm/b/Functions2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
move-result-object v1
check-cast v1, Lcom/vtosters/lite/data/Analytics$l;
const-string v2, "popup"
const-string v3, "background_v2"
.line 47
invoke-virtual {v1, v2, v3}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
const-string v2, "action"
const-string v3, "link"
.line 48
invoke-virtual {v1, v2, v3}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
const-string v2, "newEventBuilder.invoke(T\u2026ION_POPUP_ACTION, \"link\")"
invoke-static {v1, v2}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
.line 49
invoke-virtual {v0, v1}, Lcom/vk/music/stats/VKMusicStatsTracker$a;->a(Lcom/vtosters/lite/data/Analytics$l;)V
return-void
.end method
.method public a(J)V
.locals 0
.line 3
invoke-static {p0, p1, p2}, Lcom/vk/music/stats/MusicStatsTracker$a;->a(Lcom/vk/music/stats/MusicStatsTracker;J)V
return-void
.end method
.method public a(Landroid/content/Intent;Ljava/lang/String;)V
.locals 0
.line 2
invoke-static {p0, p1, p2}, Lcom/vk/music/stats/MusicStatsTracker$a;->a(Lcom/vk/music/stats/MusicStatsTracker;Landroid/content/Intent;Ljava/lang/String;)V
return-void
.end method
.method public a(Lcom/vk/music/stats/PlayerStateChangedParams;)V
.locals 4
.line 8
sget-object v0, Lcom/vk/music/stats/VKMusicStatsTracker;->c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
iget-object v1, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->b:Lkotlin/jvm/b/Functions2;
const-string v2, "audio_player"
invoke-interface {v1, v2}, Lkotlin/jvm/b/Functions2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
move-result-object v1
check-cast v1, Lcom/vtosters/lite/data/Analytics$l;
.line 9
invoke-virtual {p1}, Lcom/vk/music/stats/PlayerStateChangedParams;->a()Ljava/lang/String;
move-result-object v2
const-string v3, "state"
invoke-virtual {v1, v3, v2}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 10
invoke-virtual {p1}, Lcom/vk/music/stats/PlayerStateChangedParams;->c()Ljava/lang/String;
move-result-object v2
const-string v3, "prev_state"
invoke-virtual {v1, v3, v2}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 11
invoke-virtual {p1}, Lcom/vk/music/stats/PlayerStateChangedParams;->b()J
move-result-wide v2
invoke-static {v2, v3}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
move-result-object p1
const-string v2, "duration"
invoke-virtual {v1, v2, p1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
const-string p1, "newEventBuilder.invoke(T\u2026TION, params.durationSec)"
invoke-static {v1, p1}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
.line 12
invoke-virtual {v0, v1}, Lcom/vk/music/stats/VKMusicStatsTracker$a;->a(Lcom/vtosters/lite/data/Analytics$l;)V
return-void
.end method
.method public a(Lcom/vk/music/stats/i/MusicPlaybackParams;)V
.locals 2
.line 7
sget-object v0, Lcom/vk/music/stats/VKMusicStatsTracker;->c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
const-string v1, "music_stop_playback"
invoke-direct {p0, p1, v1}, Lcom/vk/music/stats/VKMusicStatsTracker;->a(Lcom/vk/music/stats/i/MusicPlaybackParams;Ljava/lang/String;)Lcom/vtosters/lite/data/Analytics$l;
move-result-object p1
invoke-virtual {v0, p1}, Lcom/vk/music/stats/VKMusicStatsTracker$a;->a(Lcom/vtosters/lite/data/Analytics$l;)V
return-void
.end method
.method public a(Ljava/lang/String;)V
.locals 3
.line 13
sget-object v0, Lcom/vk/music/stats/VKMusicStatsTracker;->c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
iget-object v1, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->b:Lkotlin/jvm/b/Functions2;
const-string v2, "playlist_start"
invoke-interface {v1, v2}, Lkotlin/jvm/b/Functions2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
move-result-object v1
check-cast v1, Lcom/vtosters/lite/data/Analytics$l;
const-string v2, "type"
.line 14
invoke-virtual {v1, v2, p1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
const-string p1, "newEventBuilder.invoke(T\u2026ING_STARTED_TYPE, source)"
invoke-static {v1, p1}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
.line 15
invoke-virtual {v0, v1}, Lcom/vk/music/stats/VKMusicStatsTracker$a;->a(Lcom/vtosters/lite/data/Analytics$l;)V
return-void
.end method
.method public a(Ljava/lang/String;Lcom/vk/music/stats/MusicStatsRefer;)V
.locals 2
.line 4
sget-object p2, Lcom/vk/music/stats/VKMusicStatsTracker;->c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
iget-object v0, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->b:Lkotlin/jvm/b/Functions2;
const-string v1, "music_subscription_show"
invoke-interface {v0, v1}, Lkotlin/jvm/b/Functions2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
move-result-object v0
check-cast v0, Lcom/vtosters/lite/data/Analytics$l;
const-string v1, "popup"
.line 5
invoke-virtual {v0, v1, p1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
const-string p1, "newEventBuilder.invoke(T\u2026ION_POPUP_SOURCE, source)"
invoke-static {v0, p1}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
.line 6
invoke-virtual {p2, v0}, Lcom/vk/music/stats/VKMusicStatsTracker$a;->a(Lcom/vtosters/lite/data/Analytics$l;)V
return-void
.end method
.method public a(Ljava/lang/String;Ljava/lang/String;)V
.locals 4
const-string v0, "success"
.line 40
invoke-static {v0, p2}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/Object;)Z
move-result v1
.line 41
iget-object v2, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->b:Lkotlin/jvm/b/Functions2;
const-string v3, "music_subscription_purchase_result"
invoke-interface {v2, v3}, Lkotlin/jvm/b/Functions2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
move-result-object v2
check-cast v2, Lcom/vtosters/lite/data/Analytics$l;
const-string v3, "popup"
.line 42
invoke-virtual {v2, v3, p1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
if-eqz v1, :cond_0
goto :goto_0
:cond_0
const-string v0, "fail"
:goto_0
const-string p1, "status"
.line 43
invoke-virtual {v2, p1, v0}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
if-nez v1, :cond_1
const-string p1, "reason"
.line 44
invoke-virtual {v2, p1, p2}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
.line 45
:cond_1
sget-object p1, Lcom/vk/music/stats/VKMusicStatsTracker;->c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
const-string p2, "builder"
invoke-static {v2, p2}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
invoke-virtual {p1, v2}, Lcom/vk/music/stats/VKMusicStatsTracker$a;->a(Lcom/vtosters/lite/data/Analytics$l;)V
return-void
.end method
.method public a(Z)V
.locals 0
.line 1
invoke-static {p0, p1}, Lcom/vk/music/stats/MusicStatsTracker$a;->a(Lcom/vk/music/stats/MusicStatsTracker;Z)V
return-void
.end method
.method public b()V
.locals 4
.line 6
sget-object v0, Lcom/vk/music/stats/VKMusicStatsTracker;->c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
iget-object v1, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->b:Lkotlin/jvm/b/Functions2;
const-string v2, "music_subscription_push"
invoke-interface {v1, v2}, Lkotlin/jvm/b/Functions2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
move-result-object v1
check-cast v1, Lcom/vtosters/lite/data/Analytics$l;
const-string v2, "action"
const-string v3, "send"
.line 7
invoke-virtual {v1, v2, v3}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
const-string v2, "newEventBuilder.invoke(T\u2026ION_POPUP_ACTION, \"send\")"
invoke-static {v1, v2}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
.line 8
invoke-virtual {v0, v1}, Lcom/vk/music/stats/VKMusicStatsTracker$a;->a(Lcom/vtosters/lite/data/Analytics$l;)V
return-void
.end method
.method public b(Lcom/vk/music/stats/i/MusicPlaybackParams;)V
.locals 2
.line 1
sget-object v0, Lcom/vk/music/stats/VKMusicStatsTracker;->c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
const-string v1, "music_start_playback"
invoke-direct {p0, p1, v1}, Lcom/vk/music/stats/VKMusicStatsTracker;->a(Lcom/vk/music/stats/i/MusicPlaybackParams;Ljava/lang/String;)Lcom/vtosters/lite/data/Analytics$l;
move-result-object p1
invoke-virtual {v0, p1}, Lcom/vk/music/stats/VKMusicStatsTracker$a;->a(Lcom/vtosters/lite/data/Analytics$l;)V
return-void
.end method
.method public b(Ljava/lang/String;)V
.locals 3
.line 9
sget-object v0, Lcom/vk/music/stats/VKMusicStatsTracker;->c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
iget-object v1, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->b:Lkotlin/jvm/b/Functions2;
const-string v2, "music_subscription_free_displayed"
invoke-interface {v1, v2}, Lkotlin/jvm/b/Functions2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
move-result-object v1
check-cast v1, Lcom/vtosters/lite/data/Analytics$l;
const-string v2, "popup"
.line 10
invoke-virtual {v1, v2, p1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
const-string p1, "newEventBuilder.invoke(T\u2026ION_POPUP_SOURCE, source)"
invoke-static {v1, p1}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
.line 11
invoke-virtual {v0, v1}, Lcom/vk/music/stats/VKMusicStatsTracker$a;->a(Lcom/vtosters/lite/data/Analytics$l;)V
return-void
.end method
.method public b(Ljava/lang/String;Ljava/lang/String;)V
.locals 3
.line 2
sget-object v0, Lcom/vk/music/stats/VKMusicStatsTracker;->c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
iget-object v1, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->b:Lkotlin/jvm/b/Functions2;
const-string v2, "music_subscription_action"
invoke-interface {v1, v2}, Lkotlin/jvm/b/Functions2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
move-result-object v1
check-cast v1, Lcom/vtosters/lite/data/Analytics$l;
const-string v2, "popup"
.line 3
invoke-virtual {v1, v2, p1}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
const-string p1, "action"
.line 4
invoke-virtual {v1, p1, p2}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
const-string p1, "newEventBuilder.invoke(T\u2026ION_POPUP_ACTION, action)"
invoke-static {v1, p1}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
.line 5
invoke-virtual {v0, v1}, Lcom/vk/music/stats/VKMusicStatsTracker$a;->a(Lcom/vtosters/lite/data/Analytics$l;)V
return-void
.end method
.method public b(Z)V
.locals 0
return-void
.end method
.method public c()V
.locals 4
.line 3
sget-object v0, Lcom/vk/music/stats/VKMusicStatsTracker;->c:Lcom/vk/music/stats/VKMusicStatsTracker$a;
iget-object v1, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->b:Lkotlin/jvm/b/Functions2;
const-string v2, "music_subscription_push"
invoke-interface {v1, v2}, Lkotlin/jvm/b/Functions2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
move-result-object v1
check-cast v1, Lcom/vtosters/lite/data/Analytics$l;
const-string v2, "action"
const-string v3, "open"
.line 4
invoke-virtual {v1, v2, v3}, Lcom/vtosters/lite/data/Analytics$l;->a(Ljava/lang/String;Ljava/lang/Object;)Lcom/vtosters/lite/data/Analytics$l;
const-string v2, "newEventBuilder.invoke(T\u2026ION_POPUP_ACTION, \"open\")"
invoke-static {v1, v2}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/String;)V
.line 5
invoke-virtual {v0, v1}, Lcom/vk/music/stats/VKMusicStatsTracker$a;->a(Lcom/vtosters/lite/data/Analytics$l;)V
return-void
.end method
.method public c(Lcom/vk/music/stats/i/MusicPlaybackParams;)V
.locals 0
.line 1
invoke-static {p0, p1}, Lcom/vk/music/stats/MusicStatsTracker$a;->b(Lcom/vk/music/stats/MusicStatsTracker;Lcom/vk/music/stats/i/MusicPlaybackParams;)V
return-void
.end method
.method public c(Z)V
.locals 0
.line 2
invoke-static {p0, p1}, Lcom/vk/music/stats/MusicStatsTracker$a;->b(Lcom/vk/music/stats/MusicStatsTracker;Z)V
return-void
.end method
.method public d()V
.locals 0
.line 1
invoke-static {p0}, Lcom/vk/music/stats/MusicStatsTracker$a;->a(Lcom/vk/music/stats/MusicStatsTracker;)V
return-void
.end method
.method public d(Lcom/vk/music/stats/i/MusicPlaybackParams;)V
.locals 2
.line 2
iget-object v0, p0, Lcom/vk/music/stats/VKMusicStatsTracker;->a:Ljava/lang/String;
const-string v1, "pause"
invoke-static {v1, v0}, Lkotlin/jvm/internal/Intrinsics;->a(Ljava/lang/Object;Ljava/lang/Object;)Z
move-result v0
if-eqz v0, :cond_0
.line 3
invoke-virtual {p0, p1}, Lcom/vk/music/stats/VKMusicStatsTracker;->a(Lcom/vk/music/stats/i/MusicPlaybackParams;)V
:cond_0
return-void
.end method
@@ -35,7 +35,7 @@
const-string v0, "func_v" const-string v0, "func_v"
const/16 v1, 0x1b const/16 v1, 0x25
.line 3 .line 3
invoke-virtual {p0, v0, v1}, Lcom/vk/api/base/ApiRequest;->b(Ljava/lang/String;I)Lcom/vk/api/base/ApiRequest; invoke-virtual {p0, v0, v1}, Lcom/vk/api/base/ApiRequest;->b(Ljava/lang/String;I)Lcom/vk/api/base/ApiRequest;
@@ -39,7 +39,7 @@
.line 3 .line 3
invoke-virtual {p0, v0, p1}, Lcom/vk/api/base/ApiRequest;->b(Ljava/lang/String;I)Lcom/vk/api/base/ApiRequest; invoke-virtual {p0, v0, p1}, Lcom/vk/api/base/ApiRequest;->b(Ljava/lang/String;I)Lcom/vk/api/base/ApiRequest;
const/16 v0, 0xb const/16 v0, 0x17
const-string v1, "func_v" const-string v1, "func_v"
@@ -476,89 +476,89 @@
invoke-direct {v2}, Landroid/util/SparseArray;-><init>()V invoke-direct {v2}, Landroid/util/SparseArray;-><init>()V
const-string v4, "cities" # const-string v4, "cities"
.line 20 # .line 20
invoke-virtual {v1, v4}, Lorg/json/JSONObject;->getJSONArray(Ljava/lang/String;)Lorg/json/JSONArray; # invoke-virtual {v1, v4}, Lorg/json/JSONObject;->getJSONArray(Ljava/lang/String;)Lorg/json/JSONArray;
move-result-object v4 # move-result-object v4
const/4 v9, 0x0 # const/4 v9, 0x0
.line 21 # .line 21
:goto_3 # :goto_3
invoke-virtual {v4}, Lorg/json/JSONArray;->length()I # invoke-virtual {v4}, Lorg/json/JSONArray;->length()I
move-result v10 # move-result v10
const-string v11, "title" const-string v11, "title"
if-ge v9, v10, :cond_4 # if-ge v9, v10, :cond_4
.line 22 # .line 22
invoke-virtual {v4, v9}, Lorg/json/JSONArray;->getJSONObject(I)Lorg/json/JSONObject; # invoke-virtual {v4, v9}, Lorg/json/JSONArray;->getJSONObject(I)Lorg/json/JSONObject;
move-result-object v10 # move-result-object v10
.line 23 # .line 23
invoke-virtual {v10, v3}, Lorg/json/JSONObject;->getInt(Ljava/lang/String;)I # invoke-virtual {v10, v3}, Lorg/json/JSONObject;->getInt(Ljava/lang/String;)I
move-result v12 # move-result v12
invoke-virtual {v10, v11}, Lorg/json/JSONObject;->getString(Ljava/lang/String;)Ljava/lang/String; # invoke-virtual {v10, v11}, Lorg/json/JSONObject;->getString(Ljava/lang/String;)Ljava/lang/String;
move-result-object v10 # move-result-object v10
invoke-virtual {v2, v12, v10}, Landroid/util/SparseArray;->put(ILjava/lang/Object;)V # invoke-virtual {v2, v12, v10}, Landroid/util/SparseArray;->put(ILjava/lang/Object;)V
add-int/lit8 v9, v9, 0x1 # add-int/lit8 v9, v9, 0x1
goto :goto_3 # goto :goto_3
.line 24 # .line 24
:cond_4 # :cond_4
new-instance v4, Landroid/util/SparseArray; # new-instance v4, Landroid/util/SparseArray;
invoke-direct {v4}, Landroid/util/SparseArray;-><init>()V # invoke-direct {v4}, Landroid/util/SparseArray;-><init>()V
const-string v9, "cities" # const-string v9, "cities"
.line 25 # .line 25
invoke-virtual {v1, v9}, Lorg/json/JSONObject;->getJSONArray(Ljava/lang/String;)Lorg/json/JSONArray; # invoke-virtual {v1, v9}, Lorg/json/JSONObject;->getJSONArray(Ljava/lang/String;)Lorg/json/JSONArray;
move-result-object v9 # move-result-object v9
const/4 v10, 0x0 # const/4 v10, 0x0
.line 26 # .line 26
:goto_4 # :goto_4
invoke-virtual {v9}, Lorg/json/JSONArray;->length()I # invoke-virtual {v9}, Lorg/json/JSONArray;->length()I
move-result v12 # move-result v12
if-ge v10, v12, :cond_5 # if-ge v10, v12, :cond_5
.line 27 # .line 27
invoke-virtual {v9, v10}, Lorg/json/JSONArray;->getJSONObject(I)Lorg/json/JSONObject; # invoke-virtual {v9, v10}, Lorg/json/JSONArray;->getJSONObject(I)Lorg/json/JSONObject;
move-result-object v12 # move-result-object v12
.line 28 # .line 28
invoke-virtual {v12, v3}, Lorg/json/JSONObject;->getInt(Ljava/lang/String;)I # invoke-virtual {v12, v3}, Lorg/json/JSONObject;->getInt(Ljava/lang/String;)I
move-result v13 # move-result v13
invoke-virtual {v12, v11}, Lorg/json/JSONObject;->getString(Ljava/lang/String;)Ljava/lang/String; # invoke-virtual {v12, v11}, Lorg/json/JSONObject;->getString(Ljava/lang/String;)Ljava/lang/String;
move-result-object v12 # move-result-object v12
invoke-virtual {v4, v13, v12}, Landroid/util/SparseArray;->put(ILjava/lang/Object;)V # invoke-virtual {v4, v13, v12}, Landroid/util/SparseArray;->put(ILjava/lang/Object;)V
add-int/lit8 v10, v10, 0x1 # add-int/lit8 v10, v10, 0x1
goto :goto_4 # goto :goto_4
:cond_5 # :cond_5
const-string v4, "can_write_private_message" const-string v4, "can_write_private_message"
.line 29 .line 29
@@ -285,7 +285,8 @@
const-string p1, "func_v" const-string p1, "func_v"
const/16 v0, 0x15 #upgrade func_v to 0x16 to fix issue related with outdated gettings of post topics
const/16 v0, 0x16
.line 9 .line 9
invoke-virtual {p0, p1, v0}, Lcom/vk/api/base/ApiRequest;->b(Ljava/lang/String;I)Lcom/vk/api/base/ApiRequest; invoke-virtual {p0, p1, v0}, Lcom/vk/api/base/ApiRequest;->b(Ljava/lang/String;I)Lcom/vk/api/base/ApiRequest;
@@ -385,6 +386,7 @@
.end annotation .end annotation
.end param .end param
const/4 v0, 0x0 const/4 v0, 0x0
:try_start_0 :try_start_0
@@ -503,18 +505,22 @@
iput-object v1, v3, Lcom/vtosters/lite/api/execute/GetWallInfo$a;->e:Lcom/vk/auth/api/AccountPhoneVerify; iput-object v1, v3, Lcom/vtosters/lite/api/execute/GetWallInfo$a;->e:Lcom/vk/auth/api/AccountPhoneVerify;
const-string v1, "post_topics" invoke-static {v3}, Lru/vtosters/hooks/PostTopicsHook;->hook(Lcom/vtosters/lite/api/execute/GetWallInfo$a;)V
.line 17 # const-string v1, "post_topics"
invoke-virtual {p1, v1}, Lorg/json/JSONObject;->optJSONArray(Ljava/lang/String;)Lorg/json/JSONArray;
move-result-object v1 # .line 17
# invoke-virtual {p1, v1}, Lorg/json/JSONObject;->optJSONArray(Ljava/lang/String;)Lorg/json/JSONArray;
invoke-static {v1}, Lcom/vk/dto/newsfeed/PostTopic;->a(Lorg/json/JSONArray;)Ljava/util/List; # move-result-object v1
# invoke-static {v1}, Lcom/vk/dto/newsfeed/PostTopic;->a(Lorg/json/JSONArray;)Ljava/util/List;
# move-result-object v1
# iput-object v1, v3, Lcom/vtosters/lite/api/execute/GetWallInfo$a;->f:Ljava/util/List;
move-result-object v1
iput-object v1, v3, Lcom/vtosters/lite/api/execute/GetWallInfo$a;->f:Ljava/util/List;
const-string v1, "special_events" const-string v1, "special_events"
@@ -43,103 +43,9 @@
sput-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->c:Ljava/lang/Object; sput-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->c:Ljava/lang/Object;
.line 3
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List; sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/AdwHomeBadger; invoke-static {v0}, Lru/vtosters/hooks/ShortcutBadgerHook;->init(Ljava/util/List;)V
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 4
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/ApexHomeBadger;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 5
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/DefaultBadger;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 6
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/NewHtcHomeBadger;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 7
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/NovaHomeBadger;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 8
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/SonyHomeBadger;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 9
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/AsusHomeBadger;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 10
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/HuaweiHomeBadger;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 11
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/OPPOHomeBader;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 12
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/SamsungHomeBadger;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 13
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/ZukHomeBadger;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 14
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/VivoHomeBadger;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 15
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/ZTEHomeBadger;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
.line 16
sget-object v0, Lme/leolin/shortcutbadger/ShortcutBadger;->a:Ljava/util/List;
const-class v1, Lme/leolin/shortcutbadger/impl/EverythingMeHomeBadger;
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
return-void return-void
.end method .end method