soul-browser/sources/java/android/support/v4/media/MediaMetadataCompat.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

420 lines
18 KiB
Java

package android.support.v4.media;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.media.MediaMetadata;
import android.media.Rating;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.RestrictTo;
import androidx.collection.ArrayMap;
import androidx.collection.SimpleArrayMap;
import java.util.Set;
@SuppressLint({"BanParcelableUsage"})
/* loaded from: classes.dex */
public final class MediaMetadataCompat implements Parcelable {
public static final Parcelable.Creator<MediaMetadataCompat> CREATOR;
static final ArrayMap<String, Integer> METADATA_KEYS_TYPE;
public static final String METADATA_KEY_ADVERTISEMENT = "android.media.metadata.ADVERTISEMENT";
public static final String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM";
public static final String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
public static final String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
public static final String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
public static final String METADATA_KEY_ART = "android.media.metadata.ART";
public static final String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST";
public static final String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
public static final String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR";
public static final String METADATA_KEY_BT_FOLDER_TYPE = "android.media.metadata.BT_FOLDER_TYPE";
public static final String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION";
public static final String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER";
public static final String METADATA_KEY_DATE = "android.media.metadata.DATE";
public static final String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
public static final String METADATA_KEY_DISPLAY_DESCRIPTION = "android.media.metadata.DISPLAY_DESCRIPTION";
public static final String METADATA_KEY_DISPLAY_ICON = "android.media.metadata.DISPLAY_ICON";
public static final String METADATA_KEY_DISPLAY_ICON_URI = "android.media.metadata.DISPLAY_ICON_URI";
public static final String METADATA_KEY_DISPLAY_SUBTITLE = "android.media.metadata.DISPLAY_SUBTITLE";
public static final String METADATA_KEY_DISPLAY_TITLE = "android.media.metadata.DISPLAY_TITLE";
public static final String METADATA_KEY_DOWNLOAD_STATUS = "android.media.metadata.DOWNLOAD_STATUS";
public static final String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
public static final String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
public static final String METADATA_KEY_MEDIA_ID = "android.media.metadata.MEDIA_ID";
public static final String METADATA_KEY_MEDIA_URI = "android.media.metadata.MEDIA_URI";
public static final String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
public static final String METADATA_KEY_RATING = "android.media.metadata.RATING";
public static final String METADATA_KEY_TITLE = "android.media.metadata.TITLE";
public static final String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
public static final String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING";
public static final String METADATA_KEY_WRITER = "android.media.metadata.WRITER";
public static final String METADATA_KEY_YEAR = "android.media.metadata.YEAR";
static final int METADATA_TYPE_BITMAP = 2;
static final int METADATA_TYPE_LONG = 0;
static final int METADATA_TYPE_RATING = 3;
static final int METADATA_TYPE_TEXT = 1;
private static final String[] PREFERRED_BITMAP_ORDER;
private static final String[] PREFERRED_DESCRIPTION_ORDER;
private static final String[] PREFERRED_URI_ORDER;
private static final String TAG = "MediaMetadata";
final Bundle mBundle;
private MediaDescriptionCompat mDescription;
private MediaMetadata mMetadataFwk;
/* JADX WARN: Type inference failed for: r0v0, types: [androidx.collection.ArrayMap<java.lang.String, java.lang.Integer>, androidx.collection.SimpleArrayMap] */
static {
?? simpleArrayMap = new SimpleArrayMap(0);
METADATA_KEYS_TYPE = simpleArrayMap;
simpleArrayMap.put(METADATA_KEY_TITLE, 1);
simpleArrayMap.put(METADATA_KEY_ARTIST, 1);
simpleArrayMap.put(METADATA_KEY_DURATION, 0);
simpleArrayMap.put(METADATA_KEY_ALBUM, 1);
simpleArrayMap.put(METADATA_KEY_AUTHOR, 1);
simpleArrayMap.put(METADATA_KEY_WRITER, 1);
simpleArrayMap.put(METADATA_KEY_COMPOSER, 1);
simpleArrayMap.put(METADATA_KEY_COMPILATION, 1);
simpleArrayMap.put(METADATA_KEY_DATE, 1);
simpleArrayMap.put(METADATA_KEY_YEAR, 0);
simpleArrayMap.put(METADATA_KEY_GENRE, 1);
simpleArrayMap.put(METADATA_KEY_TRACK_NUMBER, 0);
simpleArrayMap.put(METADATA_KEY_NUM_TRACKS, 0);
simpleArrayMap.put(METADATA_KEY_DISC_NUMBER, 0);
simpleArrayMap.put(METADATA_KEY_ALBUM_ARTIST, 1);
simpleArrayMap.put(METADATA_KEY_ART, 2);
simpleArrayMap.put(METADATA_KEY_ART_URI, 1);
simpleArrayMap.put(METADATA_KEY_ALBUM_ART, 2);
simpleArrayMap.put(METADATA_KEY_ALBUM_ART_URI, 1);
simpleArrayMap.put(METADATA_KEY_USER_RATING, 3);
simpleArrayMap.put(METADATA_KEY_RATING, 3);
simpleArrayMap.put(METADATA_KEY_DISPLAY_TITLE, 1);
simpleArrayMap.put(METADATA_KEY_DISPLAY_SUBTITLE, 1);
simpleArrayMap.put(METADATA_KEY_DISPLAY_DESCRIPTION, 1);
simpleArrayMap.put(METADATA_KEY_DISPLAY_ICON, 2);
simpleArrayMap.put(METADATA_KEY_DISPLAY_ICON_URI, 1);
simpleArrayMap.put(METADATA_KEY_MEDIA_ID, 1);
simpleArrayMap.put(METADATA_KEY_BT_FOLDER_TYPE, 0);
simpleArrayMap.put(METADATA_KEY_MEDIA_URI, 1);
simpleArrayMap.put(METADATA_KEY_ADVERTISEMENT, 0);
simpleArrayMap.put(METADATA_KEY_DOWNLOAD_STATUS, 0);
PREFERRED_DESCRIPTION_ORDER = new String[]{METADATA_KEY_TITLE, METADATA_KEY_ARTIST, METADATA_KEY_ALBUM, METADATA_KEY_ALBUM_ARTIST, METADATA_KEY_WRITER, METADATA_KEY_AUTHOR, METADATA_KEY_COMPOSER};
PREFERRED_BITMAP_ORDER = new String[]{METADATA_KEY_DISPLAY_ICON, METADATA_KEY_ART, METADATA_KEY_ALBUM_ART};
PREFERRED_URI_ORDER = new String[]{METADATA_KEY_DISPLAY_ICON_URI, METADATA_KEY_ART_URI, METADATA_KEY_ALBUM_ART_URI};
CREATOR = new Parcelable.Creator<MediaMetadataCompat>() { // from class: android.support.v4.media.MediaMetadataCompat.1
/* JADX WARN: Can't rename method to resolve collision */
@Override // android.os.Parcelable.Creator
public MediaMetadataCompat createFromParcel(Parcel parcel) {
return new MediaMetadataCompat(parcel);
}
/* JADX WARN: Can't rename method to resolve collision */
@Override // android.os.Parcelable.Creator
public MediaMetadataCompat[] newArray(int i) {
return new MediaMetadataCompat[i];
}
};
}
public MediaMetadataCompat(Bundle bundle) {
Bundle bundle2 = new Bundle(bundle);
this.mBundle = bundle2;
MediaSessionCompat.ensureClassLoader(bundle2);
}
public static MediaMetadataCompat fromMediaMetadata(Object obj) {
if (obj != null) {
Parcel obtain = Parcel.obtain();
MediaMetadata mediaMetadata = (MediaMetadata) obj;
mediaMetadata.writeToParcel(obtain, 0);
obtain.setDataPosition(0);
MediaMetadataCompat createFromParcel = CREATOR.createFromParcel(obtain);
obtain.recycle();
createFromParcel.mMetadataFwk = mediaMetadata;
return createFromParcel;
}
return null;
}
public boolean containsKey(String str) {
return this.mBundle.containsKey(str);
}
@Override // android.os.Parcelable
public int describeContents() {
return 0;
}
public Bitmap getBitmap(String str) {
try {
return (Bitmap) this.mBundle.getParcelable(str);
} catch (Exception e) {
Log.w(TAG, "Failed to retrieve a key as Bitmap.", e);
return null;
}
}
public Bundle getBundle() {
return new Bundle(this.mBundle);
}
public MediaDescriptionCompat getDescription() {
Uri uri;
Bitmap bitmap;
Uri uri2;
MediaDescriptionCompat mediaDescriptionCompat = this.mDescription;
if (mediaDescriptionCompat != null) {
return mediaDescriptionCompat;
}
String string = getString(METADATA_KEY_MEDIA_ID);
CharSequence[] charSequenceArr = new CharSequence[3];
CharSequence text = getText(METADATA_KEY_DISPLAY_TITLE);
if (!TextUtils.isEmpty(text)) {
charSequenceArr[0] = text;
charSequenceArr[1] = getText(METADATA_KEY_DISPLAY_SUBTITLE);
charSequenceArr[2] = getText(METADATA_KEY_DISPLAY_DESCRIPTION);
} else {
int i = 0;
int i2 = 0;
while (i < 3) {
String[] strArr = PREFERRED_DESCRIPTION_ORDER;
if (i2 >= strArr.length) {
break;
}
int i3 = i2 + 1;
CharSequence text2 = getText(strArr[i2]);
if (!TextUtils.isEmpty(text2)) {
charSequenceArr[i] = text2;
i++;
}
i2 = i3;
}
}
int i4 = 0;
while (true) {
String[] strArr2 = PREFERRED_BITMAP_ORDER;
uri = null;
if (i4 < strArr2.length) {
bitmap = getBitmap(strArr2[i4]);
if (bitmap != null) {
break;
}
i4++;
} else {
bitmap = null;
break;
}
}
int i5 = 0;
while (true) {
String[] strArr3 = PREFERRED_URI_ORDER;
if (i5 < strArr3.length) {
String string2 = getString(strArr3[i5]);
if (!TextUtils.isEmpty(string2)) {
uri2 = Uri.parse(string2);
break;
}
i5++;
} else {
uri2 = null;
break;
}
}
String string3 = getString(METADATA_KEY_MEDIA_URI);
if (!TextUtils.isEmpty(string3)) {
uri = Uri.parse(string3);
}
MediaDescriptionCompat.Builder builder = new MediaDescriptionCompat.Builder();
builder.setMediaId(string);
builder.setTitle(charSequenceArr[0]);
builder.setSubtitle(charSequenceArr[1]);
builder.setDescription(charSequenceArr[2]);
builder.setIconBitmap(bitmap);
builder.setIconUri(uri2);
builder.setMediaUri(uri);
Bundle bundle = new Bundle();
if (this.mBundle.containsKey(METADATA_KEY_BT_FOLDER_TYPE)) {
bundle.putLong(MediaDescriptionCompat.EXTRA_BT_FOLDER_TYPE, getLong(METADATA_KEY_BT_FOLDER_TYPE));
}
if (this.mBundle.containsKey(METADATA_KEY_DOWNLOAD_STATUS)) {
bundle.putLong(MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS, getLong(METADATA_KEY_DOWNLOAD_STATUS));
}
if (!bundle.isEmpty()) {
builder.setExtras(bundle);
}
MediaDescriptionCompat build = builder.build();
this.mDescription = build;
return build;
}
public long getLong(String str) {
return this.mBundle.getLong(str, 0L);
}
public Object getMediaMetadata() {
if (this.mMetadataFwk == null) {
MediaMetadata.Builder builder = new MediaMetadata.Builder();
for (String str : this.mBundle.keySet()) {
Integer num = (Integer) METADATA_KEYS_TYPE.get(str);
if (num == null) {
num = -1;
}
int intValue = num.intValue();
if (intValue != 0) {
if (intValue != 1) {
if (intValue != 2) {
if (intValue != 3) {
Object obj = this.mBundle.get(str);
if (obj != null && !(obj instanceof CharSequence)) {
if (obj instanceof Long) {
builder.putLong(str, ((Long) obj).longValue());
} else if (obj instanceof Bitmap) {
builder.putBitmap(str, (Bitmap) obj);
} else if (obj instanceof Rating) {
builder.putRating(str, (Rating) obj);
}
} else {
builder.putText(str, (CharSequence) obj);
}
} else {
builder.putRating(str, (Rating) this.mBundle.getParcelable(str));
}
} else {
builder.putBitmap(str, (Bitmap) this.mBundle.getParcelable(str));
}
} else {
builder.putText(str, this.mBundle.getCharSequence(str));
}
} else {
builder.putLong(str, this.mBundle.getLong(str, 0L));
}
}
this.mMetadataFwk = builder.build();
}
return this.mMetadataFwk;
}
public RatingCompat getRating(String str) {
try {
return RatingCompat.fromRating(this.mBundle.getParcelable(str));
} catch (Exception e) {
Log.w(TAG, "Failed to retrieve a key as Rating.", e);
return null;
}
}
public String getString(String str) {
CharSequence charSequence = this.mBundle.getCharSequence(str);
if (charSequence != null) {
return charSequence.toString();
}
return null;
}
public CharSequence getText(String str) {
return this.mBundle.getCharSequence(str);
}
public Set<String> keySet() {
return this.mBundle.keySet();
}
public int size() {
return this.mBundle.size();
}
@Override // android.os.Parcelable
public void writeToParcel(Parcel parcel, int i) {
parcel.writeBundle(this.mBundle);
}
/* loaded from: classes.dex */
public static final class Builder {
private final Bundle mBundle;
public Builder() {
this.mBundle = new Bundle();
}
private Bitmap scaleBitmap(Bitmap bitmap, int i) {
float f = i;
float min = Math.min(f / bitmap.getWidth(), f / bitmap.getHeight());
return Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth() * min), (int) (bitmap.getHeight() * min), true);
}
public MediaMetadataCompat build() {
return new MediaMetadataCompat(this.mBundle);
}
public Builder putBitmap(String str, Bitmap bitmap) {
ArrayMap<String, Integer> arrayMap = MediaMetadataCompat.METADATA_KEYS_TYPE;
if (arrayMap.containsKey(str) && ((Integer) arrayMap.get(str)).intValue() != 2) {
throw new IllegalArgumentException(a.l("The ", str, " key cannot be used to put a Bitmap"));
}
this.mBundle.putParcelable(str, bitmap);
return this;
}
public Builder putLong(String str, long j) {
ArrayMap<String, Integer> arrayMap = MediaMetadataCompat.METADATA_KEYS_TYPE;
if (arrayMap.containsKey(str) && ((Integer) arrayMap.get(str)).intValue() != 0) {
throw new IllegalArgumentException(a.l("The ", str, " key cannot be used to put a long"));
}
this.mBundle.putLong(str, j);
return this;
}
public Builder putRating(String str, RatingCompat ratingCompat) {
ArrayMap<String, Integer> arrayMap = MediaMetadataCompat.METADATA_KEYS_TYPE;
if (arrayMap.containsKey(str) && ((Integer) arrayMap.get(str)).intValue() != 3) {
throw new IllegalArgumentException(a.l("The ", str, " key cannot be used to put a Rating"));
}
this.mBundle.putParcelable(str, (Parcelable) ratingCompat.getRating());
return this;
}
public Builder putString(String str, String str2) {
ArrayMap<String, Integer> arrayMap = MediaMetadataCompat.METADATA_KEYS_TYPE;
if (arrayMap.containsKey(str) && ((Integer) arrayMap.get(str)).intValue() != 1) {
throw new IllegalArgumentException(a.l("The ", str, " key cannot be used to put a String"));
}
this.mBundle.putCharSequence(str, str2);
return this;
}
public Builder putText(String str, CharSequence charSequence) {
ArrayMap<String, Integer> arrayMap = MediaMetadataCompat.METADATA_KEYS_TYPE;
if (arrayMap.containsKey(str) && ((Integer) arrayMap.get(str)).intValue() != 1) {
throw new IllegalArgumentException(a.l("The ", str, " key cannot be used to put a CharSequence"));
}
this.mBundle.putCharSequence(str, charSequence);
return this;
}
public Builder(MediaMetadataCompat mediaMetadataCompat) {
Bundle bundle = new Bundle(mediaMetadataCompat.mBundle);
this.mBundle = bundle;
MediaSessionCompat.ensureClassLoader(bundle);
}
@RestrictTo
public Builder(MediaMetadataCompat mediaMetadataCompat, int i) {
this(mediaMetadataCompat);
for (String str : this.mBundle.keySet()) {
Object obj = this.mBundle.get(str);
if (obj instanceof Bitmap) {
Bitmap bitmap = (Bitmap) obj;
if (bitmap.getHeight() > i || bitmap.getWidth() > i) {
putBitmap(str, scaleBitmap(bitmap, i));
}
}
}
}
}
public MediaMetadataCompat(Parcel parcel) {
this.mBundle = parcel.readBundle(MediaSessionCompat.class.getClassLoader());
}
}