soul-browser/sources/java/org/jsoup/nodes/Attributes.java
KaKi87 550ddb0413
Decompile and recreate Soul Browser v1.4.85 with APK CI builds (#1)
* 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>
2026-08-10 16:07:14 +02:00

591 lines
17 KiB
Java

package org.jsoup.nodes;
import com.google.android.gms.ads.RequestConfiguration;
import j$.util.DesugarCollections;
import j$.util.Objects;
import java.io.Serializable;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import org.jsoup.helper.Validate;
import org.jsoup.internal.Normalizer;
import org.jsoup.internal.QuietAppendable;
import org.jsoup.internal.SharedConstants;
import org.jsoup.internal.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Range;
import org.jsoup.parser.ParseSettings;
/* loaded from: classes4.dex */
public class Attributes implements Iterable<Attribute>, Cloneable {
/* renamed from: c, reason: collision with root package name */
public int f22561c = 0;
public String[] f = new String[3];
public Object[] g = new Object[3];
/* loaded from: classes4.dex */
public static class Dataset extends AbstractMap<String, String> {
/* renamed from: c, reason: collision with root package name */
public final Attributes f22563c;
/* loaded from: classes4.dex */
public class DatasetIterator implements Iterator<Map.Entry<String, String>> {
/* renamed from: c, reason: collision with root package name */
public final Iterator f22564c;
public Attribute f;
public DatasetIterator() {
this.f22564c = Dataset.this.f22563c.iterator();
}
@Override // java.util.Iterator
public final boolean hasNext() {
while (true) {
Iterator it = this.f22564c;
if (it.hasNext()) {
Attribute attribute = (Attribute) it.next();
this.f = attribute;
String str = attribute.f22560c;
if (str.startsWith("data-") && str.length() > 5) {
return true;
}
} else {
return false;
}
}
}
@Override // java.util.Iterator
public final Map.Entry<String, String> next() {
return new Attribute(this.f.getKey().substring(5), this.f.getValue());
}
@Override // java.util.Iterator
public final void remove() {
Dataset.this.f22563c.remove(this.f.getKey());
}
}
/* loaded from: classes4.dex */
public class EntrySet extends AbstractSet<Map.Entry<String, String>> {
public EntrySet() {
}
@Override // java.util.AbstractCollection, java.util.Collection, java.lang.Iterable, java.util.Set
public final Iterator iterator() {
return new DatasetIterator();
}
@Override // java.util.AbstractCollection, java.util.Collection, java.util.Set
public final int size() {
int i = 0;
while (new DatasetIterator().hasNext()) {
i++;
}
return i;
}
}
public Dataset(Attributes attributes) {
this.f22563c = attributes;
}
@Override // java.util.AbstractMap, java.util.Map
public final Set entrySet() {
return new EntrySet();
}
@Override // java.util.AbstractMap, java.util.Map
public final Object put(Object obj, Object obj2) {
String str;
String str2 = (String) obj2;
String C = android.support.v4.media.a.C("data-", (String) obj);
Attributes attributes = this.f22563c;
if (attributes.hasKey(C)) {
str = attributes.get(C);
} else {
str = null;
}
attributes.put(C, str2);
return str;
}
}
public static boolean m(String str) {
if (str.length() <= 1 || str.charAt(0) != '/') {
return false;
}
return true;
}
public final void a(String str, Serializable serializable) {
c(this.f22561c + 1);
String[] strArr = this.f;
int i = this.f22561c;
strArr[i] = str;
this.g[i] = serializable;
this.f22561c = i + 1;
}
public Attributes add(String str, String str2) {
a(str, str2);
return this;
}
public void addAll(Attributes attributes) {
boolean z;
int size = attributes.size();
if (size != 0) {
c(this.f22561c + size);
if (this.f22561c != 0) {
z = true;
} else {
z = false;
}
Iterator<Attribute> it = attributes.iterator();
while (it.hasNext()) {
Attribute next = it.next();
if (z) {
put(next);
} else {
a(next.getKey(), next.getValue());
}
}
}
}
public List<Attribute> asList() {
ArrayList arrayList = new ArrayList(this.f22561c);
for (int i = 0; i < this.f22561c; i++) {
String str = this.f[i];
if (!m(str)) {
arrayList.add(new Attribute(str, (String) this.g[i], this));
}
}
return DesugarCollections.unmodifiableList(arrayList);
}
public Attribute attribute(String str) {
String str2;
int i = i(str);
if (i == -1) {
return null;
}
Object obj = this.g[i];
if (obj == null) {
str2 = RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED;
} else {
str2 = (String) obj;
}
return new Attribute(str, str2, this);
}
public final void c(int i) {
boolean z;
if (i >= this.f22561c) {
z = true;
} else {
z = false;
}
Validate.isTrue(z);
String[] strArr = this.f;
int length = strArr.length;
if (length >= i) {
return;
}
int i2 = 3;
if (length >= 3) {
i2 = this.f22561c * 2;
}
if (i <= i2) {
i = i2;
}
this.f = (String[]) Arrays.copyOf(strArr, i);
this.g = Arrays.copyOf(this.g, i);
}
public Map<String, String> dataset() {
return new Dataset(this);
}
public int deduplicate(ParseSettings parseSettings) {
int i = 0;
if (this.f22561c == 0) {
return 0;
}
boolean preserveAttributeCase = parseSettings.preserveAttributeCase();
int i2 = 0;
while (i < this.f22561c) {
String str = this.f[i];
i++;
int i3 = i;
while (i3 < this.f22561c) {
if ((preserveAttributeCase && str.equals(this.f[i3])) || (!preserveAttributeCase && str.equalsIgnoreCase(this.f[i3]))) {
i2++;
q(i3);
i3--;
}
i3++;
}
}
return i2;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Attributes attributes = (Attributes) obj;
if (this.f22561c != attributes.f22561c) {
return false;
}
for (int i = 0; i < this.f22561c; i++) {
int i2 = attributes.i(this.f[i]);
if (i2 == -1 || !Objects.equals(this.g[i], attributes.g[i2])) {
return false;
}
}
return true;
}
public final void g(QuietAppendable quietAppendable, Document.OutputSettings outputSettings) {
String validKey;
int i = this.f22561c;
for (int i2 = 0; i2 < i; i2++) {
String str = this.f[i2];
if (!m(str) && (validKey = Attribute.getValidKey(str, outputSettings.syntax())) != null) {
Attribute.a(validKey, (String) this.g[i2], quietAppendable.append(' '), outputSettings);
}
}
}
public String get(String str) {
Object obj;
int i = i(str);
if (i == -1 || (obj = this.g[i]) == null) {
return RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED;
}
return (String) obj;
}
public String getIgnoreCase(String str) {
Object obj;
int k = k(str);
if (k == -1 || (obj = this.g[k]) == null) {
return RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED;
}
return (String) obj;
}
public boolean hasDeclaredValueForKey(String str) {
int i = i(str);
if (i != -1 && this.g[i] != null) {
return true;
}
return false;
}
public boolean hasDeclaredValueForKeyIgnoreCase(String str) {
int k = k(str);
if (k != -1 && this.g[k] != null) {
return true;
}
return false;
}
public boolean hasKey(String str) {
if (i(str) != -1) {
return true;
}
return false;
}
public boolean hasKeyIgnoreCase(String str) {
if (k(str) != -1) {
return true;
}
return false;
}
public int hashCode() {
return Arrays.hashCode(this.g) + (((this.f22561c * 31) + Arrays.hashCode(this.f)) * 31);
}
public String html() {
StringBuilder borrowBuilder = StringUtil.borrowBuilder();
g(QuietAppendable.wrap(borrowBuilder), new Document.OutputSettings());
return StringUtil.releaseBuilder(borrowBuilder);
}
public final int i(String str) {
Validate.notNull(str);
for (int i = 0; i < this.f22561c; i++) {
if (str.equals(this.f[i])) {
return i;
}
}
return -1;
}
public boolean isEmpty() {
if (size() == 0) {
return true;
}
return false;
}
@Override // java.lang.Iterable
public Iterator<Attribute> iterator() {
return new Iterator<Attribute>() { // from class: org.jsoup.nodes.Attributes.1
/* renamed from: c, reason: collision with root package name */
public int f22562c;
public int f = 0;
{
this.f22562c = Attributes.this.f22561c;
}
@Override // java.util.Iterator
public final boolean hasNext() {
Attributes attributes = Attributes.this;
if (attributes.f22561c == this.f22562c) {
while (true) {
int i = this.f;
if (i >= attributes.f22561c || !Attributes.m(attributes.f[i])) {
break;
}
this.f++;
}
if (this.f < attributes.f22561c) {
return true;
}
return false;
}
throw new ConcurrentModificationException("Use Iterator#remove() instead to remove attributes while iterating.");
}
@Override // java.util.Iterator
public final Attribute next() {
Attributes attributes = Attributes.this;
int i = attributes.f22561c;
if (i == this.f22562c) {
int i2 = this.f;
if (i2 < i) {
Attribute attribute = new Attribute(attributes.f[i2], (String) attributes.g[this.f], attributes);
this.f++;
return attribute;
}
throw new NoSuchElementException();
}
throw new ConcurrentModificationException("Use Iterator#remove() instead to remove attributes while iterating.");
}
@Override // java.util.Iterator
public final void remove() {
int i = this.f - 1;
this.f = i;
Attributes.this.q(i);
this.f22562c--;
}
};
}
public final int k(String str) {
Validate.notNull(str);
for (int i = 0; i < this.f22561c; i++) {
if (str.equalsIgnoreCase(this.f[i])) {
return i;
}
}
return -1;
}
public void normalize() {
for (int i = 0; i < this.f22561c; i++) {
String str = this.f[i];
if (!m(str)) {
this.f[i] = Normalizer.lowerCase(str);
}
}
}
public final void p(String str, String str2) {
int k = k(str);
if (k != -1) {
this.g[k] = str2;
if (!this.f[k].equals(str)) {
this.f[k] = str;
return;
}
return;
}
a(str, str2);
}
public Attributes put(String str, String str2) {
Validate.notNull(str);
int i = i(str);
if (i != -1) {
this.g[i] = str2;
return this;
}
a(str, str2);
return this;
}
public final void q(int i) {
boolean z;
if (i >= this.f22561c) {
z = true;
} else {
z = false;
}
Validate.isFalse(z);
int i2 = (this.f22561c - i) - 1;
if (i2 > 0) {
String[] strArr = this.f;
int i3 = i + 1;
System.arraycopy(strArr, i3, strArr, i, i2);
Object[] objArr = this.g;
System.arraycopy(objArr, i3, objArr, i, i2);
}
int i4 = this.f22561c - 1;
this.f22561c = i4;
this.f[i4] = null;
this.g[i4] = null;
}
public final Map r() {
int i = i(SharedConstants.UserDataKey);
if (i == -1) {
HashMap hashMap = new HashMap();
a(SharedConstants.UserDataKey, hashMap);
return hashMap;
}
return (Map) this.g[i];
}
public void remove(String str) {
int i = i(str);
if (i != -1) {
q(i);
}
}
public void removeIgnoreCase(String str) {
int k = k(str);
if (k != -1) {
q(k);
}
}
public int size() {
if (this.f22561c == 0) {
return 0;
}
int i = 0;
for (int i2 = 0; i2 < this.f22561c; i2++) {
if (!m(this.f[i2])) {
i++;
}
}
return i;
}
public Range.AttributeRange sourceRange(String str) {
if (!hasKey(str)) {
return Range.AttributeRange.f22581c;
}
Map map = (Map) userData(SharedConstants.AttrRangeKey);
if (map == null) {
return Range.AttributeRange.f22581c;
}
Range.AttributeRange attributeRange = (Range.AttributeRange) map.get(str);
return attributeRange != null ? attributeRange : Range.AttributeRange.f22581c;
}
public String toString() {
return html();
}
public Object userData(String str) {
Validate.notNull(str);
if (hasKey(SharedConstants.UserDataKey)) {
return r().get(str);
}
return null;
}
public Attributes clone() {
try {
Attributes attributes = (Attributes) super.clone();
attributes.f22561c = this.f22561c;
attributes.f = (String[]) Arrays.copyOf(this.f, this.f22561c);
attributes.g = Arrays.copyOf(this.g, this.f22561c);
int i = i(SharedConstants.UserDataKey);
if (i != -1) {
this.g[i] = new HashMap((Map) this.g[i]);
}
return attributes;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
public Attributes put(String str, boolean z) {
if (z) {
p(str, null);
return this;
}
remove(str);
return this;
}
public Attributes userData(String str, Object obj) {
Validate.notNull(str);
if (obj == null && !hasKey(SharedConstants.UserDataKey)) {
return this;
}
Map r = r();
if (obj == null) {
r.remove(str);
return this;
}
r.put(str, obj);
return this;
}
public Attributes sourceRange(String str, Range.AttributeRange attributeRange) {
Validate.notNull(str);
Validate.notNull(attributeRange);
Map map = (Map) userData(SharedConstants.AttrRangeKey);
if (map == null) {
map = new HashMap();
userData(SharedConstants.AttrRangeKey, map);
}
map.put(str, attributeRange);
return this;
}
public Attributes put(Attribute attribute) {
Validate.notNull(attribute);
put(attribute.getKey(), attribute.getValue());
attribute.g = this;
return this;
}
}