Minamp 1.1

- Run network/TLS work on 256 KB-stack threads (net/Threads.java): Android 2.x's
  ~16 KB default stack overflowed during the bundled TLS handshake
- Close pooled TLS connections off the caller thread
- Try several Plex music-transcoder URL variants until the server accepts one,
  and remember the one that worked
- Accept pasted server URLs with paths; default to 443 for https
- Catch fatal errors and save a crash report (shown on next launch and written
  to Minamp-error.txt on the SD card)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xockoandClaude Opus 5.5 committed 2026-10-14 19:59:58 +02:00
1 parent 948d1198ad
commit 0a2ac901bd
16 files changed
+417 -80

No files matched your search

+44 -4
View File
@@ -43,7 +43,20 @@ public class PlexTest {
}
}
public static void main(String[] args) throws Exception {
public static void main(final String[] args) throws Exception {
// run everything on the same kind of thread the app uses (256 KB stack, Dalvik's max)
final Throwable[] err = {null};
Thread t = com.minamp.net.Threads.create(new Runnable() {
public void run() { try { realMain(args); } catch (Throwable e) { err[0] = e; } }
}, "test");
t.start();
t.join();
if (err[0] != null) { err[0].printStackTrace(); failures++; }
System.out.println(failures == 0 ? "ALL PASSED" : failures + " FAILED");
System.exit(failures == 0 ? 0 : 1);
}
static void realMain(String[] args) throws Exception {
CertVerifier.setRootStore(roots(args[0]));
Plex.clientId = "test-client";
@@ -91,6 +104,7 @@ public class PlexTest {
check(res.size() == 4 && res.get(0).type == Item.HEADER && res.get(1).type == Item.ARTIST && res.get(3).type == Item.TRACK,
"search hubs grouped (" + res.size() + ")");
check(lib.libraryRadio().size() == 2, "library radio");
check(lib.topRatedRadio().size() == 1, "'>>' filter reaches the server percent-encoded and decoded intact");
String img = s2.imageUrl("/library/metadata/10/thumb/1", 64);
Http.Response ir = Http.get(img, null, 10000);
byte[] ib = ir.readAll();
@@ -110,13 +124,31 @@ public class PlexTest {
check(hc.getResponseCode() == 206 && body.length == 299000 && (body[0] & 255) == (1000 * 7) % 256,
"proxy direct stream with Range over TLS (" + hc.getResponseCode() + ", " + body.length + "B)");
final int[] accepted = {-1};
final String[] refused = {null};
proxy.listener = new StreamProxy.Listener() {
public void onError(String id, int code, String m) { refused[0] = code + " " + m; }
public void onAccepted(String id, int index) { accepted[0] = index; }
};
String id2 = proxy.newId();
String local2 = proxy.register(id2, lib.transcodeUrl(tracks.get(1), 192, 30500, "sess1"), "mp3");
String local2 = proxy.register(id2, lib.transcodeUrls(tracks.get(1), 192, 30500, "sess1"), "mp3");
hc = (HttpURLConnection) new URL(local2).openConnection(Proxy.NO_PROXY);
byte[] tbody = read(hc.getInputStream());
String ts = new String(tbody, "ISO-8859-1");
check(hc.getResponseCode() == 200 && ts.startsWith("TRANSCODE offset=30 bitrate=192|") && hc.getHeaderField("Content-Length") == null,
"proxy de-chunks transcode stream (" + tbody.length + "B)");
check(accepted[0] == 1 && refused[0] == null, "refused transcode variant skipped, second accepted (index " + accepted[0] + ")");
Library.preferredVariant = Library.variantOrder()[accepted[0]];
check(Library.variantOrder()[0] == 1, "accepted variant is tried first next time");
// every variant refused -> error carries the server's words
Library.preferredVariant = 0;
String id4 = proxy.newId();
java.util.List<String> bad = new java.util.ArrayList<String>();
bad.add(lib.transcodeUrls(tracks.get(1), 192, 0, "s4").get(0));
String local4 = proxy.register(id4, bad, "mp3");
hc = (HttpURLConnection) new URL(local4).openConnection(Proxy.NO_PROXY);
int c4 = hc.getResponseCode();
check(c4 == 400 && refused[0] != null && refused[0].indexOf("400 Bad Request") >= 0, "refusal reported with server text: " + refused[0]);
// abort mid-stream
String id3 = proxy.newId();
@@ -153,8 +185,16 @@ public class PlexTest {
check(Server.normalizeManual("192.168.1.5").equals("http://192.168.1.5:32400"), "manual URL normalise");
check(Server.normalizeManual("https://plex.example.com/").equals("https://plex.example.com"), "manual https URL kept");
System.out.println(failures == 0 ? "ALL PASSED" : failures + " FAILED");
System.exit(failures == 0 ? 0 : 1);
check(Server.normalizeManual("http://192.168.1.5:32400/web/index.html#!/").equals("http://192.168.1.5:32400"), "pasted web-app path stripped");
check(Server.normalizeManual("http://192.168.1.5").equals("http://192.168.1.5:32400"), "explicit http gets Plex port");
CertVerifier.setRootStore(roots(args[0]));
Http.evictAll();
try {
s2.items("/library/nonexistent");
check(false, "error names the failing call");
} catch (Plex.PlexException e) {
check(e.getMessage().indexOf("/library/nonexistent") >= 0 && e.getMessage().indexOf("X-Plex-Token") < 0, "error names the failing call: " + e.getMessage());
}
}
static byte[] read(InputStream in) throws Exception {