Compare commits
121
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9eb29488d | ||
|
|
be3957db33 | ||
|
|
126f5259d1 | ||
|
|
2d1867197f | ||
|
|
3852425d2c | ||
|
|
c1d4216416 | ||
|
|
0f45a8d175 | ||
|
|
15ed01b4d3 | ||
|
|
41763a4b54 | ||
|
|
d98d81f105 | ||
|
|
899554a571 | ||
|
|
87b1a89bd8 | ||
|
|
c2b51338e8 | ||
|
|
1d03182a1f | ||
|
|
bbad64c0aa | ||
|
|
53081115cc | ||
|
|
af4f069eb4 | ||
|
|
904814e5cb | ||
|
|
c240db520d | ||
|
|
8f9235e6db | ||
|
|
10b27566c0 | ||
|
|
16b67cf6c6 | ||
|
|
23436f1026 | ||
|
|
6998bdba1c | ||
|
|
5aa0fe9959 | ||
|
|
88f0939f04 | ||
|
|
73653fa2e0 | ||
|
|
c812b13446 | ||
|
|
ea9291a5eb | ||
|
|
8d93e298b4 | ||
|
|
49d448ad99 | ||
|
|
6bcc278dee | ||
|
|
cff0a98227 | ||
|
|
3529eb7ba1 | ||
|
|
2ee4bf1107 | ||
|
|
ac43a7794b | ||
|
|
47b2519ca5 | ||
|
|
701674ce45 | ||
|
|
e19a005362 | ||
|
|
e11e97cd29 | ||
|
|
ab2715456f | ||
|
|
68526f0ba2 | ||
|
|
b3243f1d41 | ||
|
|
175866ddc5 | ||
|
|
f691f8cc9e | ||
|
|
305614dae6 | ||
|
|
4bbcde750a | ||
|
|
e159b4f594 | ||
|
|
204b0c6e2c | ||
|
|
522f6cd42b | ||
|
|
7dd9e5ff3a | ||
|
|
07f8542f56 | ||
|
|
6b1e6f07c5 | ||
|
|
5466dd72dd | ||
|
|
5ac3b9cf6e | ||
|
|
de6edc795a | ||
|
|
19d36272cb | ||
|
|
d2fe435ad2 | ||
|
|
b6e7d24979 | ||
|
|
d10d5eca4b | ||
|
|
67f1477907 | ||
|
|
18ef4eda21 | ||
|
|
84cf9ba10a | ||
|
|
b05a239b90 | ||
|
|
8959558c64 | ||
|
|
e19ed8845d | ||
|
|
b5ae2662db | ||
|
|
1a7a0e7f4f | ||
|
|
953aa790e3 | ||
|
|
c1de68893c | ||
|
|
e0d3f22f16 | ||
|
|
d4710663ff | ||
|
|
60e32df046 | ||
|
|
bbc4aa98f7 | ||
|
|
287af14589 | ||
|
|
18f40e0da9 | ||
|
|
9ff8c1d9fe | ||
|
|
91440e4f8b | ||
|
|
a195e05d7b | ||
|
|
8866bf90c7 | ||
|
|
eab5b7074e | ||
|
|
bdee6c08c0 | ||
|
|
0744613aa0 | ||
|
|
f6de4c5bc9 | ||
|
|
f59e93aab6 | ||
|
|
2d97341886 | ||
|
|
b247c5c090 | ||
|
|
fd6e866f6f | ||
|
|
780ebce3ff | ||
|
|
404594df87 | ||
|
|
2a85b3a4f0 | ||
|
|
413701d28e | ||
|
|
016bd342c4 | ||
|
|
d04b2249f0 | ||
|
|
8eb7ded6ba | ||
|
|
1f9c6fd80c | ||
|
|
4ec84e3754 | ||
|
|
3b8af6e477 | ||
|
|
ad3f70f4ac | ||
|
|
611f4d3159 | ||
|
|
cb38660a3a | ||
|
|
f6f0fb3d08 | ||
|
|
dab50535ef | ||
|
|
d9300fc621 | ||
|
|
48eba3ccbb | ||
|
|
2336da53be | ||
|
|
7319714140 | ||
|
|
857db4879a | ||
|
|
b5db820733 | ||
|
|
c668105003 | ||
|
|
dd6bbcbc2c | ||
|
|
4ed0749027 | ||
|
|
3b834c2688 | ||
|
|
0c5a40bedc | ||
|
|
8146b863b1 | ||
|
|
c64f8a1b2d | ||
|
|
dd6916c08a | ||
|
|
58c14fbd4f | ||
|
|
3b830f5e2e | ||
|
|
c304313be9 | ||
|
|
3068ff76c1 |
@@ -21,14 +21,21 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up NDK
|
||||
uses: nttld/setup-ndk@v1
|
||||
with:
|
||||
ndk-version: r25c
|
||||
add-to-path: false
|
||||
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'adopt'
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
|
||||
- name: Download tools
|
||||
run: |
|
||||
sudo apt update
|
||||
@@ -47,6 +54,8 @@ jobs:
|
||||
java -jar scripts/apktool.jar b smali -o smali/VTLite.apk --use-aapt2 -p scripts/framework/
|
||||
zipalign -p -f 4 smali/VTLite.apk smali/VTLite.apk_aligned
|
||||
mv smali/VTLite.apk_aligned smali/VTLite.apk
|
||||
env:
|
||||
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
|
||||
- name: Sign and verify the apk
|
||||
run: |
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="RClass Regeneration" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/scripts/rclass_regenerator.sh" />
|
||||
<option name="SCRIPT_OPTIONS" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="/bin/zsh" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="true" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration default="false" name="RClass Regeneration" type="BatchConfigurationType" factoryName="Batch">
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<module name="" />
|
||||
<option name="SCRIPT_NAME" value="./scripts/rclass_regenerator.bat" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Update APKs Jars (MacOS)" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/scripts/update_jars_brew.sh" />
|
||||
<option name="SCRIPT_OPTIONS" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="/bin/zsh" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="true" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Update APKs Jars" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/scripts/update_jars.sh" />
|
||||
<option name="SCRIPT_OPTIONS" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="/bin/zsh" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="true" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:buildAndInstallVTLBeta]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:buildAndInstallVTLBeta" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:buildAndInstallVTLDev]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:buildAndInstallVTLDev" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:buildAndInstallVTLRelease]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:buildAndInstallVTLRelease" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:buildAndLaunchVTLBeta]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:buildAndLaunchVTLBeta" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:buildAndLaunchVTLDev]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:buildAndLaunchVTLDev" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:buildAndLaunchVTLRelease]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:buildAndLaunchVTLRelease" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:buildVTLBeta]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:buildVTLBeta" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:buildVTLDev]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:buildVTLDev" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:buildVTLRelease]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:buildVTLRelease" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:exportDexBeta]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:exportDexBeta" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:exportDexDev]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:exportDexDev" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:exportDexRelease]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:exportDexRelease" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:prepareDexForMergeDev]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:prepareDexForMergeDev" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="lite [app:prepareDexForMergeRelease]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="app:prepareDexForMergeRelease" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="-Xms4g -Xmx4g" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
+36
-37
@@ -20,9 +20,9 @@ cargo {
|
||||
def smaliFolder = projectDir.toPath().resolve("../smali").normalize()
|
||||
def scriptsFolder = projectDir.toPath().resolve("../scripts").normalize()
|
||||
//you can add own folders with decompiled smali code
|
||||
def dexes=smaliFolder.toFile()
|
||||
.listFiles( { f -> f.isDirectory() && f.name.startsWith("smali") } as FileFilter)
|
||||
.size()
|
||||
def dexes = smaliFolder.toFile()
|
||||
.listFiles({ f -> f.isDirectory() && f.name.startsWith("smali") } as FileFilter)
|
||||
.size()
|
||||
|
||||
versionFile {
|
||||
file = projectDir.toPath().resolve("src/main/assets/version.properties").toFile()
|
||||
@@ -91,11 +91,13 @@ task testClasses {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.microsoft.appcenter:appcenter-analytics:5.0.2'
|
||||
implementation 'com.microsoft.appcenter:appcenter-crashes:5.0.2'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
|
||||
implementation 'com.microsoft.appcenter:appcenter-analytics:5.0.4'
|
||||
implementation 'com.microsoft.appcenter:appcenter-crashes:5.0.4'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
|
||||
implementation 'net.sourceforge.streamsupport:streamsupport-minifuture:1.7.4'
|
||||
implementation 'com.google.guava:guava:23.3-android'
|
||||
implementation 'com.google.guava:guava:32.0.0-android'
|
||||
|
||||
implementation 'com.mpatric:mp3agic:0.9.1'
|
||||
|
||||
implementation fileTree(dir: 'libs', include: ['*.aar'])
|
||||
compileOnly fileTree(dir: 'libs', include: ['*.jar'])
|
||||
@@ -105,38 +107,35 @@ task generateBuildTasks() {
|
||||
android.applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
def buildType = output.name.toString().capitalize()
|
||||
if(buildType=="Base")return
|
||||
if (buildType == "Base") return
|
||||
task "exportDex$buildType"() {
|
||||
dependsOn('assemble' + buildType)
|
||||
doLast {
|
||||
try {
|
||||
def suffix=buildType.toLowerCase()
|
||||
String apkPath=projectDir.getAbsolutePath()+"/build/outputs/apk/$suffix/app-$suffix"
|
||||
def apk=new File(apkPath+"-unsigned.apk")
|
||||
if(!apk.exists())apk=new File(apkPath+".apk")
|
||||
def zip=new ZipFile(apk)
|
||||
def entries=zip.entries()
|
||||
def dexCounter=dexes
|
||||
while(entries.hasMoreElements())
|
||||
{
|
||||
def entry=entries.nextElement()
|
||||
String filename
|
||||
if(entry.name.matches("^classes(?:(?=\\d)2|)\\.dex\$"))filename="classes${++dexCounter}.dex"
|
||||
else if(entry.name=="assets/version.properties")filename="version.properties"
|
||||
else continue
|
||||
println("Exporting "+entry.name)
|
||||
def tmpFile=new File(projectDir,filename)
|
||||
def is=zip.getInputStream(entry)
|
||||
def fos=new FileOutputStream(tmpFile)
|
||||
def buff=new byte[0x800]
|
||||
int len
|
||||
while((len=is.read(buff))>0)fos.write(buff,0,len)
|
||||
is.close()
|
||||
fos.close()
|
||||
}
|
||||
def suffix = buildType.toLowerCase()
|
||||
String apkPath = projectDir.getAbsolutePath() + "/build/outputs/apk/$suffix/app-$suffix"
|
||||
def apk = new File(apkPath + "-unsigned.apk")
|
||||
if (!apk.exists()) apk = new File(apkPath + ".apk")
|
||||
def zip = new ZipFile(apk)
|
||||
def dexCounter = dexes
|
||||
zip.stream()
|
||||
.filter(entry -> entry.name.matches("^classes(?:(?=\\d)2|)\\.dex\$") || entry.name == "assets/version.properties")
|
||||
.forEach(entry -> {
|
||||
String filename
|
||||
if (entry.name.matches("^classes(?:(?=\\d)2|)\\.dex\$")) filename = "classes${++dexCounter}.dex"
|
||||
else filename = "version.properties"
|
||||
println("Exporting " + entry.name)
|
||||
def tmpFile = new File(projectDir, filename)
|
||||
try (def is = zip.getInputStream(entry); def fos = new FileOutputStream(tmpFile)) {
|
||||
def buff = new byte[0x800]
|
||||
int len
|
||||
while ((len = is.read(buff)) > 0) fos.write(buff, 0, len)
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
task "prepareDexForMerge$buildType"(type: Copy) {
|
||||
@@ -152,19 +151,19 @@ task generateBuildTasks() {
|
||||
include 'version.properties'
|
||||
into 'assets'
|
||||
}
|
||||
from('../native-effects/target/aarch64-linux-android/release'){
|
||||
from('../native-effects/target/aarch64-linux-android/release') {
|
||||
include 'libnative_effects.so'
|
||||
into 'lib/arm64-v8a'
|
||||
}
|
||||
from('../native-effects/target/armv7-linux-androideabi/release'){
|
||||
from('../native-effects/target/armv7-linux-androideabi/release') {
|
||||
include 'libnative_effects.so'
|
||||
into 'lib/armeabi-v7a'
|
||||
}
|
||||
}
|
||||
task "cleanTemporaryFiles$buildType"(type:Delete)
|
||||
task "cleanTemporaryFiles$buildType"(type: Delete)
|
||||
{
|
||||
delete fileTree(dir:projectDir,include:["*.dex","version.properties"])
|
||||
delete fileTree(dir:smaliFolder,include:['*.dex',"assets/version.properties"])
|
||||
delete fileTree(dir: projectDir, include: ["*.dex", "version.properties"])
|
||||
delete fileTree(dir: smaliFolder, include: ['*.dex', "assets/version.properties"])
|
||||
}
|
||||
task "buildVTL$buildType"(type: Exec) {
|
||||
dependsOn('prepareDexForMerge' + buildType)
|
||||
|
||||
Binary file not shown.
Vendored
+1
-1
@@ -35,7 +35,7 @@
|
||||
-optimizationpasses 5
|
||||
-keepattributes SourceFile, LineNumberTable
|
||||
|
||||
-keep,allowoptimization class ru.vtosters.hooks.**, ru.vtosters.lite.utils.AndroidUtils, ru.vtosters.lite.utils.NetworkUtils, ru.vtosters.lite.utils.CrashReporter, ru.vtosters.lite.ui.activities.**, ru.vtosters.lite.services.**, ru.vtosters.lite.ui.fragments.**, ru.vtosters.lite.themes.**, ru.vtosters.lite.music.hook.**, ru.vtosters.lite.music.cache.injectors.**, ru.vtosters.lite.ui.wallpapers.NativeEffects, com.aefyr.tsg.g2.TelegramStickersService {
|
||||
-keep,allowoptimization class ru.vtosters.hooks.**, ru.vtosters.sponsorpost.internal.Native, ru.vtosters.lite.utils.AndroidUtils, ru.vtosters.lite.utils.NetworkUtils, ru.vtosters.lite.utils.CrashReporter, ru.vtosters.lite.ui.activities.**, ru.vtosters.lite.services.**, ru.vtosters.lite.ui.fragments.**, ru.vtosters.lite.themes.**, ru.vtosters.lite.music.hook.**, ru.vtosters.lite.music.cache.injectors.**, ru.vtosters.lite.ui.wallpapers.NativeEffects, com.aefyr.tsg.g2.TelegramStickersService {
|
||||
public <fields>;
|
||||
public <methods>;
|
||||
public <init>(...);
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.os.RemoteException;
|
||||
import bruhcollective.itaysonlab.libvkx.ILibVkxService;
|
||||
import com.vk.dto.music.MusicTrack;
|
||||
import com.vk.music.common.MusicPlaybackLaunchContext;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -33,7 +34,7 @@ public class LibVKXClient {
|
||||
public static boolean isVkxInstalled() {
|
||||
try {
|
||||
getGlobalContext().getPackageManager().getPackageInfo("ua.itaysonlab.vkx", 0);
|
||||
return isValidSignature();
|
||||
return isValidSignature() && !Preferences.serverFeaturesDisable();
|
||||
} catch (Exception unused) {
|
||||
return false;
|
||||
}
|
||||
@@ -80,6 +81,7 @@ public class LibVKXClient {
|
||||
lambdaplay(list, musicTrack, iLibVkxService, null);
|
||||
}
|
||||
|
||||
public static String asId(MusicTrack musicTrack)
|
||||
{ return musicTrack.y1(); }
|
||||
public static String asId(MusicTrack musicTrack) {
|
||||
return musicTrack.y1();
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
package com.arthenica.ffmpegkit;
|
||||
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import com.arthenica.smartexception.java.Exceptions;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class NativeLoader {
|
||||
static final String[] FFMPEG_LIBRARIES = {"avutil", "swresample", "avcodec", "avformat", "avfilter", "avdevice"};
|
||||
|
||||
private static void loadLibrary(String libraryName) {
|
||||
System.loadLibrary(libraryName);
|
||||
}
|
||||
|
||||
private static List<String> loadExternalLibraries() {
|
||||
//return Packages.getExternalLibraries();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static String loadNativeAbi() {
|
||||
return AbiDetect.getNativeAbi();
|
||||
}
|
||||
|
||||
static String loadAbi() {
|
||||
return AbiDetect.getAbi();
|
||||
}
|
||||
|
||||
static String loadPackageName() {
|
||||
return Packages.getPackageName();
|
||||
}
|
||||
|
||||
static String loadVersion() {
|
||||
return FFmpegKitConfig.getVersion();
|
||||
}
|
||||
|
||||
static boolean loadIsLTSBuild() {
|
||||
return AbiDetect.isNativeLTSBuild();
|
||||
}
|
||||
|
||||
static int loadLogLevel() {
|
||||
return FFmpegKitConfig.getNativeLogLevel();
|
||||
}
|
||||
|
||||
static String loadBuildDate() {
|
||||
return FFmpegKitConfig.getBuildDate();
|
||||
}
|
||||
|
||||
static void enableRedirection() {
|
||||
FFmpegKitConfig.enableRedirection();
|
||||
}
|
||||
|
||||
static void loadFFmpegKitAbiDetect() {
|
||||
loadLibrary("ffmpegkit_abidetect");
|
||||
}
|
||||
|
||||
static boolean loadFFmpeg() {
|
||||
boolean nativeFFmpegLoaded = false;
|
||||
boolean nativeFFmpegTriedAndFailed = false;
|
||||
|
||||
if (AbiDetect.ARM_V7A.equals(loadNativeAbi())) {
|
||||
try {
|
||||
for (String ffmpegLibrary : FFMPEG_LIBRARIES) {
|
||||
loadLibrary(ffmpegLibrary + "_neon");
|
||||
}
|
||||
nativeFFmpegLoaded = true;
|
||||
} catch (final Error e) {
|
||||
android.util.Log.i(FFmpegKitConfig.TAG, String.format("NEON supported armeabi-v7a ffmpeg library not found. Loading default armeabi-v7a library.%s", Exceptions.getStackTraceString(e)));
|
||||
nativeFFmpegTriedAndFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nativeFFmpegLoaded) {
|
||||
for (String ffmpegLibrary : FFMPEG_LIBRARIES) {
|
||||
loadLibrary(ffmpegLibrary);
|
||||
}
|
||||
}
|
||||
return nativeFFmpegTriedAndFailed;
|
||||
}
|
||||
|
||||
static void loadFFmpegKit(boolean nativeFFmpegTriedAndFailed) {
|
||||
boolean nativeFFmpegKitLoaded = false;
|
||||
if (!nativeFFmpegTriedAndFailed && "arm-v7a".equals(loadNativeAbi())) {
|
||||
try {
|
||||
loadLibrary("ffmpegkit_armv7a_neon");
|
||||
nativeFFmpegKitLoaded = true;
|
||||
AbiDetect.setArmV7aNeonLoaded();
|
||||
} catch (Error e) {
|
||||
Log.i("ffmpeg-kit", String.format("NEON supported armeabi-v7a ffmpegkit library not found. Loading default armeabi-v7a library.%s", Exceptions.getStackTraceString(e)));
|
||||
}
|
||||
}
|
||||
if (!nativeFFmpegKitLoaded) {
|
||||
loadLibrary("ffmpegkit");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static String getDeviceDebugInformation() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("brand: ");
|
||||
stringBuilder.append(Build.BRAND);
|
||||
stringBuilder.append(", model: ");
|
||||
stringBuilder.append(Build.MODEL);
|
||||
stringBuilder.append(", device: ");
|
||||
stringBuilder.append(Build.DEVICE);
|
||||
stringBuilder.append(", api level: ");
|
||||
stringBuilder.append(Build.VERSION.SDK_INT);
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
stringBuilder.append(", abis: ");
|
||||
stringBuilder.append(FFmpegKitConfig.argumentsToString(Build.SUPPORTED_ABIS));
|
||||
stringBuilder.append(", 32bit abis: ");
|
||||
stringBuilder.append(FFmpegKitConfig.argumentsToString(Build.SUPPORTED_32_BIT_ABIS));
|
||||
stringBuilder.append(", 64bit abis: ");
|
||||
stringBuilder.append(FFmpegKitConfig.argumentsToString(Build.SUPPORTED_64_BIT_ABIS));
|
||||
} else {
|
||||
stringBuilder.append(", cpu abis: ");
|
||||
stringBuilder.append(Build.CPU_ABI);
|
||||
stringBuilder.append(", cpu abi2s: ");
|
||||
stringBuilder.append(Build.CPU_ABI2);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,732 +0,0 @@
|
||||
/*
|
||||
* BSD 3-Clause License
|
||||
*
|
||||
* Copyright (c) 2020, Taner Sener
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.arthenica.smartexception;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>Abstract class that includes common variables and methods for different <code>Exceptions</code> implementations.
|
||||
*
|
||||
* @author Taner Sener
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public abstract class AbstractExceptions {
|
||||
|
||||
/**
|
||||
* <p>Default max depth used in methods which do not have a maxDepth argument.
|
||||
*/
|
||||
public static final int DEFAULT_MAX_DEPTH = 10;
|
||||
|
||||
/**
|
||||
* <p>Default value for ignoring all causes when stack trace elements are printed or converted to string.
|
||||
*/
|
||||
public static final boolean DEFAULT_IGNORE_ALL_CAUSES = false;
|
||||
|
||||
/**
|
||||
* <p>Stores global root package names.
|
||||
*/
|
||||
public static final Set<String> rootPackageSet = Collections.synchronizedSet(new HashSet<String>());
|
||||
|
||||
/**
|
||||
* <p>Stores global group package names.
|
||||
*/
|
||||
public static final Set<String> groupPackageSet = Collections.synchronizedSet(new HashSet<String>());
|
||||
|
||||
/**
|
||||
* <p>Stores global ignore package names.
|
||||
*/
|
||||
public static final Set<String> ignorePackageSet = Collections.synchronizedSet(new HashSet<String>());
|
||||
|
||||
/**
|
||||
* <p>Stores global ignore cause package names.
|
||||
*/
|
||||
public static final Set<String> ignoreCausePackageSet = Collections.synchronizedSet(new HashSet<String>());
|
||||
|
||||
/**
|
||||
* <p>Stores the value of global ignore all causes option.
|
||||
*/
|
||||
public static boolean ignoreAllCauses = DEFAULT_IGNORE_ALL_CAUSES;
|
||||
|
||||
/**
|
||||
* <p>Stores the global stack trace serializer implementation.
|
||||
*/
|
||||
public static StackTraceElementSerializer stackTraceElementSerializer;
|
||||
|
||||
/**
|
||||
* <p>Registers a new root package.
|
||||
*
|
||||
* @param packageString root package name to register
|
||||
*/
|
||||
public static void registerRootPackage(final String packageString) {
|
||||
rootPackageSet.add(packageString);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Clears previously registered root packages.
|
||||
*/
|
||||
public static void clearRootPackages() {
|
||||
rootPackageSet.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Registers a new group package.
|
||||
*
|
||||
* @param packageString group package name to register
|
||||
*/
|
||||
public static void registerGroupPackage(final String packageString) {
|
||||
groupPackageSet.add(packageString);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Clears previously registered group packages.
|
||||
*/
|
||||
public static void clearGroupPackages() {
|
||||
groupPackageSet.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the global stack trace serializer implementation which is used to serialize {@link StackTraceElement}
|
||||
* objects in <code>getStackTraceString</code> methods.
|
||||
*
|
||||
* @return current stack trace serializer implementation
|
||||
*/
|
||||
public static StackTraceElementSerializer getStackTraceElementSerializer() {
|
||||
return stackTraceElementSerializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the global stack trace serializer implementation which is used to serialize {@link StackTraceElement}
|
||||
* objects in <code>getStackTraceString</code> methods.
|
||||
*
|
||||
* @param stackTraceElementSerializer new stack trace serializer implementation
|
||||
*/
|
||||
public static void setStackTraceElementSerializer(final StackTraceElementSerializer stackTraceElementSerializer) {
|
||||
AbstractExceptions.stackTraceElementSerializer = stackTraceElementSerializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Registers a new ignore package.
|
||||
*
|
||||
* @param packageString ignore package name to register
|
||||
* @param ignoreCauseClasses ignore cause classes from this package too
|
||||
*/
|
||||
public static void registerIgnorePackage(final String packageString, final boolean ignoreCauseClasses) {
|
||||
ignorePackageSet.add(packageString);
|
||||
if (ignoreCauseClasses) {
|
||||
ignoreCausePackageSet.add(packageString);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Clears previously registered ignore packages.
|
||||
*/
|
||||
public static void clearIgnorePackages() {
|
||||
ignorePackageSet.clear();
|
||||
ignoreCausePackageSet.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the value of ignore all causes option.
|
||||
*
|
||||
* @return the value of global ignore all causes option. If value is true then stack trace elements printed or
|
||||
* converted to string will not include causes. If value is false causes will be appended to the stack trace of
|
||||
* the main throwable.
|
||||
*/
|
||||
public static boolean getIgnoreAllCauses() {
|
||||
return ignoreAllCauses;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the value of ignore all causes option.
|
||||
*
|
||||
* @param ignoreAllCauses new global ignore all causes option. If value is true then stack trace elements printed
|
||||
* or converted to string will not include causes. If value is false causes will be appended to the stack trace of
|
||||
* the main throwable.
|
||||
*/
|
||||
public static void setIgnoreAllCauses(final boolean ignoreAllCauses) {
|
||||
AbstractExceptions.ignoreAllCauses = ignoreAllCauses;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code>.
|
||||
*
|
||||
* <p>This method uses root packages registered by {@link #registerRootPackage(String)}, group packages registered
|
||||
* by {@link #registerGroupPackage(String)} and ignore packages registered by
|
||||
* {@link #registerIgnorePackage(String, boolean)} to build the smart stack trace.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable) {
|
||||
return getStackTraceString(throwable, false, rootPackageSet, groupPackageSet, ignorePackageSet, 0, ignoreAllCauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code>.
|
||||
*
|
||||
* <p>This method uses root packages registered by {@link #registerRootPackage(String)}, group packages registered
|
||||
* by {@link #registerGroupPackage(String)} and ignore packages registered by
|
||||
* {@link #registerIgnorePackage(String, boolean)} to build the smart stack trace.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param ignoreAllCauses ignore all causes in the exception chain
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final boolean ignoreAllCauses) {
|
||||
return getStackTraceString(throwable, false, rootPackageSet, groupPackageSet, ignorePackageSet, 0, ignoreAllCauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using packages provided.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param rootPackageSet root packages to use for building the stack trace
|
||||
* @param groupPackageSet group packages to use for building the stack trace
|
||||
* @param ignorePackageSet ignore packages to use for building the stack trace
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet) {
|
||||
return getStackTraceString(throwable, false, rootPackageSet, groupPackageSet, ignorePackageSet, 0, ignoreAllCauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using packages provided.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param rootPackageSet root packages to use for building the stack trace
|
||||
* @param groupPackageSet group packages to use for building the stack trace
|
||||
* @param ignorePackageSet ignore packages to use for building the stack trace
|
||||
* @param ignoreAllCauses ignore all causes in the exception chain
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet, final boolean ignoreAllCauses) {
|
||||
return getStackTraceString(throwable, false, rootPackageSet, groupPackageSet, ignorePackageSet, 0, ignoreAllCauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using root package provided.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param rootPackage root package to use for building the stack trace
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final String rootPackage) {
|
||||
return getStackTraceString(throwable, false, Collections.singleton(rootPackage), new HashSet<String>(), new HashSet<String>(), 0, ignoreAllCauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using root package provided.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param rootPackage root package to use for building the stack trace
|
||||
* @param groupPackage group package to use for building the stack trace
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final String rootPackage, final String groupPackage) {
|
||||
return getStackTraceString(throwable, false, Collections.singleton(rootPackage), Collections.singleton(groupPackage), new HashSet<String>(), 0, ignoreAllCauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using elements found until the maxDepth.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param maxDepth max depth in exception chain that will be used
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final int maxDepth) {
|
||||
return getStackTraceString(throwable, false, new HashSet<String>(), new HashSet<String>(), new HashSet<String>(), maxDepth, ignoreAllCauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using elements found until the maxDepth.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param maxDepth max depth in exception chain that will be used
|
||||
* @param ignoreAllCauses ignore all causes in the exception chain
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final int maxDepth, final boolean ignoreAllCauses) {
|
||||
return getStackTraceString(throwable, false, new HashSet<String>(), new HashSet<String>(), new HashSet<String>(), maxDepth, ignoreAllCauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using parameters provided.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param isCause throwable is a cause or not
|
||||
* @param rootPackageSet root packages to use for building the stack trace
|
||||
* @param groupPackageSet group packages to use for building the stack trace
|
||||
* @param ignorePackageSet ignore packages to use for building the stack trace
|
||||
* @param maxDepth max depth in exception chain that will be used
|
||||
* @param ignoreAllCauses ignore all causes in the exception chain
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final boolean isCause, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet, final int maxDepth, final boolean ignoreAllCauses) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
if (throwable == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
final String className = throwable.getClass().getName();
|
||||
|
||||
final StackTraceElement[] stackTraceElements;
|
||||
if (maxDepth > 0) {
|
||||
stackTraceElements = getStackTrace(throwable, maxDepth);
|
||||
} else {
|
||||
stackTraceElements = getStackTrace(throwable, rootPackageSet, ignorePackageSet);
|
||||
}
|
||||
String message = throwable.getLocalizedMessage();
|
||||
if (isEmpty(message)) {
|
||||
message = throwable.getMessage();
|
||||
}
|
||||
|
||||
/* PRINT MESSAGE */
|
||||
if (isCause) {
|
||||
builder.append(System.lineSeparator());
|
||||
builder.append("Caused by: ");
|
||||
builder.append(className);
|
||||
if (!isEmpty(message)) {
|
||||
builder.append(": ");
|
||||
builder.append(message);
|
||||
}
|
||||
} else {
|
||||
builder.append(System.lineSeparator());
|
||||
builder.append(className);
|
||||
if (!isEmpty(message)) {
|
||||
builder.append(": ");
|
||||
builder.append(message);
|
||||
}
|
||||
}
|
||||
|
||||
/* PRINT SHORT STACK TRACE */
|
||||
String currentGroupPackage = null;
|
||||
StackTraceElement firstStackTraceElementInTheGroup = null;
|
||||
int currentGroupCount = 0;
|
||||
for (StackTraceElement traceElement : stackTraceElements) {
|
||||
String traceElementClassName = traceElement.getClassName();
|
||||
String groupPackageMatch = getContainingPackage(traceElementClassName, groupPackageSet);
|
||||
|
||||
if (groupPackageMatch != null) {
|
||||
if (!groupPackageMatch.equals(currentGroupPackage)) {
|
||||
appendStackTraceGroupElement(builder, currentGroupPackage, currentGroupCount, firstStackTraceElementInTheGroup);
|
||||
|
||||
builder.append(System.lineSeparator());
|
||||
builder.append("\tat ");
|
||||
|
||||
currentGroupPackage = groupPackageMatch;
|
||||
firstStackTraceElementInTheGroup = traceElement;
|
||||
currentGroupCount = 1;
|
||||
} else {
|
||||
currentGroupCount++;
|
||||
}
|
||||
} else {
|
||||
currentGroupCount = appendStackTraceGroupElement(builder, currentGroupPackage, currentGroupCount, firstStackTraceElementInTheGroup);
|
||||
|
||||
builder.append(System.lineSeparator());
|
||||
builder.append("\tat ");
|
||||
if (stackTraceElementSerializer == null) {
|
||||
throw new IllegalArgumentException("Stack trace element serializer not initialized.");
|
||||
} else {
|
||||
builder.append(stackTraceElementSerializer.toString(traceElement));
|
||||
}
|
||||
currentGroupPackage = null;
|
||||
}
|
||||
}
|
||||
|
||||
appendStackTraceGroupElement(builder, currentGroupPackage, currentGroupCount, firstStackTraceElementInTheGroup);
|
||||
|
||||
final Throwable cause = throwable.getCause();
|
||||
if (cause != null && !containsPackage(className, ignoreCausePackageSet) && !ignoreAllCauses) {
|
||||
builder.append(getStackTraceString(cause, true, rootPackageSet, groupPackageSet, ignorePackageSet, maxDepth, ignoreAllCauses));
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Appends stack trace group information for the given parameters.
|
||||
*
|
||||
* @param stringBuilder string builder that group stack trace information will be appended
|
||||
* @param currentGroupPackage package name of the current group
|
||||
* @param numberOfElementsInTheCurrentGroup number of elements in the current group
|
||||
* @param firstStackTraceElementInTheGroup first stack trace element of this group
|
||||
* @return new value for the group element count
|
||||
*/
|
||||
public static int appendStackTraceGroupElement(final StringBuilder stringBuilder, final String currentGroupPackage, final int numberOfElementsInTheCurrentGroup, final StackTraceElement firstStackTraceElementInTheGroup) {
|
||||
if (numberOfElementsInTheCurrentGroup > 0) {
|
||||
if (stackTraceElementSerializer == null) {
|
||||
throw new IllegalArgumentException("Stack trace element serializer not initialized.");
|
||||
} else {
|
||||
stringBuilder.append((numberOfElementsInTheCurrentGroup == 1) ? stackTraceElementSerializer.toString(firstStackTraceElementInTheGroup) : String.format("%s%s ... %d more", stackTraceElementSerializer.getModuleName(firstStackTraceElementInTheGroup), currentGroupPackage, (numberOfElementsInTheCurrentGroup - 1)));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns true if package of the given class name matches one of package names provided in
|
||||
* <code>packageSet</code>.
|
||||
*
|
||||
* @param fullClassName fully qualified class name
|
||||
* @param packageSet set containing package names
|
||||
* @return true if package of the given class name matches one of package names provided in <code>packageSet</code>,
|
||||
* false otherwise
|
||||
*/
|
||||
public static boolean containsPackage(final String fullClassName, final Set<String> packageSet) {
|
||||
return getContainingPackage(fullClassName, packageSet) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Checks if one of the package names in the <code>packageSet</code> matches the package of the given class name
|
||||
* and returns the matching package name.
|
||||
*
|
||||
* @param fullClassName fully qualified class name
|
||||
* @param packageSet set containing package names
|
||||
* @return one of the package names in the <code>packageSet</code> that matches the package of the given class name
|
||||
* or null if no matching package name is found in the <code>packageSet</code>
|
||||
*/
|
||||
public static String getContainingPackage(final String fullClassName, final Set<String> packageSet) {
|
||||
for (final String parentExceptionPackage : packageSet) {
|
||||
if (fullClassName.startsWith(parentExceptionPackage)) {
|
||||
return parentExceptionPackage;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns all messages found in the exception chain of the <code>throwable</code> as a single string.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @return a string containing all messages found in the exception chain
|
||||
*/
|
||||
public static String getAllMessages(final Throwable throwable) {
|
||||
final StringBuilder messageBuilder = new StringBuilder();
|
||||
getAllMessages(throwable, messageBuilder);
|
||||
return messageBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Adds all messages found in the exception chain of the <code>throwable</code> into the given message builder.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param messageBuilder message builder
|
||||
*/
|
||||
public static void getAllMessages(final Throwable throwable, final StringBuilder messageBuilder) {
|
||||
if (throwable != null) {
|
||||
final String message = throwable.getMessage();
|
||||
if (!isEmpty(message)) {
|
||||
if (messageBuilder.length() != 0) {
|
||||
messageBuilder.append(System.lineSeparator());
|
||||
messageBuilder.append(" - Caused by: ");
|
||||
}
|
||||
messageBuilder.append(message);
|
||||
}
|
||||
getAllMessages(throwable.getCause(), messageBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Builds a smart stack trace for the given <code>throwable</code> using elements found until the maxDepth and
|
||||
* elements of it.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param maxDepth max depth in exception chain that will be returned
|
||||
* @return an array containing stack trace elements
|
||||
*/
|
||||
public static StackTraceElement[] getStackTrace(final Throwable throwable, final int maxDepth) {
|
||||
final ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>();
|
||||
|
||||
if (throwable != null) {
|
||||
StackTraceElement[] stackTrace = throwable.getStackTrace();
|
||||
for (int i = 0; (i < stackTrace.length) && (i < maxDepth); i++) {
|
||||
list.add(stackTrace[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return list.toArray(new StackTraceElement[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Builds a smart stack trace for the given <code>throwable</code> using packages provided and returns elements
|
||||
* of it.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param rootPackageSet root packages to use for building the stack trace
|
||||
* @param ignorePackageSet ignore packages to use for building the stack trace
|
||||
* @return an array containing stack trace elements
|
||||
*/
|
||||
public static StackTraceElement[] getStackTrace(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> ignorePackageSet) {
|
||||
final ArrayList<StackTraceElement> list = new ArrayList<StackTraceElement>();
|
||||
final ArrayList<StackTraceElement> partialList = new ArrayList<StackTraceElement>();
|
||||
|
||||
if (throwable != null) {
|
||||
for (StackTraceElement stackTraceElement : throwable.getStackTrace()) {
|
||||
final String className = stackTraceElement.getClassName();
|
||||
if (!isEmpty(className)) {
|
||||
if (containsPackage(className, rootPackageSet)) {
|
||||
list.addAll(partialList);
|
||||
list.add(stackTraceElement);
|
||||
} else if (!containsPackage(className, ignorePackageSet)) {
|
||||
partialList.add(stackTraceElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (list.isEmpty()) {
|
||||
list.addAll(partialList);
|
||||
}
|
||||
|
||||
return list.toArray(new StackTraceElement[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns true if the given cause class is found in the exception chain of the <code>throwable</code>.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Search starts from the <code>throwable</code> itself and goes through the exception chain up until
|
||||
* {@link #DEFAULT_MAX_DEPTH}.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param causeClass class to search for
|
||||
* @return true if the given cause class is found in the exception chain of the <code>throwable</code>, false
|
||||
* otherwise
|
||||
*/
|
||||
public static boolean containsCause(final Throwable throwable, final Class<?> causeClass) {
|
||||
return containsCause(throwable, causeClass, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns true if the given cause class and cause message is found in the exception chain of the
|
||||
* <code>throwable</code>.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Search starts from the <code>throwable</code> itself and goes through the exception chain up until
|
||||
* {@link #DEFAULT_MAX_DEPTH}.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param causeClass class to search for
|
||||
* @param causeMessage message to search for
|
||||
* @return true if the given cause class and cause message is found in the exception chain of the
|
||||
* <code>throwable</code>, false otherwise
|
||||
*/
|
||||
public static boolean containsCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage) {
|
||||
return (searchCause(throwable, causeClass, causeMessage, DEFAULT_MAX_DEPTH) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the cause of the <code>throwable</code> by walking through the exception chain.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @return the cause of the <code>throwable</code> found or null if <code>throwable</code> does not have a cause
|
||||
*/
|
||||
public static Throwable getCause(final Throwable throwable) {
|
||||
return getCause(throwable, DEFAULT_MAX_DEPTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the cause of the <code>throwable</code> by walking through the exception chain.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Note that this method walks through the exception chain up to given <code>maxDepth</code>. If exception chain
|
||||
* includes more items than <code>maxDepth</code>, cause found at <code>maxDepth</code> level is returned.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param maxDepth max depth in exception chain that will be searched
|
||||
* @return the cause of the <code>throwable</code> found until <code>maxDepth</code> is reached in the exception
|
||||
* chain or null if <code>throwable</code> does not have a cause
|
||||
*/
|
||||
public static Throwable getCause(final Throwable throwable, final int maxDepth) {
|
||||
if (throwable == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (maxDepth <= 0) {
|
||||
return throwable;
|
||||
}
|
||||
|
||||
final Throwable cause = throwable.getCause();
|
||||
if (cause == null) {
|
||||
return throwable;
|
||||
} else {
|
||||
return getCause(cause, maxDepth - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Searches for the given cause class in the exception chain of the <code>throwable</code>.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Search starts from the <code>throwable</code> itself and goes through the exception chain up until
|
||||
* {@link #DEFAULT_MAX_DEPTH}.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param causeClass class to search for
|
||||
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
|
||||
*/
|
||||
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass) {
|
||||
return searchCause(throwable, causeClass, null, DEFAULT_MAX_DEPTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Searches for the given cause class and cause message in the exception chain of the <code>throwable</code>.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Search starts from the <code>throwable</code> itself and goes through the exception chain up until
|
||||
* {@link #DEFAULT_MAX_DEPTH}.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param causeClass class to search for
|
||||
* @param causeMessage message to search for
|
||||
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
|
||||
* and cause message
|
||||
*/
|
||||
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage) {
|
||||
return searchCause(throwable, causeClass, causeMessage, DEFAULT_MAX_DEPTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Searches for the given cause class and cause message in the exception chain of the <code>throwable</code>.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Search starts from the <code>throwable</code> itself and goes through the exception chain up until the given
|
||||
* <code>maxDepth</code>.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param causeClass class to search for
|
||||
* @param causeMessage message to search for
|
||||
* @param maxDepth max depth in exception chain that will be searched
|
||||
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
|
||||
* and cause message
|
||||
*/
|
||||
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage, final int maxDepth) {
|
||||
if (throwable == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isEmpty(causeMessage)) {
|
||||
if (throwable.getClass().equals(causeClass)) {
|
||||
return throwable;
|
||||
}
|
||||
} else {
|
||||
if (throwable.getClass().equals(causeClass) && getAllMessages(throwable).toLowerCase().contains(causeMessage.toLowerCase())) {
|
||||
return throwable;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxDepth <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Throwable cause = throwable.getCause();
|
||||
if (cause == null) {
|
||||
return null;
|
||||
} else {
|
||||
return searchCause(cause, causeClass, causeMessage, maxDepth - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Searches for the given cause class in the exception chain of the <code>throwable</code>.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Search starts from the <code>throwable</code> itself and goes through the exception chain up until the given
|
||||
* <code>maxDepth</code>.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param causeClass class to search for
|
||||
* @param maxDepth max depth in exception chain that will be searched
|
||||
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
|
||||
*/
|
||||
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final int maxDepth) {
|
||||
if (throwable == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (throwable.getClass().equals(causeClass)) {
|
||||
return throwable;
|
||||
}
|
||||
|
||||
if (maxDepth <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Throwable cause = throwable.getCause();
|
||||
if (cause == null) {
|
||||
return null;
|
||||
} else {
|
||||
return searchCause(cause, causeClass, maxDepth - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Checks if given string is empty or not.
|
||||
*
|
||||
* @param value string to check
|
||||
* @return true if given string is null or has zero length after trim(), false otherwise
|
||||
*/
|
||||
public static boolean isEmpty(final String value) {
|
||||
if (value == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return value.trim().length() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the package name of this class.
|
||||
*
|
||||
* @param className fully qualified class name
|
||||
* @return name of the package
|
||||
*/
|
||||
public static String packageName(final String className) {
|
||||
if (className == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
int index = className.lastIndexOf(".");
|
||||
if (index >= 0) {
|
||||
return className.substring(0, index);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* BSD 3-Clause License
|
||||
*
|
||||
* Copyright (c) 2020, Taner Sener
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.arthenica.smartexception;
|
||||
|
||||
/**
|
||||
* <p>Base interface for classes which can serialize {@link StackTraceElement} objects.
|
||||
*
|
||||
* @author Taner Sener
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public interface StackTraceElementSerializer {
|
||||
|
||||
/**
|
||||
* <p>Converts the given <code>stackTraceElement</code> into a string.
|
||||
*
|
||||
* @param stackTraceElement stack trace element to convert
|
||||
* @return string representing the given <code>stackTraceElement</code>
|
||||
*/
|
||||
String toString(final StackTraceElement stackTraceElement);
|
||||
|
||||
/**
|
||||
* <p>Returns module name for the given <code>stackTraceElement</code>.
|
||||
*
|
||||
* @param stackTraceElement stack trace element to use
|
||||
* @return module name of the given <code>stackTraceElement</code> or an empty string if implementation does not
|
||||
* support printing module names
|
||||
*/
|
||||
String getModuleName(final StackTraceElement stackTraceElement);
|
||||
|
||||
/**
|
||||
* <p>Returns string definition used to print native methods.
|
||||
*
|
||||
* @return string definition used to print native methods
|
||||
*/
|
||||
String getNativeMethodDefinition();
|
||||
|
||||
/**
|
||||
* <p>Returns string definition used to print methods with unknown source.
|
||||
*
|
||||
* @return string definition used to print methods with unknown source
|
||||
*/
|
||||
String getUnknownSourceDefinition();
|
||||
|
||||
}
|
||||
@@ -1,423 +0,0 @@
|
||||
/*
|
||||
* BSD 3-Clause License
|
||||
*
|
||||
* Copyright (c) 2020, Taner Sener
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.arthenica.smartexception.java;
|
||||
|
||||
import com.arthenica.smartexception.AbstractExceptions;
|
||||
import com.arthenica.smartexception.StackTraceElementSerializer;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>Utility class to handle Throwable objects and stack traces. This implementation is compatible with all Java and
|
||||
* Android versions.
|
||||
*
|
||||
* @author Taner Sener
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Exceptions {
|
||||
|
||||
static {
|
||||
AbstractExceptions.setStackTraceElementSerializer(new StackTraceElementSerializer() {
|
||||
|
||||
@Override
|
||||
public String toString(StackTraceElement stackTraceElement) {
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
stringBuilder.append(stackTraceElement.getClassName());
|
||||
stringBuilder.append(".");
|
||||
stringBuilder.append(stackTraceElement.getMethodName());
|
||||
|
||||
if (stackTraceElement.isNativeMethod()) {
|
||||
stringBuilder.append("(Native Method)");
|
||||
} else if ((stackTraceElement.getFileName() != null) && (stackTraceElement.getFileName().length() > 0)) {
|
||||
stringBuilder.append("(");
|
||||
stringBuilder.append(stackTraceElement.getFileName());
|
||||
if (stackTraceElement.getLineNumber() >= 0) {
|
||||
stringBuilder.append(":");
|
||||
stringBuilder.append(stackTraceElement.getLineNumber());
|
||||
}
|
||||
stringBuilder.append(")");
|
||||
} else {
|
||||
stringBuilder.append("(Unknown Source)");
|
||||
}
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModuleName(StackTraceElement stackTraceElement) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNativeMethodDefinition() {
|
||||
return "(Native Method)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnknownSourceDefinition() {
|
||||
return "(Unknown Source)";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Registers a new root package.
|
||||
*
|
||||
* @param packageString root package name to register
|
||||
*/
|
||||
public static void registerRootPackage(final String packageString) {
|
||||
AbstractExceptions.registerRootPackage(packageString);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Clears previously registered root packages.
|
||||
*/
|
||||
public static void clearRootPackages() {
|
||||
AbstractExceptions.clearRootPackages();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Registers a new group package.
|
||||
*
|
||||
* @param packageString group package name to register
|
||||
*/
|
||||
public static void registerGroupPackage(final String packageString) {
|
||||
AbstractExceptions.registerGroupPackage(packageString);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Clears previously registered group packages.
|
||||
*/
|
||||
public static void clearGroupPackages() {
|
||||
AbstractExceptions.clearGroupPackages();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the global stack trace serializer implementation which is used to serialize {@link StackTraceElement}
|
||||
* objects in <code>getStackTraceString</code> methods.
|
||||
*
|
||||
* @return current stack trace serializer implementation
|
||||
*/
|
||||
public static StackTraceElementSerializer getStackTraceElementSerializer() {
|
||||
return AbstractExceptions.getStackTraceElementSerializer();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the global stack trace serializer implementation which is used to serialize {@link StackTraceElement}
|
||||
* objects in <code>getStackTraceString</code> methods.
|
||||
*
|
||||
* @param stackTraceElementSerializer new stack trace serializer implementation
|
||||
*/
|
||||
public static void setStackTraceElementSerializer(final StackTraceElementSerializer stackTraceElementSerializer) {
|
||||
AbstractExceptions.setStackTraceElementSerializer(stackTraceElementSerializer);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Registers a new ignore package.
|
||||
*
|
||||
* @param packageString ignore package name to register
|
||||
* @param ignoreCauseClasses ignore cause classes from this package too
|
||||
*/
|
||||
public static void registerIgnorePackage(final String packageString, final boolean ignoreCauseClasses) {
|
||||
AbstractExceptions.registerIgnorePackage(packageString, ignoreCauseClasses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Clears previously registered ignore packages.
|
||||
*/
|
||||
public static void clearIgnorePackages() {
|
||||
AbstractExceptions.clearIgnorePackages();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the value of ignore all causes option.
|
||||
*
|
||||
* @return the value of global ignore all causes option. If value is true then stack trace elements printed or
|
||||
* converted to string will not include causes. If value is false causes will be appended to the stack trace of
|
||||
* the main throwable.
|
||||
*/
|
||||
public static boolean getIgnoreAllCauses() {
|
||||
return AbstractExceptions.getIgnoreAllCauses();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the value of ignore all causes option.
|
||||
*
|
||||
* @param ignoreAllCauses new global ignore all causes option. If value is true then stack trace elements printed
|
||||
* or converted to string will not include causes. If value is false causes will be appended to the stack trace of
|
||||
* the main throwable.
|
||||
*/
|
||||
public static void setIgnoreAllCauses(final boolean ignoreAllCauses) {
|
||||
AbstractExceptions.setIgnoreAllCauses(ignoreAllCauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code>.
|
||||
*
|
||||
* <p>This method uses root packages registered by {@link #registerRootPackage(String)}, group packages registered
|
||||
* by {@link #registerGroupPackage(String)} and ignore packages registered by
|
||||
* {@link #registerIgnorePackage(String, boolean)} to build the smart stack trace.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable) {
|
||||
return AbstractExceptions.getStackTraceString(throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code>.
|
||||
*
|
||||
* <p>This method uses root packages registered by {@link #registerRootPackage(String)}, group packages registered
|
||||
* by {@link #registerGroupPackage(String)} and ignore packages registered by
|
||||
* {@link #registerIgnorePackage(String, boolean)} to build the smart stack trace.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param ignoreAllCauses ignore all causes in the exception chain
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final boolean ignoreAllCauses) {
|
||||
return AbstractExceptions.getStackTraceString(throwable, ignoreAllCauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using packages provided.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param rootPackageSet root packages to use for building the stack trace
|
||||
* @param groupPackageSet group packages to use for building the stack trace
|
||||
* @param ignorePackageSet ignore packages to use for building the stack trace
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet) {
|
||||
return AbstractExceptions.getStackTraceString(throwable, rootPackageSet, groupPackageSet, ignorePackageSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using packages provided.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param rootPackageSet root packages to use for building the stack trace
|
||||
* @param groupPackageSet group packages to use for building the stack trace
|
||||
* @param ignorePackageSet ignore packages to use for building the stack trace
|
||||
* @param ignoreAllCauses ignore all causes in the exception chain
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final Set<String> rootPackageSet, final Set<String> groupPackageSet, final Set<String> ignorePackageSet, final boolean ignoreAllCauses) {
|
||||
return AbstractExceptions.getStackTraceString(throwable, rootPackageSet, groupPackageSet, ignorePackageSet, ignoreAllCauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using root package provided.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param rootPackage root package to use for building the stack trace
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final String rootPackage) {
|
||||
return AbstractExceptions.getStackTraceString(throwable, rootPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using root package provided.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param rootPackage root package to use for building the stack trace
|
||||
* @param groupPackage group package to use for building the stack trace
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final String rootPackage, final String groupPackage) {
|
||||
return AbstractExceptions.getStackTraceString(throwable, rootPackage, groupPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using elements found until the maxDepth.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param maxDepth max depth in exception chain that will be used
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final int maxDepth) {
|
||||
return AbstractExceptions.getStackTraceString(throwable, maxDepth);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the smart stack trace for the given <code>throwable</code> using elements found until the maxDepth.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param maxDepth max depth in exception chain that will be used
|
||||
* @param ignoreAllCauses ignore all causes in the exception chain
|
||||
* @return a string containing the smart stack trace for the given <code>throwable</code>
|
||||
*/
|
||||
public static String getStackTraceString(final Throwable throwable, final int maxDepth, final boolean ignoreAllCauses) {
|
||||
return AbstractExceptions.getStackTraceString(throwable, maxDepth, ignoreAllCauses);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns all messages found in the exception chain of the <code>throwable</code> as a single string.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @return a string containing all messages found in the exception chain
|
||||
*/
|
||||
public static String getAllMessages(final Throwable throwable) {
|
||||
return AbstractExceptions.getAllMessages(throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns true if the given cause class is found in the exception chain of the <code>throwable</code>.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Search starts from the <code>throwable</code> itself and goes through the exception chain up until
|
||||
* {@link AbstractExceptions#DEFAULT_MAX_DEPTH}.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param causeClass class to search for
|
||||
* @return true if the given cause class is found in the exception chain of the <code>throwable</code>, false
|
||||
* otherwise
|
||||
*/
|
||||
public static boolean containsCause(final Throwable throwable, final Class<?> causeClass) {
|
||||
return AbstractExceptions.containsCause(throwable, causeClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns true if the given cause class and cause message is found in the exception chain of the
|
||||
* <code>throwable</code>.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Search starts from the <code>throwable</code> itself and goes through the exception chain up until
|
||||
* {@link AbstractExceptions#DEFAULT_MAX_DEPTH}.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param causeClass class to search for
|
||||
* @param causeMessage message to search for
|
||||
* @return true if the given cause class and cause message is found in the exception chain of the
|
||||
* <code>throwable</code>, false otherwise
|
||||
*/
|
||||
public static boolean containsCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage) {
|
||||
return AbstractExceptions.containsCause(throwable, causeClass, causeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the cause of the <code>throwable</code> by walking through the exception chain.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @return the cause of the <code>throwable</code> found or null if <code>throwable</code> does not have a cause
|
||||
*/
|
||||
public static Throwable getCause(final Throwable throwable) {
|
||||
return AbstractExceptions.getCause(throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the cause of the <code>throwable</code> by walking through the exception chain.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Note that this method walks through the exception chain up to given <code>maxDepth</code>. If exception chain
|
||||
* includes more items than <code>maxDepth</code>, cause found at <code>maxDepth</code> level is returned.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param maxDepth max depth in exception chain that will be searched
|
||||
* @return the cause of the <code>throwable</code> found until <code>maxDepth</code> is reached in the exception
|
||||
* chain or null if <code>throwable</code> does not have a cause
|
||||
*/
|
||||
public static Throwable getCause(final Throwable throwable, final int maxDepth) {
|
||||
return AbstractExceptions.getCause(throwable, maxDepth);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Searches for the given cause class in the exception chain of the <code>throwable</code>.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Search starts from the <code>throwable</code> itself and goes through the exception chain up until
|
||||
* {@link AbstractExceptions#DEFAULT_MAX_DEPTH}.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param causeClass class to search for
|
||||
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
|
||||
*/
|
||||
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass) {
|
||||
return AbstractExceptions.searchCause(throwable, causeClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Searches for the given cause class and cause message in the exception chain of the <code>throwable</code>.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Search starts from the <code>throwable</code> itself and goes through the exception chain up until
|
||||
* {@link AbstractExceptions#DEFAULT_MAX_DEPTH}.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param causeClass class to search for
|
||||
* @param causeMessage message to search for
|
||||
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
|
||||
* and cause message
|
||||
*/
|
||||
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage) {
|
||||
return AbstractExceptions.searchCause(throwable, causeClass, causeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Searches for the given cause class and cause message in the exception chain of the <code>throwable</code>.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Search starts from the <code>throwable</code> itself and goes through the exception chain up until the given
|
||||
* <code>maxDepth</code>.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param causeClass class to search for
|
||||
* @param causeMessage message to search for
|
||||
* @param maxDepth max depth in exception chain that will be searched
|
||||
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
|
||||
* and cause message
|
||||
*/
|
||||
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final String causeMessage, final int maxDepth) {
|
||||
return AbstractExceptions.searchCause(throwable, causeClass, causeMessage, maxDepth);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Searches for the given cause class in the exception chain of the <code>throwable</code>.
|
||||
* <br>
|
||||
* <br>
|
||||
* <p>Search starts from the <code>throwable</code> itself and goes through the exception chain up until the given
|
||||
* <code>maxDepth</code>.
|
||||
*
|
||||
* @param throwable parent throwable
|
||||
* @param causeClass class to search for
|
||||
* @param maxDepth max depth in exception chain that will be searched
|
||||
* @return the <code>throwable</code> found or null if no class in exception chain matches the given cause class
|
||||
*/
|
||||
public static Throwable searchCause(final Throwable throwable, final Class<?> causeClass, final int maxDepth) {
|
||||
return AbstractExceptions.searchCause(throwable, causeClass, maxDepth);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -59,26 +59,22 @@ public class ArscBlamer {
|
||||
* Maps type chunk entries to blamed resources.
|
||||
*/
|
||||
private final Multimap<TypeChunk.Entry, ResourceEntry> typeEntryToBlame = HashMultimap.create();
|
||||
|
||||
/**
|
||||
* Maps resources to the type chunk entries they reference.
|
||||
*/
|
||||
private Multimap<ResourceEntry, TypeChunk.Entry> resourceEntries;
|
||||
|
||||
/**
|
||||
* Maps resources which have no base config to the type chunk entries they reference.
|
||||
*/
|
||||
private Multimap<ResourceEntry, TypeChunk.Entry> baselessKeys;
|
||||
|
||||
/**
|
||||
* Contains all of the type chunks in {@link #resourceTable}.
|
||||
*/
|
||||
private List<TypeChunk> typeChunks;
|
||||
|
||||
/**
|
||||
* This is the {@link ResourceTableChunk} inside of the resources.arsc file in the APK.
|
||||
*/
|
||||
private final ResourceTableChunk resourceTable;
|
||||
/**
|
||||
* Maps resources to the type chunk entries they reference.
|
||||
*/
|
||||
private Multimap<ResourceEntry, TypeChunk.Entry> resourceEntries;
|
||||
/**
|
||||
* Maps resources which have no base config to the type chunk entries they reference.
|
||||
*/
|
||||
private Multimap<ResourceEntry, TypeChunk.Entry> baselessKeys;
|
||||
/**
|
||||
* Contains all of the type chunks in {@link #resourceTable}.
|
||||
*/
|
||||
private List<TypeChunk> typeChunks;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ArscBlamer}.
|
||||
@@ -90,6 +86,14 @@ public class ArscBlamer {
|
||||
this.stringToBlame = createEntryListArray(resourceTable.getStringPool().getStringCount());
|
||||
}
|
||||
|
||||
private static List<ResourceEntry>[] createEntryListArray(int size) {
|
||||
ArrayListResourceEntry[] result = new ArrayListResourceEntry[size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
result[i] = new ArrayListResourceEntry();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates blame mappings.
|
||||
*/
|
||||
@@ -257,14 +261,6 @@ public class ArscBlamer {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static List<ResourceEntry>[] createEntryListArray(int size) {
|
||||
ArrayListResourceEntry[] result = new ArrayListResourceEntry[size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
result[i] = new ArrayListResourceEntry();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows creation of concrete parameterized type arr {@link ArscBlamer#createEntryListArray}.
|
||||
*/
|
||||
@@ -283,6 +279,12 @@ public class ArscBlamer {
|
||||
private final String typeName;
|
||||
private final String entryName;
|
||||
|
||||
private ResourceEntry(String packageName, String typeName, String entryName) {
|
||||
this.packageName = packageName;
|
||||
this.typeName = typeName;
|
||||
this.entryName = entryName;
|
||||
}
|
||||
|
||||
static ResourceEntry create(TypeChunk.Entry entry) {
|
||||
PackageChunk packageChunk = Preconditions.checkNotNull(entry.parent().getPackageChunk());
|
||||
String packageName = packageChunk.getPackageName();
|
||||
@@ -291,12 +293,6 @@ public class ArscBlamer {
|
||||
return new ResourceEntry(packageName, typeName, entryName);
|
||||
}
|
||||
|
||||
private ResourceEntry(String packageName, String typeName, String entryName) {
|
||||
this.packageName = packageName;
|
||||
this.typeName = typeName;
|
||||
this.entryName = entryName;
|
||||
}
|
||||
|
||||
public String packageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
+221
-240
@@ -31,6 +31,148 @@ import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
* Describes a particular resource configuration.
|
||||
*/
|
||||
public class BinaryResourceConfiguration implements SerializableResource {
|
||||
/**
|
||||
* The below constants are from android.content.res.Configuration.
|
||||
*/
|
||||
private static final int DENSITY_DPI_UNDEFINED = 0;
|
||||
private static final int DENSITY_DPI_LDPI = 120;
|
||||
private static final int DENSITY_DPI_MDPI = 160;
|
||||
private static final int DENSITY_DPI_TVDPI = 213;
|
||||
private static final int DENSITY_DPI_HDPI = 240;
|
||||
private static final int DENSITY_DPI_XHDPI = 320;
|
||||
private static final int DENSITY_DPI_XXHDPI = 480;
|
||||
private static final int DENSITY_DPI_XXXHDPI = 640;
|
||||
private static final int DENSITY_DPI_ANY = 0xFFFE;
|
||||
private static final int DENSITY_DPI_NONE = 0xFFFF;
|
||||
private static final Map<Integer, String> DENSITY_DPI_VALUES =
|
||||
ImmutableMap.<Integer, String>builder()
|
||||
.put(DENSITY_DPI_UNDEFINED, "")
|
||||
.put(DENSITY_DPI_LDPI, "ldpi")
|
||||
.put(DENSITY_DPI_MDPI, "mdpi")
|
||||
.put(DENSITY_DPI_TVDPI, "tvdpi")
|
||||
.put(DENSITY_DPI_HDPI, "hdpi")
|
||||
.put(DENSITY_DPI_XHDPI, "xhdpi")
|
||||
.put(DENSITY_DPI_XXHDPI, "xxhdpi")
|
||||
.put(DENSITY_DPI_XXXHDPI, "xxxhdpi")
|
||||
.put(DENSITY_DPI_ANY, "anydpi")
|
||||
.put(DENSITY_DPI_NONE, "nodpi")
|
||||
.build();
|
||||
private static final int KEYBOARD_NOKEYS = 1;
|
||||
private static final int KEYBOARD_QWERTY = 2;
|
||||
private static final int KEYBOARD_12KEY = 3;
|
||||
private static final Map<Integer, String> KEYBOARD_VALUES = ImmutableMap.of(
|
||||
KEYBOARD_NOKEYS, "nokeys",
|
||||
KEYBOARD_QWERTY, "qwerty",
|
||||
KEYBOARD_12KEY, "12key");
|
||||
private static final int KEYBOARDHIDDEN_MASK = 0x03;
|
||||
private static final int KEYBOARDHIDDEN_NO = 1;
|
||||
private static final int KEYBOARDHIDDEN_YES = 2;
|
||||
private static final int KEYBOARDHIDDEN_SOFT = 3;
|
||||
private static final Map<Integer, String> KEYBOARDHIDDEN_VALUES = ImmutableMap.of(
|
||||
KEYBOARDHIDDEN_NO, "keysexposed",
|
||||
KEYBOARDHIDDEN_YES, "keyshidden",
|
||||
KEYBOARDHIDDEN_SOFT, "keyssoft");
|
||||
private static final int NAVIGATION_NONAV = 1;
|
||||
private static final int NAVIGATION_DPAD = 2;
|
||||
private static final int NAVIGATION_TRACKBALL = 3;
|
||||
private static final int NAVIGATION_WHEEL = 4;
|
||||
private static final Map<Integer, String> NAVIGATION_VALUES = ImmutableMap.of(
|
||||
NAVIGATION_NONAV, "nonav",
|
||||
NAVIGATION_DPAD, "dpad",
|
||||
NAVIGATION_TRACKBALL, "trackball",
|
||||
NAVIGATION_WHEEL, "wheel");
|
||||
private static final int NAVIGATIONHIDDEN_MASK = 0x0C;
|
||||
private static final int NAVIGATIONHIDDEN_NO = 0x04;
|
||||
private static final int NAVIGATIONHIDDEN_YES = 0x08;
|
||||
private static final Map<Integer, String> NAVIGATIONHIDDEN_VALUES = ImmutableMap.of(
|
||||
NAVIGATIONHIDDEN_NO, "navexposed",
|
||||
NAVIGATIONHIDDEN_YES, "navhidden");
|
||||
private static final int ORIENTATION_PORTRAIT = 0x01;
|
||||
private static final int ORIENTATION_LANDSCAPE = 0x02;
|
||||
private static final Map<Integer, String> ORIENTATION_VALUES = ImmutableMap.of(
|
||||
ORIENTATION_PORTRAIT, "port",
|
||||
ORIENTATION_LANDSCAPE, "land");
|
||||
private static final int SCREENLAYOUT_LAYOUTDIR_MASK = 0xC0;
|
||||
private static final int SCREENLAYOUT_LAYOUTDIR_LTR = 0x40;
|
||||
private static final int SCREENLAYOUT_LAYOUTDIR_RTL = 0x80;
|
||||
private static final Map<Integer, String> SCREENLAYOUT_LAYOUTDIR_VALUES = ImmutableMap.of(
|
||||
SCREENLAYOUT_LAYOUTDIR_LTR, "ldltr",
|
||||
SCREENLAYOUT_LAYOUTDIR_RTL, "ldrtl");
|
||||
private static final int SCREENLAYOUT_LONG_MASK = 0x30;
|
||||
private static final int SCREENLAYOUT_LONG_NO = 0x10;
|
||||
private static final int SCREENLAYOUT_LONG_YES = 0x20;
|
||||
private static final Map<Integer, String> SCREENLAYOUT_LONG_VALUES = ImmutableMap.of(
|
||||
SCREENLAYOUT_LONG_NO, "notlong",
|
||||
SCREENLAYOUT_LONG_YES, "long");
|
||||
private static final int SCREENLAYOUT_ROUND_MASK = 0x03;
|
||||
private static final int SCREENLAYOUT_ROUND_NO = 0x01;
|
||||
private static final int SCREENLAYOUT_ROUND_YES = 0x02;
|
||||
private static final Map<Integer, String> SCREENLAYOUT_ROUND_VALUES = ImmutableMap.of(
|
||||
SCREENLAYOUT_ROUND_NO, "notround",
|
||||
SCREENLAYOUT_ROUND_YES, "round");
|
||||
private static final int SCREENLAYOUT_SIZE_MASK = 0x0F;
|
||||
private static final int SCREENLAYOUT_SIZE_SMALL = 0x01;
|
||||
private static final int SCREENLAYOUT_SIZE_NORMAL = 0x02;
|
||||
private static final int SCREENLAYOUT_SIZE_LARGE = 0x03;
|
||||
private static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;
|
||||
private static final Map<Integer, String> SCREENLAYOUT_SIZE_VALUES = ImmutableMap.of(
|
||||
SCREENLAYOUT_SIZE_SMALL, "small",
|
||||
SCREENLAYOUT_SIZE_NORMAL, "normal",
|
||||
SCREENLAYOUT_SIZE_LARGE, "large",
|
||||
SCREENLAYOUT_SIZE_XLARGE, "xlarge");
|
||||
private static final int TOUCHSCREEN_NOTOUCH = 1;
|
||||
private static final int TOUCHSCREEN_FINGER = 3;
|
||||
private static final Map<Integer, String> TOUCHSCREEN_VALUES = ImmutableMap.of(
|
||||
TOUCHSCREEN_NOTOUCH, "notouch",
|
||||
TOUCHSCREEN_FINGER, "finger");
|
||||
private static final int UI_MODE_NIGHT_MASK = 0x30;
|
||||
private static final int UI_MODE_NIGHT_NO = 0x10;
|
||||
private static final int UI_MODE_NIGHT_YES = 0x20;
|
||||
private static final Map<Integer, String> UI_MODE_NIGHT_VALUES = ImmutableMap.of(
|
||||
UI_MODE_NIGHT_NO, "notnight",
|
||||
UI_MODE_NIGHT_YES, "night");
|
||||
private static final int UI_MODE_TYPE_MASK = 0x0F;
|
||||
private static final int UI_MODE_TYPE_DESK = 0x02;
|
||||
private static final int UI_MODE_TYPE_CAR = 0x03;
|
||||
private static final int UI_MODE_TYPE_TELEVISION = 0x04;
|
||||
private static final int UI_MODE_TYPE_APPLIANCE = 0x05;
|
||||
private static final int UI_MODE_TYPE_WATCH = 0x06;
|
||||
private static final int UI_MODE_TYPE_VR_HEADSET = 0x07;
|
||||
// start - miui
|
||||
private static final int UI_MODE_TYPE_GODZILLAUI = 0x0b;
|
||||
private static final int UI_MODE_TYPE_SMALLUI = 0x0c;
|
||||
private static final int UI_MODE_TYPE_MEDIUMUI = 0x0d;
|
||||
private static final int UI_MODE_TYPE_LARGEUI = 0x0e;
|
||||
private static final int UI_MODE_TYPE_HUGEUI = 0x0f;
|
||||
private static final Map<Integer, String> UI_MODE_TYPE_VALUES =
|
||||
ImmutableMap.<Integer, String>builder()
|
||||
.put(UI_MODE_TYPE_DESK, "desk")
|
||||
.put(UI_MODE_TYPE_CAR, "car")
|
||||
.put(UI_MODE_TYPE_TELEVISION, "television")
|
||||
.put(UI_MODE_TYPE_APPLIANCE, "appliance")
|
||||
.put(UI_MODE_TYPE_WATCH, "watch")
|
||||
.put(UI_MODE_TYPE_VR_HEADSET, "vrheadset")
|
||||
.put(UI_MODE_TYPE_GODZILLAUI, "godzillaui")
|
||||
.put(UI_MODE_TYPE_SMALLUI, "smallui")
|
||||
.put(UI_MODE_TYPE_MEDIUMUI, "mediumui")
|
||||
.put(UI_MODE_TYPE_LARGEUI, "largeui")
|
||||
.put(UI_MODE_TYPE_HUGEUI, "hugeui").build();
|
||||
/**
|
||||
* The minimum size in bytes that this configuration must be to contain screen config info.
|
||||
*/
|
||||
private static final int SCREEN_CONFIG_MIN_SIZE = 32;
|
||||
/**
|
||||
* The minimum size in bytes that this configuration must be to contain screen dp info.
|
||||
*/
|
||||
private static final int SCREEN_DP_MIN_SIZE = 36;
|
||||
/**
|
||||
* The minimum size in bytes that this configuration must be to contain locale info.
|
||||
*/
|
||||
private static final int LOCALE_MIN_SIZE = 48;
|
||||
/**
|
||||
* The minimum size in bytes that this config must be to contain the screenConfig extension.
|
||||
*/
|
||||
private static final int SCREEN_CONFIG_EXTENSION_MIN_SIZE = 52;
|
||||
private final int size;
|
||||
private final int mcc;
|
||||
private final int mnc;
|
||||
@@ -53,9 +195,60 @@ public class BinaryResourceConfiguration implements SerializableResource {
|
||||
private final int screenHeightDp;
|
||||
private final byte[] localeScript;
|
||||
private final byte[] localeVariant;
|
||||
// end - miui
|
||||
private final int screenLayout2;
|
||||
private final byte[] unknown;
|
||||
|
||||
private BinaryResourceConfiguration(int size,
|
||||
int mcc,
|
||||
int mnc,
|
||||
byte[] language,
|
||||
byte[] region,
|
||||
int orientation,
|
||||
int touchscreen,
|
||||
int density,
|
||||
int keyboard,
|
||||
int navigation,
|
||||
int inputFlags,
|
||||
int screenWidth,
|
||||
int screenHeight,
|
||||
int sdkVersion,
|
||||
int minorVersion,
|
||||
int screenLayout,
|
||||
int uiMode,
|
||||
int smallestScreenWidthDp,
|
||||
int screenWidthDp,
|
||||
int screenHeightDp,
|
||||
byte[] localeScript,
|
||||
byte[] localeVariant,
|
||||
int screenLayout2,
|
||||
byte[] unknown) {
|
||||
this.size = size;
|
||||
this.mcc = mcc;
|
||||
this.mnc = mnc;
|
||||
this.language = language;
|
||||
this.region = region;
|
||||
this.orientation = orientation;
|
||||
this.touchscreen = touchscreen;
|
||||
this.density = density;
|
||||
this.keyboard = keyboard;
|
||||
this.navigation = navigation;
|
||||
this.inputFlags = inputFlags;
|
||||
this.screenWidth = screenWidth;
|
||||
this.screenHeight = screenHeight;
|
||||
this.sdkVersion = sdkVersion;
|
||||
this.minorVersion = minorVersion;
|
||||
this.screenLayout = screenLayout;
|
||||
this.uiMode = uiMode;
|
||||
this.smallestScreenWidthDp = smallestScreenWidthDp;
|
||||
this.screenWidthDp = screenWidthDp;
|
||||
this.screenHeightDp = screenHeightDp;
|
||||
this.localeScript = localeScript;
|
||||
this.localeVariant = localeVariant;
|
||||
this.screenLayout2 = screenLayout2;
|
||||
this.unknown = unknown;
|
||||
}
|
||||
|
||||
static BinaryResourceConfiguration create(ByteBuffer buffer) {
|
||||
int startPosition = buffer.position(); // The starting buffer position to calculate bytes read.
|
||||
int size = buffer.getInt();
|
||||
@@ -121,245 +314,6 @@ public class BinaryResourceConfiguration implements SerializableResource {
|
||||
screenHeightDp, localeScript, localeVariant, screenLayout2, unknown);
|
||||
}
|
||||
|
||||
private BinaryResourceConfiguration(int size,
|
||||
int mcc,
|
||||
int mnc,
|
||||
byte[] language,
|
||||
byte[] region,
|
||||
int orientation,
|
||||
int touchscreen,
|
||||
int density,
|
||||
int keyboard,
|
||||
int navigation,
|
||||
int inputFlags,
|
||||
int screenWidth,
|
||||
int screenHeight,
|
||||
int sdkVersion,
|
||||
int minorVersion,
|
||||
int screenLayout,
|
||||
int uiMode,
|
||||
int smallestScreenWidthDp,
|
||||
int screenWidthDp,
|
||||
int screenHeightDp,
|
||||
byte[] localeScript,
|
||||
byte[] localeVariant,
|
||||
int screenLayout2,
|
||||
byte[] unknown) {
|
||||
this.size = size;
|
||||
this.mcc = mcc;
|
||||
this.mnc = mnc;
|
||||
this.language = language;
|
||||
this.region = region;
|
||||
this.orientation = orientation;
|
||||
this.touchscreen = touchscreen;
|
||||
this.density = density;
|
||||
this.keyboard = keyboard;
|
||||
this.navigation = navigation;
|
||||
this.inputFlags = inputFlags;
|
||||
this.screenWidth = screenWidth;
|
||||
this.screenHeight = screenHeight;
|
||||
this.sdkVersion = sdkVersion;
|
||||
this.minorVersion = minorVersion;
|
||||
this.screenLayout = screenLayout;
|
||||
this.uiMode = uiMode;
|
||||
this.smallestScreenWidthDp = smallestScreenWidthDp;
|
||||
this.screenWidthDp = screenWidthDp;
|
||||
this.screenHeightDp = screenHeightDp;
|
||||
this.localeScript = localeScript;
|
||||
this.localeVariant = localeVariant;
|
||||
this.screenLayout2 = screenLayout2;
|
||||
this.unknown = unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* The different types of configs that can be present in a {@link BinaryResourceConfiguration}.
|
||||
*/
|
||||
public enum Type {
|
||||
MCC,
|
||||
MNC,
|
||||
LANGUAGE_STRING,
|
||||
REGION_STRING,
|
||||
SCREEN_LAYOUT_DIRECTION,
|
||||
SMALLEST_SCREEN_WIDTH_DP,
|
||||
SCREEN_WIDTH_DP,
|
||||
SCREEN_HEIGHT_DP,
|
||||
SCREEN_LAYOUT_SIZE,
|
||||
SCREEN_LAYOUT_LONG,
|
||||
SCREEN_LAYOUT_ROUND,
|
||||
ORIENTATION,
|
||||
UI_MODE_TYPE,
|
||||
UI_MODE_NIGHT,
|
||||
DENSITY_DPI,
|
||||
TOUCHSCREEN,
|
||||
KEYBOARD_HIDDEN,
|
||||
KEYBOARD,
|
||||
NAVIGATION_HIDDEN,
|
||||
NAVIGATION,
|
||||
SDK_VERSION
|
||||
}
|
||||
|
||||
/**
|
||||
* The below constants are from android.content.res.Configuration.
|
||||
*/
|
||||
private static final int DENSITY_DPI_UNDEFINED = 0;
|
||||
private static final int DENSITY_DPI_LDPI = 120;
|
||||
private static final int DENSITY_DPI_MDPI = 160;
|
||||
private static final int DENSITY_DPI_TVDPI = 213;
|
||||
private static final int DENSITY_DPI_HDPI = 240;
|
||||
private static final int DENSITY_DPI_XHDPI = 320;
|
||||
private static final int DENSITY_DPI_XXHDPI = 480;
|
||||
private static final int DENSITY_DPI_XXXHDPI = 640;
|
||||
private static final int DENSITY_DPI_ANY = 0xFFFE;
|
||||
private static final int DENSITY_DPI_NONE = 0xFFFF;
|
||||
private static final Map<Integer, String> DENSITY_DPI_VALUES =
|
||||
ImmutableMap.<Integer, String>builder()
|
||||
.put(DENSITY_DPI_UNDEFINED, "")
|
||||
.put(DENSITY_DPI_LDPI, "ldpi")
|
||||
.put(DENSITY_DPI_MDPI, "mdpi")
|
||||
.put(DENSITY_DPI_TVDPI, "tvdpi")
|
||||
.put(DENSITY_DPI_HDPI, "hdpi")
|
||||
.put(DENSITY_DPI_XHDPI, "xhdpi")
|
||||
.put(DENSITY_DPI_XXHDPI, "xxhdpi")
|
||||
.put(DENSITY_DPI_XXXHDPI, "xxxhdpi")
|
||||
.put(DENSITY_DPI_ANY, "anydpi")
|
||||
.put(DENSITY_DPI_NONE, "nodpi")
|
||||
.build();
|
||||
|
||||
private static final int KEYBOARD_NOKEYS = 1;
|
||||
private static final int KEYBOARD_QWERTY = 2;
|
||||
private static final int KEYBOARD_12KEY = 3;
|
||||
private static final Map<Integer, String> KEYBOARD_VALUES = ImmutableMap.of(
|
||||
KEYBOARD_NOKEYS, "nokeys",
|
||||
KEYBOARD_QWERTY, "qwerty",
|
||||
KEYBOARD_12KEY, "12key");
|
||||
|
||||
private static final int KEYBOARDHIDDEN_MASK = 0x03;
|
||||
private static final int KEYBOARDHIDDEN_NO = 1;
|
||||
private static final int KEYBOARDHIDDEN_YES = 2;
|
||||
private static final int KEYBOARDHIDDEN_SOFT = 3;
|
||||
private static final Map<Integer, String> KEYBOARDHIDDEN_VALUES = ImmutableMap.of(
|
||||
KEYBOARDHIDDEN_NO, "keysexposed",
|
||||
KEYBOARDHIDDEN_YES, "keyshidden",
|
||||
KEYBOARDHIDDEN_SOFT, "keyssoft");
|
||||
|
||||
private static final int NAVIGATION_NONAV = 1;
|
||||
private static final int NAVIGATION_DPAD = 2;
|
||||
private static final int NAVIGATION_TRACKBALL = 3;
|
||||
private static final int NAVIGATION_WHEEL = 4;
|
||||
private static final Map<Integer, String> NAVIGATION_VALUES = ImmutableMap.of(
|
||||
NAVIGATION_NONAV, "nonav",
|
||||
NAVIGATION_DPAD, "dpad",
|
||||
NAVIGATION_TRACKBALL, "trackball",
|
||||
NAVIGATION_WHEEL, "wheel");
|
||||
|
||||
private static final int NAVIGATIONHIDDEN_MASK = 0x0C;
|
||||
private static final int NAVIGATIONHIDDEN_NO = 0x04;
|
||||
private static final int NAVIGATIONHIDDEN_YES = 0x08;
|
||||
private static final Map<Integer, String> NAVIGATIONHIDDEN_VALUES = ImmutableMap.of(
|
||||
NAVIGATIONHIDDEN_NO, "navexposed",
|
||||
NAVIGATIONHIDDEN_YES, "navhidden");
|
||||
|
||||
private static final int ORIENTATION_PORTRAIT = 0x01;
|
||||
private static final int ORIENTATION_LANDSCAPE = 0x02;
|
||||
private static final Map<Integer, String> ORIENTATION_VALUES = ImmutableMap.of(
|
||||
ORIENTATION_PORTRAIT, "port",
|
||||
ORIENTATION_LANDSCAPE, "land");
|
||||
|
||||
private static final int SCREENLAYOUT_LAYOUTDIR_MASK = 0xC0;
|
||||
private static final int SCREENLAYOUT_LAYOUTDIR_LTR = 0x40;
|
||||
private static final int SCREENLAYOUT_LAYOUTDIR_RTL = 0x80;
|
||||
private static final Map<Integer, String> SCREENLAYOUT_LAYOUTDIR_VALUES = ImmutableMap.of(
|
||||
SCREENLAYOUT_LAYOUTDIR_LTR, "ldltr",
|
||||
SCREENLAYOUT_LAYOUTDIR_RTL, "ldrtl");
|
||||
|
||||
private static final int SCREENLAYOUT_LONG_MASK = 0x30;
|
||||
private static final int SCREENLAYOUT_LONG_NO = 0x10;
|
||||
private static final int SCREENLAYOUT_LONG_YES = 0x20;
|
||||
private static final Map<Integer, String> SCREENLAYOUT_LONG_VALUES = ImmutableMap.of(
|
||||
SCREENLAYOUT_LONG_NO, "notlong",
|
||||
SCREENLAYOUT_LONG_YES, "long");
|
||||
|
||||
private static final int SCREENLAYOUT_ROUND_MASK = 0x03;
|
||||
private static final int SCREENLAYOUT_ROUND_NO = 0x01;
|
||||
private static final int SCREENLAYOUT_ROUND_YES = 0x02;
|
||||
private static final Map<Integer, String> SCREENLAYOUT_ROUND_VALUES = ImmutableMap.of(
|
||||
SCREENLAYOUT_ROUND_NO, "notround",
|
||||
SCREENLAYOUT_ROUND_YES, "round");
|
||||
|
||||
private static final int SCREENLAYOUT_SIZE_MASK = 0x0F;
|
||||
private static final int SCREENLAYOUT_SIZE_SMALL = 0x01;
|
||||
private static final int SCREENLAYOUT_SIZE_NORMAL = 0x02;
|
||||
private static final int SCREENLAYOUT_SIZE_LARGE = 0x03;
|
||||
private static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;
|
||||
private static final Map<Integer, String> SCREENLAYOUT_SIZE_VALUES = ImmutableMap.of(
|
||||
SCREENLAYOUT_SIZE_SMALL, "small",
|
||||
SCREENLAYOUT_SIZE_NORMAL, "normal",
|
||||
SCREENLAYOUT_SIZE_LARGE, "large",
|
||||
SCREENLAYOUT_SIZE_XLARGE, "xlarge");
|
||||
|
||||
private static final int TOUCHSCREEN_NOTOUCH = 1;
|
||||
private static final int TOUCHSCREEN_FINGER = 3;
|
||||
private static final Map<Integer, String> TOUCHSCREEN_VALUES = ImmutableMap.of(
|
||||
TOUCHSCREEN_NOTOUCH, "notouch",
|
||||
TOUCHSCREEN_FINGER, "finger");
|
||||
|
||||
private static final int UI_MODE_NIGHT_MASK = 0x30;
|
||||
private static final int UI_MODE_NIGHT_NO = 0x10;
|
||||
private static final int UI_MODE_NIGHT_YES = 0x20;
|
||||
private static final Map<Integer, String> UI_MODE_NIGHT_VALUES = ImmutableMap.of(
|
||||
UI_MODE_NIGHT_NO, "notnight",
|
||||
UI_MODE_NIGHT_YES, "night");
|
||||
|
||||
private static final int UI_MODE_TYPE_MASK = 0x0F;
|
||||
private static final int UI_MODE_TYPE_DESK = 0x02;
|
||||
private static final int UI_MODE_TYPE_CAR = 0x03;
|
||||
private static final int UI_MODE_TYPE_TELEVISION = 0x04;
|
||||
private static final int UI_MODE_TYPE_APPLIANCE = 0x05;
|
||||
private static final int UI_MODE_TYPE_WATCH = 0x06;
|
||||
private static final int UI_MODE_TYPE_VR_HEADSET = 0x07;
|
||||
|
||||
// start - miui
|
||||
private static final int UI_MODE_TYPE_GODZILLAUI = 0x0b;
|
||||
private static final int UI_MODE_TYPE_SMALLUI = 0x0c;
|
||||
private static final int UI_MODE_TYPE_MEDIUMUI = 0x0d;
|
||||
private static final int UI_MODE_TYPE_LARGEUI = 0x0e;
|
||||
private static final int UI_MODE_TYPE_HUGEUI = 0x0f;
|
||||
// end - miui
|
||||
|
||||
private static final Map<Integer, String> UI_MODE_TYPE_VALUES =
|
||||
ImmutableMap.<Integer, String>builder()
|
||||
.put(UI_MODE_TYPE_DESK, "desk")
|
||||
.put(UI_MODE_TYPE_CAR, "car")
|
||||
.put(UI_MODE_TYPE_TELEVISION, "television")
|
||||
.put(UI_MODE_TYPE_APPLIANCE, "appliance")
|
||||
.put(UI_MODE_TYPE_WATCH, "watch")
|
||||
.put(UI_MODE_TYPE_VR_HEADSET, "vrheadset")
|
||||
.put(UI_MODE_TYPE_GODZILLAUI, "godzillaui")
|
||||
.put(UI_MODE_TYPE_SMALLUI, "smallui")
|
||||
.put(UI_MODE_TYPE_MEDIUMUI, "mediumui")
|
||||
.put(UI_MODE_TYPE_LARGEUI, "largeui")
|
||||
.put(UI_MODE_TYPE_HUGEUI, "hugeui").build();
|
||||
|
||||
/**
|
||||
* The minimum size in bytes that this configuration must be to contain screen config info.
|
||||
*/
|
||||
private static final int SCREEN_CONFIG_MIN_SIZE = 32;
|
||||
|
||||
/**
|
||||
* The minimum size in bytes that this configuration must be to contain screen dp info.
|
||||
*/
|
||||
private static final int SCREEN_DP_MIN_SIZE = 36;
|
||||
|
||||
/**
|
||||
* The minimum size in bytes that this configuration must be to contain locale info.
|
||||
*/
|
||||
private static final int LOCALE_MIN_SIZE = 48;
|
||||
|
||||
/**
|
||||
* The minimum size in bytes that this config must be to contain the screenConfig extension.
|
||||
*/
|
||||
private static final int SCREEN_CONFIG_EXTENSION_MIN_SIZE = 52;
|
||||
|
||||
/**
|
||||
* The number of bytes that this resource configuration takes up.
|
||||
*/
|
||||
@@ -708,7 +662,7 @@ public class BinaryResourceConfiguration implements SerializableResource {
|
||||
Map<Type, String> result = new LinkedHashMap<>(); // Preserve order for #toString().
|
||||
result.put(Type.MCC, mcc() != 0 ? "mcc" + mcc() : "");
|
||||
result.put(Type.MNC, mnc() != 0 ? "mnc" + mnc() : "");
|
||||
result.put(Type.LANGUAGE_STRING, !languageString().isEmpty() ? "" + languageString() : "");
|
||||
result.put(Type.LANGUAGE_STRING, !languageString().isEmpty() ? languageString() : "");
|
||||
result.put(Type.REGION_STRING, !regionString().isEmpty() ? "r" + regionString() : "");
|
||||
result.put(Type.SCREEN_LAYOUT_DIRECTION,
|
||||
getOrDefault(SCREENLAYOUT_LAYOUTDIR_VALUES, screenLayoutDirection(), ""));
|
||||
@@ -742,4 +696,31 @@ public class BinaryResourceConfiguration implements SerializableResource {
|
||||
V value = map.get(key);
|
||||
return value != null ? value : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* The different types of configs that can be present in a {@link BinaryResourceConfiguration}.
|
||||
*/
|
||||
public enum Type {
|
||||
MCC,
|
||||
MNC,
|
||||
LANGUAGE_STRING,
|
||||
REGION_STRING,
|
||||
SCREEN_LAYOUT_DIRECTION,
|
||||
SMALLEST_SCREEN_WIDTH_DP,
|
||||
SCREEN_WIDTH_DP,
|
||||
SCREEN_HEIGHT_DP,
|
||||
SCREEN_LAYOUT_SIZE,
|
||||
SCREEN_LAYOUT_LONG,
|
||||
SCREEN_LAYOUT_ROUND,
|
||||
ORIENTATION,
|
||||
UI_MODE_TYPE,
|
||||
UI_MODE_NIGHT,
|
||||
DENSITY_DPI,
|
||||
TOUCHSCREEN,
|
||||
KEYBOARD_HIDDEN,
|
||||
KEYBOARD,
|
||||
NAVIGATION_HIDDEN,
|
||||
NAVIGATION,
|
||||
SDK_VERSION
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -49,6 +49,12 @@ public class BinaryResourceIdentifier {
|
||||
private final int typeId;
|
||||
private final int entryId;
|
||||
|
||||
private BinaryResourceIdentifier(int packageId, int typeId, int entryId) {
|
||||
this.packageId = packageId;
|
||||
this.typeId = typeId;
|
||||
this.entryId = entryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link BinaryResourceIdentifier} from a {@code resourceId} of the form 0xpptteeee.
|
||||
*/
|
||||
@@ -69,12 +75,6 @@ public class BinaryResourceIdentifier {
|
||||
return new BinaryResourceIdentifier(packageId, typeId, entryId);
|
||||
}
|
||||
|
||||
private BinaryResourceIdentifier(int packageId, int typeId, int entryId) {
|
||||
this.packageId = packageId;
|
||||
this.typeId = typeId;
|
||||
this.entryId = entryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The (1-based) id of the {@link PackageChunk} containing this resource.
|
||||
*/
|
||||
|
||||
+18
-18
@@ -31,24 +31,6 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
*/
|
||||
public final class BinaryResourceString {
|
||||
|
||||
/**
|
||||
* Type of {@link BinaryResourceString} to encode / decode.
|
||||
*/
|
||||
public enum Type {
|
||||
UTF8(UTF_8),
|
||||
UTF16(UTF_16LE);
|
||||
|
||||
private final Charset charset;
|
||||
|
||||
Type(Charset charset) {
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
public Charset charset() {
|
||||
return charset;
|
||||
}
|
||||
}
|
||||
|
||||
private BinaryResourceString() {
|
||||
} // Private constructor
|
||||
|
||||
@@ -166,4 +148,22 @@ public final class BinaryResourceString {
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of {@link BinaryResourceString} to encode / decode.
|
||||
*/
|
||||
public enum Type {
|
||||
UTF8(UTF_8),
|
||||
UTF16(UTF_16LE);
|
||||
|
||||
private final Charset charset;
|
||||
|
||||
Type(Charset charset) {
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
public Charset charset() {
|
||||
return charset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+77
-79
@@ -31,6 +31,78 @@ import java.util.Objects;
|
||||
*/
|
||||
public class BinaryResourceValue implements SerializableResource {
|
||||
|
||||
/**
|
||||
* The serialized size in bytes of a {@link BinaryResourceValue}.
|
||||
*/
|
||||
public static final int SIZE = 8;
|
||||
public int size;
|
||||
public Type type;
|
||||
public int data;
|
||||
public BinaryResourceValue(int size, Type type, int data) {
|
||||
this.size = size;
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static BinaryResourceValue create(ByteBuffer buffer) {
|
||||
int size = (buffer.getShort() & 0xFFFF);
|
||||
buffer.get(); // Unused
|
||||
Type type = Type.fromCode(buffer.get());
|
||||
int data = buffer.getInt();
|
||||
return new BinaryResourceValue(size, type, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The length in bytes of this value.
|
||||
*/
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* The raw data type of this value.
|
||||
*/
|
||||
public Type type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual 4-byte value; interpretation of the value depends on {@code dataType}.
|
||||
*/
|
||||
public int data() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toByteArray() {
|
||||
return toByteArray(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toByteArray(boolean shrink) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putShort((short) size());
|
||||
buffer.put((byte) 0); // Unused
|
||||
buffer.put(type().code());
|
||||
buffer.putInt(data());
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
BinaryResourceValue that = (BinaryResourceValue) o;
|
||||
return size == that.size &&
|
||||
data == that.data &&
|
||||
type == that.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(size, type, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resource type codes.
|
||||
*/
|
||||
@@ -100,8 +172,6 @@ public class BinaryResourceValue implements SerializableResource {
|
||||
*/
|
||||
INT_COLOR_RGB4(0x1f);
|
||||
|
||||
private final byte code;
|
||||
|
||||
private static final Map<Byte, Type> FROM_BYTE;
|
||||
|
||||
static {
|
||||
@@ -112,90 +182,18 @@ public class BinaryResourceValue implements SerializableResource {
|
||||
FROM_BYTE = builder.build();
|
||||
}
|
||||
|
||||
private final byte code;
|
||||
|
||||
Type(int code) {
|
||||
this.code = UnsignedBytes.checkedCast(code);
|
||||
}
|
||||
|
||||
public byte code() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static Type fromCode(byte code) {
|
||||
return Preconditions.checkNotNull(FROM_BYTE.get(code), "Unknown resource type: %s", code);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The serialized size in bytes of a {@link BinaryResourceValue}.
|
||||
*/
|
||||
public static final int SIZE = 8;
|
||||
|
||||
public int size;
|
||||
public Type type;
|
||||
public int data;
|
||||
|
||||
public static BinaryResourceValue create(ByteBuffer buffer) {
|
||||
int size = (buffer.getShort() & 0xFFFF);
|
||||
buffer.get(); // Unused
|
||||
Type type = Type.fromCode(buffer.get());
|
||||
int data = buffer.getInt();
|
||||
return new BinaryResourceValue(size, type, data);
|
||||
}
|
||||
|
||||
public BinaryResourceValue(int size, Type type, int data) {
|
||||
this.size = size;
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* The length in bytes of this value.
|
||||
*/
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* The raw data type of this value.
|
||||
*/
|
||||
public Type type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual 4-byte value; interpretation of the value depends on {@code dataType}.
|
||||
*/
|
||||
public int data() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toByteArray() {
|
||||
return toByteArray(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toByteArray(boolean shrink) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putShort((short) size());
|
||||
buffer.put((byte) 0); // Unused
|
||||
buffer.put(type().code());
|
||||
buffer.putInt(data());
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
BinaryResourceValue that = (BinaryResourceValue) o;
|
||||
return size == that.size &&
|
||||
data == that.data &&
|
||||
type == that.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(size, type, data);
|
||||
public byte code() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,86 +35,36 @@ import java.util.Map;
|
||||
*/
|
||||
public abstract class Chunk implements SerializableResource {
|
||||
|
||||
/**
|
||||
* Types of chunks that can exist.
|
||||
*/
|
||||
public enum Type {
|
||||
NULL(0x0000),
|
||||
STRING_POOL(0x0001),
|
||||
TABLE(0x0002),
|
||||
XML(0x0003),
|
||||
XML_START_NAMESPACE(0x0100),
|
||||
XML_END_NAMESPACE(0x0101),
|
||||
XML_START_ELEMENT(0x0102),
|
||||
XML_END_ELEMENT(0x0103),
|
||||
XML_CDATA(0x0104),
|
||||
XML_RESOURCE_MAP(0x0180),
|
||||
TABLE_PACKAGE(0x0200),
|
||||
TABLE_TYPE(0x0201),
|
||||
TABLE_TYPE_SPEC(0x0202),
|
||||
TABLE_LIBRARY(0x0203);
|
||||
|
||||
private final short code;
|
||||
|
||||
private static final Map<Short, Type> FROM_SHORT;
|
||||
|
||||
static {
|
||||
Builder<Short, Type> builder = ImmutableMap.builder();
|
||||
for (Type type : values()) {
|
||||
builder.put(type.code(), type);
|
||||
}
|
||||
FROM_SHORT = builder.build();
|
||||
}
|
||||
|
||||
Type(int code) {
|
||||
this.code = Shorts.checkedCast(code);
|
||||
}
|
||||
|
||||
public short code() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static Type fromCode(short code) {
|
||||
return Preconditions.checkNotNull(FROM_SHORT.get(code), "Unknown chunk type: %s", code);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The byte boundary to pad chunks on.
|
||||
*/
|
||||
public static final int PAD_BOUNDARY = 4;
|
||||
|
||||
/**
|
||||
* The number of bytes in every chunk that describes chunk type, header size, and chunk size.
|
||||
*/
|
||||
public static final int METADATA_SIZE = 8;
|
||||
|
||||
/**
|
||||
* The offset in bytes, from the start of the chunk, where the chunk size can be found.
|
||||
*/
|
||||
private static final int CHUNK_SIZE_OFFSET = 4;
|
||||
|
||||
/**
|
||||
* Size of the chunk header in bytes.
|
||||
*/
|
||||
protected final int headerSize;
|
||||
/**
|
||||
* headerSize + dataSize. The total size of this chunk.
|
||||
*/
|
||||
protected final int chunkSize;
|
||||
/**
|
||||
* Offset of this chunk from the start of the file.
|
||||
*/
|
||||
protected final int offset;
|
||||
/**
|
||||
* The parent to this chunk, if any.
|
||||
*/
|
||||
@Nullable
|
||||
private final Chunk parent;
|
||||
|
||||
/**
|
||||
* Size of the chunk header in bytes.
|
||||
*/
|
||||
protected final int headerSize;
|
||||
|
||||
/**
|
||||
* headerSize + dataSize. The total size of this chunk.
|
||||
*/
|
||||
protected final int chunkSize;
|
||||
|
||||
/**
|
||||
* Offset of this chunk from the start of the file.
|
||||
*/
|
||||
protected final int offset;
|
||||
|
||||
protected Chunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
this.parent = parent;
|
||||
offset = buffer.position() - 2;
|
||||
@@ -122,6 +72,74 @@ public abstract class Chunk implements SerializableResource {
|
||||
chunkSize = buffer.getInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new chunk whose contents start at {@code buffer}'s current position.
|
||||
*
|
||||
* @param buffer A buffer positioned at the start of a chunk.
|
||||
* @return new chunk
|
||||
*/
|
||||
public static Chunk newInstance(ByteBuffer buffer) {
|
||||
return newInstance(buffer, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new chunk whose contents start at {@code buffer}'s current position.
|
||||
*
|
||||
* @param buffer A buffer positioned at the start of a chunk.
|
||||
* @param parent The parent to this chunk (or null if there's no parent).
|
||||
* @return new chunk
|
||||
*/
|
||||
public static Chunk newInstance(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
Chunk result;
|
||||
Type type = Type.fromCode(buffer.getShort());
|
||||
switch (type) {
|
||||
case STRING_POOL:
|
||||
result = new StringPoolChunk(buffer, parent);
|
||||
break;
|
||||
case TABLE:
|
||||
result = new ResourceTableChunk(buffer, parent);
|
||||
break;
|
||||
case XML:
|
||||
result = new XmlChunk(buffer, parent);
|
||||
break;
|
||||
case XML_START_NAMESPACE:
|
||||
result = new XmlNamespaceStartChunk(buffer, parent);
|
||||
break;
|
||||
case XML_END_NAMESPACE:
|
||||
result = new XmlNamespaceEndChunk(buffer, parent);
|
||||
break;
|
||||
case XML_START_ELEMENT:
|
||||
result = new XmlStartElementChunk(buffer, parent);
|
||||
break;
|
||||
case XML_END_ELEMENT:
|
||||
result = new XmlEndElementChunk(buffer, parent);
|
||||
break;
|
||||
case XML_CDATA:
|
||||
result = new XmlCdataChunk(buffer, parent);
|
||||
break;
|
||||
case XML_RESOURCE_MAP:
|
||||
result = new XmlResourceMapChunk(buffer, parent);
|
||||
break;
|
||||
case TABLE_PACKAGE:
|
||||
result = new PackageChunk(buffer, parent);
|
||||
break;
|
||||
case TABLE_TYPE:
|
||||
result = new TypeChunk(buffer, parent);
|
||||
break;
|
||||
case TABLE_TYPE_SPEC:
|
||||
result = new TypeSpecChunk(buffer, parent);
|
||||
break;
|
||||
case TABLE_LIBRARY:
|
||||
result = new LibraryChunk(buffer, parent);
|
||||
break;
|
||||
default:
|
||||
result = new UnknownChunk(buffer, parent);
|
||||
}
|
||||
result.init(buffer);
|
||||
result.seekToEndOfChunk(buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes initialization of a chunk. This should be called immediately after the constructor.
|
||||
* This is separate from the constructor so that the header of a chunk can be fully initialized
|
||||
@@ -256,70 +274,46 @@ public abstract class Chunk implements SerializableResource {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new chunk whose contents start at {@code buffer}'s current position.
|
||||
*
|
||||
* @param buffer A buffer positioned at the start of a chunk.
|
||||
* @return new chunk
|
||||
* Types of chunks that can exist.
|
||||
*/
|
||||
public static Chunk newInstance(ByteBuffer buffer) {
|
||||
return newInstance(buffer, null);
|
||||
}
|
||||
public enum Type {
|
||||
NULL(0x0000),
|
||||
STRING_POOL(0x0001),
|
||||
TABLE(0x0002),
|
||||
XML(0x0003),
|
||||
XML_START_NAMESPACE(0x0100),
|
||||
XML_END_NAMESPACE(0x0101),
|
||||
XML_START_ELEMENT(0x0102),
|
||||
XML_END_ELEMENT(0x0103),
|
||||
XML_CDATA(0x0104),
|
||||
XML_RESOURCE_MAP(0x0180),
|
||||
TABLE_PACKAGE(0x0200),
|
||||
TABLE_TYPE(0x0201),
|
||||
TABLE_TYPE_SPEC(0x0202),
|
||||
TABLE_LIBRARY(0x0203);
|
||||
|
||||
/**
|
||||
* Creates a new chunk whose contents start at {@code buffer}'s current position.
|
||||
*
|
||||
* @param buffer A buffer positioned at the start of a chunk.
|
||||
* @param parent The parent to this chunk (or null if there's no parent).
|
||||
* @return new chunk
|
||||
*/
|
||||
public static Chunk newInstance(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
Chunk result;
|
||||
Type type = Type.fromCode(buffer.getShort());
|
||||
switch (type) {
|
||||
case STRING_POOL:
|
||||
result = new StringPoolChunk(buffer, parent);
|
||||
break;
|
||||
case TABLE:
|
||||
result = new ResourceTableChunk(buffer, parent);
|
||||
break;
|
||||
case XML:
|
||||
result = new XmlChunk(buffer, parent);
|
||||
break;
|
||||
case XML_START_NAMESPACE:
|
||||
result = new XmlNamespaceStartChunk(buffer, parent);
|
||||
break;
|
||||
case XML_END_NAMESPACE:
|
||||
result = new XmlNamespaceEndChunk(buffer, parent);
|
||||
break;
|
||||
case XML_START_ELEMENT:
|
||||
result = new XmlStartElementChunk(buffer, parent);
|
||||
break;
|
||||
case XML_END_ELEMENT:
|
||||
result = new XmlEndElementChunk(buffer, parent);
|
||||
break;
|
||||
case XML_CDATA:
|
||||
result = new XmlCdataChunk(buffer, parent);
|
||||
break;
|
||||
case XML_RESOURCE_MAP:
|
||||
result = new XmlResourceMapChunk(buffer, parent);
|
||||
break;
|
||||
case TABLE_PACKAGE:
|
||||
result = new PackageChunk(buffer, parent);
|
||||
break;
|
||||
case TABLE_TYPE:
|
||||
result = new TypeChunk(buffer, parent);
|
||||
break;
|
||||
case TABLE_TYPE_SPEC:
|
||||
result = new TypeSpecChunk(buffer, parent);
|
||||
break;
|
||||
case TABLE_LIBRARY:
|
||||
result = new LibraryChunk(buffer, parent);
|
||||
break;
|
||||
default:
|
||||
result = new UnknownChunk(buffer, parent);
|
||||
private static final Map<Short, Type> FROM_SHORT;
|
||||
|
||||
static {
|
||||
Builder<Short, Type> builder = ImmutableMap.builder();
|
||||
for (Type type : values()) {
|
||||
builder.put(type.code(), type);
|
||||
}
|
||||
FROM_SHORT = builder.build();
|
||||
}
|
||||
|
||||
private final short code;
|
||||
|
||||
Type(int code) {
|
||||
this.code = Shorts.checkedCast(code);
|
||||
}
|
||||
|
||||
public static Type fromCode(short code) {
|
||||
return Preconditions.checkNotNull(FROM_SHORT.get(code), "Unknown chunk type: %s", code);
|
||||
}
|
||||
|
||||
public short code() {
|
||||
return code;
|
||||
}
|
||||
result.init(buffer);
|
||||
result.seekToEndOfChunk(buffer);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public final class LibraryChunk extends Chunk {
|
||||
*/
|
||||
private final List<Entry> entries = new ArrayList<>();
|
||||
|
||||
protected LibraryChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
LibraryChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
entryCount = buffer.getInt();
|
||||
}
|
||||
@@ -98,17 +98,17 @@ public final class LibraryChunk extends Chunk {
|
||||
private final int packageId;
|
||||
private final String packageName;
|
||||
|
||||
private Entry(int packageId, String packageName) {
|
||||
this.packageId = packageId;
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
static Entry create(ByteBuffer buffer, int offset) {
|
||||
int packageId = buffer.getInt(offset);
|
||||
String packageName = PackageUtils.readPackageName(buffer, offset + 4);
|
||||
return new Entry(packageId, packageName);
|
||||
}
|
||||
|
||||
private Entry(int packageId, String packageName) {
|
||||
this.packageId = packageId;
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id assigned to the shared library at build time.
|
||||
*/
|
||||
|
||||
@@ -43,58 +43,48 @@ public final class PackageChunk extends ChunkWithChunks {
|
||||
* Offset in bytes, from the start of the chunk, where {@code keyStringsOffset} can be found.
|
||||
*/
|
||||
private static final int KEY_OFFSET_OFFSET = 276;
|
||||
|
||||
/**
|
||||
* The package id if this is a base package, or 0 if not a base package.
|
||||
*/
|
||||
private int id;
|
||||
|
||||
/**
|
||||
* The name of the package.
|
||||
*/
|
||||
private String packageName;
|
||||
|
||||
/**
|
||||
* The offset (from {@code offset}) in the original buffer where type strings start.
|
||||
*/
|
||||
private final int typeStringsOffset;
|
||||
|
||||
/**
|
||||
* The index into the type string pool of the last public type.
|
||||
*/
|
||||
private final int lastPublicType;
|
||||
|
||||
/**
|
||||
* An offset to the string pool that contains the key strings for this package.
|
||||
*/
|
||||
private final int keyStringsOffset;
|
||||
|
||||
/**
|
||||
* The index into the key string pool of the last public key.
|
||||
*/
|
||||
private final int lastPublicKey;
|
||||
|
||||
/**
|
||||
* An offset to the type ID(s). This is undocumented in the original code.
|
||||
*/
|
||||
private final int typeIdOffset;
|
||||
|
||||
/**
|
||||
* Contains a mapping of a type index to its {@link TypeSpecChunk}.
|
||||
*/
|
||||
private final Map<Integer, TypeSpecChunk> typeSpecs = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Contains a mapping of a type index to all of the {@link TypeChunk} with that index.
|
||||
*/
|
||||
private final Multimap<Integer, TypeChunk> types = ArrayListMultimap.create();
|
||||
|
||||
/**
|
||||
* The package id if this is a base package, or 0 if not a base package.
|
||||
*/
|
||||
private int id;
|
||||
/**
|
||||
* The name of the package.
|
||||
*/
|
||||
private String packageName;
|
||||
/**
|
||||
* May contain a library chunk for mapping dynamic references to resolved references.
|
||||
*/
|
||||
private Optional<LibraryChunk> libraryChunk = Optional.empty();
|
||||
|
||||
protected PackageChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
PackageChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
id = buffer.getInt();
|
||||
packageName = PackageUtils.readPackageName(buffer, buffer.position());
|
||||
|
||||
@@ -36,17 +36,16 @@ import java.util.Map;
|
||||
*/
|
||||
public final class ResourceTableChunk extends ChunkWithChunks {
|
||||
|
||||
/**
|
||||
* The packages contained in this resource table.
|
||||
*/
|
||||
private final Map<String, PackageChunk> packages = new HashMap<>();
|
||||
/**
|
||||
* A string pool containing all string resource values in the entire resource table.
|
||||
*/
|
||||
private StringPoolChunk stringPool;
|
||||
|
||||
/**
|
||||
* The packages contained in this resource table.
|
||||
*/
|
||||
private final Map<String, PackageChunk> packages = new HashMap<>();
|
||||
|
||||
protected ResourceTableChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
ResourceTableChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
// packageCount. We ignore this, because we already know how many chunks we have.
|
||||
Preconditions.checkState(buffer.getInt() >= 1, "ResourceTableChunk package count was < 1.");
|
||||
|
||||
@@ -89,7 +89,7 @@ public final class StringPoolChunk extends Chunk {
|
||||
*/
|
||||
private boolean isOriginalDeduped = false;
|
||||
|
||||
protected StringPoolChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
StringPoolChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
stringCount = buffer.getInt();
|
||||
styleCount = buffer.getInt();
|
||||
@@ -310,6 +310,10 @@ public final class StringPoolChunk extends Chunk {
|
||||
static final int RES_STRING_POOL_SPAN_END = 0xFFFFFFFF;
|
||||
private final List<StringPoolSpan> spans;
|
||||
|
||||
private StringPoolStyle(List<StringPoolSpan> spans) {
|
||||
this.spans = spans;
|
||||
}
|
||||
|
||||
static StringPoolStyle create(ByteBuffer buffer, int offset, StringPoolChunk parent) {
|
||||
Builder<StringPoolSpan> spans = ImmutableList.builder();
|
||||
int nameIndex = buffer.getInt(offset);
|
||||
@@ -321,10 +325,6 @@ public final class StringPoolChunk extends Chunk {
|
||||
return new StringPoolStyle(spans.build());
|
||||
}
|
||||
|
||||
private StringPoolStyle(List<StringPoolSpan> spans) {
|
||||
this.spans = spans;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toByteArray() throws IOException {
|
||||
return toByteArray(false);
|
||||
@@ -384,13 +384,6 @@ public final class StringPoolChunk extends Chunk {
|
||||
private final int stop;
|
||||
private final StringPoolChunk parent;
|
||||
|
||||
static StringPoolSpan create(ByteBuffer buffer, int offset, StringPoolChunk parent) {
|
||||
int nameIndex = buffer.getInt(offset);
|
||||
int start = buffer.getInt(offset + 4);
|
||||
int stop = buffer.getInt(offset + 8);
|
||||
return new StringPoolSpan(nameIndex, start, stop, parent);
|
||||
}
|
||||
|
||||
private StringPoolSpan(int nameIndex, int start, int stop, StringPoolChunk parent) {
|
||||
this.nameIndex = nameIndex;
|
||||
this.start = start;
|
||||
@@ -398,6 +391,13 @@ public final class StringPoolChunk extends Chunk {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
static StringPoolSpan create(ByteBuffer buffer, int offset, StringPoolChunk parent) {
|
||||
int nameIndex = buffer.getInt(offset);
|
||||
int start = buffer.getInt(offset + 4);
|
||||
int stop = buffer.getInt(offset + 8);
|
||||
return new StringPoolSpan(nameIndex, start, stop, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final byte[] toByteArray() {
|
||||
return toByteArray(false);
|
||||
|
||||
@@ -52,18 +52,16 @@ public final class TypeChunk extends Chunk {
|
||||
* The offset (from {@code offset}) in the original buffer where {@code entries} start.
|
||||
*/
|
||||
private final int entriesStart;
|
||||
|
||||
/**
|
||||
* A sparse list of resource entries defined by this chunk.
|
||||
*/
|
||||
private final Map<Integer, Entry> entries = new TreeMap<>();
|
||||
/**
|
||||
* The resource configuration that these resource entries correspond to.
|
||||
*/
|
||||
private BinaryResourceConfiguration configuration;
|
||||
|
||||
/**
|
||||
* A sparse list of resource entries defined by this chunk.
|
||||
*/
|
||||
private final Map<Integer, Entry> entries = new TreeMap<>();
|
||||
|
||||
protected TypeChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
TypeChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
id = UnsignedBytes.toInt(buffer.get());
|
||||
buffer.position(buffer.position() + 3); // Skip 3 bytes for packing
|
||||
@@ -176,13 +174,13 @@ public final class TypeChunk extends Chunk {
|
||||
}
|
||||
}
|
||||
|
||||
protected String getString(int index) {
|
||||
private String getString(int index) {
|
||||
ResourceTableChunk resourceTable = getResourceTableChunk();
|
||||
Preconditions.checkNotNull(resourceTable, "%s has no resource table.", getClass());
|
||||
return resourceTable.getStringPool().getString(index);
|
||||
}
|
||||
|
||||
protected String getKeyName(int index) {
|
||||
private String getKeyName(int index) {
|
||||
PackageChunk packageChunk = getPackageChunk();
|
||||
Preconditions.checkNotNull(packageChunk, "%s has no parent package.", getClass());
|
||||
StringPoolChunk keyPool = packageChunk.getKeyStringPool();
|
||||
@@ -190,7 +188,7 @@ public final class TypeChunk extends Chunk {
|
||||
return keyPool.getString(index);
|
||||
}
|
||||
|
||||
protected void updateKey(int index, String value) {
|
||||
private void updateKey(int index, String value) {
|
||||
PackageChunk packageChunk = getPackageChunk();
|
||||
Preconditions.checkNotNull(packageChunk, "%s has no parent package.", getClass());
|
||||
StringPoolChunk keyPool = packageChunk.getKeyStringPool();
|
||||
@@ -293,10 +291,10 @@ public final class TypeChunk extends Chunk {
|
||||
private final int headerSize;
|
||||
private final int flags;
|
||||
private final int keyIndex;
|
||||
private BinaryResourceValue value;
|
||||
private Map<Integer, BinaryResourceValue> values;
|
||||
private final int parentEntry;
|
||||
private final TypeChunk parent;
|
||||
private BinaryResourceValue value;
|
||||
private final Map<Integer, BinaryResourceValue> values;
|
||||
|
||||
private Entry(int headerSize,
|
||||
int flags,
|
||||
@@ -314,6 +312,52 @@ public final class TypeChunk extends Chunk {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Entry} whose contents start at the 0-based position in
|
||||
* {@code buffer} given by a 4-byte value read from {@code buffer} and then added to
|
||||
* {@code baseOffset}. If the value read from {@code buffer} is equal to {@link #NO_ENTRY}, then
|
||||
* null is returned as there is no resource at that position.
|
||||
*
|
||||
* <p>Otherwise, this position is parsed and returned as an {@link Entry}.
|
||||
*
|
||||
* @param buffer A buffer positioned at an offset to an {@link Entry}.
|
||||
* @param baseOffset Offset that must be added to the value at {@code buffer}'s position.
|
||||
* @param parent The {@link TypeChunk} that this resource entry belongs to.
|
||||
* @return New {@link Entry} or null if there is no resource at this location.
|
||||
*/
|
||||
@Nullable
|
||||
public static Entry create(ByteBuffer buffer, int baseOffset, TypeChunk parent) {
|
||||
int offset = buffer.getInt();
|
||||
if (offset == NO_ENTRY) {
|
||||
return null;
|
||||
}
|
||||
int position = buffer.position();
|
||||
buffer.position(baseOffset + offset); // Set buffer position to resource entry start
|
||||
Entry result = newInstance(buffer, parent);
|
||||
buffer.position(position); // Restore buffer position
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Entry newInstance(ByteBuffer buffer, TypeChunk parent) {
|
||||
int headerSize = buffer.getShort() & 0xFFFF;
|
||||
int flags = buffer.getShort() & 0xFFFF;
|
||||
int keyIndex = buffer.getInt();
|
||||
BinaryResourceValue value = null;
|
||||
Map<Integer, BinaryResourceValue> values = new LinkedHashMap<>();
|
||||
int parentEntry = 0;
|
||||
if ((flags & FLAG_COMPLEX) != 0) {
|
||||
parentEntry = buffer.getInt();
|
||||
int valueCount = buffer.getInt();
|
||||
for (int i = 0; i < valueCount; ++i) {
|
||||
values.put(buffer.getInt(), BinaryResourceValue.create(buffer));
|
||||
}
|
||||
} else {
|
||||
value = BinaryResourceValue.create(buffer);
|
||||
}
|
||||
return new Entry(headerSize, flags, keyIndex, value, values, parentEntry, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of bytes in the header of the {@link Entry}.
|
||||
*/
|
||||
@@ -422,52 +466,6 @@ public final class TypeChunk extends Chunk {
|
||||
return (flags() & FLAG_COMPLEX) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Entry} whose contents start at the 0-based position in
|
||||
* {@code buffer} given by a 4-byte value read from {@code buffer} and then added to
|
||||
* {@code baseOffset}. If the value read from {@code buffer} is equal to {@link #NO_ENTRY}, then
|
||||
* null is returned as there is no resource at that position.
|
||||
*
|
||||
* <p>Otherwise, this position is parsed and returned as an {@link Entry}.
|
||||
*
|
||||
* @param buffer A buffer positioned at an offset to an {@link Entry}.
|
||||
* @param baseOffset Offset that must be added to the value at {@code buffer}'s position.
|
||||
* @param parent The {@link TypeChunk} that this resource entry belongs to.
|
||||
* @return New {@link Entry} or null if there is no resource at this location.
|
||||
*/
|
||||
@Nullable
|
||||
public static Entry create(ByteBuffer buffer, int baseOffset, TypeChunk parent) {
|
||||
int offset = buffer.getInt();
|
||||
if (offset == NO_ENTRY) {
|
||||
return null;
|
||||
}
|
||||
int position = buffer.position();
|
||||
buffer.position(baseOffset + offset); // Set buffer position to resource entry start
|
||||
Entry result = newInstance(buffer, parent);
|
||||
buffer.position(position); // Restore buffer position
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Entry newInstance(ByteBuffer buffer, TypeChunk parent) {
|
||||
int headerSize = buffer.getShort() & 0xFFFF;
|
||||
int flags = buffer.getShort() & 0xFFFF;
|
||||
int keyIndex = buffer.getInt();
|
||||
BinaryResourceValue value = null;
|
||||
Map<Integer, BinaryResourceValue> values = new LinkedHashMap<>();
|
||||
int parentEntry = 0;
|
||||
if ((flags & FLAG_COMPLEX) != 0) {
|
||||
parentEntry = buffer.getInt();
|
||||
int valueCount = buffer.getInt();
|
||||
for (int i = 0; i < valueCount; ++i) {
|
||||
values.put(buffer.getInt(), BinaryResourceValue.create(buffer));
|
||||
}
|
||||
} else {
|
||||
value = BinaryResourceValue.create(buffer);
|
||||
}
|
||||
return new Entry(headerSize, flags, keyIndex, value, values, parentEntry, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final byte[] toByteArray() {
|
||||
return toByteArray(false);
|
||||
|
||||
@@ -39,7 +39,7 @@ public final class TypeSpecChunk extends Chunk {
|
||||
*/
|
||||
private final int[] resources;
|
||||
|
||||
protected TypeSpecChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
TypeSpecChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
id = UnsignedBytes.toInt(buffer.get());
|
||||
buffer.position(buffer.position() + 3); // Skip 3 bytes for packing
|
||||
|
||||
@@ -34,7 +34,7 @@ public final class UnknownChunk extends Chunk {
|
||||
|
||||
private final byte[] payload;
|
||||
|
||||
protected UnknownChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
UnknownChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
|
||||
type = Type.fromCode(buffer.getShort(offset));
|
||||
|
||||
@@ -36,6 +36,18 @@ public class XmlAttribute implements SerializableResource {
|
||||
private final BinaryResourceValue typedValue;
|
||||
private final XmlNodeChunk parent;
|
||||
|
||||
private XmlAttribute(int namespaceIndex,
|
||||
int nameIndex,
|
||||
int rawValueIndex,
|
||||
BinaryResourceValue typedValue,
|
||||
XmlNodeChunk parent) {
|
||||
this.namespaceIndex = namespaceIndex;
|
||||
this.nameIndex = nameIndex;
|
||||
this.rawValueIndex = rawValueIndex;
|
||||
this.typedValue = typedValue;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link XmlAttribute} based on the bytes at the current {@code buffer} position.
|
||||
*
|
||||
@@ -50,18 +62,6 @@ public class XmlAttribute implements SerializableResource {
|
||||
return new XmlAttribute(namespace, name, rawValue, typedValue, parent);
|
||||
}
|
||||
|
||||
private XmlAttribute(int namespaceIndex,
|
||||
int nameIndex,
|
||||
int rawValueIndex,
|
||||
BinaryResourceValue typedValue,
|
||||
XmlNodeChunk parent) {
|
||||
this.namespaceIndex = namespaceIndex;
|
||||
this.nameIndex = nameIndex;
|
||||
this.rawValueIndex = rawValueIndex;
|
||||
this.typedValue = typedValue;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* A string reference to the namespace URI, or -1 if not present.
|
||||
*/
|
||||
|
||||
@@ -37,7 +37,7 @@ public final class XmlCdataChunk extends XmlNodeChunk {
|
||||
*/
|
||||
private final BinaryResourceValue binaryResourceValue;
|
||||
|
||||
protected XmlCdataChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
XmlCdataChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
rawValue = buffer.getInt();
|
||||
binaryResourceValue = BinaryResourceValue.create(buffer);
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.nio.ByteBuffer;
|
||||
*/
|
||||
public final class XmlChunk extends ChunkWithChunks {
|
||||
|
||||
protected XmlChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
XmlChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public final class XmlEndElementChunk extends XmlNodeChunk {
|
||||
*/
|
||||
private final int name;
|
||||
|
||||
protected XmlEndElementChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
XmlEndElementChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
namespace = buffer.getInt();
|
||||
name = buffer.getInt();
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import java.nio.ByteBuffer;
|
||||
*/
|
||||
public final class XmlNamespaceEndChunk extends XmlNamespaceChunk {
|
||||
|
||||
protected XmlNamespaceEndChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
XmlNamespaceEndChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import java.nio.ByteBuffer;
|
||||
*/
|
||||
public final class XmlNamespaceStartChunk extends XmlNamespaceChunk {
|
||||
|
||||
protected XmlNamespaceStartChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
XmlNamespaceStartChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ public final class XmlStartElementChunk extends XmlNodeChunk {
|
||||
*/
|
||||
private final List<XmlAttribute> attributes = new ArrayList<>();
|
||||
|
||||
protected XmlStartElementChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
XmlStartElementChunk(ByteBuffer buffer, @Nullable Chunk parent) {
|
||||
super(buffer, parent);
|
||||
namespace = buffer.getInt();
|
||||
name = buffer.getInt();
|
||||
|
||||
@@ -25,7 +25,7 @@ public class AudioGetLyrics extends ApiRequest<AudioGetLyrics.a> {
|
||||
public a a(@NonNull JSONObject jSONObject) {
|
||||
var aVar = new a();
|
||||
|
||||
if (Preferences.getBoolValue("useGenius", false)) {
|
||||
if (Preferences.getBoolValue("useGenius", false) && !Preferences.serverFeaturesDisable()) {
|
||||
aVar.a = Genius.getTextMusic(musicTrack);
|
||||
return aVar;
|
||||
}
|
||||
|
||||
@@ -7,16 +7,6 @@ import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class GiftGetByStickerId extends ApiRequest<GiftGetByStickerId.a> {
|
||||
public static class a {
|
||||
public final int a;
|
||||
public final CatalogedGift b;
|
||||
|
||||
public a(int i, CatalogedGift catalogedGift) {
|
||||
this.a = i;
|
||||
this.b = catalogedGift;
|
||||
}
|
||||
}
|
||||
|
||||
public GiftGetByStickerId(Context context, int i) {
|
||||
super("execute.getGiftByStickerId");
|
||||
b("sticker_id", i);
|
||||
@@ -30,4 +20,14 @@ public class GiftGetByStickerId extends ApiRequest<GiftGetByStickerId.a> {
|
||||
return new a(jSONObject2.optInt("balance"),
|
||||
new CatalogedGift(jSONObject2.getJSONObject("gift")));
|
||||
}
|
||||
|
||||
public static class a {
|
||||
public final int a;
|
||||
public final CatalogedGift b;
|
||||
|
||||
public a(int i, CatalogedGift catalogedGift) {
|
||||
this.a = i;
|
||||
this.b = catalogedGift;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,15 @@ public class RecoloredDrawable extends Drawable implements Drawable.Callback {
|
||||
onStateChange(new int[0]);
|
||||
}
|
||||
|
||||
public RecoloredDrawable(Drawable drawable, int i) {
|
||||
this(drawable, new ColorStateList(new int[][]{new int[0]}, new int[]{i}));
|
||||
}
|
||||
|
||||
public RecoloredDrawable() {
|
||||
this.c = 255;
|
||||
this.d = 255;
|
||||
}
|
||||
|
||||
public void a(int i) {
|
||||
a(new ColorStateList(new int[][]{new int[0]}, new int[]{i}));
|
||||
}
|
||||
@@ -120,13 +129,4 @@ public class RecoloredDrawable extends Drawable implements Drawable.Callback {
|
||||
public Drawable a() {
|
||||
return this.drawable;
|
||||
}
|
||||
|
||||
public RecoloredDrawable(Drawable drawable, int i) {
|
||||
this(drawable, new ColorStateList(new int[][]{new int[0]}, new int[]{i}));
|
||||
}
|
||||
|
||||
public RecoloredDrawable() {
|
||||
this.c = 255;
|
||||
this.d = 255;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,13 @@ public final class VerifyInfoHelper {
|
||||
public static final VerifyInfoHelper h;
|
||||
public static int devIcon = R.drawable.ic_favorite_16;
|
||||
|
||||
static {
|
||||
h = new VerifyInfoHelper();
|
||||
}
|
||||
|
||||
private VerifyInfoHelper() {
|
||||
}
|
||||
|
||||
public static Integer enumSwitchMapping(VerifyInfoHelper.ColorTheme color) {
|
||||
return switch (color) {
|
||||
case normal -> 1;
|
||||
@@ -30,18 +37,47 @@ public final class VerifyInfoHelper {
|
||||
};
|
||||
}
|
||||
|
||||
public enum ColorTheme {
|
||||
white,
|
||||
normal,
|
||||
light,
|
||||
ultraLight
|
||||
public static Drawable b(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, boolean dev, Context context, ColorTheme colorTheme, int i, Object obj) {
|
||||
if ((i & 8) != 0) {
|
||||
colorTheme = ColorTheme.normal;
|
||||
}
|
||||
return verifyInfoHelper.b(z, z2, dev, context, colorTheme);
|
||||
}
|
||||
|
||||
static {
|
||||
h = new VerifyInfoHelper();
|
||||
public static Drawable b(VerifyInfoHelper verifyInfoHelper, VerifyInfo verifyInfo, Context context, ColorTheme colorTheme, int i, Object obj) {
|
||||
return b(verifyInfoHelper, verifyInfo.u1(), verifyInfo.t1(), verifyInfo.dev(), context, colorTheme, i, obj);
|
||||
}
|
||||
|
||||
private VerifyInfoHelper() {
|
||||
public static Drawable b(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, Context context, ColorTheme colorTheme, int i, Object obj) {
|
||||
return b(verifyInfoHelper, z, z2, false, context, colorTheme, i, obj);
|
||||
}
|
||||
|
||||
public static Drawable a(VerifyInfoHelper verifyInfoHelper, VerifyInfo verifyInfo, Context context, ColorTheme colorTheme, int i, Object obj) {
|
||||
if ((i & 4) != 0) {
|
||||
colorTheme = ColorTheme.normal;
|
||||
}
|
||||
return verifyInfoHelper.b(verifyInfo, context, colorTheme);
|
||||
}
|
||||
|
||||
public static Drawable a(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, boolean dev, Context context, ColorTheme colorTheme, int i, Object obj) {
|
||||
if ((i & 8) != 0) {
|
||||
colorTheme = ColorTheme.normal;
|
||||
}
|
||||
return verifyInfoHelper.a(z, z2, dev, context, colorTheme);
|
||||
}
|
||||
|
||||
public static Drawable a(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, Context context, ColorTheme colorTheme, int i, Object obj) {
|
||||
return a(verifyInfoHelper, z, z2, false, context, colorTheme, i, obj);
|
||||
}
|
||||
|
||||
public static void a(VerifyInfoHelper verifyInfoHelper, TextView textView, VerifyInfo verifyInfo, boolean z, ColorTheme colorTheme, int i, Object obj) {
|
||||
if ((i & 4) != 0) {
|
||||
z = false;
|
||||
}
|
||||
if ((i & 8) != 0) {
|
||||
colorTheme = ColorTheme.normal;
|
||||
}
|
||||
verifyInfoHelper.a(textView, verifyInfo, z, colorTheme);
|
||||
}
|
||||
|
||||
private int a() {
|
||||
@@ -89,7 +125,6 @@ public final class VerifyInfoHelper {
|
||||
return b(this, z, z2, false, context, null, 8, null);
|
||||
}
|
||||
|
||||
|
||||
public int b(ColorTheme colorTheme) {
|
||||
return a(colorTheme);
|
||||
}
|
||||
@@ -104,7 +139,6 @@ public final class VerifyInfoHelper {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Drawable b(Context context, VerifyInfo verifyInfo) {
|
||||
if (verifyInfo.dev()) {
|
||||
return new RecoloredDrawable(ContextCompat.getDrawable(context, devIcon), c(ColorTheme.normal));
|
||||
@@ -123,21 +157,6 @@ public final class VerifyInfoHelper {
|
||||
return b(verifyInfo.u1(), verifyInfo.t1(), verifyInfo.dev(), context, colorTheme);
|
||||
}
|
||||
|
||||
public static Drawable b(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, boolean dev, Context context, ColorTheme colorTheme, int i, Object obj) {
|
||||
if ((i & 8) != 0) {
|
||||
colorTheme = ColorTheme.normal;
|
||||
}
|
||||
return verifyInfoHelper.b(z, z2, dev, context, colorTheme);
|
||||
}
|
||||
|
||||
public static Drawable b(VerifyInfoHelper verifyInfoHelper, VerifyInfo verifyInfo, Context context, ColorTheme colorTheme, int i, Object obj) {
|
||||
return b(verifyInfoHelper, verifyInfo.u1(), verifyInfo.t1(), verifyInfo.dev(), context, colorTheme, i, obj);
|
||||
}
|
||||
|
||||
public static Drawable b(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, Context context, ColorTheme colorTheme, int i, Object obj) {
|
||||
return b(verifyInfoHelper, z, z2, false, context, colorTheme, i, obj);
|
||||
}
|
||||
|
||||
public Drawable a(Context context, VerifyInfo verifyInfo) {
|
||||
if (verifyInfo.dev()) {
|
||||
return new RecoloredDrawable(ContextCompat.getDrawable(context, devIcon), c(ColorTheme.normal));
|
||||
@@ -181,28 +200,10 @@ public final class VerifyInfoHelper {
|
||||
return new RecoloredDrawable(ContextCompat.getDrawable(context, i), c2);
|
||||
}
|
||||
|
||||
public static Drawable a(VerifyInfoHelper verifyInfoHelper, VerifyInfo verifyInfo, Context context, ColorTheme colorTheme, int i, Object obj) {
|
||||
if ((i & 4) != 0) {
|
||||
colorTheme = ColorTheme.normal;
|
||||
}
|
||||
return verifyInfoHelper.b(verifyInfo, context, colorTheme);
|
||||
}
|
||||
|
||||
public Drawable a(VerifyInfo verifyInfo, Context context, ColorTheme colorTheme) {
|
||||
return a(verifyInfo.u1(), verifyInfo.t1(), verifyInfo.dev(), context, colorTheme);
|
||||
}
|
||||
|
||||
public static Drawable a(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, boolean dev, Context context, ColorTheme colorTheme, int i, Object obj) {
|
||||
if ((i & 8) != 0) {
|
||||
colorTheme = ColorTheme.normal;
|
||||
}
|
||||
return verifyInfoHelper.a(z, z2, dev, context, colorTheme);
|
||||
}
|
||||
|
||||
public static Drawable a(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, Context context, ColorTheme colorTheme, int i, Object obj) {
|
||||
return a(verifyInfoHelper, z, z2, false, context, colorTheme, i, obj);
|
||||
}
|
||||
|
||||
public Drawable a(boolean z, boolean z2, Context context, ColorTheme colorTheme) {
|
||||
return a(z, z2, false, context, colorTheme);
|
||||
}
|
||||
@@ -230,16 +231,6 @@ public final class VerifyInfoHelper {
|
||||
return new RecoloredDrawable(ContextCompat.getDrawable(context, i), c2);
|
||||
}
|
||||
|
||||
public static void a(VerifyInfoHelper verifyInfoHelper, TextView textView, VerifyInfo verifyInfo, boolean z, ColorTheme colorTheme, int i, Object obj) {
|
||||
if ((i & 4) != 0) {
|
||||
z = false;
|
||||
}
|
||||
if ((i & 8) != 0) {
|
||||
colorTheme = ColorTheme.normal;
|
||||
}
|
||||
verifyInfoHelper.a(textView, verifyInfo, z, colorTheme);
|
||||
}
|
||||
|
||||
public void a(TextView textView, VerifyInfo verifyInfo, boolean z, ColorTheme colorTheme) {
|
||||
Drawable drawable;
|
||||
Context context = textView.getContext();
|
||||
@@ -267,4 +258,11 @@ public final class VerifyInfoHelper {
|
||||
}
|
||||
ViewExtKt.p(imageView);
|
||||
}
|
||||
|
||||
public enum ColorTheme {
|
||||
white,
|
||||
normal,
|
||||
light,
|
||||
ultraLight
|
||||
}
|
||||
}
|
||||
+25
-25
@@ -31,30 +31,6 @@ public final class DialogGetMentionSuggestionCmd extends BaseImEngineCmd<Suggest
|
||||
private final boolean e;
|
||||
private final Object f;
|
||||
|
||||
public static final class a<T> implements Comparator<Member> {
|
||||
List a;
|
||||
|
||||
a(List list) {
|
||||
this.a = list;
|
||||
}
|
||||
|
||||
@Override // java.util.Comparator
|
||||
/* renamed from: a */
|
||||
public int compare(Member member, Member member2) {
|
||||
int indexOf = this.a.indexOf(member);
|
||||
int indexOf2 = this.a.indexOf(member2);
|
||||
int i = indexOf;
|
||||
if (indexOf < 0) {
|
||||
i = Integer.MAX_VALUE;
|
||||
}
|
||||
int i2 = indexOf2;
|
||||
if (indexOf2 < 0) {
|
||||
i2 = Integer.MAX_VALUE;
|
||||
}
|
||||
return Intrinsics.a(i, i2);
|
||||
}
|
||||
}
|
||||
|
||||
public DialogGetMentionSuggestionCmd(int i, String str, Source source, boolean z, Object obj) {
|
||||
this.f2365b = i;
|
||||
this.c = str;
|
||||
@@ -150,7 +126,7 @@ public final class DialogGetMentionSuggestionCmd extends BaseImEngineCmd<Suggest
|
||||
Collection<Member> a2;
|
||||
Source source;
|
||||
if (ImDialogsUtils.d(this.f2365b) != PeerType.CHAT) {
|
||||
return new Suggestion((EntityValue) null, (ProfilesInfo) null);
|
||||
return new Suggestion(null, null);
|
||||
}
|
||||
Member Z = imEnvironment.Z();
|
||||
int d = imEnvironment.a0().n().d();
|
||||
@@ -235,4 +211,28 @@ public final class DialogGetMentionSuggestionCmd extends BaseImEngineCmd<Suggest
|
||||
public String toString() {
|
||||
return "DialogGetMentionSuggestionCmd(dialogId=" + this.f2365b + ", query=" + this.c + ", source=" + this.d + ", isAwaitNetwork=" + this.e + ", changerTag=" + this.f + ")";
|
||||
}
|
||||
|
||||
public static final class a<T> implements Comparator<Member> {
|
||||
List a;
|
||||
|
||||
a(List list) {
|
||||
this.a = list;
|
||||
}
|
||||
|
||||
@Override // java.util.Comparator
|
||||
/* renamed from: a */
|
||||
public int compare(Member member, Member member2) {
|
||||
int indexOf = this.a.indexOf(member);
|
||||
int indexOf2 = this.a.indexOf(member2);
|
||||
int i = indexOf;
|
||||
if (indexOf < 0) {
|
||||
i = Integer.MAX_VALUE;
|
||||
}
|
||||
int i2 = indexOf2;
|
||||
if (indexOf2 < 0) {
|
||||
i2 = Integer.MAX_VALUE;
|
||||
}
|
||||
return Intrinsics.a(i, i2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ import java.util.List;
|
||||
public final class DialogActionsHelper {
|
||||
public static final DialogActionsHelper a = new DialogActionsHelper();
|
||||
|
||||
public final List<DialogAction> a(ImConfig imConfig, Dialog dialog, ProfilesSimpleInfo profilesSimpleInfo) {
|
||||
public List<DialogAction> a(ImConfig imConfig, Dialog dialog, ProfilesSimpleInfo profilesSimpleInfo) {
|
||||
if (dialog != null && profilesSimpleInfo != null) {
|
||||
long b2 = TimeProvider.f.b();
|
||||
ChatSettings z1 = dialog.z1();
|
||||
@@ -84,7 +84,7 @@ public final class DialogActionsHelper {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public final List<DialogAction> a(Dialog dialog, ProfilesSimpleInfo profilesSimpleInfo) {
|
||||
public List<DialogAction> a(Dialog dialog, ProfilesSimpleInfo profilesSimpleInfo) {
|
||||
long b2 = TimeProvider.f.b();
|
||||
Profile profile = profilesSimpleInfo.get(dialog.getId());
|
||||
|
||||
@@ -138,7 +138,7 @@ public final class DialogActionsHelper {
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public final boolean a(Dialog dialog) {
|
||||
public boolean a(Dialog dialog) {
|
||||
if (dialog.V1() || !dialog.y1()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,11 @@ import java.util.List;
|
||||
public final class MsgActionHelper {
|
||||
public static final MsgActionHelper a = new MsgActionHelper();
|
||||
|
||||
public final List<MsgAction> a(ImEngine imEngine, Dialog dialog, Collection<? extends Msg> collection) {
|
||||
public List<MsgAction> a(ImEngine imEngine, Dialog dialog, Collection<? extends Msg> collection) {
|
||||
return a(imEngine != null ? imEngine.g() : null, dialog, collection);
|
||||
}
|
||||
|
||||
public final List<MsgAction> a(ImConfig imConfig, Dialog dialog, Collection<? extends Msg> collection) {
|
||||
public List<MsgAction> a(ImConfig imConfig, Dialog dialog, Collection<? extends Msg> collection) {
|
||||
if (imConfig != null && dialog != null && collection != null) {
|
||||
MsgPermissionHelper.a aVar = new MsgPermissionHelper.a(imConfig, dialog, collection);
|
||||
ArrayList<MsgAction> arrayList = new ArrayList<>();
|
||||
|
||||
+29
-137
@@ -74,11 +74,7 @@ public class VhBindArgs {
|
||||
|
||||
private boolean L() {
|
||||
boolean var1;
|
||||
if (this.K() <= this.m && !TimeProvider.f.c()) {
|
||||
var1 = false;
|
||||
} else {
|
||||
var1 = true;
|
||||
}
|
||||
var1 = this.K() > this.m || TimeProvider.f.c();
|
||||
|
||||
return var1;
|
||||
}
|
||||
@@ -109,11 +105,7 @@ public class VhBindArgs {
|
||||
public boolean B() {
|
||||
AdapterEntry var1 = this.a;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.c()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.c();
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -121,11 +113,7 @@ public class VhBindArgs {
|
||||
public boolean C() {
|
||||
AdapterEntry var1 = this.a;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.c() && this.a.c.getLocalId() == this.b.c.getLocalId()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.c() && this.a.c.getLocalId() == this.b.c.getLocalId();
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -133,11 +121,7 @@ public class VhBindArgs {
|
||||
public boolean D() {
|
||||
AdapterEntry var1 = this.a;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.a == 83) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.a == 83;
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -145,11 +129,7 @@ public class VhBindArgs {
|
||||
public boolean E() {
|
||||
Msg var1 = this.b.c;
|
||||
boolean var2;
|
||||
if (var1 instanceof MsgFromUser && ((MsgFromUser) var1).i2()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 instanceof MsgFromUser && ((MsgFromUser) var1).i2();
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -157,11 +137,7 @@ public class VhBindArgs {
|
||||
public boolean F() {
|
||||
Msg var1 = this.b.c;
|
||||
boolean var2;
|
||||
if (var1 instanceof MsgFromUser && ((MsgFromUser) var1).F0()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 instanceof MsgFromUser && ((MsgFromUser) var1).F0();
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -169,11 +145,7 @@ public class VhBindArgs {
|
||||
public boolean G() {
|
||||
AdapterEntry var1 = this.b;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.a == 51) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.a == 51;
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -186,11 +158,7 @@ public class VhBindArgs {
|
||||
long var1 = this.K();
|
||||
long var3 = this.m;
|
||||
boolean var5;
|
||||
if (var1 > var3 && var1 < var3 * 2L) {
|
||||
var5 = true;
|
||||
} else {
|
||||
var5 = false;
|
||||
}
|
||||
var5 = var1 > var3 && var1 < var3 * 2L;
|
||||
|
||||
return var5;
|
||||
}
|
||||
@@ -206,18 +174,10 @@ public class VhBindArgs {
|
||||
MsgFromUser var7 = (MsgFromUser) var1;
|
||||
Msg var3 = this.a.c;
|
||||
boolean var4;
|
||||
if (var3 != null && var3.d() == MsgSyncState.DONE) {
|
||||
var4 = true;
|
||||
} else {
|
||||
var4 = false;
|
||||
}
|
||||
var4 = var3 != null && var3.d() == MsgSyncState.DONE;
|
||||
|
||||
boolean var5;
|
||||
if (this.o == ImBgSyncState.CONNECTED) {
|
||||
var5 = true;
|
||||
} else {
|
||||
var5 = false;
|
||||
}
|
||||
var5 = this.o == ImBgSyncState.CONNECTED;
|
||||
|
||||
boolean var6 = var2;
|
||||
if (!var7.H0()) {
|
||||
@@ -242,7 +202,7 @@ public class VhBindArgs {
|
||||
byte var2 = 0;
|
||||
int var3 = var2;
|
||||
if (var1) {
|
||||
AttachAudioMsg var4 = (AttachAudioMsg) ((MsgFromUser) this.b.c).c(AttachAudioMsg.class, false);
|
||||
AttachAudioMsg var4 = ((MsgFromUser) this.b.c).c(AttachAudioMsg.class, false);
|
||||
var3 = var2;
|
||||
if (var4 != null) {
|
||||
var3 = var4.f();
|
||||
@@ -267,11 +227,7 @@ public class VhBindArgs {
|
||||
public boolean c() {
|
||||
Msg var1 = this.b.c;
|
||||
boolean var2;
|
||||
if (var1 instanceof MsgFromUser && ((MsgFromUser) var1).I0()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 instanceof MsgFromUser && ((MsgFromUser) var1).I0();
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -279,22 +235,14 @@ public class VhBindArgs {
|
||||
public boolean d() {
|
||||
Msg var1 = this.b.c;
|
||||
boolean var2;
|
||||
if (var1 instanceof WithUserContent && ((WithUserContent) var1).D0() != null) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 instanceof WithUserContent && ((WithUserContent) var1).D0() != null;
|
||||
|
||||
return var2;
|
||||
}
|
||||
|
||||
public boolean e() {
|
||||
boolean var1;
|
||||
if (this.b.i > 0) {
|
||||
var1 = true;
|
||||
} else {
|
||||
var1 = false;
|
||||
}
|
||||
var1 = this.b.i > 0;
|
||||
|
||||
return var1;
|
||||
}
|
||||
@@ -317,11 +265,7 @@ public class VhBindArgs {
|
||||
public boolean g() {
|
||||
Msg var1 = this.b.c;
|
||||
boolean var2;
|
||||
if (var1 instanceof MsgFromUser && ((MsgFromUser) var1).G0()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 instanceof MsgFromUser && ((MsgFromUser) var1).G0();
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -329,33 +273,21 @@ public class VhBindArgs {
|
||||
public boolean h() {
|
||||
Msg var1 = this.b.c;
|
||||
boolean var2;
|
||||
if (var1 instanceof MsgFromUser && ((MsgFromUser) var1).Z1()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 instanceof MsgFromUser && ((MsgFromUser) var1).Z1();
|
||||
|
||||
return var2;
|
||||
}
|
||||
|
||||
public boolean i() {
|
||||
boolean var1;
|
||||
if (this.j && !this.u() && !this.l()) {
|
||||
var1 = true;
|
||||
} else {
|
||||
var1 = false;
|
||||
}
|
||||
var1 = this.j && !this.u() && !this.l();
|
||||
|
||||
return var1;
|
||||
}
|
||||
|
||||
public boolean j() {
|
||||
boolean var1;
|
||||
if (!this.j || this.u() || this.B() && this.A() && !this.a.c.H1()) {
|
||||
var1 = false;
|
||||
} else {
|
||||
var1 = true;
|
||||
}
|
||||
var1 = this.j && !this.u() && (!this.B() || !this.A() || this.a.c.H1());
|
||||
|
||||
return var1;
|
||||
}
|
||||
@@ -363,11 +295,7 @@ public class VhBindArgs {
|
||||
public boolean k() {
|
||||
Dialog var1 = this.e;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.U1()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.U1();
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -375,11 +303,7 @@ public class VhBindArgs {
|
||||
public boolean l() {
|
||||
Dialog var1 = this.e;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.V1()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.V1();
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -387,11 +311,7 @@ public class VhBindArgs {
|
||||
public boolean m() {
|
||||
Dialog var1 = this.e;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.W1()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.W1();
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -404,11 +324,7 @@ public class VhBindArgs {
|
||||
public boolean o() {
|
||||
AdapterEntry var1 = this.b;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.a == 101) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.a == 101;
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -416,11 +332,7 @@ public class VhBindArgs {
|
||||
public boolean p() {
|
||||
Msg var1 = this.b.c;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.G1()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.G1();
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -443,11 +355,7 @@ public class VhBindArgs {
|
||||
public boolean r() {
|
||||
Msg var1 = this.b.c;
|
||||
boolean var2;
|
||||
if (var1 instanceof MsgFromUser && ((MsgFromUser) var1).e2()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 instanceof MsgFromUser && ((MsgFromUser) var1).e2();
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -488,27 +396,19 @@ public class VhBindArgs {
|
||||
public boolean v() {
|
||||
IntSet var1 = this.r;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.a(this.b.c.getLocalId())) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.a(this.b.c.getLocalId());
|
||||
|
||||
return var2;
|
||||
}
|
||||
|
||||
public boolean w() {
|
||||
return this.z() ^ true;
|
||||
return !this.z();
|
||||
}
|
||||
|
||||
public boolean x() {
|
||||
AdapterEntry var1 = this.c;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.a == 100) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.a == 100;
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -516,11 +416,7 @@ public class VhBindArgs {
|
||||
public boolean y() {
|
||||
AdapterEntry var1 = this.c;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.a == 96) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.a == 96;
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -528,11 +424,7 @@ public class VhBindArgs {
|
||||
public boolean z() {
|
||||
AdapterEntry var1 = this.c;
|
||||
boolean var2;
|
||||
if (var1 != null && var1.c() && this.c.c.getLocalId() == this.b.c.getLocalId()) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = var1 != null && var1.c() && this.c.c.getLocalId() == this.b.c.getLocalId();
|
||||
|
||||
return var2;
|
||||
}
|
||||
|
||||
+3
-3
@@ -46,7 +46,7 @@ public final class MsgPartCallHolder extends MsgPartHolderBase<AttachCall> {
|
||||
this.G = new StringBuilder();
|
||||
}
|
||||
|
||||
private final void a(Msg var1) {
|
||||
private void a(Msg var1) {
|
||||
this.G.setLength(0);
|
||||
MsgTimeFormatter var2 = this.F;
|
||||
Context var3 = this.C;
|
||||
@@ -55,7 +55,7 @@ public final class MsgPartCallHolder extends MsgPartHolderBase<AttachCall> {
|
||||
this.H.setTimeText(this.G);
|
||||
}
|
||||
|
||||
private final void a(boolean var1) {
|
||||
private void a(boolean var1) {
|
||||
MsgPartIconTwoRowView var2 = this.H;
|
||||
int var3;
|
||||
if (var1) {
|
||||
@@ -67,7 +67,7 @@ public final class MsgPartCallHolder extends MsgPartHolderBase<AttachCall> {
|
||||
var2.setIcon(var3);
|
||||
}
|
||||
|
||||
private final void a(boolean var1, AttachCall var2) {
|
||||
private void a(boolean var1, AttachCall var2) {
|
||||
boolean var3 = !var1;
|
||||
if (var2.h() == CallState.ERROR) {
|
||||
this.H.setSubtitleText(m.vkim_msg_list_call_error);
|
||||
|
||||
+103
-158
@@ -49,6 +49,7 @@ import com.vk.im.ui.views.msg.bubble.MsgBubbleView;
|
||||
import com.vk.im.ui.views.sticker.StickerAnimationState;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.b.Functions;
|
||||
import ru.vtosters.lite.themes.ThemesHacks;
|
||||
|
||||
public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
public static final int h0 = Screen.a(124);
|
||||
@@ -56,46 +57,6 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
private static final int[][] j0;
|
||||
private static final int[][] k0;
|
||||
private static final int[][] l0;
|
||||
private final MsgPartHolderBase B;
|
||||
private final MsgPartHolderBindArgs C = new MsgPartHolderBindArgs();
|
||||
private final Rect D = new Rect();
|
||||
private final Rect E = new Rect();
|
||||
private final Rect F = new Rect();
|
||||
private final Rect G = new Rect();
|
||||
private ColorDrawable H;
|
||||
private final int I;
|
||||
private final int J;
|
||||
private final int K;
|
||||
private final int L;
|
||||
private final int M;
|
||||
private Drawable N;
|
||||
private Drawable O;
|
||||
private BombView P;
|
||||
private BombView.d Q;
|
||||
private int R;
|
||||
private int S;
|
||||
private final DisplayNameFormatter T = new DisplayNameFormatter();
|
||||
private final StringBuilder U = new StringBuilder();
|
||||
private final StringBuilder V = new StringBuilder();
|
||||
private final String W;
|
||||
private final String X;
|
||||
private final String Y;
|
||||
private boolean Z;
|
||||
private BubbleColors a0;
|
||||
private final FluidHorizontalLayout b;
|
||||
@ColorInt
|
||||
private int b0;
|
||||
private final AvatarView c;
|
||||
private MsgListAdapterCallback c0;
|
||||
private final Space d;
|
||||
private Msg d0;
|
||||
private final MsgBubbleView e;
|
||||
private Dialog e0;
|
||||
private final MsgStatusView f;
|
||||
private int f0;
|
||||
private final ImageView g;
|
||||
private h g0 = new h();
|
||||
private final Space h;
|
||||
|
||||
static {
|
||||
int[] var0 = new int[]{0, 0, 0, 0};
|
||||
@@ -119,20 +80,61 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
l0 = new int[][]{var0, {4, 4, 0, 0, 0, 2, 8, 0}, var1, var2, {4, 0, 0, 0, 0, 2, 8, 0}, {0, 0, 0, 0, 0, 2, 8, 0}, {4, 4, 0, 0, 0, 2, 8, 0}, {0, 0, 0, 0, 0, 0, 0, 0}};
|
||||
}
|
||||
|
||||
private final MsgPartHolderBase B;
|
||||
private final MsgPartHolderBindArgs C = new MsgPartHolderBindArgs();
|
||||
private final Rect D = new Rect();
|
||||
private final Rect E = new Rect();
|
||||
private final Rect F = new Rect();
|
||||
private final Rect G = new Rect();
|
||||
private final int I;
|
||||
private final int J;
|
||||
private final int K;
|
||||
private final int L;
|
||||
private final int M;
|
||||
private final DisplayNameFormatter T = new DisplayNameFormatter();
|
||||
private final StringBuilder U = new StringBuilder();
|
||||
private final StringBuilder V = new StringBuilder();
|
||||
private final String W;
|
||||
private final String X;
|
||||
private final String Y;
|
||||
private final FluidHorizontalLayout b;
|
||||
private final AvatarView c;
|
||||
private final Space d;
|
||||
private final MsgBubbleView e;
|
||||
private final MsgStatusView f;
|
||||
private final ImageView g;
|
||||
private final Space h;
|
||||
private final ColorDrawable H;
|
||||
private Drawable N;
|
||||
private Drawable O;
|
||||
private final BombView P;
|
||||
private final BombView.d Q;
|
||||
private final int R;
|
||||
private final int S;
|
||||
private boolean Z;
|
||||
private BubbleColors a0;
|
||||
@ColorInt
|
||||
private int b0;
|
||||
private MsgListAdapterCallback c0;
|
||||
private Msg d0;
|
||||
private Dialog e0;
|
||||
private int f0;
|
||||
private final h g0 = new h();
|
||||
|
||||
public VhMsg(View itemView, MsgPartHolderBase vhBase) {
|
||||
super(itemView);
|
||||
Context context = itemView.getContext();
|
||||
LayoutInflater var4 = LayoutInflater.from(context);
|
||||
this.b = (FluidHorizontalLayout) itemView;
|
||||
this.c = (AvatarView) itemView.findViewById(com.vk.im.ui.h.avatar);
|
||||
this.d = (Space) itemView.findViewById(com.vk.im.ui.h.avatar_space);
|
||||
this.e = (MsgBubbleView) itemView.findViewById(com.vk.im.ui.h.bubble);
|
||||
this.f = (MsgStatusView) itemView.findViewById(com.vk.im.ui.h.status);
|
||||
this.g = (ImageView) itemView.findViewById(com.vk.im.ui.h.vkim_channel_share);
|
||||
this.h = (Space) itemView.findViewById(com.vk.im.ui.h.status_space);
|
||||
this.P = (BombView) itemView.findViewById(com.vk.im.ui.h.bomb);
|
||||
this.c = itemView.findViewById(com.vk.im.ui.h.avatar);
|
||||
this.d = itemView.findViewById(com.vk.im.ui.h.avatar_space);
|
||||
this.e = itemView.findViewById(com.vk.im.ui.h.bubble);
|
||||
this.f = itemView.findViewById(com.vk.im.ui.h.status);
|
||||
this.g = itemView.findViewById(com.vk.im.ui.h.vkim_channel_share);
|
||||
this.h = itemView.findViewById(com.vk.im.ui.h.status_space);
|
||||
this.P = itemView.findViewById(com.vk.im.ui.h.bomb);
|
||||
this.B = vhBase;
|
||||
this.H = new ColorDrawable(context.getResources().getColor(com.vk.im.ui.d.msg_search_selection));
|
||||
this.H = new ColorDrawable(ThemesHacks.getColors(context, com.vk.im.ui.d.msg_search_selection));
|
||||
this.I = ContextExtKt.b(context, com.vk.im.ui.e.msg_bubble_max_width);
|
||||
this.J = ContextExtKt.b(context, com.vk.im.ui.e.msg_reply_max_width);
|
||||
this.K = ContextExtKt.b(context, com.vk.im.ui.e.msg_sticker_max_width);
|
||||
@@ -149,49 +151,39 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
var6.right = var7.rightMargin;
|
||||
var6.top = var7.topMargin;
|
||||
var6.bottom = var7.bottomMargin;
|
||||
ViewExtKt.b(this.c, new View.OnClickListener() {
|
||||
public void onClick(View var1) {
|
||||
if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) {
|
||||
VhMsg.this.c0.a(VhMsg.this.d0.getFrom());
|
||||
}
|
||||
|
||||
ViewExtKt.b(this.c, var1 -> {
|
||||
if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) {
|
||||
VhMsg.this.c0.a(VhMsg.this.d0.getFrom());
|
||||
}
|
||||
});
|
||||
this.c.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
public boolean onLongClick(View var1) {
|
||||
if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) {
|
||||
VhMsg.this.c0.a(VhMsg.this.d0.getFrom());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
ViewExtKt.b(this.g, new View.OnClickListener() {
|
||||
public void onClick(View var1) {
|
||||
if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) {
|
||||
VhMsg.this.c0.a(VhMsg.this.d0);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
ViewExtKt.b(this.itemView, new View.OnClickListener() {
|
||||
public void onClick(View var1) {
|
||||
if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) {
|
||||
VhMsg.this.c0.a(VhMsg.this.d0.getLocalId());
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
this.itemView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
public boolean onLongClick(View var1) {
|
||||
if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) {
|
||||
VhMsg.this.c0.b(VhMsg.this.d0.getLocalId());
|
||||
}
|
||||
|
||||
this.c.setOnLongClickListener(var1 -> {
|
||||
if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) {
|
||||
VhMsg.this.c0.a(VhMsg.this.d0.getFrom());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
ViewExtKt.b(this.g, var1 -> {
|
||||
if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) {
|
||||
VhMsg.this.c0.a(VhMsg.this.d0);
|
||||
}
|
||||
|
||||
});
|
||||
ViewExtKt.b(this.itemView, (View.OnClickListener) var1 -> {
|
||||
if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) {
|
||||
VhMsg.this.c0.a(VhMsg.this.d0.getLocalId());
|
||||
}
|
||||
|
||||
});
|
||||
this.itemView.setOnLongClickListener((View.OnLongClickListener) var1 -> {
|
||||
if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) {
|
||||
VhMsg.this.c0.b(VhMsg.this.d0.getLocalId());
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
this.R = ContextExtKt.i(context, com.vk.im.ui.c.im_msg_part_corner_radius_small);
|
||||
this.S = ContextExtKt.i(context, com.vk.im.ui.c.im_msg_part_corner_radius_big);
|
||||
this.c0 = null;
|
||||
@@ -203,6 +195,10 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
};
|
||||
}
|
||||
|
||||
public static VhMsg a(LayoutInflater var0, ViewGroup var1, MsgPartHolderBase var2) {
|
||||
return new VhMsg(var0.inflate(j.vkim_msg_list_item_msg_from_user, var1, false), var2);
|
||||
}
|
||||
|
||||
private int a(Style var1, Style var2, boolean var3) {
|
||||
int var4;
|
||||
if (var3) {
|
||||
@@ -283,20 +279,15 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
case 103:
|
||||
return VhMsg.Style.EMPTY;
|
||||
default:
|
||||
StringBuilder var3 = new StringBuilder();
|
||||
var3.append("Unknown viewType: ");
|
||||
var3.append(var1);
|
||||
throw new IllegalArgumentException(var3.toString());
|
||||
String var3 = "Unknown viewType: " +
|
||||
var1;
|
||||
throw new IllegalArgumentException(var3);
|
||||
}
|
||||
}
|
||||
|
||||
return VhMsg.Style.TWO_LINE;
|
||||
}
|
||||
|
||||
public static VhMsg a(LayoutInflater var0, ViewGroup var1, MsgPartHolderBase var2) {
|
||||
return new VhMsg(var0.inflate(j.vkim_msg_list_item_msg_from_user, var1, false), var2);
|
||||
}
|
||||
|
||||
private void a(VhBindArgs args, Rect rect) {
|
||||
Style var3 = this.a(args.b);
|
||||
boolean var4 = args.b.f();
|
||||
@@ -411,11 +402,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
Msg var10 = var5.c;
|
||||
var9 = var6;
|
||||
if (var10 != null) {
|
||||
if (var10.v1() == args.g.t1()) {
|
||||
var9 = true;
|
||||
} else {
|
||||
var9 = false;
|
||||
}
|
||||
var9 = var10.v1() == args.g.t1();
|
||||
|
||||
if (var10.O1()) {
|
||||
int var12 = var10.d().ordinal();
|
||||
@@ -433,11 +420,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
b = args.I();
|
||||
}
|
||||
} else {
|
||||
if (var10.C1() <= args.i) {
|
||||
var6 = true;
|
||||
} else {
|
||||
var6 = false;
|
||||
}
|
||||
var6 = var10.C1() <= args.i;
|
||||
|
||||
if (!var6 && !var9) {
|
||||
var11 = MsgStatus.UNREAD;
|
||||
@@ -575,18 +558,14 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
partArgs.o = args.n;
|
||||
partArgs.s = args.v();
|
||||
partArgs.t = args.q;
|
||||
partArgs.u = var4.b() ^ true;
|
||||
partArgs.u = !var4.b();
|
||||
boolean var5;
|
||||
if (var3.i > 0) {
|
||||
var5 = true;
|
||||
} else {
|
||||
var5 = false;
|
||||
}
|
||||
var5 = var3.i > 0;
|
||||
|
||||
partArgs.v = var5;
|
||||
partArgs.w = args.k;
|
||||
partArgs.x = args.l;
|
||||
partArgs.y = this.Z ^ true;
|
||||
partArgs.y = !this.Z;
|
||||
partArgs.z = args.s;
|
||||
partArgs.A = args.t;
|
||||
partArgs.l = this.b0;
|
||||
@@ -671,7 +650,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
private void f(VhBindArgs args) {
|
||||
Msg var2 = args.b.c;
|
||||
if (var2 != null) {
|
||||
this.P.setStateListener((BombView.d) null);
|
||||
this.P.setStateListener(null);
|
||||
if (var2.M1() && !var2.E1()) {
|
||||
this.P.setVisibility(View.GONE);
|
||||
} else {
|
||||
@@ -810,24 +789,12 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
this.e.setFwdPadding(this.D);
|
||||
this.e.setContentPadding(this.E);
|
||||
boolean var7;
|
||||
if (args.b.a == 83) {
|
||||
var7 = true;
|
||||
} else {
|
||||
var7 = false;
|
||||
}
|
||||
var7 = args.b.a == 83;
|
||||
|
||||
boolean var5;
|
||||
if (args.a.a == 83) {
|
||||
var5 = true;
|
||||
} else {
|
||||
var5 = false;
|
||||
}
|
||||
var5 = args.a.a == 83;
|
||||
|
||||
if (!args.F() || !var7 && !var5) {
|
||||
var5 = true;
|
||||
} else {
|
||||
var5 = false;
|
||||
}
|
||||
var5 = !args.F() || !var7 && !var5;
|
||||
|
||||
MsgBubbleView var8 = this.e;
|
||||
boolean var6 = var4;
|
||||
@@ -904,18 +871,10 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
return false;
|
||||
} else {
|
||||
boolean var5;
|
||||
if (var2.a == 50) {
|
||||
var5 = true;
|
||||
} else {
|
||||
var5 = false;
|
||||
}
|
||||
var5 = var2.a == 50;
|
||||
|
||||
boolean var6;
|
||||
if (!args.z() && var2.i == 0) {
|
||||
var6 = true;
|
||||
} else {
|
||||
var6 = false;
|
||||
}
|
||||
var6 = !args.z() && var2.i == 0;
|
||||
|
||||
if (var5 || var6 || args.y() || args.x()) {
|
||||
var4 = true;
|
||||
@@ -934,11 +893,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
|
||||
private boolean u(int var1) {
|
||||
boolean var2;
|
||||
if (var1 != 2 && var1 != 3) {
|
||||
var2 = false;
|
||||
} else {
|
||||
var2 = true;
|
||||
}
|
||||
var2 = var1 == 2 || var1 == 3;
|
||||
|
||||
return var2;
|
||||
}
|
||||
@@ -960,9 +915,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
Msg var1 = this.d0;
|
||||
if (var1 != null) {
|
||||
Dialog var2 = this.e0;
|
||||
if (var2 != null && MsgPermissionHelper.b.a(var2, var1)) {
|
||||
return true;
|
||||
}
|
||||
return var2 != null && MsgPermissionHelper.b.a(var2, var1);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -997,11 +950,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
|
||||
public void a(VhBindArgs args) {
|
||||
boolean var2;
|
||||
if (VKThemeHelper.l() == VKTheme.VKAPP_LIGHT) {
|
||||
var2 = true;
|
||||
} else {
|
||||
var2 = false;
|
||||
}
|
||||
var2 = VKThemeHelper.l() == VKTheme.VKAPP_LIGHT;
|
||||
|
||||
this.Z = var2;
|
||||
AdapterEntry var3 = args.b;
|
||||
@@ -1062,11 +1011,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
|
||||
public boolean f0() {
|
||||
boolean var1;
|
||||
if (this.f0 == 100) {
|
||||
var1 = true;
|
||||
} else {
|
||||
var1 = false;
|
||||
}
|
||||
var1 = this.f0 == 100;
|
||||
|
||||
return var1;
|
||||
}
|
||||
@@ -1083,7 +1028,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
this.B.c(var1);
|
||||
}
|
||||
|
||||
private static enum Style {
|
||||
private enum Style {
|
||||
BUTTON(6),
|
||||
EMPTY(7),
|
||||
FWD_SENDER(4),
|
||||
@@ -1095,14 +1040,14 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b {
|
||||
|
||||
public final int index;
|
||||
|
||||
private Style(int var3) {
|
||||
Style(int var3) {
|
||||
this.index = var3;
|
||||
}
|
||||
}
|
||||
|
||||
private class h implements Functions<Unit> {
|
||||
private int a;
|
||||
private Runnable b;
|
||||
private final int a;
|
||||
private final Runnable b;
|
||||
|
||||
private h() {
|
||||
this.a = Screen.a(12);
|
||||
|
||||
@@ -26,30 +26,23 @@ import com.vtosters.lite.R;
|
||||
|
||||
public final class MentionsController {
|
||||
private final RichEditText a;
|
||||
|
||||
private final ImEngine mImEngine;
|
||||
private final View j;
|
||||
private final b k;
|
||||
private boolean state;
|
||||
private CoordinatorLayout mCoordinatorLayout;
|
||||
private VkBottomSheetBehavior<RecyclerView> mBottomSheetBehavior;
|
||||
private boolean e;
|
||||
private DialogMentionComponent mDialogMentionComponent;
|
||||
private MentionsManager mMentionsManager;
|
||||
private final ImEngine mImEngine;
|
||||
private int i;
|
||||
private final View j;
|
||||
private final b k;
|
||||
|
||||
public interface b {
|
||||
boolean c();
|
||||
|
||||
boolean d();
|
||||
}
|
||||
private final DialogMentionComponent mDialogMentionComponent;
|
||||
private final MentionsManager mMentionsManager;
|
||||
private final int i;
|
||||
|
||||
public MentionsController(ImEngine imEngine, int i, View view, b bVar) {
|
||||
this.mImEngine = imEngine;
|
||||
this.i = i;
|
||||
this.j = view;
|
||||
this.k = bVar;
|
||||
this.a = (RichEditText) this.j.findViewById(R.id.writebar_edit);
|
||||
this.a = this.j.findViewById(R.id.writebar_edit);
|
||||
this.mMentionsManager = new MentionsManager(this.a, new MentionSuggestionsSupplier() {
|
||||
|
||||
@Override
|
||||
@@ -71,7 +64,7 @@ public final class MentionsController {
|
||||
|
||||
@Override
|
||||
public void b() {
|
||||
MentionsController.this.mDialogMentionComponent.a(0, (String) null);
|
||||
MentionsController.this.mDialogMentionComponent.a(0, null);
|
||||
MentionsController.this.g();
|
||||
}
|
||||
});
|
||||
@@ -92,18 +85,18 @@ public final class MentionsController {
|
||||
});
|
||||
}
|
||||
|
||||
public final void g() {
|
||||
public void g() {
|
||||
this.e = false;
|
||||
j();
|
||||
}
|
||||
|
||||
private final void h() {
|
||||
private void h() {
|
||||
if (this.state) {
|
||||
return;
|
||||
}
|
||||
View inflate = ((ViewStub) this.j.findViewById(R.id.mentions_container_stub)).inflate();
|
||||
ViewGroup viewGroup = (ViewGroup) inflate.findViewById(R.id.mentions_container);
|
||||
viewGroup.addView(this.mDialogMentionComponent.a(viewGroup, (Bundle) null));
|
||||
ViewGroup viewGroup = inflate.findViewById(R.id.mentions_container);
|
||||
viewGroup.addView(this.mDialogMentionComponent.a(viewGroup, null));
|
||||
this.mCoordinatorLayout = inflate.findViewById(R.id.mentions_cl);
|
||||
this.mBottomSheetBehavior = (VkBottomSheetBehavior<RecyclerView>) ((CoordinatorLayout.LayoutParams) viewGroup.getLayoutParams()).getBehavior();
|
||||
this.mBottomSheetBehavior.a(new VkBottomSheetBehavior.b() {
|
||||
@@ -120,12 +113,12 @@ public final class MentionsController {
|
||||
this.state = true;
|
||||
}
|
||||
|
||||
public final void i() {
|
||||
public void i() {
|
||||
this.e = true;
|
||||
j();
|
||||
}
|
||||
|
||||
public final void j() {
|
||||
public void j() {
|
||||
if (this.k.d()) {
|
||||
Context context = this.j.getContext();
|
||||
Activity f = ContextExtKt.f(context);
|
||||
@@ -139,27 +132,33 @@ public final class MentionsController {
|
||||
}
|
||||
}
|
||||
|
||||
public final void a() {
|
||||
public void a() {
|
||||
this.mDialogMentionComponent.g();
|
||||
}
|
||||
|
||||
public final void b() {
|
||||
public void b() {
|
||||
this.mDialogMentionComponent.h();
|
||||
}
|
||||
|
||||
public final b c() {
|
||||
public b c() {
|
||||
return this.k;
|
||||
}
|
||||
|
||||
public final int d() {
|
||||
public int d() {
|
||||
return this.i;
|
||||
}
|
||||
|
||||
public final void e() {
|
||||
public void e() {
|
||||
this.mDialogMentionComponent.q();
|
||||
}
|
||||
|
||||
public final void f() {
|
||||
public void f() {
|
||||
this.mDialogMentionComponent.r();
|
||||
}
|
||||
|
||||
public interface b {
|
||||
boolean c();
|
||||
|
||||
boolean d();
|
||||
}
|
||||
}
|
||||
@@ -12,15 +12,15 @@ import android.view.ViewGroup;
|
||||
import com.vk.im.ui.o;
|
||||
|
||||
public class StoryBorderView extends View {
|
||||
private boolean B;
|
||||
private final Paint a;
|
||||
private final int g;
|
||||
private final int h;
|
||||
private boolean B;
|
||||
private LinearGradient f15747b;
|
||||
private int f15748c;
|
||||
private int f15749d;
|
||||
private int f15750e;
|
||||
private int f15751f;
|
||||
private final int g;
|
||||
private final int h;
|
||||
|
||||
public StoryBorderView(Context context) {
|
||||
this(context, null, 0, 6);
|
||||
@@ -34,10 +34,32 @@ public class StoryBorderView extends View {
|
||||
this(context, (i2 & 2) != 0 ? null : attributeSet, (i2 & 4) != 0 ? 0 : i);
|
||||
}
|
||||
|
||||
public StoryBorderView(Context context, AttributeSet attributeSet, int i) {
|
||||
super(context, attributeSet, i);
|
||||
Paint paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
this.a = paint;
|
||||
TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, o.StoryBorderView);
|
||||
setBorderColor(obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderColor, 0));
|
||||
this.g = obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderGradientStartColor, 0);
|
||||
this.h = obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderGradientEndColor, 0);
|
||||
setBorderWidth(obtainStyledAttributes.getDimensionPixelSize(o.StoryBorderView_vkim_borderWidth, 0));
|
||||
obtainStyledAttributes.recycle();
|
||||
}
|
||||
|
||||
public int getBorderColor() {
|
||||
return this.f15749d;
|
||||
}
|
||||
|
||||
public void setBorderColor(int i) {
|
||||
if (this.f15749d != i) {
|
||||
this.f15749d = i;
|
||||
this.a.setColor(i);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public int getBorderGradientEndColor() {
|
||||
return this.h;
|
||||
}
|
||||
@@ -50,14 +72,33 @@ public class StoryBorderView extends View {
|
||||
return this.f15750e;
|
||||
}
|
||||
|
||||
public void setBorderWidth(int i) {
|
||||
if (this.f15750e != i) {
|
||||
this.f15750e = i;
|
||||
this.a.setStrokeWidth(i);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public int getPadding() {
|
||||
return this.f15751f;
|
||||
}
|
||||
|
||||
public void setPadding(int i) {
|
||||
if (this.f15751f != i) {
|
||||
this.f15751f = i;
|
||||
setPadding(i, i, i, i);
|
||||
}
|
||||
}
|
||||
|
||||
public int getViewSize() {
|
||||
return this.f15748c;
|
||||
}
|
||||
|
||||
public void setViewSize(int i) {
|
||||
this.f15748c = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
canvas.drawOval(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), getHeight() - getPaddingBottom(), this.a);
|
||||
@@ -69,22 +110,6 @@ public class StoryBorderView extends View {
|
||||
setMeasuredDimension(i3, i3);
|
||||
}
|
||||
|
||||
public void setBorderColor(int i) {
|
||||
if (this.f15749d != i) {
|
||||
this.f15749d = i;
|
||||
this.a.setColor(i);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public void setBorderWidth(int i) {
|
||||
if (this.f15750e != i) {
|
||||
this.f15750e = i;
|
||||
this.a.setStrokeWidth(i);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLayoutParams(ViewGroup.LayoutParams layoutParams) {
|
||||
super.setLayoutParams(layoutParams);
|
||||
@@ -108,29 +133,4 @@ public class StoryBorderView extends View {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public void setPadding(int i) {
|
||||
if (this.f15751f != i) {
|
||||
this.f15751f = i;
|
||||
setPadding(i, i, i, i);
|
||||
}
|
||||
}
|
||||
|
||||
public void setViewSize(int i) {
|
||||
this.f15748c = i;
|
||||
}
|
||||
|
||||
public StoryBorderView(Context context, AttributeSet attributeSet, int i) {
|
||||
super(context, attributeSet, i);
|
||||
Paint paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
this.a = paint;
|
||||
TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, o.StoryBorderView);
|
||||
setBorderColor(obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderColor, 0));
|
||||
this.g = obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderGradientStartColor, 0);
|
||||
this.h = obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderGradientEndColor, 0);
|
||||
setBorderWidth(obtainStyledAttributes.getDimensionPixelSize(o.StoryBorderView_vkim_borderWidth, 0));
|
||||
obtainStyledAttributes.recycle();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,8 @@ public class MediaImageEncoder {
|
||||
return compressBitmap(bitmap, file, CompressFormat.JPEG, quality);
|
||||
}
|
||||
|
||||
private static boolean compressBitmapLossless(Bitmap bitmap, File file) {
|
||||
return compressBitmap(bitmap, file, CompressFormat.PNG, 100);
|
||||
public static boolean needToCompress() {
|
||||
return Preferences.getPreferences().getBoolean("compressPhotos", true);
|
||||
}
|
||||
|
||||
private static boolean compressBitmapNative(Bitmap bitmap, File file, int quality) {
|
||||
@@ -37,7 +37,7 @@ public class MediaImageEncoder {
|
||||
byte[] jpegData = MediaNative.compressBitmapJpeg(bitmap, quality);
|
||||
|
||||
if (jpegData == null) {
|
||||
return false;
|
||||
return compressBitmapJpeg(bitmap, file, quality);
|
||||
}
|
||||
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
|
||||
@@ -51,43 +51,21 @@ public class MediaImageEncoder {
|
||||
|
||||
public static boolean encodePicture(Bitmap bitmap, File file, int quality) {
|
||||
if (bitmap != null && !bitmap.isRecycled() && bitmap.getWidth() * bitmap.getHeight() != 0) {
|
||||
switch (Preferences.getPreferences().getString("compression", "jpeg")) {
|
||||
case "skip" -> {
|
||||
return compressBitmapLossless(bitmap, file);
|
||||
}
|
||||
case "jpeg" -> {
|
||||
return compressBitmapJpeg(bitmap, file, quality);
|
||||
}
|
||||
case "native" -> {
|
||||
return compressBitmapNative(bitmap, file, quality);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean needToSkipCompression() {
|
||||
return Preferences.getPreferences().getString("compression", "jpeg").equals("skip");
|
||||
}
|
||||
|
||||
public static boolean needToCompress() {
|
||||
return !needToSkipCompression();
|
||||
}
|
||||
|
||||
public static boolean encodeJpeg(Bitmap bitmap, File file) {
|
||||
return encodePicture(bitmap, file, 90);
|
||||
}
|
||||
|
||||
public static boolean encodeJpegWithoutCompression(Bitmap bitmap, File file) {
|
||||
return encodePicture(bitmap, file, 95);
|
||||
}
|
||||
|
||||
public static boolean encodeJpeg(Bitmap bitmap, File file, int quality) {
|
||||
if (bitmap != null && !bitmap.isRecycled() && bitmap.getWidth() * bitmap.getHeight() != 0) {
|
||||
return needToCompress() ? compressBitmapNative(bitmap, file, quality) : compressBitmapJpeg(bitmap, file, quality);
|
||||
return compressBitmapNative(bitmap, file, quality);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean encodeJpeg(Bitmap bitmap, File file) {
|
||||
return encodePicture(bitmap, file, Preferences.compress(85));
|
||||
}
|
||||
|
||||
public static boolean encodeJpegWithoutCompression(Bitmap bitmap, File file) {
|
||||
return encodePicture(bitmap, file, 100);
|
||||
}
|
||||
|
||||
public static boolean encodeJpeg(Bitmap bitmap, File file, int quality) {
|
||||
return encodePicture(bitmap, file, Preferences.compress(85));
|
||||
}
|
||||
}
|
||||
@@ -248,7 +248,6 @@ public final class MediaNative {
|
||||
if (isMediaLoaded) {
|
||||
return;
|
||||
}
|
||||
NativeLibLoader.loadLibrary("ffmpeg");
|
||||
isMediaLoaded = NativeLibLoader.loadLibrary("vkmedia");
|
||||
isMediaLoaded = NativeLibLoader.loadLibrary("vkmediaencoder");
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,7 +156,7 @@ public class LyricsHolder extends RecyclerHolder<PlayerInfo> implements View.OnC
|
||||
|
||||
@Override // com.vk.api.base.ApiCallback
|
||||
public void a(VKApiExecutionException vKApiExecutionException) {
|
||||
if (Preferences.getBoolValue("useGenius", false)) {
|
||||
if (Preferences.getBoolValue("useGenius", false) && !Preferences.serverFeaturesDisable()) {
|
||||
var text = Genius.getTextMusic(a);
|
||||
var lyrics = new AudioGetLyrics.a();
|
||||
lyrics.a = text;
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.vk.newsfeed.holders;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.vk.core.dialogs.alert.VkAlertDialog;
|
||||
import com.vk.core.ui.themes.VKThemeHelper;
|
||||
import com.vk.dto.newsfeed.entries.NewsEntry;
|
||||
import com.vk.dto.newsfeed.entries.Post;
|
||||
import com.vk.dto.newsfeed.entries.PromoPost;
|
||||
import com.vk.extensions.ViewExtKt;
|
||||
import com.vtosters.lite.R;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
import ru.vtosters.lite.utils.AndroidUtils;
|
||||
import ru.vtosters.lite.utils.newsfeed.NewsFeedFiltersUtils;
|
||||
import ru.vtosters.sponsorpost.internal.Native;
|
||||
import ru.vtosters.sponsorpost.internal.VotesPreferences;
|
||||
import ru.vtosters.sponsorpost.internal.VotesService;
|
||||
import ru.vtosters.sponsorpost.utils.PostsPreferences;
|
||||
|
||||
public final class AdMarkHolder extends BaseNewsEntryHolder<NewsEntry> {
|
||||
private final TextView F;
|
||||
|
||||
@SuppressLint("ResourceType")
|
||||
public AdMarkHolder(ViewGroup viewGroup) {
|
||||
super(R.layout.marked_as_ads, viewGroup);
|
||||
View view = ((RecyclerView.ViewHolder) this).itemView;
|
||||
this.F = ViewExtKt.a(view, R.id.text, (View.OnClickListener) null);
|
||||
}
|
||||
|
||||
@SuppressLint("ResourceType")
|
||||
public void b(NewsEntry newsEntry) { // onBind
|
||||
String disclamer = null;
|
||||
Drawable drawable = null;
|
||||
int height = 0;
|
||||
|
||||
if (newsEntry instanceof Post) {
|
||||
Post post = ((Post) newsEntry);
|
||||
if (post.L1()) {
|
||||
drawable = VKThemeHelper.a(R.drawable.marked_as_ads, R.attr.icon_tertiary);
|
||||
int ownerId = post.b();
|
||||
int postId = post.P1();
|
||||
int date = post.K();
|
||||
String text = post.getText();
|
||||
|
||||
if (PostsPreferences.isPostAd(ownerId, postId)) {
|
||||
disclamer = "SponsorPost: Реклама";
|
||||
if (Preferences.isValidSignature() && Native.canVote()) {
|
||||
this.F.setOnClickListener(listener -> voteDialog(ownerId, postId, date, this.F.getContext()));
|
||||
}
|
||||
} else if (VotesPreferences.isPostAd(ownerId, postId)) {
|
||||
disclamer = "SponsorPost: Возможно реклама";
|
||||
if (Preferences.isValidSignature() && Native.canVote()) {
|
||||
this.F.setOnClickListener(listener -> voteDialog(ownerId, postId, date, this.F.getContext()));
|
||||
}
|
||||
} else if (NewsFeedFiltersUtils.sponsorFilters(text)) {
|
||||
disclamer = "SponsorPost: Заблокировано фильтрами";
|
||||
this.F.setOnClickListener(listener -> AndroidUtils.sendToast("Заблокировано по выражению: " + NewsFeedFiltersUtils.sponsorFiltersBanWord(text)));
|
||||
} else {
|
||||
disclamer = m(R.string.sponsored_post_in_group);
|
||||
}
|
||||
|
||||
height = e0().getDimensionPixelSize(R.dimen.newsfeed_ad_mark_post_height);
|
||||
}
|
||||
} else if (newsEntry instanceof PromoPost) {
|
||||
PromoPost promoPost = (PromoPost) newsEntry;
|
||||
if (!promoPost.E1().isEmpty()) {
|
||||
height = e0().getDimensionPixelSize(R.dimen.newsfeed_ad_mark_promo_post_height);
|
||||
disclamer = promoPost.E1();
|
||||
}
|
||||
}
|
||||
|
||||
this.F.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, null, null);
|
||||
this.F.setMinHeight(height);
|
||||
this.F.setText(disclamer);
|
||||
}
|
||||
|
||||
public static void voteDialog(int ownerId, int postId, int date, Context ctx) {
|
||||
new VkAlertDialog.Builder(ctx)
|
||||
.setTitle("SponsorPost")
|
||||
.setMessage("Этот пост является рекламным?")
|
||||
.setPositiveButton("Да", ((dialog, which) -> {
|
||||
int resp = VotesService.ratePost(ownerId, postId, date, true).optInt("code");
|
||||
|
||||
if (resp == 201 || resp == 100) {
|
||||
AndroidUtils.sendToast("Спасибо за голос!");
|
||||
} else {
|
||||
AndroidUtils.sendToast("Ваш голос уже учтен");
|
||||
}
|
||||
}))
|
||||
.setNeutralButton("Нет", ((dialog, which) -> {
|
||||
int resp = VotesService.ratePost(ownerId, postId, date, false).optInt("code");
|
||||
|
||||
if (resp == 201 || resp == 100) {
|
||||
AndroidUtils.sendToast("Спасибо за голос!");
|
||||
} else {
|
||||
AndroidUtils.sendToast("Ваш голос уже учтен");
|
||||
}
|
||||
}))
|
||||
.show();
|
||||
}
|
||||
}
|
||||
@@ -36,37 +36,37 @@ public final class CommunityBorderedImageView extends BorderedCircleImageView im
|
||||
|
||||
public CommunityBorderedImageView(Context context, AttributeSet attributeSet, int i) {
|
||||
super(context, attributeSet, i);
|
||||
this.g0 = VKThemeHelper.d((int) R.attr.accent);
|
||||
this.h0 = ContextExtKt.a(context, (int) R.color.gray_200);
|
||||
this.g0 = VKThemeHelper.d(R.attr.accent);
|
||||
this.h0 = ContextExtKt.a(context, R.color.gray_200);
|
||||
this.i0 = new PorterDuffColorFilter(this.g0, PorterDuff.Mode.SRC_IN);
|
||||
this.j0 = new PorterDuffColorFilter(this.h0, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
public final void c(int unread, int read) { // get unread and read resid
|
||||
public void c(int unread, int read) { // get unread and read resid
|
||||
this.unread = unread;
|
||||
this.read = read;
|
||||
this.T = BitmapFactory.decodeResource(getResources(), this.unread);
|
||||
}
|
||||
|
||||
public final int getPrimaryColor() {
|
||||
public int getPrimaryColor() {
|
||||
return this.g0;
|
||||
}
|
||||
|
||||
public final void setPrimaryColor(int i) {
|
||||
public void setPrimaryColor(int i) {
|
||||
this.g0 = i;
|
||||
this.i0 = new PorterDuffColorFilter(i, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
public final int getWasViewedColor() {
|
||||
public int getWasViewedColor() {
|
||||
return this.h0;
|
||||
}
|
||||
|
||||
public final void setWasViewedColor(int i) {
|
||||
public void setWasViewedColor(int i) {
|
||||
this.h0 = i;
|
||||
this.j0 = new PorterDuffColorFilter(i, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
public final void o() {
|
||||
public void o() {
|
||||
this.f0 = false;
|
||||
l();
|
||||
}
|
||||
@@ -79,7 +79,7 @@ public final class CommunityBorderedImageView extends BorderedCircleImageView im
|
||||
}
|
||||
}
|
||||
|
||||
public final void setStoryContainer(StoriesContainer storiesContainer) {
|
||||
public void setStoryContainer(StoriesContainer storiesContainer) {
|
||||
if (storiesContainer.L1()) {
|
||||
this.f0 = true;
|
||||
m();
|
||||
|
||||
@@ -30,14 +30,14 @@ public class TargetImageView extends VKMultiImageView {
|
||||
private static final int I = Screen.a(2);
|
||||
private final int B;
|
||||
private final int C;
|
||||
private final RectF f21629d;
|
||||
private final Paint f21630e;
|
||||
private final RectF g;
|
||||
private final Paint h;
|
||||
private Drawable D;
|
||||
private String[] F;
|
||||
private int G;
|
||||
private final RectF f21629d;
|
||||
private final Paint f21630e;
|
||||
private Canvas f21631f;
|
||||
private final RectF g;
|
||||
private final Paint h;
|
||||
|
||||
public TargetImageView(Context context, Drawable d) {
|
||||
this(context, null, 0, 6);
|
||||
@@ -51,6 +51,43 @@ public class TargetImageView extends VKMultiImageView {
|
||||
this(context, (i2 & 2) != 0 ? null : attributeSet, (i2 & 4) != 0 ? 0 : i);
|
||||
}
|
||||
|
||||
public TargetImageView(Context context, AttributeSet attributeSet, int i) {
|
||||
super(context, attributeSet, i);
|
||||
this.f21629d = new RectF();
|
||||
Paint paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
paint.setDither(true);
|
||||
paint.setFilterBitmap(true);
|
||||
this.f21630e = paint;
|
||||
this.g = new RectF();
|
||||
Paint paint2 = new Paint();
|
||||
paint2.setAntiAlias(true);
|
||||
paint2.setStrokeWidth(I);
|
||||
paint2.setStyle(Paint.Style.STROKE);
|
||||
this.h = paint2;
|
||||
this.B = getAccentColor();
|
||||
this.C = this.B;
|
||||
Drawable c2 = ContextExtKt.c(context, R.drawable.ic_check_circle_composite_24_full);
|
||||
if (c2 != null) {
|
||||
this.D = c2;
|
||||
this.F = new String[4];
|
||||
int i2 = I * 2;
|
||||
setPadding(i2, i2, i2, i2);
|
||||
if (attributeSet != null) {
|
||||
TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, a0.TargetImageView);
|
||||
setSelected(obtainStyledAttributes.getBoolean(0, false));
|
||||
obtainStyledAttributes.recycle();
|
||||
}
|
||||
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.user_placeholder);
|
||||
for (int i3 = 0; i3 <= 3; i3++) {
|
||||
a();
|
||||
DraweeHolder<GenericDraweeHierarchy> a3 = this.a.a(i3);
|
||||
a3.b().e(drawable);
|
||||
}
|
||||
setScaleType(ScalingUtils.b.o);
|
||||
}
|
||||
}
|
||||
|
||||
private void e() {
|
||||
int i = this.G;
|
||||
for (int i2 = 0; i2 < i; i2++) {
|
||||
@@ -251,41 +288,4 @@ public class TargetImageView extends VKMultiImageView {
|
||||
drawable.setBounds(i - drawable.getIntrinsicWidth(), i2 - this.D.getIntrinsicHeight(), i, i2);
|
||||
f();
|
||||
}
|
||||
|
||||
public TargetImageView(Context context, AttributeSet attributeSet, int i) {
|
||||
super(context, attributeSet, i);
|
||||
this.f21629d = new RectF();
|
||||
Paint paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
paint.setDither(true);
|
||||
paint.setFilterBitmap(true);
|
||||
this.f21630e = paint;
|
||||
this.g = new RectF();
|
||||
Paint paint2 = new Paint();
|
||||
paint2.setAntiAlias(true);
|
||||
paint2.setStrokeWidth(I);
|
||||
paint2.setStyle(Paint.Style.STROKE);
|
||||
this.h = paint2;
|
||||
this.B = getAccentColor();
|
||||
this.C = this.B;
|
||||
Drawable c2 = ContextExtKt.c(context, R.drawable.ic_check_circle_composite_24_full);
|
||||
if (c2 != null) {
|
||||
this.D = c2;
|
||||
this.F = new String[4];
|
||||
int i2 = I * 2;
|
||||
setPadding(i2, i2, i2, i2);
|
||||
if (attributeSet != null) {
|
||||
TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, a0.TargetImageView);
|
||||
setSelected(obtainStyledAttributes.getBoolean(0, false));
|
||||
obtainStyledAttributes.recycle();
|
||||
}
|
||||
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.user_placeholder);
|
||||
for (int i3 = 0; i3 <= 3; i3++) {
|
||||
a();
|
||||
DraweeHolder<GenericDraweeHierarchy> a3 = this.a.a(i3);
|
||||
a3.b().e(drawable);
|
||||
}
|
||||
setScaleType(ScalingUtils.b.o);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,6 +104,25 @@ public final class StickerDetailsAdapter extends RecyclerView.Adapter<RecyclerVi
|
||||
}
|
||||
}
|
||||
|
||||
private static final class d extends RecyclerView.ViewHolder {
|
||||
private final VKStickerImageView mImage;
|
||||
|
||||
public d(ViewGroup viewGroup) {
|
||||
super(new VKStickerImageView(viewGroup.getContext()));
|
||||
this.mImage = (VKStickerImageView) itemView;
|
||||
this.mImage.setAspectRatio(1.0f);
|
||||
this.mImage.setClickable(true);
|
||||
this.mImage.getHierarchy().a().setVisible(true, true);
|
||||
this.mImage.getHierarchy().a(0);
|
||||
this.mImage.setContentDescription(this.mImage.getContext().getString(R.string.stickers_accessibility_sticker));
|
||||
}
|
||||
|
||||
public void a(StickerItem stickerItem) {
|
||||
this.mImage.a(stickerItem.h(Screen.a(80)));
|
||||
this.mImage.setTag(R.id.id, stickerItem.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private final class c extends RecyclerView.ViewHolder {
|
||||
private final VKImageView mImageBg;
|
||||
private final VKImageView mPackImage;
|
||||
@@ -149,23 +168,4 @@ public final class StickerDetailsAdapter extends RecyclerView.Adapter<RecyclerVi
|
||||
this.mDescription.setText(stickerStockItem.C1());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class d extends RecyclerView.ViewHolder {
|
||||
private final VKStickerImageView mImage;
|
||||
|
||||
public d(ViewGroup viewGroup) {
|
||||
super(new VKStickerImageView(viewGroup.getContext()));
|
||||
this.mImage = (VKStickerImageView) itemView;
|
||||
this.mImage.setAspectRatio(1.0f);
|
||||
this.mImage.setClickable(true);
|
||||
this.mImage.getHierarchy().a().setVisible(true, true);
|
||||
this.mImage.getHierarchy().a(0);
|
||||
this.mImage.setContentDescription(this.mImage.getContext().getString(R.string.stickers_accessibility_sticker));
|
||||
}
|
||||
|
||||
public void a(StickerItem stickerItem) {
|
||||
this.mImage.a(stickerItem.h(Screen.a(80)));
|
||||
this.mImage.setTag(R.id.id, stickerItem.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -382,7 +382,7 @@ public class StoryCircleImageView extends BorderedCircleImageView implements The
|
||||
return;
|
||||
}
|
||||
|
||||
pipelineDraweeControllerBuilder.a((Supplier<DataSource<CloseableReference<CloseableImage>>>) () -> StoryCircleImageView.this.a(list));
|
||||
pipelineDraweeControllerBuilder.a(() -> StoryCircleImageView.this.a(list));
|
||||
return;
|
||||
}
|
||||
pipelineDraweeControllerBuilder.b(null);
|
||||
|
||||
@@ -13025,7 +13025,7 @@ public final class R {
|
||||
public static final int ic_launcher_shine = 0x7f0f005d; // 2131689565
|
||||
public static final int ic_launcher_shine_background = 0x7f0f005e; // 2131689566
|
||||
public static final int ic_launcher_shine_foreground = 0x7f0f005f; // 2131689567
|
||||
public static final int vt_adaptive_launcher_foneground = 0x7f0f0043; // 2131689539
|
||||
public static final int vt_adaptive_launcher_foreground = 0x7f0f0043; // 2131689539
|
||||
public static final int vt_launcher_round = 0x7f0f0046; // 2131689542
|
||||
public static final int ic_logo_facebook_28 = 0x7f0f0003; // 2131689475
|
||||
public static final int ic_logo_google_28 = 0x7f0f0004; // 2131689476
|
||||
@@ -19661,38 +19661,39 @@ public final class R {
|
||||
public static final int cache_size = 0x7f12188d; // 2131892365
|
||||
public static final int cache_size_summ = 0x7f12188e; // 2131892366
|
||||
public static final int clear_all_cache = 0x7f12188f; // 2131892367
|
||||
public static final int invalidate_theme_cache_each_update_title = 0x7f121890; // 2131892368
|
||||
public static final int invertFilters = 0x7f121891; // 2131892369
|
||||
public static final int invertFilters_summ = 0x7f121892; // 2131892370
|
||||
public static final int invertcached_summ = 0x7f121893; // 2131892371
|
||||
public static final int invertcached_title = 0x7f121894; // 2131892372
|
||||
public static final int microg_dialog1 = 0x7f121895; // 2131892373
|
||||
public static final int microg_dialog2 = 0x7f121896; // 2131892374
|
||||
public static final int microg_dialog3 = 0x7f121897; // 2131892375
|
||||
public static final int serverFeaturesDisable = 0x7f121898; // 2131892376
|
||||
public static final int serverFeaturesDisable_summ = 0x7f121899; // 2131892377
|
||||
public static final int sett_autoupdates = 0x7f12189a; // 2131892378
|
||||
public static final int sett_autoupdates_summ = 0x7f12189b; // 2131892379
|
||||
public static final int sett_battery = 0x7f12189c; // 2131892380
|
||||
public static final int sett_battery_summ1 = 0x7f12189d; // 2131892381
|
||||
public static final int sett_battery_summ2 = 0x7f12189e; // 2131892382
|
||||
public static final int sett_chats = 0x7f12189f; // 2131892383
|
||||
public static final int sett_chats_summ = 0x7f1218a0; // 2131892384
|
||||
public static final int sett_community = 0x7f1218a1; // 2131892385
|
||||
public static final int sett_community_summ = 0x7f1218a2; // 2131892386
|
||||
public static final int sett_missing_links = 0x7f1218a3; // 2131892387
|
||||
public static final int sett_missing_links_summ = 0x7f1218a4; // 2131892388
|
||||
public static final int sett_nogms_summ = 0x7f1218a5; // 2131892389
|
||||
public static final int sett_notifs = 0x7f1218a6; // 2131892390
|
||||
public static final int sett_notifs_summ = 0x7f1218a7; // 2131892391
|
||||
public static final int sett_recommendations = 0x7f1218a8; // 2131892392
|
||||
public static final int tgs_token_missing = 0x7f1218aa; // 2131892394
|
||||
public static final int tgs_token_reset = 0x7f1218ab; // 2131892395
|
||||
public static final int tgs_token_reset_dialog = 0x7f1218ac; // 2131892396
|
||||
public static final int tgs_token_reset_menu = 0x7f1218ad; // 2131892397
|
||||
public static final int update_err = 0x7f1218ae; // 2131892398
|
||||
public static final int update_latest = 0x7f1218af; // 2131892399
|
||||
public static final int APKTOOL_DUMMY_18a9 = 0x7f1218a9; // 2131892393
|
||||
public static final int disable_roaming_state = 0x7f121890; // 2131892368
|
||||
public static final int disable_roaming_state_submit = 0x7f121891; // 2131892369
|
||||
public static final int invalidate_theme_cache_each_update_title = 0x7f121892; // 2131892370
|
||||
public static final int invertFilters = 0x7f121893; // 2131892371
|
||||
public static final int invertFilters_summ = 0x7f121894; // 2131892372
|
||||
public static final int invertcached_summ = 0x7f121895; // 2131892373
|
||||
public static final int invertcached_title = 0x7f121896; // 2131892374
|
||||
public static final int microg_dialog1 = 0x7f121897; // 2131892375
|
||||
public static final int microg_dialog2 = 0x7f121898; // 2131892376
|
||||
public static final int microg_dialog3 = 0x7f121899; // 2131892377
|
||||
public static final int serverFeaturesDisable = 0x7f12189a; // 2131892378
|
||||
public static final int serverFeaturesDisable_summ = 0x7f12189b; // 2131892379
|
||||
public static final int sett_autoupdates = 0x7f12189c; // 2131892380
|
||||
public static final int sett_autoupdates_summ = 0x7f12189d; // 2131892381
|
||||
public static final int sett_battery = 0x7f12189e; // 2131892382
|
||||
public static final int sett_battery_summ1 = 0x7f12189f; // 2131892383
|
||||
public static final int sett_battery_summ2 = 0x7f1218a0; // 2131892384
|
||||
public static final int sett_chats = 0x7f1218a1; // 2131892385
|
||||
public static final int sett_chats_summ = 0x7f1218a2; // 2131892386
|
||||
public static final int sett_community = 0x7f1218a3; // 2131892387
|
||||
public static final int sett_community_summ = 0x7f1218a4; // 2131892388
|
||||
public static final int sett_missing_links = 0x7f1218a5; // 2131892389
|
||||
public static final int sett_missing_links_summ = 0x7f1218a6; // 2131892390
|
||||
public static final int sett_nogms_summ = 0x7f1218a7; // 2131892391
|
||||
public static final int sett_notifs = 0x7f1218a8; // 2131892392
|
||||
public static final int sett_notifs_summ = 0x7f1218a9; // 2131892393
|
||||
public static final int sett_recommendations = 0x7f1218aa; // 2131892394
|
||||
public static final int tgs_token_missing = 0x7f1218ab; // 2131892395
|
||||
public static final int tgs_token_reset = 0x7f1218ac; // 2131892396
|
||||
public static final int tgs_token_reset_dialog = 0x7f1218ad; // 2131892397
|
||||
public static final int tgs_token_reset_menu = 0x7f1218ae; // 2131892398
|
||||
public static final int update_err = 0x7f1218af; // 2131892399
|
||||
public static final int update_latest = 0x7f1218b0; // 2131892400
|
||||
}
|
||||
|
||||
public static final class style {
|
||||
|
||||
@@ -1,505 +0,0 @@
|
||||
package com.vtosters.lite.api.execute;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.RectF;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import com.vk.api.base.utils.ApiUtils;
|
||||
import com.vk.core.network.Network;
|
||||
import com.vk.core.util.AppContextHolder;
|
||||
import com.vk.core.util.Screen;
|
||||
import com.vk.dto.common.data.VKList;
|
||||
import com.vk.dto.gift.GiftItem;
|
||||
import com.vk.dto.group.Group;
|
||||
import com.vk.dto.newsfeed.entries.ProfilesRecommendations;
|
||||
import com.vk.dto.photo.Photo;
|
||||
import com.vk.dto.user.UserProfile;
|
||||
import com.vk.dto.user.deactivation.UserDeactivation;
|
||||
import com.vtosters.lite.api.ExtendedUserProfile;
|
||||
import com.vtosters.lite.auth.VKAccountManager;
|
||||
import com.vtosters.lite.utils.Utils;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import ru.vtosters.hooks.OnlineFormatterHook;
|
||||
import ru.vtosters.hooks.RenameHook;
|
||||
import ru.vtosters.hooks.ssfs.ProfileHook;
|
||||
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
|
||||
import ru.vtosters.lite.proxy.ProxyUtils;
|
||||
import ru.vtosters.lite.utils.AccountManagerUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GetFullUserProfile extends GetFullProfile<ExtendedUserProfile> {
|
||||
private static final OkHttpClient mClient = VtOkHttpClient.getInstance();
|
||||
|
||||
public GetFullUserProfile(int i, String str, String str2) {
|
||||
super(i, "execute.getFullProfileNewNew");
|
||||
i = i == 0 ? VKAccountManager.d().D0() : i;
|
||||
b("user_id", i);
|
||||
b("func_v", 23); // 11
|
||||
this.F = i;
|
||||
if (!TextUtils.isEmpty(str2)) {
|
||||
c("source", str2);
|
||||
}
|
||||
b("photo_sizes", 1);
|
||||
b("skip_hidden", 1);
|
||||
if (TextUtils.isEmpty(str)) {
|
||||
return;
|
||||
}
|
||||
c("access_keys", str);
|
||||
}
|
||||
|
||||
public JSONArray getCitiesNames(String ids) {
|
||||
var request = new Request.a()
|
||||
.b("https://" + ProxyUtils.getApi() + "/method/" + "database.getCitiesById"
|
||||
+ "?v=5.119"
|
||||
+ "&city_ids="
|
||||
+ ids
|
||||
+ "&access_token="
|
||||
+ AccountManagerUtils.getUserToken())
|
||||
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8")).a();
|
||||
|
||||
try {
|
||||
return new JSONObject(mClient.a(request).execute().a().g()).getJSONArray("response");
|
||||
} catch (JSONException | IOException e) {
|
||||
Log.d(this.getClass().getSimpleName(), e.toString());
|
||||
}
|
||||
|
||||
return new JSONArray();
|
||||
}
|
||||
|
||||
public JSONArray getCountriesNames(String ids) {
|
||||
var request = new Request.a()
|
||||
.b("https://" + ProxyUtils.getApi() + "/method/" + "database.getCountriesById"
|
||||
+ "?v=5.119"
|
||||
+ "&country_ids="
|
||||
+ ids
|
||||
+ "&access_token="
|
||||
+ AccountManagerUtils.getUserToken())
|
||||
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8")).a();
|
||||
|
||||
try {
|
||||
return new JSONObject(mClient.a(request).execute().a().g()).getJSONArray("response");
|
||||
} catch (JSONException | IOException e) {
|
||||
Log.d(this.getClass().getSimpleName(), e.toString());
|
||||
}
|
||||
|
||||
return new JSONArray();
|
||||
}
|
||||
|
||||
|
||||
protected ExtendedUserProfile o() {
|
||||
return new ExtendedUserProfile();
|
||||
}
|
||||
|
||||
@SuppressLint("ResourceType")
|
||||
public void a(ExtendedUserProfile extendedUserProfile, JSONObject jSONObject) throws JSONException {
|
||||
char c;
|
||||
RenameHook.injectIntoJson(jSONObject);
|
||||
JSONObject onlineHook = OnlineFormatterHook.onlineHook(jSONObject);
|
||||
UserProfile userProfile = extendedUserProfile.a;
|
||||
int i = onlineHook.getInt("id");
|
||||
this.F = i;
|
||||
userProfile.b = i;
|
||||
ProfileHook.fetchInfo(extendedUserProfile, onlineHook);
|
||||
|
||||
extendedUserProfile.a.c = onlineHook.getString("first_name");
|
||||
extendedUserProfile.a.e = onlineHook.getString("last_name");
|
||||
extendedUserProfile.a.d = extendedUserProfile.a.c + " " + extendedUserProfile.a.e;
|
||||
extendedUserProfile.a.f = onlineHook.getString(Screen.a() > 1.0f ? "photo_medium_rec" : "photo_rec");
|
||||
extendedUserProfile.a.h = onlineHook.getInt("friend_status") == 3;
|
||||
extendedUserProfile.j = onlineHook.optString("photo_max", onlineHook.getString("photo_medium_rec"));
|
||||
extendedUserProfile.m = onlineHook.optString("activity", "");
|
||||
extendedUserProfile.a.g = onlineHook.getInt("sex") == 1;
|
||||
extendedUserProfile.a.E = UserProfile.d(jSONObject);
|
||||
|
||||
if (onlineHook.has("crop_photo")) {
|
||||
extendedUserProfile.k = new Photo(onlineHook.getJSONObject("crop_photo").getJSONObject("photo"));
|
||||
JSONObject jSONObject2 = onlineHook.getJSONObject("crop_photo").getJSONObject("rect");
|
||||
JSONObject jSONObject3 = onlineHook.getJSONObject("crop_photo").getJSONObject("crop");
|
||||
double d = jSONObject3.getDouble("x");
|
||||
double d2 = jSONObject3.getDouble("x2");
|
||||
double d3 = jSONObject3.getDouble("y");
|
||||
double d4 = jSONObject3.getDouble("y2");
|
||||
double d5 = jSONObject2.getDouble("x");
|
||||
double d6 = jSONObject2.getDouble("x2");
|
||||
double d7 = jSONObject2.getDouble("y");
|
||||
double d8 = (d2 - d) / 100.0d;
|
||||
double d9 = (d4 - d3) / 100.0d;
|
||||
double d10 = (d / 100.0d) + ((d5 / 100.0d) * d8);
|
||||
double d11 = (d3 / 100.0d) + ((d7 / 100.0d) * d9);
|
||||
extendedUserProfile.l = new RectF((float) d10, (float) d11, (float) (d10 + (((d6 - d5) / 100.0d) * d8)), (float) (d11 + (((jSONObject2.getDouble("y2") - d7) / 100.0d) * d9)));
|
||||
}
|
||||
|
||||
SparseArray<String> sparseArray = new SparseArray<>();
|
||||
SparseArray<String> sparseArray2 = new SparseArray<>();
|
||||
|
||||
if (onlineHook.has("cities") && onlineHook.getJSONArray("cities").length() > 0) {
|
||||
List<String> cityNames = new ArrayList<>();
|
||||
|
||||
JSONArray cities = onlineHook.getJSONArray("cities");
|
||||
|
||||
for (int i21 = 0; i21 < cities.length(); i21++) {
|
||||
cityNames.add(cities.getString(i21));
|
||||
}
|
||||
|
||||
JSONArray citiesNamesJSONArray = getCitiesNames(String.join(", ", cityNames));
|
||||
|
||||
Log.d(this.getClass().getSimpleName(), citiesNamesJSONArray.toString());
|
||||
|
||||
for (int i22 = 0; i22 < citiesNamesJSONArray.length(); i22++) {
|
||||
JSONObject cityJSONObject = citiesNamesJSONArray.getJSONObject(i22);
|
||||
int cityid = cityJSONObject.getInt("id");
|
||||
String cityTitle = cityJSONObject.getString("title");
|
||||
sparseArray.put(cityid, cityTitle);
|
||||
}
|
||||
|
||||
extendedUserProfile.i0 = sparseArray.get(cities.getInt(0));
|
||||
}
|
||||
|
||||
if (onlineHook.has("countries") && onlineHook.getJSONArray("countries").length() > 0) {
|
||||
JSONArray countries = onlineHook.getJSONArray("countries");
|
||||
List<String> countryList = new ArrayList<>();
|
||||
|
||||
for (int i23 = 0; i23 < countries.length(); i23++) {
|
||||
countryList.add(countries.getString(i23));
|
||||
}
|
||||
|
||||
JSONArray countryInfo = getCountriesNames(String.join(", ", countryList));
|
||||
|
||||
Log.d(this.getClass().getSimpleName(), countryInfo.toString());
|
||||
|
||||
for (int i24 = 0; i24 < countryInfo.length(); i24++) {
|
||||
JSONObject country = countryInfo.getJSONObject(i24);
|
||||
int countryid = country.getInt("id");
|
||||
String countryTitle = country.getString("title");
|
||||
sparseArray2.put(countryid, countryTitle);
|
||||
}
|
||||
|
||||
extendedUserProfile.j0 = sparseArray2.get(countries.getInt(0));
|
||||
}
|
||||
|
||||
extendedUserProfile.U = onlineHook.getInt("can_write_private_message") == 1;
|
||||
extendedUserProfile.X = onlineHook.getInt("can_post") == 1;
|
||||
extendedUserProfile.Y = onlineHook.optInt("can_suggest") == 1;
|
||||
extendedUserProfile.V = onlineHook.optInt("can_see_all_posts") == 1;
|
||||
extendedUserProfile.f0 = onlineHook.optInt("can_see_archived_posts") == 1;
|
||||
extendedUserProfile.a0 = "all".equals(onlineHook.optString("wall_default"));
|
||||
extendedUserProfile.W = onlineHook.optBoolean("can_call", false);
|
||||
extendedUserProfile.Z = onlineHook.optInt("blacklisted_by_me") == 1;
|
||||
|
||||
if (onlineHook.optInt("blacklisted") == 1) {
|
||||
extendedUserProfile.Y0 = new ExtendedUserProfile.c();
|
||||
}
|
||||
|
||||
extendedUserProfile.u = onlineHook.optInt("relation");
|
||||
if (onlineHook.has("relation_partner")) {
|
||||
extendedUserProfile.v = onlineHook.getJSONObject("relation_partner").getInt("id");
|
||||
extendedUserProfile.w = onlineHook.getJSONObject("relation_partner").getString("first_name") + " " + onlineHook.getJSONObject("relation_partner").getString("last_name");
|
||||
}
|
||||
|
||||
if (onlineHook.has("bdate")) {
|
||||
String string = onlineHook.getString("bdate");
|
||||
extendedUserProfile.a.I = string;
|
||||
String[] split = string.split("\\.");
|
||||
extendedUserProfile.s = Integer.parseInt(split[0]);
|
||||
extendedUserProfile.t = Integer.parseInt(split[1]);
|
||||
if (split.length > 2) {
|
||||
extendedUserProfile.r = Integer.parseInt(split[2]);
|
||||
}
|
||||
}
|
||||
|
||||
extendedUserProfile.d = onlineHook.optString("first_name_dat", extendedUserProfile.a.c);
|
||||
extendedUserProfile.b = onlineHook.optString("first_name_gen", extendedUserProfile.a.c);
|
||||
extendedUserProfile.c = onlineHook.optString("first_name_ins", extendedUserProfile.a.c);
|
||||
extendedUserProfile.h = onlineHook.optString("first_name_acc", extendedUserProfile.a.c);
|
||||
extendedUserProfile.g = onlineHook.optString("last_name_dat", extendedUserProfile.a.e);
|
||||
extendedUserProfile.e = onlineHook.optString("last_name_gen", extendedUserProfile.a.e);
|
||||
extendedUserProfile.f = onlineHook.optString("last_name_ins", extendedUserProfile.a.e);
|
||||
|
||||
String optString = onlineHook.optString("last_name_acc", extendedUserProfile.a.e);
|
||||
extendedUserProfile.i = optString;
|
||||
|
||||
if (onlineHook.has("mobile_phone") && !onlineHook.getString("mobile_phone").isEmpty()) {
|
||||
extendedUserProfile.l0 = onlineHook.getString("mobile_phone");
|
||||
}
|
||||
|
||||
if (onlineHook.has("home_phone") && !onlineHook.getString("home_phone").isEmpty()) {
|
||||
extendedUserProfile.m0 = onlineHook.getString("home_phone");
|
||||
}
|
||||
|
||||
if (onlineHook.has("skype")) {
|
||||
extendedUserProfile.n0 = onlineHook.getString("skype");
|
||||
}
|
||||
|
||||
if (onlineHook.has("twitter")) {
|
||||
extendedUserProfile.o0 = onlineHook.getString("twitter");
|
||||
}
|
||||
|
||||
if (onlineHook.has("livejournal")) {
|
||||
extendedUserProfile.r0 = onlineHook.getString("livejournal");
|
||||
}
|
||||
|
||||
if (onlineHook.has("facebook") && onlineHook.optLong("facebook", -1L) != -1) {
|
||||
extendedUserProfile.q0 = onlineHook.getLong("facebook");
|
||||
extendedUserProfile.p0 = onlineHook.getString("facebook_name");
|
||||
}
|
||||
|
||||
if (onlineHook.has("instagram")) {
|
||||
extendedUserProfile.u0 = onlineHook.getString("instagram");
|
||||
}
|
||||
|
||||
extendedUserProfile.R0 = onlineHook.getInt("friend_status");
|
||||
JSONArray optJSONArray = onlineHook.optJSONArray("schools");
|
||||
extendedUserProfile.v0 = new ArrayList<>();
|
||||
|
||||
ArrayList arrayList = null;
|
||||
if (optJSONArray != null) {
|
||||
for (int i4 = 0; i4 < optJSONArray.length(); i4++) {
|
||||
ExtendedUserProfile.f fVar = new ExtendedUserProfile.f();
|
||||
JSONObject jSONObject6 = optJSONArray.getJSONObject(i4);
|
||||
fVar.c = sparseArray.get(jSONObject6.optInt(optString));
|
||||
fVar.a = jSONObject6.optString("name", "???");
|
||||
fVar.g = jSONObject6.optInt("year_from");
|
||||
fVar.f = jSONObject6.optInt("year_to");
|
||||
fVar.h = jSONObject6.optInt("year_graduated");
|
||||
fVar.b = jSONObject6.optString("class", null);
|
||||
fVar.d = jSONObject6.optString("speciality", null);
|
||||
fVar.e = jSONObject6.optString("type_str", AppContextHolder.a.getResources().getString(2131889117));
|
||||
extendedUserProfile.v0.add(fVar);
|
||||
}
|
||||
}
|
||||
extendedUserProfile.w0 = new ArrayList<>();
|
||||
|
||||
JSONArray optJSONArray2 = onlineHook.optJSONArray("universities");
|
||||
if (optJSONArray2 != null) {
|
||||
for (int i5 = 0; i5 < optJSONArray2.length(); i5++) {
|
||||
ExtendedUserProfile.g gVar = new ExtendedUserProfile.g();
|
||||
JSONObject jSONObject7 = optJSONArray2.getJSONObject(i5);
|
||||
gVar.a = jSONObject7.getString("name").trim();
|
||||
if (jSONObject7.has("faculty_name")) {
|
||||
gVar.b = jSONObject7.getString("faculty_name").trim();
|
||||
}
|
||||
if (jSONObject7.has("chair_name")) {
|
||||
gVar.c = jSONObject7.getString("chair_name").trim();
|
||||
}
|
||||
gVar.d = jSONObject7.optInt("graduation");
|
||||
extendedUserProfile.w0.add(gVar);
|
||||
}
|
||||
}
|
||||
|
||||
if (onlineHook.has("interests") && onlineHook.getString("interests").length() > 0) {
|
||||
extendedUserProfile.y0 = onlineHook.getString("interests");
|
||||
}
|
||||
|
||||
if (onlineHook.has("movies") && onlineHook.getString("movies").length() > 0) {
|
||||
extendedUserProfile.A0 = onlineHook.getString("movies");
|
||||
}
|
||||
|
||||
if (onlineHook.has("music") && onlineHook.getString("music").length() > 0) {
|
||||
extendedUserProfile.z0 = onlineHook.getString("music");
|
||||
}
|
||||
|
||||
if (onlineHook.has("tv") && onlineHook.getString("tv").length() > 0) {
|
||||
extendedUserProfile.B0 = onlineHook.getString("tv");
|
||||
}
|
||||
|
||||
if (onlineHook.has("books") && onlineHook.getString("books").length() > 0) {
|
||||
extendedUserProfile.C0 = onlineHook.getString("books");
|
||||
}
|
||||
|
||||
if (onlineHook.has("games") && onlineHook.getString("games").length() > 0) {
|
||||
extendedUserProfile.D0 = onlineHook.getString("games");
|
||||
}
|
||||
|
||||
if (onlineHook.has("about") && onlineHook.getString("about").length() > 0) {
|
||||
extendedUserProfile.F0 = onlineHook.getString("about");
|
||||
}
|
||||
|
||||
if (onlineHook.has("quotes") && onlineHook.getString("quotes").length() > 0) {
|
||||
extendedUserProfile.E0 = onlineHook.getString("quotes");
|
||||
}
|
||||
|
||||
if (onlineHook.has("activities") && onlineHook.getString("activities").length() > 0) {
|
||||
extendedUserProfile.x0 = onlineHook.getString("activities");
|
||||
}
|
||||
|
||||
if (onlineHook.has("home_town") && onlineHook.getString("home_town").length() > 0) {
|
||||
extendedUserProfile.g0 = onlineHook.getString("home_town");
|
||||
}
|
||||
|
||||
if (onlineHook.has("site") && onlineHook.getString("site").length() > 0) {
|
||||
extendedUserProfile.M = onlineHook.getString("site");
|
||||
}
|
||||
|
||||
extendedUserProfile.a.Q.b(onlineHook);
|
||||
|
||||
JSONObject optJSONObject = onlineHook.optJSONObject("personal");
|
||||
if (optJSONObject != null) {
|
||||
JSONArray optJSONArray3 = optJSONObject.optJSONArray("langs");
|
||||
|
||||
if (optJSONArray3 != null) {
|
||||
ArrayList arrayList2 = new ArrayList<>();
|
||||
for (int i6 = 0; i6 < optJSONArray3.length(); i6++) {
|
||||
arrayList2.add(optJSONArray3.getString(i6));
|
||||
}
|
||||
extendedUserProfile.G0 = TextUtils.join(", ", arrayList2);
|
||||
}
|
||||
|
||||
extendedUserProfile.J0 = optJSONObject.optInt("political");
|
||||
extendedUserProfile.H0 = optJSONObject.optString("religion");
|
||||
extendedUserProfile.K0 = optJSONObject.optInt("life_main");
|
||||
extendedUserProfile.L0 = optJSONObject.optInt("people_main");
|
||||
extendedUserProfile.I0 = optJSONObject.optString("inspired_by");
|
||||
extendedUserProfile.M0 = optJSONObject.optInt("smoking");
|
||||
extendedUserProfile.N0 = optJSONObject.optInt("alcohol");
|
||||
}
|
||||
|
||||
SparseArray sparseArray3 = new SparseArray();
|
||||
JSONArray optJSONArray4 = onlineHook.optJSONArray("relatives_profiles");
|
||||
if (optJSONArray4 != null) {
|
||||
for (int i7 = 0; i7 < optJSONArray4.length(); i7++) {
|
||||
UserProfile userProfile2 = new UserProfile(optJSONArray4.getJSONObject(i7));
|
||||
sparseArray3.put(userProfile2.b, userProfile2);
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray optJSONArray5 = onlineHook.optJSONArray("relatives");
|
||||
if (optJSONArray5 != null) {
|
||||
ArrayList arrayList3 = null;
|
||||
ArrayList arrayList4 = null;
|
||||
ArrayList arrayList5 = null;
|
||||
ArrayList arrayList6 = null;
|
||||
for (int i8 = 0; i8 < optJSONArray5.length(); i8++) {
|
||||
JSONObject jSONObject8 = optJSONArray5.getJSONObject(i8);
|
||||
int i9 = jSONObject8.getInt("id");
|
||||
if (ApiUtils.a(sparseArray3, i9)) {
|
||||
String valueOf = jSONObject8.getString("type");
|
||||
switch (valueOf.hashCode()) {
|
||||
case -995424086 -> {
|
||||
if (valueOf.equals("parent")) {
|
||||
c = 4;
|
||||
break;
|
||||
}
|
||||
c = 65535;
|
||||
}
|
||||
case -268316490 -> {
|
||||
if (valueOf.equals("grandparent")) {
|
||||
c = 1;
|
||||
break;
|
||||
}
|
||||
c = 65535;
|
||||
}
|
||||
case 94631196 -> {
|
||||
if (valueOf.equals("child")) {
|
||||
c = 2;
|
||||
break;
|
||||
}
|
||||
c = 65535;
|
||||
}
|
||||
case 395180944 -> {
|
||||
if (valueOf.equals("grandchild")) {
|
||||
c = 0;
|
||||
break;
|
||||
}
|
||||
c = 65535;
|
||||
}
|
||||
case 2083595970 -> {
|
||||
if (valueOf.equals("sibling")) {
|
||||
c = 3;
|
||||
break;
|
||||
}
|
||||
c = 65535;
|
||||
}
|
||||
default -> c = 65535;
|
||||
}
|
||||
switch (c) {
|
||||
case 0 -> arrayList6 = Utils.a(arrayList6, sparseArray3.get(i9));
|
||||
case 1 -> arrayList5 = Utils.a(arrayList5, sparseArray3.get(i9));
|
||||
case 2 -> arrayList4 = Utils.a(arrayList4, sparseArray3.get(i9));
|
||||
case 3 -> arrayList3 = Utils.a(arrayList3, sparseArray3.get(i9));
|
||||
case 4 -> arrayList = Utils.a(arrayList, sparseArray3.get(i9));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extendedUserProfile.A = Utils.a((ArrayList<UserProfile>) arrayList, UserProfile.CREATOR);
|
||||
extendedUserProfile.B = Utils.a((ArrayList<UserProfile>) arrayList3, UserProfile.CREATOR);
|
||||
extendedUserProfile.C = Utils.a((ArrayList<UserProfile>) arrayList4, UserProfile.CREATOR);
|
||||
extendedUserProfile.D = Utils.a((ArrayList<UserProfile>) arrayList5, UserProfile.CREATOR);
|
||||
extendedUserProfile.E = Utils.a((ArrayList<UserProfile>) arrayList6, UserProfile.CREATOR);
|
||||
}
|
||||
|
||||
JSONObject optJSONObject2 = onlineHook.optJSONObject("owner_state");
|
||||
if (optJSONObject2 != null) {
|
||||
extendedUserProfile.q = UserDeactivation.CREATOR.a(optJSONObject2);
|
||||
}
|
||||
|
||||
JSONObject optJSONObject3 = onlineHook.optJSONObject("gifts");
|
||||
if (optJSONObject3 != null) {
|
||||
extendedUserProfile.y1 = new VKList<>(optJSONObject3, GiftItem.C);
|
||||
}
|
||||
|
||||
JSONArray optJSONArray6 = onlineHook.optJSONArray("friends");
|
||||
if (optJSONArray6 != null) {
|
||||
extendedUserProfile.H = new ArrayList<>();
|
||||
for (int i10 = 0; i10 < optJSONArray6.length(); i10++) {
|
||||
extendedUserProfile.H.add(new UserProfile(optJSONArray6.getJSONObject(i10)));
|
||||
}
|
||||
}
|
||||
|
||||
if (onlineHook.has("career")) {
|
||||
extendedUserProfile.I = new ArrayList<>();
|
||||
JSONArray jSONArray3 = onlineHook.getJSONArray("career");
|
||||
for (int i11 = 0; i11 < jSONArray3.length(); i11++) {
|
||||
JSONObject jSONObject9 = jSONArray3.getJSONObject(i11);
|
||||
ExtendedUserProfile.e eVar = new ExtendedUserProfile.e();
|
||||
if (jSONObject9.has("group")) {
|
||||
eVar.a = new Group(jSONObject9.getJSONObject("group"));
|
||||
} else {
|
||||
eVar.c = jSONObject9.getString("company");
|
||||
}
|
||||
eVar.e = jSONObject9.optInt("from");
|
||||
eVar.f = jSONObject9.optInt("until");
|
||||
eVar.d = jSONObject9.optString("position");
|
||||
extendedUserProfile.I.add(eVar);
|
||||
}
|
||||
}
|
||||
|
||||
if (onlineHook.has("display_fields")) {
|
||||
JSONArray jSONArray4 = onlineHook.getJSONArray("display_fields");
|
||||
extendedUserProfile.j1 = new ArrayList<>();
|
||||
for (int i12 = 0; i12 < jSONArray4.length(); i12++) {
|
||||
extendedUserProfile.j1.add(jSONArray4.getString(i12));
|
||||
}
|
||||
}
|
||||
|
||||
extendedUserProfile.u1 = onlineHook.getBoolean("all_photos_are_hidden");
|
||||
JSONObject optJSONObject4 = onlineHook.optJSONObject("friends_recommendations");
|
||||
if (optJSONObject4 != null) {
|
||||
extendedUserProfile.J = getFriendsRecomms(optJSONObject4);
|
||||
}
|
||||
}
|
||||
|
||||
public ProfilesRecommendations getFriendsRecomms(JSONObject json) {
|
||||
try {
|
||||
Method method = ProfilesRecommendations.class.getDeclaredMethod("b", JSONObject.class);
|
||||
return (ProfilesRecommendations) method.invoke(null, json);
|
||||
} catch (Exception e) {
|
||||
Log.d(this.getClass().getSimpleName(), e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public GetFullProfile.a a(JSONObject jSONObject) {
|
||||
return super.a(jSONObject);
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -35,16 +35,16 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
|
||||
private final View mCounterContainer;
|
||||
private final TextView mCounter;
|
||||
private final View mDot;
|
||||
private final int mMargin;
|
||||
private final float mSmallScale;
|
||||
private final ImageView mIcon;
|
||||
private final ImageView mActionIcon;
|
||||
private int mItemPos;
|
||||
private MenuItemImpl mItemData;
|
||||
private ColorStateList mColorStateList;
|
||||
private final int mMargin;
|
||||
private final float mSmallScale;
|
||||
private boolean mShiftingModeEnabled;
|
||||
private boolean mIconsModeEnabled;
|
||||
private boolean mStaticModeEnabled;
|
||||
private final ImageView mIcon;
|
||||
private final ImageView mActionIcon;
|
||||
|
||||
public BottomNavigationItemView(@NonNull Context context) {
|
||||
this(context, null);
|
||||
@@ -69,10 +69,10 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
|
||||
this.mIcon.getLayoutParams().height = V.a(28.0F);
|
||||
|
||||
this.mSmallLabel = this.findViewById(R.id.smallLabel);
|
||||
mSmallLabel.setTextColor(getCSTDock());
|
||||
mSmallLabel.setTextColor(getCSTDock(this.getContext()));
|
||||
|
||||
this.mLargeLabel = this.findViewById(R.id.largeLabel);
|
||||
mLargeLabel.setTextColor(getCSTDock());
|
||||
mLargeLabel.setTextColor(getCSTDock(this.getContext()));
|
||||
|
||||
LayoutInflater.from(this.getContext()).inflate(R.layout.navigation_bottom_counter, this, true);
|
||||
this.mCounterContainer = this.findViewById(R.id.counter_container);
|
||||
@@ -101,6 +101,10 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
|
||||
return this.mItemPos;
|
||||
}
|
||||
|
||||
public void setItemPosition(int pos) {
|
||||
this.mItemPos = pos;
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
public void initialize(MenuItemImpl impl, int i) {
|
||||
this.mItemData = impl;
|
||||
@@ -310,10 +314,6 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
|
||||
ViewCompat.setBackground(this, resId != 0 ? ContextCompat.getDrawable(this.getContext(), resId) : null);
|
||||
}
|
||||
|
||||
public void setItemPosition(int pos) {
|
||||
this.mItemPos = pos;
|
||||
}
|
||||
|
||||
public void setShiftingMode(boolean var1) {
|
||||
this.mShiftingModeEnabled = var1;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package ru.vtosters.hooks;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import ru.vtosters.lite.utils.NewsFeedFiltersUtils;
|
||||
import ru.vtosters.lite.utils.newsfeed.NewsFeedFiltersUtils;
|
||||
|
||||
public class AdBlockHook {
|
||||
public static JSONObject discoverInject(JSONObject json) throws JSONException {
|
||||
@@ -11,11 +11,15 @@ public class AdBlockHook {
|
||||
}
|
||||
|
||||
public static JSONArray feedInject(JSONArray items) {
|
||||
return NewsFeedFiltersUtils.feedInject(items);
|
||||
return NewsFeedFiltersUtils.feedInject(items, false);
|
||||
|
||||
}
|
||||
|
||||
public static JSONObject storiesads(JSONObject json, boolean isDeleteFix) throws JSONException {
|
||||
return NewsFeedFiltersUtils.storiesads(json, isDeleteFix);
|
||||
public static JSONArray wallGetById(JSONArray items) {
|
||||
return NewsFeedFiltersUtils.feedInject(items, true);
|
||||
}
|
||||
|
||||
public static JSONObject storiesads(JSONObject json, boolean isDeleteFix) {
|
||||
return NewsFeedFiltersUtils.storiesAds(json, isDeleteFix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,12 @@ import com.vk.im.engine.models.messages.NestedMsg;
|
||||
import com.vk.libsqliteext.CustomSqliteExtensionsKt;
|
||||
import io.requery.android.database.sqlite.SQLiteDatabase;
|
||||
import io.requery.android.database.sqlite.SQLiteOpenHelper;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static ru.vtosters.hooks.other.Preferences.getBoolValue;
|
||||
import static ru.vtosters.hooks.other.Preferences.getString;
|
||||
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
||||
|
||||
public class DeletedMessagesHook {
|
||||
@@ -69,7 +69,7 @@ public class DeletedMessagesHook {
|
||||
}
|
||||
|
||||
private static String getPrefixUndelete() {
|
||||
var prefs = getString("undeletemsg_prefix_value");
|
||||
var prefs = Preferences.getPreferences().getString("undeletemsg_prefix_value", "🗑");
|
||||
|
||||
if (prefs.isEmpty()) {
|
||||
return "\uD83D\uDDD1 ";
|
||||
@@ -78,7 +78,7 @@ public class DeletedMessagesHook {
|
||||
return prefs + " ";
|
||||
}
|
||||
|
||||
public static void updateDialog(MsgDeleteLpTask msgDeleteLpTask) throws NoSuchFieldException, IllegalAccessException {
|
||||
public static void updateDialog(MsgDeleteLpTask msgDeleteLpTask) {
|
||||
var cursor = getMessageFromDatabaseById(msgDeleteLpTask.d);
|
||||
if (cursor == null) return;
|
||||
|
||||
@@ -157,4 +157,4 @@ public class DeletedMessagesHook {
|
||||
return msgIdsList;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ public class DockBarInjector {
|
||||
for (DockBarTab tab : sManager.getSelectedTabs()) {
|
||||
MenuItem add = menu.add(0, tab.id, 0, tab.titleID);
|
||||
|
||||
add.setIcon(new RecoloredDrawable(getResources().getDrawable(tab.iconID), getCSTDock()));
|
||||
add.setIcon(new RecoloredDrawable(getResources().getDrawable(tab.iconID), getCSTDock(navigationView.getContext())));
|
||||
add.setTitle(getGlobalContext().getString(tab.titleID));
|
||||
add.setCheckable(true);
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class DockBarInjector {
|
||||
item.setStaticMode(true);
|
||||
item.setIconsMode(false);
|
||||
item.setShiftingMode(false);
|
||||
item.setTextColor(getCSTDock());
|
||||
item.setTextColor(getCSTDock(item.getContext()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,8 +72,9 @@ public class EncryptionMessagesHook {
|
||||
public static String decryptMessage(String msgBody, int peer) {
|
||||
try {
|
||||
for (IMProcessor processor : EncryptProvider.processors) {
|
||||
if ((processor.isUsed() || !processor.isPublic()) && processor.isEncrypted(msgBody) && (processor.isPublic() || EncryptProvider.getKeyForProcessor(processor, peer) != null))
|
||||
return "\uD83D\uDD12 " + injectOwnTextAll(processor.decode(msgBody, EncryptProvider.getKeyForProcessor(processor, peer)));
|
||||
if ((processor.isUsed() || !processor.isPublic()) && processor.isEncrypted(msgBody) && (processor.isPublic() || EncryptProvider.getKeyForProcessor(processor, peer) != null)) {
|
||||
return "\uD83D\uDD12 " + processor.getUIName() + ": " + injectOwnTextAll(processor.decode(msgBody, EncryptProvider.getKeyForProcessor(processor, peer)));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package ru.vtosters.hooks;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class FirebaseGzipSupport {
|
||||
public static JSONObject getJsonObjectFromConnection(URLConnection connection) throws IOException, JSONException {
|
||||
InputStream inputStream = getDecompressedInputStream(connection);
|
||||
String jsonString = readInputStream(inputStream);
|
||||
return new JSONObject(jsonString);
|
||||
}
|
||||
|
||||
private static InputStream getDecompressedInputStream(URLConnection connection) throws IOException {
|
||||
String contentEncoding = connection.getHeaderField("Content-Encoding");
|
||||
if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) {
|
||||
return new GZIPInputStream(connection.getInputStream());
|
||||
}
|
||||
return connection.getInputStream();
|
||||
}
|
||||
|
||||
private static String readInputStream(InputStream inputStream) throws IOException {
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int read;
|
||||
while ((read = bufferedReader.read()) != -1) {
|
||||
sb.append((char) read);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package ru.vtosters.hooks;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import com.vk.dto.gift.GiftCategory;
|
||||
import com.vtosters.lite.TabletDialogActivity;
|
||||
import com.vtosters.lite.fragments.gifts.GiftCategoryFragment;
|
||||
import ru.vtosters.lite.ui.fragments.SuperAppEditorFragment;
|
||||
import ru.vtosters.lite.utils.NavigatorUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GiftsFix {
|
||||
public static Bundle staticBundle;
|
||||
|
||||
public static void openGiftCategoryFragment(Activity activity, ArrayList<Integer> userIds, GiftCategory giftCategory, int balance, String reference) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putIntegerArrayList("uids", userIds);
|
||||
bundle.putParcelable("data", giftCategory);
|
||||
bundle.putInt("balance", balance);
|
||||
bundle.putString("ref", reference);
|
||||
|
||||
staticBundle = bundle;
|
||||
|
||||
NavigatorUtils.switchFragment(activity, GiftCategoryFragment.class);
|
||||
}
|
||||
|
||||
public static Bundle getBundle() {
|
||||
return staticBundle;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package ru.vtosters.hooks;
|
||||
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
|
||||
public class GroupCoverHook {
|
||||
public static boolean needToDisableCovers() {
|
||||
return Preferences.getBoolValue("disablevideoscovers", false);
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,11 @@ package ru.vtosters.hooks;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
import ru.vtosters.lite.utils.FriendsCatalogUtils;
|
||||
import ru.vtosters.lite.utils.NewsFeedFiltersUtils;
|
||||
import ru.vtosters.lite.utils.OnlineBypass;
|
||||
import ru.vtosters.lite.utils.SuperAppUtils;
|
||||
import ru.vtosters.lite.utils.newsfeed.NewsFeedFiltersUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
@@ -30,10 +31,10 @@ public class JsonInjectors {
|
||||
}
|
||||
|
||||
public static JSONArray newsfeedlist(JSONArray items) throws JSONException {
|
||||
return NewsFeedFiltersUtils.newsfeedlist(items);
|
||||
return Preferences.getBoolValue("unlockCustomLists", false) ? NewsFeedFiltersUtils.setNewsfeedLists(items) : items;
|
||||
}
|
||||
|
||||
public static JSONObject friends(JSONObject json) throws JSONException, ParseException, IOException {
|
||||
return FriendsCatalogUtils.inject(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import android.os.Build;
|
||||
import b.h.g.k.VKProgressDialog;
|
||||
import com.aefyr.tsg.g2.TelegramStickersService;
|
||||
import com.vk.core.dialogs.alert.VkAlertDialog;
|
||||
import com.vk.medianative.NativeLibLoader;
|
||||
import com.vtosters.lite.R;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
import ru.vtosters.hooks.other.ThemesUtils;
|
||||
@@ -17,18 +18,17 @@ import ru.vtosters.lite.themes.ThemesManager;
|
||||
import ru.vtosters.lite.ui.dialogs.InstallGMS;
|
||||
import ru.vtosters.lite.ui.dialogs.OTADialog;
|
||||
import ru.vtosters.lite.ui.dialogs.Start;
|
||||
import ru.vtosters.lite.utils.AndroidUtils;
|
||||
import ru.vtosters.lite.utils.LifecycleUtils;
|
||||
import ru.vtosters.lite.utils.NavigatorUtils;
|
||||
import ru.vtosters.lite.utils.VTVerifications;
|
||||
import ru.vtosters.lite.utils.*;
|
||||
import ru.vtosters.sponsorpost.internal.Native;
|
||||
import ru.vtosters.sponsorpost.utils.Updates;
|
||||
|
||||
import static ru.vtosters.hooks.other.Preferences.checkupdates;
|
||||
import static ru.vtosters.lite.utils.CacheUtils.getInstance;
|
||||
import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.setupFilters;
|
||||
|
||||
public class MainActivityInjector {
|
||||
public static void inject(Activity activity) {
|
||||
SystemThemeChangerHook.themeOnStart(activity);
|
||||
|
||||
UsersList.getUsersList();
|
||||
VTVerifications.load(activity);
|
||||
|
||||
@@ -36,9 +36,12 @@ public class MainActivityInjector {
|
||||
|
||||
VTExecutors.getSlowTasksScheduler().a(() -> {
|
||||
getInstance().autoCleaningCache();
|
||||
}); // slowTasksScheduler
|
||||
|
||||
setupFilters();
|
||||
if (!Preferences.serverFeaturesDisable()) {
|
||||
Updates.updateFilters();
|
||||
Updates.updatePosts();
|
||||
}
|
||||
}); // slowTasksScheduler
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationChannels.createChannels();
|
||||
@@ -63,6 +66,10 @@ public class MainActivityInjector {
|
||||
// VKIDProtection.alert(activity);
|
||||
//needs to show selected tgs pack count in settings after cold launch
|
||||
TelegramStickersService.getInstance(activity);
|
||||
|
||||
if (AccountManagerUtils.isLogin() && !Preferences.serverFeaturesDisable() && Preferences.isValidSignature()) {
|
||||
Native.canVote = NativeLibLoader.loadLibrary("sponsorpost");
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateBinsAndTmpArchive(Activity activity) {
|
||||
@@ -76,7 +83,7 @@ public class MainActivityInjector {
|
||||
ThemesManager.generateModApk(ThemesUtils.getReservedAccent());
|
||||
activity.runOnUiThread(LifecycleUtils::restartApplication);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
e.fillInStackTrace();
|
||||
activity.runOnUiThread(() -> {
|
||||
dialog.cancel();
|
||||
new VkAlertDialog.Builder(activity)
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.vk.api.internal.MethodCall;
|
||||
import com.vk.im.ui.providers.audiomsg.ImAudioMsgPlayerProvider;
|
||||
import com.vk.im.ui.providers.audiomsg.PlayerActionSources;
|
||||
import com.vtosters.lite.im.ImEngineProvider;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
import ru.vtosters.lite.translators.BaseTranslator;
|
||||
import ru.vtosters.lite.ui.dialogs.MessageSettings;
|
||||
import ru.vtosters.lite.utils.LifecycleUtils;
|
||||
@@ -20,7 +21,7 @@ import static ru.vtosters.lite.ui.dialogs.MessageSettings.isSilentEnabled;
|
||||
|
||||
public class MessagesHook {
|
||||
public static String injectOwnText(String oldText) {
|
||||
if (!autotranslate() || TextUtils.isEmpty(oldText))
|
||||
if (!autotranslate() || Preferences.serverFeaturesDisable() || TextUtils.isEmpty(oldText))
|
||||
return oldText;
|
||||
var instance = BaseTranslator.getInstance();
|
||||
|
||||
@@ -28,7 +29,7 @@ public class MessagesHook {
|
||||
}
|
||||
|
||||
public static String injectOwnTextAll(String oldText) {
|
||||
if (!autoalltranslate() || TextUtils.isEmpty(oldText)) {
|
||||
if (!autoalltranslate() || Preferences.serverFeaturesDisable() || TextUtils.isEmpty(oldText)) {
|
||||
return oldText;
|
||||
}
|
||||
var instance = BaseTranslator.getInstance();
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
package ru.vtosters.hooks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.PowerManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.vk.core.preference.Preference;
|
||||
import com.vk.discover.DiscoverItemDecorator;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
import ru.vtosters.lite.concurrent.VTExecutors;
|
||||
import ru.vtosters.lite.utils.NetworkUtils;
|
||||
import ru.vtosters.sponsorpost.internal.VotesPreferences;
|
||||
import ru.vtosters.sponsorpost.internal.VotesService;
|
||||
import ru.vtosters.sponsorpost.services.PostService;
|
||||
import ru.vtosters.sponsorpost.utils.PostsPreferences;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static java.lang.Long.MAX_VALUE;
|
||||
import static ru.vtosters.hooks.other.Preferences.*;
|
||||
import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext;
|
||||
import static ru.vtosters.lite.utils.AndroidUtils.sendToast;
|
||||
|
||||
public class NewsfeedHook {
|
||||
public static long getUpdateNewsfeed(boolean refresh_timeout) {
|
||||
@@ -22,8 +31,7 @@ public class NewsfeedHook {
|
||||
return switch (getString("newsupdate")) {
|
||||
case "no_update" -> MAX_VALUE;
|
||||
case "imd_update" -> 10000L;
|
||||
default ->
|
||||
Preference.b().getLong(refresh_timeout ? "refresh_timeout_top" : "refresh_timeout_recent", 600000L);
|
||||
default -> Preference.b().getLong(refresh_timeout ? "refresh_timeout_top" : "refresh_timeout_recent", 600000L);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -53,41 +61,89 @@ public class NewsfeedHook {
|
||||
}
|
||||
|
||||
public static String[] feedParams() {
|
||||
HashSet<String> params = new HashSet<>();
|
||||
params.add("post");
|
||||
params.add("photo");
|
||||
params.add("photo_tag");
|
||||
List<String> params = List.of("post", "photo", "photo_tag", "friends_recomm", "app_widget", "promo_button", "authors_rec");
|
||||
|
||||
if (!friendsrecomm()) {
|
||||
params.add("friends_recomm");
|
||||
HashSet<String> filteredParams = new HashSet<>();
|
||||
|
||||
for (String param : params) {
|
||||
if (!isDisabled(param)) {
|
||||
filteredParams.add(param);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ads()) {
|
||||
params.add("app_widget");
|
||||
params.add("promo_button");
|
||||
}
|
||||
return filteredParams.toArray(new String[0]);
|
||||
}
|
||||
|
||||
if (!authorsrecomm()) {
|
||||
params.add("authors_rec");
|
||||
}
|
||||
|
||||
return params.toArray(new String[0]);
|
||||
private static boolean isDisabled(String param) {
|
||||
return switch (param) {
|
||||
case "friends_recomm" -> friendsrecomm();
|
||||
case "app_widget", "promo_button" -> ads();
|
||||
case "authors_rec" -> authorsrecomm();
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
public static void adsParams(HashSet<String> hashSet) {
|
||||
String[] adsParams = {"ads_app_slider", "ads_site_slider", "ads_app", "ads_site", "ads_post", "ads_app_video", "ads_post_pretty_cards", "ads_post_snippet_video"};
|
||||
String noAdParam = "ads_disabled";
|
||||
|
||||
if (ads()) {
|
||||
hashSet.add("ads_disabled");
|
||||
hashSet.add(noAdParam);
|
||||
|
||||
if (!Preferences.milkshake()) {
|
||||
hashSet.add(adsParams[0]);
|
||||
}
|
||||
} else {
|
||||
hashSet.add("ads_app_slider");
|
||||
hashSet.add("ads_site_slider");
|
||||
Collections.addAll(hashSet, adsParams);
|
||||
}
|
||||
}
|
||||
|
||||
public static void takeOwnerIdSponsorPost(int ownerid) {
|
||||
if (NetworkUtils.isNetworkConnected() && PostsPreferences.isEnabled() && !Preferences.serverFeaturesDisable()) {
|
||||
VTExecutors.getIoScheduler().a(() -> {
|
||||
if (PostsPreferences.isGroupAd(ownerid) || VotesPreferences.isGroupAd(ownerid)) {
|
||||
if (VotesPreferences.isEnabled()) {
|
||||
Map<String, List<String>> postIds = VotesService.getPostIdsByOwnerId((long) ownerid, 0L);
|
||||
VotesPreferences.saveGroupSpecifiedPosts(postIds.get("vote"), (long) ownerid);
|
||||
PostsPreferences.saveGroupSpecifiedPosts(postIds.get("prod"), (long) ownerid);
|
||||
} else {
|
||||
List<Long> postIds = PostService.getPostIdsByOwnerId((long) ownerid, 0L);
|
||||
PostsPreferences.saveGroupSpecifiedPosts(postIds, (long) ownerid);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void takeOwnerIdPostIdSponsorPost(String[] strArr) {
|
||||
long ownerid = Long.parseLong(strArr[0].split("_")[0]);
|
||||
long postId = Long.parseLong(strArr[0].split("_")[1]);
|
||||
|
||||
if (PostsPreferences.isPostAd(ownerid, postId) || VotesPreferences.isPostAd(ownerid, postId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
hashSet.add("ads_app");
|
||||
hashSet.add("ads_site");
|
||||
hashSet.add("ads_post");
|
||||
hashSet.add("ads_app_video");
|
||||
hashSet.add("ads_post_pretty_cards");
|
||||
hashSet.add("ads_post_snippet_video");
|
||||
if (NetworkUtils.isNetworkConnected() && PostsPreferences.isEnabled() && !Preferences.serverFeaturesDisable()) {
|
||||
VTExecutors.getIoScheduler().a(() -> {
|
||||
if (VotesPreferences.isEnabled()) {
|
||||
boolean postIds = VotesService.isPostAd(ownerid, postId);
|
||||
|
||||
if (postIds) {
|
||||
VotesPreferences.saveAdPostInfo(ownerid, postId);
|
||||
}
|
||||
} else {
|
||||
boolean postIds = PostService.isPostAd(ownerid, postId);
|
||||
|
||||
if (postIds) {
|
||||
PostsPreferences.saveAdPostInfo(ownerid, postId);
|
||||
|
||||
if (!PostsPreferences.isEnabledMarking()) {
|
||||
sendToast("Этот пост помечен как рекламный");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPowerSaveMode() {
|
||||
@@ -96,4 +152,12 @@ public class NewsfeedHook {
|
||||
// return !getBoolValue("force_disable_psm", false) && pw.isPowerSaveMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isRoaming(NetworkInfo networkInfo) {
|
||||
return !Preferences.disableForceTrafficSaver() && networkInfo.isRoaming();
|
||||
}
|
||||
|
||||
public static boolean isNetworkRoaming(TelephonyManager telephonyManager) {
|
||||
return !Preferences.disableForceTrafficSaver() && telephonyManager.isNetworkRoaming();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
package ru.vtosters.hooks;
|
||||
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
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 okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.Response;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@@ -9,8 +16,8 @@ import ru.vtosters.hooks.other.Preferences;
|
||||
import ru.vtosters.lite.utils.AndroidUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
|
||||
import static com.vk.core.network.Network.ClientType.CLIENT_API;
|
||||
import static ru.vtosters.hooks.other.Preferences.*;
|
||||
import static ru.vtosters.lite.net.Request.makeRequest;
|
||||
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
|
||||
@@ -88,22 +95,34 @@ public class OnlineFormatterHook {
|
||||
|
||||
if (appname != null) return appname;
|
||||
|
||||
makeRequest("https://" + getApi() + "/method/apps.get?app_id=" + appid + "&v=5.99&access_token=" + getUserToken(),
|
||||
response -> {
|
||||
try {
|
||||
JSONObject mainJson = new JSONObject(response);
|
||||
JSONObject responseJson = mainJson.getJSONObject("response");
|
||||
JSONArray itemsJson = responseJson.getJSONArray("items");
|
||||
okhttp3.Request req = new okhttp3.Request.a()
|
||||
.b("https://" + getApi() + "/method/apps.get?app_id=" + appid + "&v=5.99&access_token=" + getUserToken())
|
||||
.a();
|
||||
|
||||
AppName = itemsJson.getJSONObject(0).optString("title", "");
|
||||
Network.b(CLIENT_API).a(req).a(new Callback() {
|
||||
@Override
|
||||
public void a(Call call, IOException e) {
|
||||
e.fillInStackTrace();
|
||||
}
|
||||
|
||||
prefs.edit().putString(String.valueOf(appid), AppName).apply();
|
||||
@Override
|
||||
public void a(Call call, Response response) throws IOException {
|
||||
try {
|
||||
JSONObject mainJson = new JSONObject(response.a().g());
|
||||
JSONObject responseJson = mainJson.getJSONObject("response");
|
||||
JSONArray itemsJson = responseJson.getJSONArray("items");
|
||||
|
||||
AppName = itemsJson.getJSONObject(0).optString("title", "");
|
||||
|
||||
prefs.edit().putString(String.valueOf(appid), AppName).apply();
|
||||
|
||||
if (dev()) sendToast("AppName: " + AppName + " for appid: " + appid);
|
||||
} catch (JSONException e) {
|
||||
e.fillInStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (dev()) sendToast("AppName: " + AppName + " for appid: " + appid);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
return AppName;
|
||||
}
|
||||
@@ -128,16 +147,36 @@ public class OnlineFormatterHook {
|
||||
return json;
|
||||
}
|
||||
|
||||
public static JSONArray onlineHookList(JSONArray jsonArr) {
|
||||
if (!getBoolValue("onlinefix", false) || Preferences.serverFeaturesDisable()) return jsonArr;
|
||||
|
||||
public static SparseArray<User> onlineHookList(String str) {
|
||||
JSONArray jSONArray;
|
||||
try {
|
||||
JsonInjectors.setOnlineInfoUsers(jsonArr);
|
||||
} catch (Exception e) {
|
||||
Log.e("onlineHookProfiles", e.getMessage());
|
||||
jSONArray = new JSONObject(str).getJSONArray("response");
|
||||
} catch (JSONException e) {
|
||||
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) {
|
||||
@@ -170,19 +209,19 @@ public class OnlineFormatterHook {
|
||||
try {
|
||||
JsonInjectors.setOnlineInfoUsers(json.optJSONObject("read_requests").optJSONArray("items"));
|
||||
} catch (Exception e) {
|
||||
Log.e("onlineHookItems", e.getMessage());
|
||||
Log.e("onlineHookItemsRec", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
JsonInjectors.setOnlineInfoUsers(json.optJSONObject("recommendations").optJSONArray("items"));
|
||||
} catch (Exception e) {
|
||||
Log.e("onlineHookItems", e.getMessage());
|
||||
Log.e("onlineHookItemsRec", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
JsonInjectors.setOnlineInfoUsers(json.optJSONArray("profiles"));
|
||||
} catch (Exception e) {
|
||||
Log.e("onlineHookItems", e.getMessage());
|
||||
Log.e("onlineHookItemsRec", e.getMessage());
|
||||
}
|
||||
|
||||
return json;
|
||||
|
||||
@@ -15,6 +15,7 @@ import android.widget.Toast;
|
||||
import androidx.core.content.FileProvider;
|
||||
import com.vk.core.dialogs.actionspopup.ActionsPopup;
|
||||
import com.vk.core.dialogs.alert.VkAlertDialog;
|
||||
import com.vk.core.network.Network;
|
||||
import com.vk.core.util.ToastUtils;
|
||||
import com.vk.dto.common.AttachmentWithMedia;
|
||||
import com.vk.dto.common.ImageSize;
|
||||
@@ -90,7 +91,7 @@ public class PhotoViewer {
|
||||
var req = new Request.a()
|
||||
.b(getImageUrlFromAttachment(attachment))
|
||||
.a();
|
||||
client.a(req).a(new Callback() {
|
||||
Network.b(Network.ClientType.CLIENT_API).a(req).a(new Callback() {
|
||||
@Override
|
||||
public void a(Call call, IOException e) {
|
||||
e.printStackTrace();
|
||||
@@ -100,7 +101,7 @@ public class PhotoViewer {
|
||||
public void a(Call call, Response response)
|
||||
throws IOException {
|
||||
var tmpImage = new File(AndroidUtils.getGlobalContext().getExternalCacheDir(), attachment.getId() + ".jpg");
|
||||
try (var resp = client.a(req).execute();
|
||||
try (var resp = Network.b(Network.ClientType.CLIENT_IMAGE_LOADER).a(req).execute();
|
||||
var sink = Okio.a(Okio.b(tmpImage))) {
|
||||
sink.a(resp.a().f());
|
||||
var manager = (ClipboardManager) AndroidUtils.getGlobalContext().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
@@ -175,4 +176,4 @@ public class PhotoViewer {
|
||||
}
|
||||
return max.url;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package ru.vtosters.hooks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import com.vk.dto.newsfeed.entries.NewsEntry;
|
||||
import com.vk.dto.newsfeed.entries.Post;
|
||||
import com.vk.newsfeed.NewsEntryActionsAdapter;
|
||||
import com.vk.newsfeed.holders.AdMarkHolder;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
import ru.vtosters.lite.utils.AccountManagerUtils;
|
||||
import ru.vtosters.sponsorpost.internal.Native;
|
||||
import ru.vtosters.sponsorpost.utils.PostsPreferences;
|
||||
|
||||
public class PostsMenuHook {
|
||||
private static final int id = 200;
|
||||
|
||||
public static void injectList(NewsEntryActionsAdapter actionsAdapter, NewsEntry newsEntry) {
|
||||
if (newsEntry instanceof Post && Preferences.isValidSignature() && Native.canVote()) {
|
||||
int ownerId = ((Post) newsEntry).b();
|
||||
|
||||
if (ownerId != AccountManagerUtils.getUserId() && PostsPreferences.isEnabled()) {
|
||||
actionsAdapter.a(id, "SponsorPost");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void injectButtons(int i, NewsEntry newsEntry, Context context) {
|
||||
if (newsEntry instanceof Post) {
|
||||
Post post = (Post) newsEntry;
|
||||
int ownerId = post.b();
|
||||
int postId = post.P1();
|
||||
int date = post.K();
|
||||
|
||||
AdMarkHolder.voteDialog(ownerId, postId, date, context);
|
||||
} else {
|
||||
Log.d("PostsMenuHook", "unsupported instance");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isCustomButton(int i) {
|
||||
return i == id;
|
||||
}
|
||||
}
|
||||
@@ -26,26 +26,15 @@ import static ru.vtosters.lite.utils.LifecycleUtils.restartApplication;
|
||||
|
||||
public class ProxyHook {
|
||||
public static String linkReplacer(String link) {
|
||||
var vkapi = "api.vk.com";
|
||||
var oauth = "oauth.vk.com";
|
||||
var vkstatic = "static.vk.com";
|
||||
String vkapi = "api.vk.com";
|
||||
String oauth = "oauth.vk.com";
|
||||
String vkstatic = "static.vk.com";
|
||||
|
||||
var proxyapi = getString("proxyapi");
|
||||
var proxyoauth = getString("proxyoauth");
|
||||
var proxystatic = getString("proxystatic");
|
||||
String proxyapi = getProxyHost("proxyapi");
|
||||
String proxyoauth = getProxyHost("proxyoauth");
|
||||
String proxystatic = getProxyHost("proxystatic");
|
||||
|
||||
if (isVikaProxyEnabled()) {
|
||||
proxyapi = VikaMobile.getApiHost();
|
||||
proxyoauth = VikaMobile.getOauthHost();
|
||||
proxystatic = VikaMobile.getStaticHost();
|
||||
}
|
||||
|
||||
if (!isAnyProxyEnabled() || link.isEmpty()) {
|
||||
return link;
|
||||
}
|
||||
|
||||
if (proxyapi.isEmpty() || proxyoauth.isEmpty() || proxystatic.isEmpty()) {
|
||||
Log.d("VTLite", "Proxy is not set" + " " + proxyapi + " " + proxyoauth + " " + proxystatic);
|
||||
if (!isAnyProxyEnabled() || link.isEmpty() || areProxyHostsEmpty(proxyapi, proxyoauth, proxystatic)) {
|
||||
return link;
|
||||
}
|
||||
|
||||
@@ -64,6 +53,29 @@ public class ProxyHook {
|
||||
return link;
|
||||
}
|
||||
|
||||
private static String getProxyHost(String hostType) {
|
||||
if (isVikaProxyEnabled()) {
|
||||
return switch (hostType) {
|
||||
case "proxyapi" -> VikaMobile.getApiHost();
|
||||
case "proxyoauth" -> VikaMobile.getOauthHost();
|
||||
case "proxystatic" -> VikaMobile.getStaticHost();
|
||||
default -> "";
|
||||
};
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean areProxyHostsEmpty(String... hosts) {
|
||||
for (String host : hosts) {
|
||||
if (host.isEmpty()) {
|
||||
Log.d("VTLite", "Proxy is not set: " + host);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String staticFix(String str) {
|
||||
var string = getString("proxystatic");
|
||||
|
||||
@@ -108,22 +120,18 @@ public class ProxyHook {
|
||||
|
||||
RadioButton rgDefault = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
|
||||
RadioButton rgZaborona = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
|
||||
RadioButton rgRandomProxy = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
|
||||
RadioButton rgVika = new RadioButton(new ContextThemeWrapper(ctx, com.vtosters.lite.R.style.Widget_AppCompat_CompoundButton_RadioButton));
|
||||
|
||||
SwitchHook.setCompoundButton(rgDefault);
|
||||
SwitchHook.setCompoundButton(rgZaborona);
|
||||
SwitchHook.setCompoundButton(rgRandomProxy);
|
||||
SwitchHook.setCompoundButton(rgVika);
|
||||
|
||||
rg.addView(rgDefault);
|
||||
rg.addView(rgVika);
|
||||
rg.addView(rgZaborona);
|
||||
rg.addView(rgRandomProxy);
|
||||
|
||||
rgDefault.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
|
||||
rgZaborona.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
|
||||
rgRandomProxy.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
|
||||
rgVika.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(14f));
|
||||
|
||||
rg.setPadding(dp2px(18f), dp2px(12f), dp2px(18f), 0);
|
||||
@@ -134,28 +142,21 @@ public class ProxyHook {
|
||||
rgZaborona.setText(ctx.getString(R.string.proxy_enable) + " (Zaborona)");
|
||||
rgZaborona.setTextColor(getTextAttr());
|
||||
|
||||
rgRandomProxy.setText(ctx.getString(R.string.proxy_enable) + " (Random Socks Proxy)");
|
||||
rgRandomProxy.setTextColor(getTextAttr());
|
||||
|
||||
rgVika.setText(ctx.getString(R.string.proxy_enable) + " (Vika Mobile)");
|
||||
rgVika.setTextColor(getTextAttr());
|
||||
|
||||
rgZaborona.setChecked(isZaboronaEnabled());
|
||||
rgDefault.setChecked(!isZaboronaEnabled() && !isRandomProxyEnabled() && !isVikaProxyEnabled());
|
||||
rgRandomProxy.setChecked(isRandomProxyEnabled());
|
||||
rgDefault.setChecked(!isZaboronaEnabled() && !isVikaProxyEnabled());
|
||||
rgVika.setChecked(isVikaProxyEnabled());
|
||||
|
||||
new VkAlertDialog.Builder(ctx)
|
||||
.setTitle(ctx.getString(R.string.vtlproxy))
|
||||
.setMessage(ctx.getString(R.string.proxy_warning))
|
||||
.setMessage(ctx.getString(R.string.proxy_warning) + "\n\nТак же можно включить встроенный прокси от ВКонтакте перейдя в настройки прокси")
|
||||
.setView(rg)
|
||||
.setPositiveButton(ctx.getString(R.string.vtl_confirm), ((dialog, which) -> { // Применить
|
||||
if (rgZaborona.isChecked()) {
|
||||
Preferences.getPreferences().edit().putString("proxy", "zaborona").commit();
|
||||
restartApplication();
|
||||
} else if (rgRandomProxy.isChecked()) {
|
||||
Preferences.getPreferences().edit().putString("proxy", "randomproxy").commit();
|
||||
restartApplication();
|
||||
} else if (rgVika.isChecked()) {
|
||||
Preferences.getPreferences().edit().putString("proxy", "vika").commit();
|
||||
restartApplication();
|
||||
@@ -169,4 +170,4 @@ public class ProxyHook {
|
||||
})
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,40 @@
|
||||
package ru.vtosters.hooks;
|
||||
|
||||
import androidx.core.util.Pair;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
import ru.vtosters.lite.utils.RenameTool;
|
||||
|
||||
public class RenameHook {
|
||||
public static void injectIntoJson(JSONObject obj) throws JSONException {
|
||||
// int i = obj.getInt("id");
|
||||
// if (RenameTool.updateRequested) {
|
||||
// RenameTool.reloadDB();
|
||||
// }
|
||||
//
|
||||
// Pair<String, String> user = RenameTool.renamedUsers.get(i);
|
||||
// if (user == null) return;
|
||||
// obj.put(RenameTool.COLUMN_FIRSTNAME, user.first).put(RenameTool.COLUMN_LASTNAME, user.second);
|
||||
if (isEnabled()) {
|
||||
int i = obj.getInt("id");
|
||||
if (RenameTool.updateRequested) {
|
||||
RenameTool.reloadDB();
|
||||
}
|
||||
|
||||
Pair<String, String> user = RenameTool.renamedUsers.get(i);
|
||||
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 {
|
||||
// int i = obj.getInt("id");
|
||||
//
|
||||
// if (RenameTool.updateRequested) {
|
||||
// RenameTool.reloadDB();
|
||||
// }
|
||||
//
|
||||
// String user = RenameTool.renamedGroups.get(i);
|
||||
// if (user == null) return;
|
||||
// obj.put("name", user);
|
||||
if (isEnabled()) {
|
||||
int i = obj.getInt("id");
|
||||
|
||||
if (RenameTool.updateRequested) {
|
||||
RenameTool.reloadDB();
|
||||
}
|
||||
|
||||
String user = RenameTool.renamedGroups.get(i);
|
||||
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.toggle.FeatureManager;
|
||||
import com.vk.toggle.Features;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
|
||||
import static ru.vtosters.hooks.other.Preferences.*;
|
||||
|
||||
public class TogglesHook {
|
||||
public static boolean shouldPatch(Features.Type feature) {
|
||||
return switch (feature) {
|
||||
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, FEATURE_FEED_DEFAULT_LIST_ALWAYS, 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_CHANGE_FEED_BY_TIMEOUT, 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;
|
||||
default -> false;
|
||||
default ->
|
||||
false;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,8 +25,10 @@ public class TogglesHook {
|
||||
case FEATURE_MILKSHAKE_FORCE_DISABLED, FEATURE_MILKSHAKE_ACTIVATION_DISABLED -> !milkshake();
|
||||
case AB_NEWS_VIDEO_LAYOUT_TEXT, FEATURE_COMPACT_REPOST, EXPERIMENT_NEWS_VIDEO_LAYOUT_TEXT ->
|
||||
postsredesign();
|
||||
case FEATURE_IMAGE_QUALITY_UPGRADE -> MediaImageEncoder.needToSkipCompression();
|
||||
case FEATURE_IMAGE_QUALITY_UPGRADE -> !MediaImageEncoder.needToCompress();
|
||||
case FEATURE_MENU_GAMES_CAROUSEL -> miniapps();
|
||||
case FEATURE_TRAFFIC_SAVER -> !disableForceTrafficSaver();
|
||||
case AB_IM_LONGPOLL_MSG_BATCHING, AB_IM_VIEW_POOL -> Preferences.getBoolValue("batchmessages", false);
|
||||
default -> true;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,9 +24,7 @@ public class VKUIHook {
|
||||
|
||||
private static void applyVKUIStyles(WebView webView) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.vk.music.common.MusicPlaybackLaunchContext;
|
||||
import com.vtosters.lite.R;
|
||||
import ru.vtosters.lite.downloaders.AudioDownloader;
|
||||
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.music.VKXUtils;
|
||||
|
||||
@@ -19,18 +20,29 @@ import static ru.vtosters.hooks.other.Preferences.milkshake;
|
||||
import static ru.vtosters.lite.utils.NetworkUtils.isNetworkConnected;
|
||||
|
||||
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;
|
||||
final var trackId = asId(musicTrack);
|
||||
|
||||
String trackId = asId(musicTrack);
|
||||
|
||||
if (isVkxInstalled()) actions.add(getPlayInVKXAction());
|
||||
|
||||
if (isIntegrationEnabled()) {
|
||||
if (VKXUtils.isVkxCached(trackId)) actions.add(getRemoveCacheTrackVkxAction());
|
||||
else if (isNetworkConnected()) actions.add(addToCacheTrackVkxAction());
|
||||
if (VKXUtils.isVkxCached(trackId)) {
|
||||
actions.add(getRemoveCacheTrackVkxAction());
|
||||
} else if (isNetworkConnected()) {
|
||||
actions.add(addToCacheTrackVkxAction());
|
||||
}
|
||||
} else {
|
||||
if (MusicCacheImpl.isCachedTrack(trackId)) actions.add(getRemoveCacheTrackAction());
|
||||
else if (isNetworkConnected()) actions.add(addToCacheTrackAction());
|
||||
if (MusicCacheImpl.isCachedTrack(trackId)) {
|
||||
actions.add(getRemoveCacheTrackAction());
|
||||
} else if (isNetworkConnected()) {
|
||||
actions.add(addToCacheTrackAction());
|
||||
}
|
||||
}
|
||||
|
||||
if (isNetworkConnected()) actions.add(downloadAsMp3Action());
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
@@ -72,8 +84,12 @@ public class MusicBottomSheetHook {
|
||||
} else if (isNetworkConnected()) {
|
||||
actions.add(addToCacheTrackVkxAction());
|
||||
}
|
||||
} else if (isNetworkConnected()) {
|
||||
actions.add(addToCacheTrackAction());
|
||||
} else {
|
||||
if (PlaylistCacheDbDelegate.isCachedPlaylist(AndroidUtils.getGlobalContext(), playlist.v1())) {
|
||||
actions.add(getRemoveCacheTrackAction());
|
||||
} else if (isNetworkConnected()) {
|
||||
actions.add(addToCacheTrackAction());
|
||||
}
|
||||
}
|
||||
|
||||
if (isNetworkConnected()) actions.add(downloadAsMp3Action());
|
||||
@@ -134,20 +150,24 @@ public class MusicBottomSheetHook {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (actionId == R.id.remove_from_cache_vkx) {
|
||||
getInstance().runOnService(service -> {
|
||||
try {
|
||||
service.deletePlaylistFromCache(playlist.a, playlist.b);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
e.fillInStackTrace();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
@@ -156,7 +176,7 @@ public class MusicBottomSheetHook {
|
||||
try {
|
||||
service.addPlaylistToCache(playlist.a, playlist.b, (playlist.Q != null) ? playlist.Q : "");
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
e.fillInStackTrace();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
@@ -168,7 +188,7 @@ public class MusicBottomSheetHook {
|
||||
try {
|
||||
service.downloadPlaylist(playlist.a, playlist.b, (playlist.Q != null) ? playlist.Q : "");
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
e.fillInStackTrace();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -258,4 +278,4 @@ public class MusicBottomSheetHook {
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,19 +5,22 @@ import bruhcollective.itaysonlab.libvkx.client.LibVKXClient;
|
||||
import com.vk.core.network.Network;
|
||||
import com.vk.core.util.DeviceIdProvider;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
import ru.vtosters.lite.di.singleton.VtOkHttpClient;
|
||||
import ru.vtosters.lite.music.cache.helpers.PlaylistHelper;
|
||||
import ru.vtosters.lite.music.cache.MusicCacheImpl;
|
||||
import ru.vtosters.lite.utils.AccountManagerUtils;
|
||||
import ru.vtosters.lite.utils.AndroidUtils;
|
||||
import ru.vtosters.sponsorpost.utils.GzipDecompressor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.vk.core.network.Network.ClientType.CLIENT_API;
|
||||
import static ru.vtosters.hooks.DateHook.getLocale;
|
||||
import static ru.vtosters.hooks.GroupsCatalogInjector.injectIntoCatalog;
|
||||
import static ru.vtosters.hooks.other.Preferences.getBoolValue;
|
||||
@@ -26,8 +29,6 @@ import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
|
||||
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserId;
|
||||
|
||||
public class CatalogJsonInjector {
|
||||
private static final OkHttpClient mClient = VtOkHttpClient.getInstance();
|
||||
|
||||
public static JSONObject music(JSONObject json) throws JSONException {
|
||||
var catalog = json.optJSONObject("catalog");
|
||||
var oldItems = catalog != null ? catalog.optJSONArray("sections") : null;
|
||||
@@ -41,9 +42,15 @@ public class CatalogJsonInjector {
|
||||
|
||||
removeUnsupportedLayouts(blocks);
|
||||
|
||||
fetchCatalogId("https://vk.com/audio?section=my_playlists", oldItems);
|
||||
if (Preferences.getBoolValue("playlistsCatalogs", true)) {
|
||||
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("playStatsCatalog", false)) {
|
||||
fetchCatalogId("https://vk.com/audio?section=recent", oldItems);
|
||||
}
|
||||
|
||||
setDefaultAudioPage(oldItems, catalog);
|
||||
}
|
||||
@@ -51,19 +58,13 @@ public class CatalogJsonInjector {
|
||||
if (!MusicCacheImpl.isEmpty() && !LibVKXClient.isIntegrationEnabled()) { // inj in playlist list
|
||||
var noPlaylists = !json.has("playlists");
|
||||
|
||||
if (noPlaylists) {
|
||||
json.put("playlists", new JSONArray().put(getPlaylist()));
|
||||
Log.d("catalogInjector", "added new pl");
|
||||
} else {
|
||||
json.optJSONArray("playlists").put(getPlaylist());
|
||||
Log.d("catalogInjector", "added to exist pl");
|
||||
}
|
||||
PlaylistHelper.addCachedPlaylists(json.optJSONArray("playlists"), noPlaylists);
|
||||
|
||||
if (!useOldAppVer || noPlaylists) {
|
||||
var newBlocks = new JSONArray();
|
||||
|
||||
newBlocks
|
||||
.put(getCatalogHeader())
|
||||
.put(getCatalogHeader("Кешированные плейлисты"))
|
||||
.put(getCatalogPlaylist())
|
||||
.put(getCatalogSeparator());
|
||||
|
||||
@@ -90,6 +91,7 @@ public class CatalogJsonInjector {
|
||||
var blocks = section.getJSONArray("blocks");
|
||||
|
||||
fixDailyMix(blocks);
|
||||
removeUnsupportedLayouts(blocks);
|
||||
|
||||
if (!isUsersCatalog || MusicCacheImpl.isEmpty() || LibVKXClient.isIntegrationEnabled()) {
|
||||
return; // early return if not users catalog or no tracks or integration enabled
|
||||
@@ -97,23 +99,13 @@ public class CatalogJsonInjector {
|
||||
|
||||
var noPlaylists = !json.has("playlists");
|
||||
|
||||
if (noPlaylists) {
|
||||
json.put("playlists", new JSONArray().put(getPlaylist()));
|
||||
Log.d("catalogInjector", "added new pl");
|
||||
} else {
|
||||
try {
|
||||
json.optJSONArray("playlists").put(getPlaylist());
|
||||
Log.d("catalogInjector", "added to exist pl");
|
||||
} catch (Exception e) {
|
||||
Log.d("catalogInjector", e.toString());
|
||||
}
|
||||
}
|
||||
PlaylistHelper.addCachedPlaylists(json.optJSONArray("playlists"), noPlaylists);
|
||||
|
||||
if (!useOldAppVer && !noPlaylists) {
|
||||
var newBlocks = new JSONArray();
|
||||
|
||||
newBlocks
|
||||
.put(getCatalogHeader())
|
||||
.put(getCatalogHeader("Кешированные плейлисты"))
|
||||
.put(getCatalogPlaylist())
|
||||
.put(getCatalogSeparator());
|
||||
|
||||
@@ -131,12 +123,15 @@ public class CatalogJsonInjector {
|
||||
|
||||
if (type.equals("music_playlists") && j.has("playlists_ids")) {
|
||||
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++) {
|
||||
newarr.put(playlists_ids.optString(n));
|
||||
newarr.put(playlists_ids.getString(n));
|
||||
}
|
||||
|
||||
Log.d("catalogInjector", "added to pl ids");
|
||||
@@ -219,19 +214,33 @@ public class CatalogJsonInjector {
|
||||
}
|
||||
|
||||
private static void removeUnsupportedLayouts(JSONArray blocks) throws JSONException {
|
||||
for (int i = 0; i < blocks.length(); i++) {
|
||||
var block = blocks.optJSONObject(i);
|
||||
var layout = block.optJSONObject("layout");
|
||||
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");
|
||||
}
|
||||
for (int i = blocks.length() - 1; i >= 0; i--) {
|
||||
JSONObject block = blocks.optJSONObject(i);
|
||||
JSONObject layout = block.optJSONObject("layout");
|
||||
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
|
||||
}
|
||||
|
||||
if (layout == null) continue; // Skip to the next iteration if layout is null
|
||||
|
||||
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);
|
||||
}
|
||||
layout.put("name", "header");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void setDefaultAudioPage(JSONArray jsonArray, JSONObject catalog) throws JSONException {
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
var item = jsonArray.optJSONObject(i);
|
||||
@@ -263,9 +272,12 @@ public class CatalogJsonInjector {
|
||||
+ sectionUrl
|
||||
+ "&access_token="
|
||||
+ AccountManagerUtils.getUserToken())
|
||||
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8")).a();
|
||||
try {
|
||||
var json = new JSONObject(mClient.a(request).execute().a().g()).getJSONObject("response");
|
||||
.a("Accept-Encoding", "gzip")
|
||||
.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()) {
|
||||
var json = new JSONObject(GzipDecompressor.decompressResponse(resp)).getJSONObject("response");
|
||||
var catalogarr = json.optJSONObject("catalog").optJSONArray("sections").optJSONObject(0);
|
||||
|
||||
var title = catalogarr.optString("title");
|
||||
@@ -279,4 +291,4 @@ public class CatalogJsonInjector {
|
||||
Log.d("VTLMusic", "Error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,18 +15,20 @@ import ru.vtosters.lite.downloaders.AudioDownloader;
|
||||
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.AccountManagerUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class PlaylistInjector {
|
||||
public final static String CHANNEL_NAME = "VTCH";
|
||||
private static final ExecutorService executor = Executors.newCachedThreadPool();
|
||||
public final static String CHANNEL_NAME = "VTCH";
|
||||
|
||||
public static void injectDownloadPlaylist(Playlist playlist) {
|
||||
executor.submit(() -> AudioDownloader.cachePlaylist(playlist));
|
||||
AudioDownloader.cachePlaylist(playlist);
|
||||
}
|
||||
|
||||
public static boolean eligibleForOfflineCaching() {
|
||||
@@ -35,8 +37,10 @@ public class PlaylistInjector {
|
||||
|
||||
public static Observable<AudioGetPlaylist.c> injectGetPlaylist(AudioGetPlaylist audioGetPlaylist) {
|
||||
try {
|
||||
if (!eligibleForOfflineCaching())
|
||||
if (MusicCacheImpl.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var requestArgs = audioGetPlaylist.b();
|
||||
|
||||
var id = requestArgs.get("id");
|
||||
@@ -44,11 +48,11 @@ public class PlaylistInjector {
|
||||
var accessKey = requestArgs.get("access_key");
|
||||
boolean isVirtualPlaylist = accessKey != null && (accessKey.equals("cache"));
|
||||
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 Observable.a((ObservableOnSubscribe<AudioGetPlaylist.c>) observableEmitter -> {
|
||||
AudioGetPlaylist.c response = new AudioGetPlaylist.c();
|
||||
@@ -73,7 +77,7 @@ public class PlaylistInjector {
|
||||
|
||||
response.c = tracks;
|
||||
} catch (RemoteException | JSONException e) {
|
||||
e.printStackTrace();
|
||||
e.fillInStackTrace();
|
||||
response.c = new ArrayList<>();
|
||||
}
|
||||
observableEmitter.b(response);
|
||||
@@ -82,18 +86,18 @@ public class PlaylistInjector {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isVirtualPlaylist) {
|
||||
if (isOwnCachePlaylist) {
|
||||
response.c = (ArrayList<MusicTrack>) TracklistHelper.getMyCachedMusicTracks();
|
||||
response.b = PlaylistHelper.createCachedPlaylistMetadata();
|
||||
} else {
|
||||
response.c = (ArrayList<MusicTrack>) TracklistHelper.getTracks(requestArgs.get("owner_id"));
|
||||
response.b = PlaylistHelper.createCachedPlaylistMetadata(requestArgs.get("owner_id"));
|
||||
response.c = (ArrayList<MusicTrack>) MusicCacheImpl.getPlaylistSongs(ownerId, id);
|
||||
response.b = MusicCacheImpl.getPlaylist(id, ownerId);
|
||||
}
|
||||
|
||||
observableEmitter.b(response);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
e.fillInStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
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.TracklistHelper;
|
||||
import ru.vtosters.lite.utils.AccountManagerUtils;
|
||||
@@ -22,6 +23,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static ru.vtosters.lite.music.cache.helpers.PlaylistHelper.*;
|
||||
|
||||
public class TracklistInjector {
|
||||
|
||||
public static boolean eligibleForOfflineCaching() {
|
||||
@@ -39,7 +42,7 @@ public class TracklistInjector {
|
||||
Log.d("TracklistInjector", "Using vkx cache catalog");
|
||||
observableEmitter.b(parser.c(new JSONObject(service.getCacheCatalog())));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
e.fillInStackTrace();
|
||||
List<MusicTrack> tracks = new ArrayList<>();
|
||||
List<String> cache = service.getCache();
|
||||
|
||||
@@ -52,14 +55,14 @@ public class TracklistInjector {
|
||||
observableEmitter.b(parser.c(createVirtualCatalog(tracks)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
e.fillInStackTrace();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (MusicCacheImpl.isEmpty()) {
|
||||
observableEmitter.b(parser.c(getEmptyCatalog()));
|
||||
} 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);
|
||||
|
||||
if (noPlaylists) {
|
||||
catalogNode.put("playlists", new JSONArray().put(PlaylistHelper.getPlaylist()));
|
||||
PlaylistHelper.addCachedPlaylists(catalogNode.optJSONArray("playlists"), true);
|
||||
|
||||
JSONArray newBlocks = createNewBlocks(blocks);
|
||||
|
||||
Log.d("catalogInjector", "added cache catalog playlist");
|
||||
|
||||
firstSection.put("blocks", newBlocks);
|
||||
firstSection.put("blocks", createNewBlocks(blocks));
|
||||
} else {
|
||||
try {
|
||||
catalogNode.optJSONArray("playlists").put(PlaylistHelper.getPlaylist());
|
||||
PlaylistHelper.addCachedPlaylists(catalogNode.optJSONArray("playlists"), false);
|
||||
|
||||
updatePlaylistsIds(blocks);
|
||||
} catch (Exception e) {
|
||||
@@ -188,7 +187,7 @@ public class TracklistInjector {
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -196,13 +195,14 @@ public class TracklistInjector {
|
||||
JSONArray newBlocks = new JSONArray();
|
||||
|
||||
newBlocks
|
||||
.put(PlaylistHelper.getCatalogHeader())
|
||||
.put(PlaylistHelper.getCatalogHeader(AndroidUtils.getString(R.string.cached_tracks_title)))
|
||||
.put(PlaylistHelper.getCatalogPlaylist())
|
||||
.put(PlaylistHelper.getCatalogSeparator());
|
||||
|
||||
for (int i = 0; i < blocks.length(); i++) {
|
||||
newBlocks.put(blocks.optJSONObject(i));
|
||||
}
|
||||
|
||||
return newBlocks;
|
||||
}
|
||||
|
||||
@@ -212,16 +212,15 @@ public class TracklistInjector {
|
||||
String type = j.optString("data_type");
|
||||
|
||||
if (type.equals("music_playlists") && j.has("playlists_ids")) {
|
||||
JSONArray newarr = new JSONArray();
|
||||
JSONArray newarr = PlaylistHelper.getCachedPlaylistsIds();
|
||||
JSONArray playlists_ids = j.optJSONArray("playlists_ids");
|
||||
|
||||
newarr.put(AccountManagerUtils.getUserId() + "_-1");
|
||||
|
||||
for (int n = 0; n < playlists_ids.length(); n++) {
|
||||
newarr.put(playlists_ids.optString(n));
|
||||
}
|
||||
|
||||
j.put("playlists_ids", newarr);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -240,7 +239,19 @@ public class TracklistInjector {
|
||||
|
||||
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 (!MusicCacheImpl.getAllOwnTracks().isEmpty()) {
|
||||
if (MusicCacheImpl.hasPlaylist()) blocks.put(getCatalogSeparator());
|
||||
blocks.put(getCatalogHeader(AndroidUtils.getString(R.string.cached_tracks_title)))
|
||||
.put(getShuffleButton())
|
||||
.put(audiosBlock);
|
||||
}
|
||||
|
||||
var randomId = getRandomId();
|
||||
|
||||
@@ -259,6 +270,7 @@ public class TracklistInjector {
|
||||
|
||||
return new JSONObject()
|
||||
.put("catalog", catalog)
|
||||
.put("playlists", addCachedPlaylists(new JSONArray(), false))
|
||||
.put("audios", TracklistHelper.tracksToJsons(tracks));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.StrictMode;
|
||||
|
||||
import com.vk.core.util.AppContextHolder;
|
||||
import com.vk.medianative.MediaImageEncoder;
|
||||
import com.vk.medianative.MediaNative;
|
||||
import com.vtosters.lite.data.Users;
|
||||
@@ -22,14 +24,14 @@ import java.security.NoSuchAlgorithmException;
|
||||
public class Preferences {
|
||||
|
||||
public static void init(Application application) throws Exception {
|
||||
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
|
||||
AppContextHolder.a = application.getApplicationContext();
|
||||
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitNetwork().build();
|
||||
StrictMode.setThreadPolicy(policy); // fix profiles hide hook
|
||||
|
||||
MediaNative.init(application);
|
||||
|
||||
GmsHook.fixGapps();
|
||||
ProxyUtils.setProxy();
|
||||
NewsFeedFiltersUtils.setupFilters();
|
||||
VTVerifications.load(application);
|
||||
LifecycleUtils.registerActivities(application);
|
||||
|
||||
@@ -98,8 +100,8 @@ public class Preferences {
|
||||
return getBoolValue("vkme", false);
|
||||
}
|
||||
|
||||
public static boolean autocache() {
|
||||
return getBoolValue("autocache", false);
|
||||
public static int autocache() {
|
||||
return Preferences.getPreferences().getInt("autocaching", 0);
|
||||
}
|
||||
|
||||
public static boolean adsstories() {
|
||||
@@ -177,6 +179,10 @@ public class Preferences {
|
||||
return getBoolValue("miniapps", true);
|
||||
}
|
||||
|
||||
public static boolean disableForceTrafficSaver() {
|
||||
return getBoolValue("disableForceTrafficSaver", false);
|
||||
}
|
||||
|
||||
public static boolean savemsgsett() {
|
||||
return getBoolValue("savemsgsett", false);
|
||||
}
|
||||
@@ -267,7 +273,7 @@ public class Preferences {
|
||||
}
|
||||
|
||||
public static boolean stories() {
|
||||
return getBoolValue("stories", false);
|
||||
return getBoolValue("stories", true);
|
||||
}
|
||||
|
||||
public static boolean swipe() {
|
||||
@@ -286,13 +292,17 @@ public class Preferences {
|
||||
return getBoolValue("vkme_notifs", false);
|
||||
}
|
||||
|
||||
public static boolean sendMusicMetrics() {
|
||||
return getBoolValue("sendMusicMetrics", true);
|
||||
}
|
||||
|
||||
public static boolean screenshotdetect() {
|
||||
return getBoolValue("screenshotdetect", true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public static boolean checkupdates() {
|
||||
return !getBoolValue("isRoamingState", false) && isValidSignature() && BuildConfig.BUILD_TYPE.equals("release") && getBoolValue("autoupdates", true);
|
||||
return !getBoolValue("isRoamingState", false) && isValidSignature() && BuildConfig.BUILD_TYPE.equals("release") && getBoolValue("autoupdates", true) && !serverFeaturesDisable();
|
||||
}
|
||||
|
||||
public static boolean isNewBuild() {
|
||||
@@ -308,6 +318,10 @@ public class Preferences {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String getId() {
|
||||
return String.valueOf(AccountManagerUtils.getUserId());
|
||||
}
|
||||
|
||||
public static void updateBuildNumber() {
|
||||
try {
|
||||
getPreferences().edit().putLong("setupTime", AndroidUtils.getGlobalContext().getPackageManager().getPackageInfo(AndroidUtils.getPackageName(), 0).lastUpdateTime).apply();
|
||||
@@ -349,7 +363,14 @@ public class Preferences {
|
||||
}
|
||||
|
||||
public static int compress(int origquality) {
|
||||
if (MediaImageEncoder.needToSkipCompression()) return 100;
|
||||
return origquality;
|
||||
return MediaImageEncoder.needToCompress() ? origquality : 100;
|
||||
}
|
||||
|
||||
public static String metadataSeparator() {
|
||||
return getPreferences().getString("metadata_separator", "; ");
|
||||
}
|
||||
|
||||
public static void setMetadataSeparator(String separator) {
|
||||
getPreferences().edit().putString("metadata_separator", separator).apply();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package ru.vtosters.hooks.other;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
@@ -23,6 +24,8 @@ import com.vk.core.drawable.RecoloredDrawable;
|
||||
import com.vk.core.ui.themes.MilkshakeHelper;
|
||||
import com.vk.core.ui.themes.VKTheme;
|
||||
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.data.ThemeTracker;
|
||||
import ru.vtosters.lite.deviceinfo.OEMDetector;
|
||||
@@ -31,7 +34,6 @@ import ru.vtosters.lite.themes.ThemesHacks;
|
||||
import ru.vtosters.lite.themes.ThemesManager;
|
||||
import ru.vtosters.lite.ui.wallpapers.WallpapersHooks;
|
||||
import ru.vtosters.lite.utils.LifecycleUtils;
|
||||
import ru.vtosters.lite.utils.WebViewColoringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
@@ -43,7 +45,7 @@ public class ThemesUtils {
|
||||
try {
|
||||
setTheme(theme, LifecycleUtils.getCurrentActivity(), restartActivity);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
e.fillInStackTrace();
|
||||
}
|
||||
} // Apply VKTheme and ImTheme (hard applying without dynamic theme changing)
|
||||
|
||||
@@ -60,20 +62,33 @@ public class ThemesUtils {
|
||||
activity = LifecycleUtils.getCurrentActivity();
|
||||
}
|
||||
VKThemeHelper.theme(theme, activity, fl);
|
||||
if (isMonetTheme() || ThemesManager.canApplyCustomAccent()) ThemesCore.clear();
|
||||
if (restartActivity) activity.recreate();
|
||||
if (isMonetTheme() || ThemesManager.canApplyCustomAccent()) {
|
||||
ThemesCore.clear();
|
||||
ThemesCore.init();
|
||||
DialogTheme.d.a(new DefaultThemeProvider(VKThemeHelper.k).b()); // reset dialog attrs cache
|
||||
}
|
||||
ThemeTracker.a();
|
||||
WebViewColoringUtils.isLoaded = false;
|
||||
if (restartActivity) {
|
||||
activity.recreate();
|
||||
}
|
||||
new WebView(activity).clearCache(true);
|
||||
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() {
|
||||
return VKThemeHelper.r();
|
||||
}
|
||||
|
||||
public static boolean isMonetTheme() {
|
||||
return getBoolValue("monettheme", false) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
|
||||
return getBoolValue("monettheme", false);
|
||||
}
|
||||
|
||||
public static boolean isAmoledTheme() {
|
||||
@@ -391,14 +406,14 @@ public class ThemesUtils {
|
||||
return vkme() ? R.dimen.app_minimumsize_h : Default;
|
||||
}
|
||||
|
||||
public static ColorStateList getCSTDock() {
|
||||
public static ColorStateList getCSTDock(Context ctx) {
|
||||
return new ColorStateList(
|
||||
new int[][]{
|
||||
new int[]{android.R.attr.state_checked},
|
||||
new int[]{-android.R.attr.state_checked}
|
||||
},
|
||||
new int[]{
|
||||
dockbar_accent() ? getAccentColor() : (isDarkTheme() ? getResources().getColor(R.color.white) : getResources().getColor(R.color.gray_700)),
|
||||
dockbar_accent() ? getAccentColor() : (isDarkTheme() ? ThemesHacks.getColors(ctx, R.color.white) : ThemesHacks.getColors(ctx, R.color.gray_700)),
|
||||
getColorFromAttr(R.attr.tabbar_inactive_icon)
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package ru.vtosters.lite.concurrent;
|
||||
|
||||
import com.vk.core.concurrent.VkExecutors;
|
||||
import io.reactivex.Scheduler;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
import io.reactivex.Scheduler;
|
||||
|
||||
public class VTExecutors {
|
||||
public static ExecutorService getMusicDownloadExecutor() {
|
||||
@@ -32,7 +33,21 @@ public class VTExecutors {
|
||||
}
|
||||
|
||||
private static class LazyHolder {
|
||||
public static final ExecutorService INSTANCE = Executors.newSingleThreadExecutor();
|
||||
private static final int MIN_PARALLELISM = 1;
|
||||
private static final int MAX_PARALLELISM = 7;
|
||||
private static final int PARALLELISM = clamp(
|
||||
(Runtime.getRuntime().availableProcessors() >> 1) - 1
|
||||
);
|
||||
|
||||
private static final ExecutorService INSTANCE =
|
||||
new ForkJoinPool(PARALLELISM,
|
||||
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
|
||||
(t, e) -> {},
|
||||
/* FIFO */ true);
|
||||
|
||||
private static int clamp(int value) {
|
||||
return Math.min(LazyHolder.MAX_PARALLELISM, Math.max(value, LazyHolder.MIN_PARALLELISM));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,4 +10,4 @@ public class VtOkHttpClient extends OkHttpClient {
|
||||
private static class LazyHolder {
|
||||
private static final VtOkHttpClient instance = new VtOkHttpClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import com.vk.im.engine.models.dialogs.Dialog;
|
||||
import com.vk.im.engine.models.messages.Msg;
|
||||
import com.vk.im.engine.utils.ImDialogsUtils;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.OkHttpClient;
|
||||
import ru.vtosters.hooks.other.ThemesUtils;
|
||||
import ru.vtosters.lite.concurrent.VTExecutors;
|
||||
import ru.vtosters.lite.net.Request;
|
||||
@@ -15,21 +14,49 @@ import ru.vtosters.lite.utils.AccountManagerUtils;
|
||||
import ru.vtosters.lite.utils.AndroidUtils;
|
||||
import ru.vtosters.lite.utils.LifecycleUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.vk.core.network.Network.ClientType.CLIENT_API;
|
||||
import static ru.vtosters.lite.proxy.ProxyUtils.getApi;
|
||||
import static ru.vtosters.lite.utils.AccountManagerUtils.getUserToken;
|
||||
|
||||
public class Requests {
|
||||
public static void hookRead(Dialog dialog) {
|
||||
Request.makeRequest("https://" + ProxyUtils.getApi() + "/method/messages.markAsRead?start_message_id=" + dialog.F1() + "&peer_id=" + dialog.getId() + "&v=5.119&access_token=" + AccountManagerUtils.getUserToken(), response -> {
|
||||
});
|
||||
okhttp3.Request req = new okhttp3.Request.a()
|
||||
.b("https://" + ProxyUtils.getApi() + "/method/messages.markAsRead?start_message_id=" + dialog.F1() + "&peer_id=" + dialog.getId() + "&v=5.119&access_token=" + AccountManagerUtils.getUserToken())
|
||||
.a();
|
||||
|
||||
try {
|
||||
Network.b(CLIENT_API).a(req).execute().close();;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void hookReadStartMsgTo(Msg dialog) {
|
||||
Request.makeRequest("https://" + ProxyUtils.getApi() + "/method/messages.markAsRead?start_message_id=" + dialog.C1() + "&peer_id=" + dialog.v1() + "&v=5.119&access_token=" + AccountManagerUtils.getUserToken(), response -> {
|
||||
});
|
||||
okhttp3.Request req = new okhttp3.Request.a()
|
||||
.b("https://" + ProxyUtils.getApi() + "/method/messages.markAsRead?start_message_id=" + dialog.C1() + "&peer_id=" + dialog.v1() + "&v=5.119&access_token=" + AccountManagerUtils.getUserToken())
|
||||
.a();
|
||||
|
||||
try {
|
||||
Network.b(CLIENT_API).a(req).execute().close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void hookKick(Msg dialog) {
|
||||
if (dialog.getFrom().t1() == AccountManagerUtils.getUserId()) return;
|
||||
Request.makeRequest("https://" + ProxyUtils.getApi() + "/method/messages.removeChatUser?member_id=" + dialog.getFrom().t1() + "&chat_id=" + ImDialogsUtils.c(dialog.v1()) + "&v=5.119&access_token=" + AccountManagerUtils.getUserToken(), response -> {
|
||||
});
|
||||
|
||||
okhttp3.Request req = new okhttp3.Request.a()
|
||||
.b("https://" + ProxyUtils.getApi() + "/method/messages.removeChatUser?member_id=" + dialog.getFrom().t1() + "&chat_id=" + ImDialogsUtils.c(dialog.v1()) + "&v=5.119&access_token=" + AccountManagerUtils.getUserToken())
|
||||
.a();
|
||||
|
||||
try {
|
||||
Network.b(CLIENT_API).a(req).execute().close();;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void hookDialogInfo(Dialog dialog) {
|
||||
@@ -51,7 +78,7 @@ public class Requests {
|
||||
.a(Headers.a("User-Agent", Network.l.c().a(), "Content-Type", "application/x-www-form-urlencoded; charset=utf-8"))
|
||||
.a();
|
||||
|
||||
new OkHttpClient().a(request).execute().a().g();
|
||||
Network.b(CLIENT_API).a(request).execute().a().g();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -1,26 +1,36 @@
|
||||
package ru.vtosters.lite.downloaders;
|
||||
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import bruhcollective.itaysonlab.libvkx.client.LibVKXClient;
|
||||
import com.vk.core.util.ToastUtils;
|
||||
import com.vk.dto.music.MusicTrack;
|
||||
import com.vk.dto.music.Playlist;
|
||||
import com.vtosters.lite.R;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import ru.vtosters.hooks.music.MusicCacheFilesHook;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
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.converter.playlist.PlaylistConverter;
|
||||
import ru.vtosters.lite.music.downloader.AudioGet;
|
||||
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.interfaces.Callback;
|
||||
import ru.vtosters.lite.music.notification.MusicNotificationBuilder;
|
||||
import ru.vtosters.lite.utils.AccountManagerUtils;
|
||||
import ru.vtosters.lite.utils.AndroidUtils;
|
||||
import ru.vtosters.lite.utils.IOUtils;
|
||||
import ru.vtosters.lite.utils.music.PlaylistUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||
|
||||
@@ -31,18 +41,18 @@ import static ru.vtosters.lite.utils.AndroidUtils.getString;
|
||||
*/
|
||||
|
||||
public class AudioDownloader {
|
||||
public static final ExecutorService executor = Executors.newCachedThreadPool();
|
||||
public static final String dlpath = Preferences.getBoolValue("dldir", false) ? Environment.DIRECTORY_DOWNLOADS : Environment.DIRECTORY_MUSIC;
|
||||
|
||||
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(Environment.DIRECTORY_MUSIC).getAbsolutePath();
|
||||
var downloadPath = musicPath + File.separator + playlistName;
|
||||
String musicPath = Environment.getExternalStoragePublicDirectory(dlpath).getAbsolutePath();
|
||||
String downloadPath = musicPath + File.separator + playlistName;
|
||||
|
||||
var notificationId = playlistName.hashCode();
|
||||
var notification = MusicNotificationBuilder.buildPlaylistDownloadNotification(playlistName, notificationId);
|
||||
int notificationId = playlistName.hashCode();
|
||||
NotificationCompat.Builder notification = MusicNotificationBuilder.buildPlaylistDownloadNotification(playlistName, notificationId);
|
||||
|
||||
PlaylistDownloader.downloadPlaylist(
|
||||
tracks,
|
||||
@@ -58,54 +68,96 @@ public class AudioDownloader {
|
||||
}
|
||||
|
||||
public static void cacheTrack(MusicTrack track) {
|
||||
var trackId = LibVKXClient.asId(track);
|
||||
String trackId = LibVKXClient.asId(track);
|
||||
|
||||
if (MusicCacheImpl.isCachedTrack(trackId)) {
|
||||
MusicCacheImpl.removeTrack(trackId);
|
||||
AndroidUtils.sendToast(AndroidUtils.getString("audio_deleted_from_cache"));
|
||||
return;
|
||||
} else {
|
||||
File trackFile = MusicCacheFilesHook.getTrackFile(trackId);
|
||||
if (!trackFile.exists()) {
|
||||
trackFile.getParentFile().mkdirs();
|
||||
}
|
||||
downloadM3U8(track, true);
|
||||
}
|
||||
|
||||
var trackFile = MusicCacheFilesHook.getTrackFile(trackId);
|
||||
if (!trackFile.exists())
|
||||
trackFile.getParentFile().mkdirs();
|
||||
executor.submit(() -> downloadM3U8(track, true));
|
||||
}
|
||||
|
||||
public static void cachePlaylist(Playlist playlist) {
|
||||
var tracks = PlaylistConverter.getPlaylist(playlist);
|
||||
List<MusicTrack> tracks = PlaylistConverter.getPlaylist(playlist);
|
||||
|
||||
var notificationId = playlist.g.hashCode();
|
||||
var notification = MusicNotificationBuilder.buildPlaylistDownloadNotification(playlist.g, notificationId);
|
||||
int notificationId = playlist.g.hashCode();
|
||||
NotificationCompat.Builder notification = MusicNotificationBuilder.buildPlaylistDownloadNotification(playlist.g, notificationId);
|
||||
|
||||
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,
|
||||
MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId)
|
||||
MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId),
|
||||
playlist
|
||||
);
|
||||
}
|
||||
|
||||
public static void cacheAllAudios() {
|
||||
var tracks = AudioGet.getAudios();
|
||||
List<MusicTrack> tracks = AudioGet.getAudios();
|
||||
|
||||
var notificationId = AccountManagerUtils.getUserId();
|
||||
var notification = MusicNotificationBuilder.buildAllAudiosDownloadNotification(notificationId);
|
||||
int notificationId = AccountManagerUtils.getUserId();
|
||||
NotificationCompat.Builder notification = MusicNotificationBuilder.buildAllAudiosDownloadNotification(notificationId);
|
||||
|
||||
if (tracks == null || tracks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PlaylistDownloader.cachePlaylist(
|
||||
tracks,
|
||||
MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId)
|
||||
MusicCallbackBuilder.buildPlaylistCallback(tracks.size(), notification, notificationId),
|
||||
PlaylistHelper.createCachedPlaylistMetadata()
|
||||
);
|
||||
}
|
||||
|
||||
public static void downloadAllAudios() {
|
||||
var tracks = AudioGet.getAudios();
|
||||
List<MusicTrack> tracks = AudioGet.getAudios();
|
||||
|
||||
var notificationId = AccountManagerUtils.getUserId();
|
||||
var notification = MusicNotificationBuilder.buildAllAudiosDownloadNotification(notificationId);
|
||||
int notificationId = AccountManagerUtils.getUserId();
|
||||
NotificationCompat.Builder notification = MusicNotificationBuilder.buildAllAudiosDownloadNotification(notificationId);
|
||||
|
||||
var playlistName = "Audios of " + AccountManagerUtils.getUserId();
|
||||
String playlistName = "Audios of " + AccountManagerUtils.getUserId();
|
||||
|
||||
var musicPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath();
|
||||
var downloadPath = musicPath + File.separator + playlistName;
|
||||
String musicPath = Environment.getExternalStoragePublicDirectory(dlpath).getAbsolutePath();
|
||||
String downloadPath = musicPath + File.separator + playlistName;
|
||||
|
||||
if (tracks == null || tracks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PlaylistDownloader.downloadPlaylist(
|
||||
tracks,
|
||||
@@ -116,20 +168,20 @@ public class AudioDownloader {
|
||||
}
|
||||
|
||||
private static void downloadM3U8(MusicTrack track, boolean cache) {
|
||||
if (track.D == null) {
|
||||
Objects.requireNonNull(track.D, () -> {
|
||||
ToastUtils.a(getString(R.string.link_audio_error));
|
||||
return;
|
||||
}
|
||||
|
||||
var musicPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath();
|
||||
var tempId = track.d;
|
||||
var downloadPath = musicPath + File.separator;
|
||||
var notification = MusicNotificationBuilder.buildDownloadNotification(track, tempId);
|
||||
return "link must not be null";
|
||||
});
|
||||
String musicPath = Environment.getExternalStoragePublicDirectory(dlpath).getAbsolutePath();
|
||||
int tempId = track.d;
|
||||
String downloadPath = musicPath + File.separator;
|
||||
NotificationCompat.Builder notification = MusicNotificationBuilder.buildDownloadNotification(track, tempId);
|
||||
|
||||
Callback cb = MusicCallbackBuilder.buildOneTrackCallback(tempId, notification);
|
||||
if (cache) {
|
||||
TrackDownloader.cacheTrack(track, MusicCallbackBuilder.buildOneTrackCallback(tempId, notification));
|
||||
TrackDownloader.cacheTrack(track, cb, PlaylistHelper.createCachedPlaylistMetadata());
|
||||
} else {
|
||||
TrackDownloader.downloadTrack(track, downloadPath, MusicCallbackBuilder.buildOneTrackCallback(tempId, notification));
|
||||
TrackDownloader.downloadTrack(track, downloadPath, cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user