Import minamp 1.0 source

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xockoandClaude Opus 5.5 committed 2026-10-14 19:38:37 +02:00
commit 0df8124629
194 files changed
+7319

No files matched your search

+183
View File
@@ -0,0 +1,183 @@
package com.minamp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Handler;
import com.minamp.net.CertVerifier;
import com.minamp.net.Http;
import com.minamp.plex.Library;
import com.minamp.plex.Plex;
import com.minamp.plex.Server;
import com.minamp.util.Json;
public class App extends Application {
private static App instance;
public static App get() { return instance; }
public Handler handler;
public SharedPreferences prefs;
public Server server;
public Library library;
public ImageLoader images;
// quality: 0 = original (direct play when possible), otherwise MP3 kbps
public static final int[] QUALITIES = {0, 320, 256, 192, 128, 96};
public static final String[] QUALITY_LABELS = {"Original", "320 kbps MP3", "256 kbps MP3", "192 kbps MP3", "128 kbps MP3", "96 kbps MP3"};
@Override
public void onCreate() {
super.onCreate();
instance = this;
handler = new Handler();
prefs = getSharedPreferences("minamp", MODE_PRIVATE);
// Android 2.2's HttpURLConnection pool is buggy; we use our own client, but be safe.
System.setProperty("http.keepAlive", "false");
String cid = prefs.getString("clientId", null);
if (cid == null) {
cid = UUID.randomUUID().toString();
prefs.edit().putString("clientId", cid).commit();
}
Plex.clientId = cid;
Plex.platformVersion = Build.VERSION.RELEASE;
Plex.device = Build.MODEL;
Plex.deviceName = Build.MODEL;
try { Plex.version = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; } catch (Exception ignored) {}
CertVerifier.setRootStore(new AssetRoots(this));
images = new ImageLoader(this);
loadServer();
PlayQueue.get().restore(this);
registerReceiver(new BroadcastReceiver() {
@Override public void onReceive(Context c, Intent i) {
// Network changed (Wi-Fi <-> mobile, new Wi-Fi...): re-pick the best connection lazily.
if (server != null) server.invalidate();
}
}, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
// ------------------------------------------------------------------ server/library
public void loadServer() {
String sj = prefs.getString("server", null);
String sec = prefs.getString("section", null);
server = null;
library = null;
if (sj != null) {
try {
server = Server.fromJson(Json.parseObj(sj));
if (sec != null) library = new Library(server, sec);
} catch (Exception e) {
server = null;
}
}
}
public void saveServer(Server s) {
prefs.edit().putString("server", s.toJson().toString()).remove("section").remove("sectionTitle").commit();
server = s;
library = null;
}
public void saveSection(String key, String title) {
prefs.edit().putString("section", key).putString("sectionTitle", title).commit();
library = new Library(server, key);
}
public boolean isConfigured() { return server != null && library != null; }
public String sectionTitle() { return prefs.getString("sectionTitle", "Music"); }
public void signOut() {
prefs.edit().remove("server").remove("section").remove("sectionTitle").remove("account").remove("username").commit();
server = null;
library = null;
Http.evictAll();
}
// ------------------------------------------------------------------ quality
public boolean onMobileData() {
try {
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
return ni != null && ni.getType() != ConnectivityManager.TYPE_WIFI;
} catch (Exception e) {
return false;
}
}
public int qualityHome() { return prefs.getInt("qHome", 0); }
public int qualityAway() { return prefs.getInt("qAway", 192); }
/** Max kbps for the current situation; 0 = original. */
public int currentMaxKbps() {
boolean away = server == null || !server.isLocal() || onMobileData();
int q = away ? qualityAway() : qualityHome();
if (server != null && server.isRelay() && (q == 0 || q > 192)) q = 192; // relay is bandwidth-capped
return q;
}
public boolean downloadFirst() { return prefs.getBoolean("downloadFirst", false); }
// ------------------------------------------------------------------ trust store
/** Mozilla roots shipped as assets/roots/<sha1(subject)>-<n>.der */
static final class AssetRoots implements CertVerifier.RootStore {
private final Context ctx;
private Set<String> names;
AssetRoots(Context c) { ctx = c; }
public synchronized List<byte[]> find(byte[] subjectDer) {
try {
if (names == null) {
names = new HashSet<String>();
String[] l = ctx.getAssets().list("roots");
if (l != null) for (int i = 0; i < l.length; i++) names.add(l[i]);
}
String h = CertVerifier.sha1Hex(subjectDer);
List<byte[]> out = null;
for (int i = 0; names.contains(h + "-" + i + ".der"); i++) {
if (out == null) out = new ArrayList<byte[]>();
out.add(readAll(ctx.getAssets().open("roots/" + h + "-" + i + ".der")));
}
return out;
} catch (IOException e) {
return null;
}
}
}
static byte[] readAll(InputStream in) throws IOException {
try {
ByteArrayOutputStream b = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
int n;
while ((n = in.read(buf)) > 0) b.write(buf, 0, n);
return b.toByteArray();
} finally {
in.close();
}
}
}