Private
Public Access
Import minamp 1.0 source
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
0df8124629
194 files changed
+7319
No files matched your search
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user