* Decompile and recreate Soul Browser v1.4.85 with APK CI builds Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix CI build: include bundled google.jks and remove PR trigger The apktool build failed in CI because app/unknown/.../google.jks was excluded by the *.jks gitignore rule. Whitelist app-bundled JKS files and commit the missing resource. Also remove the redundant pull_request workflow trigger. Co-authored-by: KaKi87 <KaKi87@pm.me> * Change package ID to com.github.kaki87.soulbrowser Rename the application ID so the rebuilt APK can be installed alongside the original Soul Browser from Google Play. - Update AndroidManifest package, permissions, providers, and actions - Update R class references in smali (com/github/kaki87/soulbrowser/R) - Update shortcuts.xml targetPackage - Rename app label to "Soul Rebuild" for easy identification Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix install compatibility: remove split APK metadata and bundle native libs The rebuilt APK still declared requiredSplitTypes and Play Store split metadata, causing Android to reject standalone installs as incompatible. - Remove requiredSplitTypes and split-related manifest meta-data - Merge native libs from all ABI splits with uncompressed storage - Page-align before signing for extractNativeLibs=false - Add .so to apktool doNotCompress list Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix install failure: use apksigner v2/v3 and bundle arm64 native libs Target SDK 36 requires APK Signature Scheme v2+, but jarsigner only produces v1 signatures, causing Android to reject the install. - Sign with apksigner (v1+v2+v3) instead of jarsigner - Add arm64-v8a native libraries from universal Soul Browser 1.4.79 - Set extractNativeLibs=true for reliable sideload installs - Commit stable debug keystore for consistent signatures across builds Co-authored-by: KaKi87 <KaKi87@pm.me> * Add committed debug keystore for consistent APK signatures Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix startup crash: use original classes2.dex desugar libraries Apktool recompiles smali_classes2 into a broken classes2.dex, causing ClassNotFoundException for j$.com.android.tools.r8.a at ML Kit init. Inject the original classes2.dex (Java 8+ desugar libs) after apktool build instead of using the recompiled version. Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix missing drawable resources from density split APKs The base APK is an app bundle module; density-specific drawables like seek_thumb_nor_b live in config.xhdpi.apk and were missing after rebuild, causing Resources$NotFoundException at runtime. - Merge non-9-patch resources from split APKs before apktool build - Sync public.xml IDs from R smali only when backing files exist - Add 713 density-specific resource IDs to public.xml Co-authored-by: KaKi87 <KaKi87@pm.me> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
314 lines
10 KiB
Java
314 lines
10 KiB
Java
package com.google.api.client.util;
|
|
|
|
import android.support.v4.media.a;
|
|
import j$.util.DesugarTimeZone;
|
|
import java.io.Serializable;
|
|
import java.util.Arrays;
|
|
import java.util.Date;
|
|
import java.util.GregorianCalendar;
|
|
import java.util.TimeZone;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
/* loaded from: classes3.dex */
|
|
public final class DateTime implements Serializable {
|
|
private static final long serialVersionUID = 1;
|
|
private final boolean dateOnly;
|
|
private final int tzShift;
|
|
private final long value;
|
|
private static final TimeZone GMT = DesugarTimeZone.getTimeZone("GMT");
|
|
private static final String RFC3339_REGEX = "(\\d{4})-(\\d{2})-(\\d{2})([Tt](\\d{2}):(\\d{2}):(\\d{2})(\\.\\d{1,9})?)?([Zz]|([+-])(\\d{2}):(\\d{2}))?";
|
|
private static final Pattern RFC3339_PATTERN = Pattern.compile(RFC3339_REGEX);
|
|
|
|
/* loaded from: classes3.dex */
|
|
public static class Rfc3339ParseResult implements Serializable {
|
|
private static final long serialVersionUID = 1;
|
|
private final int nanos;
|
|
private final long seconds;
|
|
private final boolean timeGiven;
|
|
private final Integer tzShift;
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public DateTime toDateTime() {
|
|
return new DateTime(!this.timeGiven, TimeUnit.SECONDS.toMillis(this.seconds) + TimeUnit.NANOSECONDS.toMillis(this.nanos), this.tzShift);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public SecondsAndNanos toSecondsAndNanos() {
|
|
return new SecondsAndNanos(this.seconds, this.nanos);
|
|
}
|
|
|
|
private Rfc3339ParseResult(long j, int i, boolean z, Integer num) {
|
|
this.seconds = j;
|
|
this.nanos = i;
|
|
this.timeGiven = z;
|
|
this.tzShift = num;
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes3.dex */
|
|
public static final class SecondsAndNanos implements Serializable {
|
|
private static long serialVersionUID = 1;
|
|
private final int nanos;
|
|
private final long seconds;
|
|
|
|
public static SecondsAndNanos ofSecondsAndNanos(long j, int i) {
|
|
return new SecondsAndNanos(j, i);
|
|
}
|
|
|
|
public boolean equals(Object obj) {
|
|
if (this == obj) {
|
|
return true;
|
|
}
|
|
if (obj != null && SecondsAndNanos.class == obj.getClass()) {
|
|
SecondsAndNanos secondsAndNanos = (SecondsAndNanos) obj;
|
|
if (this.seconds == secondsAndNanos.seconds && this.nanos == secondsAndNanos.nanos) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public int getNanos() {
|
|
return this.nanos;
|
|
}
|
|
|
|
public long getSeconds() {
|
|
return this.seconds;
|
|
}
|
|
|
|
public int hashCode() {
|
|
return j$.util.Objects.hash(Long.valueOf(this.seconds), Integer.valueOf(this.nanos));
|
|
}
|
|
|
|
public String toString() {
|
|
return String.format("Seconds: %d, Nanos: %d", Long.valueOf(this.seconds), Integer.valueOf(this.nanos));
|
|
}
|
|
|
|
private SecondsAndNanos(long j, int i) {
|
|
this.seconds = j;
|
|
this.nanos = i;
|
|
}
|
|
}
|
|
|
|
public DateTime(Date date, TimeZone timeZone) {
|
|
this(false, date.getTime(), timeZone == null ? null : Integer.valueOf(timeZone.getOffset(date.getTime()) / 60000));
|
|
}
|
|
|
|
private static void appendInt(StringBuilder sb, int i, int i2) {
|
|
if (i < 0) {
|
|
sb.append('-');
|
|
i = -i;
|
|
}
|
|
int i3 = i;
|
|
while (i3 > 0) {
|
|
i3 /= 10;
|
|
i2--;
|
|
}
|
|
for (int i4 = 0; i4 < i2; i4++) {
|
|
sb.append('0');
|
|
}
|
|
if (i != 0) {
|
|
sb.append(i);
|
|
}
|
|
}
|
|
|
|
public static DateTime parseRfc3339(String str) {
|
|
return parseRfc3339WithNanoSeconds(str).toDateTime();
|
|
}
|
|
|
|
public static SecondsAndNanos parseRfc3339ToSecondsAndNanos(String str) {
|
|
return parseRfc3339WithNanoSeconds(str).toSecondsAndNanos();
|
|
}
|
|
|
|
private static Rfc3339ParseResult parseRfc3339WithNanoSeconds(String str) {
|
|
boolean z;
|
|
boolean z2;
|
|
int i;
|
|
int i2;
|
|
int i3;
|
|
int i4;
|
|
Integer num;
|
|
Matcher matcher = RFC3339_PATTERN.matcher(str);
|
|
if (matcher.matches()) {
|
|
int parseInt = Integer.parseInt(matcher.group(1));
|
|
int parseInt2 = Integer.parseInt(matcher.group(2)) - 1;
|
|
int parseInt3 = Integer.parseInt(matcher.group(3));
|
|
if (matcher.group(4) != null) {
|
|
z = true;
|
|
} else {
|
|
z = false;
|
|
}
|
|
String group = matcher.group(9);
|
|
if (group != null) {
|
|
z2 = true;
|
|
} else {
|
|
z2 = false;
|
|
}
|
|
if (z2 && !z) {
|
|
throw new NumberFormatException(a.C("Invalid date/time format, cannot specify time zone shift without specifying time: ", str));
|
|
}
|
|
if (z) {
|
|
int parseInt4 = Integer.parseInt(matcher.group(5));
|
|
int parseInt5 = Integer.parseInt(matcher.group(6));
|
|
int parseInt6 = Integer.parseInt(matcher.group(7));
|
|
if (matcher.group(8) != null) {
|
|
String substring = matcher.group(8).substring(1);
|
|
substring.getClass();
|
|
if (substring.length() < 9) {
|
|
StringBuilder sb = new StringBuilder(9);
|
|
sb.append(substring);
|
|
for (int length = substring.length(); length < 9; length++) {
|
|
sb.append('0');
|
|
}
|
|
substring = sb.toString();
|
|
}
|
|
i4 = Integer.parseInt(substring);
|
|
i2 = parseInt5;
|
|
i3 = parseInt6;
|
|
} else {
|
|
i2 = parseInt5;
|
|
i3 = parseInt6;
|
|
i4 = 0;
|
|
}
|
|
i = parseInt4;
|
|
} else {
|
|
i = 0;
|
|
i2 = 0;
|
|
i3 = 0;
|
|
i4 = 0;
|
|
}
|
|
GregorianCalendar gregorianCalendar = new GregorianCalendar(GMT);
|
|
gregorianCalendar.clear();
|
|
gregorianCalendar.set(parseInt, parseInt2, parseInt3, i, i2, i3);
|
|
long timeInMillis = gregorianCalendar.getTimeInMillis();
|
|
if (z && z2) {
|
|
if (Character.toUpperCase(group.charAt(0)) != 'Z') {
|
|
int parseInt7 = Integer.parseInt(matcher.group(12)) + (Integer.parseInt(matcher.group(11)) * 60);
|
|
if (matcher.group(10).charAt(0) == '-') {
|
|
parseInt7 = -parseInt7;
|
|
}
|
|
timeInMillis -= parseInt7 * 60000;
|
|
num = Integer.valueOf(parseInt7);
|
|
} else {
|
|
num = 0;
|
|
}
|
|
} else {
|
|
num = null;
|
|
}
|
|
return new Rfc3339ParseResult(timeInMillis / 1000, i4, z, num);
|
|
}
|
|
throw new NumberFormatException(a.C("Invalid date/time format: ", str));
|
|
}
|
|
|
|
public boolean equals(Object obj) {
|
|
if (obj == this) {
|
|
return true;
|
|
}
|
|
if (!(obj instanceof DateTime)) {
|
|
return false;
|
|
}
|
|
DateTime dateTime = (DateTime) obj;
|
|
if (this.dateOnly == dateTime.dateOnly && this.value == dateTime.value && this.tzShift == dateTime.tzShift) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public int getTimeZoneShift() {
|
|
return this.tzShift;
|
|
}
|
|
|
|
public long getValue() {
|
|
return this.value;
|
|
}
|
|
|
|
public int hashCode() {
|
|
long j;
|
|
long j2 = this.value;
|
|
if (this.dateOnly) {
|
|
j = 1;
|
|
} else {
|
|
j = 0;
|
|
}
|
|
return Arrays.hashCode(new long[]{j2, j, this.tzShift});
|
|
}
|
|
|
|
public boolean isDateOnly() {
|
|
return this.dateOnly;
|
|
}
|
|
|
|
public String toString() {
|
|
return toStringRfc3339();
|
|
}
|
|
|
|
public String toStringRfc3339() {
|
|
StringBuilder sb = new StringBuilder();
|
|
GregorianCalendar gregorianCalendar = new GregorianCalendar(GMT);
|
|
gregorianCalendar.setTimeInMillis((this.tzShift * 60000) + this.value);
|
|
appendInt(sb, gregorianCalendar.get(1), 4);
|
|
sb.append('-');
|
|
appendInt(sb, gregorianCalendar.get(2) + 1, 2);
|
|
sb.append('-');
|
|
appendInt(sb, gregorianCalendar.get(5), 2);
|
|
if (!this.dateOnly) {
|
|
sb.append('T');
|
|
appendInt(sb, gregorianCalendar.get(11), 2);
|
|
sb.append(':');
|
|
appendInt(sb, gregorianCalendar.get(12), 2);
|
|
sb.append(':');
|
|
appendInt(sb, gregorianCalendar.get(13), 2);
|
|
if (gregorianCalendar.isSet(14)) {
|
|
sb.append('.');
|
|
appendInt(sb, gregorianCalendar.get(14), 3);
|
|
}
|
|
int i = this.tzShift;
|
|
if (i == 0) {
|
|
sb.append('Z');
|
|
} else {
|
|
if (i > 0) {
|
|
sb.append('+');
|
|
} else {
|
|
sb.append('-');
|
|
i = -i;
|
|
}
|
|
appendInt(sb, i / 60, 2);
|
|
sb.append(':');
|
|
appendInt(sb, i % 60, 2);
|
|
}
|
|
}
|
|
return sb.toString();
|
|
}
|
|
|
|
public DateTime(long j) {
|
|
this(false, j, null);
|
|
}
|
|
|
|
public DateTime(Date date) {
|
|
this(date.getTime());
|
|
}
|
|
|
|
public DateTime(long j, int i) {
|
|
this(false, j, Integer.valueOf(i));
|
|
}
|
|
|
|
public DateTime(boolean z, long j, Integer num) {
|
|
int offset;
|
|
this.dateOnly = z;
|
|
this.value = j;
|
|
if (z) {
|
|
offset = 0;
|
|
} else {
|
|
offset = num == null ? TimeZone.getDefault().getOffset(j) / 60000 : num.intValue();
|
|
}
|
|
this.tzShift = offset;
|
|
}
|
|
|
|
public DateTime(String str) {
|
|
DateTime parseRfc3339 = parseRfc3339(str);
|
|
this.dateOnly = parseRfc3339.dateOnly;
|
|
this.value = parseRfc3339.value;
|
|
this.tzShift = parseRfc3339.tzShift;
|
|
}
|
|
}
|