Android/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/TCPThread.java

423 lines
25 KiB
Java
Raw Normal View History

2024-05-09 20:30:22 +08:00
package com.xixun.xixunplayer;
import static android.view.View.VISIBLE;
import android.app.ActivityManager;
2026-01-13 15:56:06 +08:00
import android.content.ComponentName;
2025-07-28 19:14:00 +08:00
import android.content.Context;
import android.content.Intent;
2024-05-09 20:30:22 +08:00
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.StatFs;
2025-07-28 19:14:00 +08:00
import android.view.WindowManager;
2024-05-09 20:30:22 +08:00
import android.webkit.WebView;
2024-07-04 17:45:56 +08:00
import net.lingala.zip4j.ZipFile;
2024-05-09 20:30:22 +08:00
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
2025-07-28 19:14:00 +08:00
import java.net.ServerSocket;
2024-05-09 20:30:22 +08:00
import java.net.Socket;
2024-06-06 22:11:01 +08:00
import java.net.SocketTimeoutException;
2024-05-09 20:30:22 +08:00
import java.text.SimpleDateFormat;
import java.util.Arrays;
2024-06-06 22:11:01 +08:00
import java.util.Date;
2024-05-09 20:30:22 +08:00
import java.util.HashSet;
2024-07-22 17:42:12 +08:00
import java.util.TimeZone;
2024-05-09 20:30:22 +08:00
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import gnph.util.IOs;
import gnph.util.JSList;
import gnph.util.JSMap;
import gnph.util.NumFmts;
import gnph.util.O;
2024-11-25 11:50:10 +08:00
public class TCPThread extends Thread {
2025-07-28 19:14:00 +08:00
public static void startServer(int port) {
new Thread(()->{
try {
var serverSocket = new ServerSocket(port);
while(true) {
try {
Util.println("\nAccepting ...");
var socket = serverSocket.accept();
new TCPThread(MainActivity.ins, socket).start();
Util.println("\nAccepted");
} catch (Throwable e) {
var ins = MainActivity.ins;
if(ins!=null) ins.runOnUiThread(() -> Util.makeText(ins, Util.toStr(e)).show());
Util.printStackTrace(e);
}
}
} catch (Throwable e) {
var msg = e.getMessage();
if(msg==null || ! msg.contains("in use")) MainActivity.ins.runOnUiThread(() -> Util.makeText(MainActivity.ins, Util.toStr(e)).show());
Util.printStackTrace(e);
}
}).start();
}
2024-05-09 20:30:22 +08:00
MainActivity main;
Socket socket;
InputStream in;
OutputStream out;
2025-07-28 19:14:00 +08:00
SimpleDateFormat fmt = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
2024-06-06 22:11:01 +08:00
2024-11-25 11:50:10 +08:00
public TCPThread(MainActivity main, Socket socket) {
2024-05-09 20:30:22 +08:00
this.main = main;
this.socket = socket;
}
public void run() {
try {
socket.setSoTimeout(600000);
Util.socketThreads.add(this);
in = socket.getInputStream();
out = socket.getOutputStream();
2024-06-06 22:11:01 +08:00
HashSet<String> existed = null;
2024-05-09 20:30:22 +08:00
ByteArrayOutputStream progJson = null;
while(true) {
var obj = JSMap.from(in);
var _type = obj.stnn("_type");
Util.println("_type: "+_type);
if("consult".equals(_type)) {
2024-06-06 22:11:01 +08:00
JSList<JSMap> files = obj.jslist("files");
if(files==null) new JSMap("_type", _type, "idList", obj.jslist("idList")).write(out);
else {
existed = new HashSet<>();
for(var fil : files) {
var name = fil.stnn("name");
var file = new File(Util.programDir + "/" + name);
2025-08-22 23:08:48 +08:00
if(file.isFile() && file.length()==fil.lng("size")) existed.add(name);
2024-06-06 22:11:01 +08:00
}
new JSMap("_type", _type, "existed", existed).write(out);
2024-05-09 20:30:22 +08:00
}
} else if("proStart".equals(_type)) {
2025-07-28 19:14:00 +08:00
Util.downId = 0;
2024-06-06 22:11:01 +08:00
Util.deleteFiles(obj.intg("proSize"), existed);
2024-05-09 20:30:22 +08:00
} else if("fileStart".equals(_type)) {
2025-08-22 23:08:48 +08:00
var size = obj.lng("size");
2024-05-09 20:30:22 +08:00
var name = obj.stnn("id");
Util.println(" size: " + size + " name: " + name);
if(name.equals("program")) {
progJson = new ByteArrayOutputStream();
IOs.writeCloseOut(progJson, in, size);
} else {
var fOut = new FileOutputStream(Util.programDir + "/" + name);
2024-06-06 22:11:01 +08:00
try {
IOs.write(fOut, in, size);
fOut.flush();
fOut.getFD().sync();
fOut.close();
} catch(Throwable e) {
fOut.close();
new File(Util.programDir + "/" + name).delete();
}
2024-05-09 20:30:22 +08:00
}
2024-11-11 18:22:45 +08:00
} else if("setBackImg".equals(_type) || "imgFileStart".equals(_type)) {
2024-05-09 20:30:22 +08:00
var fout = new FileOutputStream(Util.backImgFile);
2025-08-22 23:08:48 +08:00
IOs.write(fout, in, obj.lng("size"));
2024-05-09 20:30:22 +08:00
fout.flush();
fout.getFD().sync();
fout.close();
2024-11-11 18:22:45 +08:00
var img = BitmapFactory.decodeFile(Util.backImgFile, Util.noScaled);
2024-08-22 17:37:46 +08:00
if(main!=null) main.runOnUiThread(() -> {
2024-11-11 18:22:45 +08:00
main.backView.cosImg = img;
2024-05-09 20:30:22 +08:00
main.backView.invalidate();
});
new JSMap("success", true).write(out);
} else if("proEnd".equals(_type)) {
2025-07-28 19:14:00 +08:00
new JSMap("_type", "AckSuccess", "success", progJson!=null).write(out);
2024-05-09 20:30:22 +08:00
if(progJson!=null) {
var json = progJson.toByteArray();
progJson = null;
2025-07-28 19:14:00 +08:00
var acti = MainActivity.ins;
if(acti!=null) acti.runOnUiThread(() -> acti.initProg(json));
2024-08-22 17:37:46 +08:00
else {
var fOut = new FileOutputStream(Util.programDir + "/program");
fOut.write(json);
2025-12-23 16:40:05 +08:00
var spaces = " ".getBytes();
for(int i=0;i<1000; i++) fOut.write(spaces);
2024-08-22 17:37:46 +08:00
fOut.flush();
fOut.getFD().sync();
fOut.close();
2025-07-28 19:14:00 +08:00
if(MainService.ins!=null) {
var intent = new Intent(MainService.ins, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainService.ins.startActivity(intent);
}
}
2026-01-13 15:56:06 +08:00
if(MainService.ins!=null) { //周鹏注释
2025-07-28 19:14:00 +08:00
var intent = new Intent("com.xixun.AccessibilityService");
intent.putExtra("newProgram", "TCP");
MainService.ins.sendBroadcast(intent);
2026-01-13 15:56:06 +08:00
2024-08-22 17:37:46 +08:00
}
2024-05-09 20:30:22 +08:00
}
2024-07-04 17:45:56 +08:00
} else if("playZipTask".equals(_type)) {
var zip = new ZipFile(Util.programDir+"/"+obj.stnn("proName"));
if(zip.isEncrypted()) zip.setPassword(new char[]{'8','8','8'});
long size = 0;
ByteArrayOutputStream jsonOut = null;
try {
var headers = zip.getFileHeaders();
for(var header : headers) {
size += header.getUncompressedSize();
if("program".equals(header.getFileName())) IOs.writeClose(jsonOut = new ByteArrayOutputStream(), zip.getInputStream(header));
}
if(jsonOut==null) {
Util.println("No 'program' File");
new JSMap("success", false, "msg", "No 'program' File").write(out);
2024-08-22 17:37:46 +08:00
if(main!=null) main.runOnUiThread(() -> Util.makeText(main, "No program File").show());
2024-07-04 17:45:56 +08:00
} else if(size==0) {
Util.println("Zip Size is 0");
new JSMap("success", false, "msg", "Zip Size is 0").write(out);
2024-08-22 17:37:46 +08:00
if(main!=null) main.runOnUiThread(() -> Util.makeText(main, "zip size is 0").show());
2024-07-04 17:45:56 +08:00
} else {
Util.deleteFiles(size, null);
for(var header : headers) if(! "program".equals(header.getFileName())) {
Util.println(" name: " + header.getFileName());
var fOut = new FileOutputStream(Util.programDir + "/" + header.getFileName());
IOs.writeCloseIn(fOut, zip.getInputStream(header));
fOut.flush();
fOut.getFD().sync();
fOut.close();
}
var json = jsonOut.toByteArray();
2025-07-28 19:14:00 +08:00
var acti = MainActivity.ins;
if(acti!=null) acti.runOnUiThread(()->acti.initProg(json));
else {
var fOut = new FileOutputStream(Util.programDir + "/program");
fOut.write(json);
2025-12-23 16:40:05 +08:00
fOut.write("{}".getBytes());
var spaces = " ".getBytes();
2025-07-28 19:14:00 +08:00
fOut.flush();
fOut.getFD().sync();
fOut.close();
if(MainService.ins!=null) {
var intent = new Intent(MainService.ins, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainService.ins.startActivity(intent);
}
}
2024-07-04 17:45:56 +08:00
new JSMap("success", true).write(out);
2025-07-28 19:14:00 +08:00
if(MainService.ins!=null) {
var intent = new Intent("com.xixun.AccessibilityService");
intent.putExtra("newProgram", "TCP");
MainService.ins.sendBroadcast(intent);
}
2024-07-04 17:45:56 +08:00
}
} catch (Exception e) {
Util.printStackTrace(e);
new JSMap("success", false).write(out);
2024-08-22 17:37:46 +08:00
if(main!=null) main.runOnUiThread(() -> Util.makeText(main, Util.toStr(e)).show());
2024-07-04 17:45:56 +08:00
}
2024-05-09 20:30:22 +08:00
} else if("DelPrograms".equals(_type)) {
2025-07-28 19:14:00 +08:00
Util.downId = 0;
2024-05-09 20:30:22 +08:00
var ok = new AtomicBoolean(false);
2025-07-28 19:14:00 +08:00
if(main!=null) {
var latch = new CountDownLatch(1);
main.runOnUiThread(() -> {
ok.set(main.delProgFile());
latch.countDown();
});
try {
latch.await();
} catch (InterruptedException ignored) {}
}
2024-05-09 20:30:22 +08:00
new JSMap("success", ok.get()).write(out);
2024-08-22 18:14:03 +08:00
} else if("getProgramName".equals(_type)) {
try {
String name = null;
var ins = MainActivity.ins;
if(ins!=null && ! ins.avas.isEmpty()) name = ins.avas.get(ins.curAva).name;
new JSMap("success", true, "name", name).write(out);
Util.println(" name "+name);
} catch (Exception e) {
Util.printStackTrace(e);
new JSMap("success", false, "msg", Util.toStr(e)).write(out);
}
2024-05-09 20:30:22 +08:00
} else if("DelBackImg".equals(_type)) {
MainActivity.ins.runOnUiThread(() -> {
MainActivity.ins.backView.cosImg = null;
MainActivity.ins.backView.invalidate();
});
new JSMap("success", new File(Util.backImgFile).delete()).write(out);
2025-07-28 19:14:00 +08:00
} else if("Config".equals(_type)) {
var entrySet = obj.entrySet();
for(var entry : entrySet) if(! entry.getKey().equals("_type")) Util.cfg.put(entry.getKey(), entry.getValue());
try (var fOut = new FileOutputStream(Util.programDir + "/cfg")) {
Util.cfg.write(fOut);
fOut.flush();
fOut.getFD().sync();
}
new JSMap("success", new File(Util.backImgFile).delete()).write(out);
2024-05-09 20:30:22 +08:00
} else if("getPlayerState".equals(_type)) {
2024-08-22 17:37:46 +08:00
var state = main==null ? 8 : main.state;
var descs = Util.getState(state);
2024-05-09 20:30:22 +08:00
new JSMap(
2024-08-22 17:37:46 +08:00
"code", state,
2024-05-09 20:30:22 +08:00
"des_en", descs[0],
"des", descs[1]
).write(out);
} else if("GetInfo".equals(_type)) {
var writer = new OutputStreamWriter(out);
2024-07-22 17:42:12 +08:00
var fmt = new SimpleDateFormat("yy-MM-dd HH:mm:ss.SSS");
2024-05-09 20:30:22 +08:00
var dur = 0;
2024-08-22 17:37:46 +08:00
if(main==null) writer.append("\nAPP is Closed\n");
else {
2025-07-28 19:14:00 +08:00
try {
var packageInfo = main.getPackageManager().getPackageInfo(main.getPackageName(), 0);
writer.append("ver: ").append(packageInfo.versionName).append("\n");
} catch (Exception ignored) {}
2024-08-22 17:37:46 +08:00
if(main.progView!=null) for(var page : main.progView.pages) dur += page.tDur;
writer.append("ProgSend: ").append(fmt.format(new File(Util.programDir + "/program").lastModified())).append(" ProgDur: ").append(String.valueOf(dur)).append("ms");
writer.append(" Size Avas: ").append(String.valueOf(main.avas.size())).append(" Pages: ").append(main.progView==null ? "null" : String.valueOf(main.progView.pages.size()));
writer.append("\n");
writer.append(" Launch: ").append(fmt.format(main.launchMilli)).append("\n");
if(main.insView==null) writer.append(" InseView is Null\n");
if(main.progView==null) writer.append(" ProgView is Null\n");
if(main.avas.isEmpty()) writer.append(" No Avas\n");
else writer.append("Page End: ").append(fmt.format(main.avas.get(main.curAva).endMilli)).append(" CurPage: ").append(String.valueOf(main.curAva)).append(" ").append(String.valueOf(main.avas.get(main.curAva).name)).append("\n");
}
2024-07-22 17:42:12 +08:00
writer.append(" Current: ").append(fmt.format(System.currentTimeMillis())).append(" ").append(String.valueOf(TimeZone.getDefault().getRawOffset()/3600000f)).append(" ").append(TimeZone.getDefault().getDisplayName()).append("\n");
2025-07-28 19:14:00 +08:00
if(main!=null) {
var mng = (WindowManager) main.getSystemService(Context.WINDOW_SERVICE);
var display = mng.getDefaultDisplay();
writer.append("RefreshRate: ").append(String.valueOf(display.getRefreshRate())).append("\n");
}
2024-05-09 20:30:22 +08:00
var statFs = new StatFs(Environment.getExternalStorageDirectory().getPath());
writer.append(" Disk: ").append(String.valueOf(statFs.getTotalBytes()/1000000)).append(" ").append(String.valueOf(statFs.getAvailableBytes()/1000000)).append(" ").append(String.valueOf(statFs.getFreeBytes()/1000000)).append(" (total avail free)\n");
2024-08-22 17:37:46 +08:00
if(main!=null) {
var actManager = (ActivityManager) main.getSystemService(MainActivity.ACTIVITY_SERVICE);
var memoryInfo = new ActivityManager.MemoryInfo();
actManager.getMemoryInfo(memoryInfo);
writer.append(" Memory: ").append(String.valueOf(memoryInfo.totalMem/1000000)).append(" ").append(String.valueOf(memoryInfo.availMem/1000000)).append(" ").append(String.valueOf(memoryInfo.threshold/1000000)).append(" ").append(String.valueOf(memoryInfo.lowMemory)).append(" (total avail threshold low)\n");
}
2024-05-09 20:30:22 +08:00
var runtime = Runtime.getRuntime();
writer.append("Runtime: ").append(String.valueOf(runtime.maxMemory()/1000000)).append(" ").append(String.valueOf(runtime.totalMemory()/1000000)).append(" ").append(NumFmts.cfix2().format(runtime.freeMemory()*0.000001)).append(" (max total free)\n");
// writer.append("/proc/stat\n");
// IOs.writeCloseIn(writer, new FileReader("/proc/stat"));
writer.append("\nSockets ").append(String.valueOf(Util.socketThreads.size())).append("\n");
for(var socket : Util.socketThreads) writer.append(" ").append(String.valueOf(socket.socket.getInetAddress())).append(":").append(String.valueOf(socket.socket.getPort())).append(" Buf:").append(String.valueOf(socket.socket.getReceiveBufferSize()/1000)).append("k SoLinger:").append(String.valueOf(socket.socket.getSoLinger())).append("\n");
writer.append("\n");
2025-07-28 19:14:00 +08:00
writer.append("Server URL "+Util.serverURL);
writer.append("\n\n");
writer.append(Util.cfg.toStr());
writer.append("\n\n");
2025-12-23 16:40:05 +08:00
writer.append("showeds "+main.showeds.size()).append(" showHides "+main.showHides.size());
writer.append("\n\n");
2025-07-28 19:14:00 +08:00
2024-05-09 20:30:22 +08:00
var latch = new CountDownLatch(1);
2024-08-22 17:37:46 +08:00
if(main!=null) main.runOnUiThread(() -> {
if(! main.avas.isEmpty()) {
var page = main.avas.get(main.curAva);
2025-08-22 23:08:48 +08:00
for(var layer : page.layers) for(var src : layer.srcs) if(src.alphaShow==1 && src.view!=null && src.view.getVisibility()==VISIBLE) {
2024-05-09 20:30:22 +08:00
try {
2025-08-22 23:08:48 +08:00
if(src.typ == 'V') {
2024-05-09 20:30:22 +08:00
var view = (SrcVideo) src.view;
if(view.ijkPlayer!=null) {
writer.append("VideoPlaying: ").append(String.valueOf(view.ijkPlayer.isPlaying())).append("\tCur/Dur: ").append(String.valueOf(view.ijkPlayer.getCurrentPosition())).append("/").append(String.valueOf(view.ijkPlayer.getDuration())).append("\n");
var mediaInfo = view.ijkPlayer.getMediaInfo();
var vStream = mediaInfo.mMeta.mVideoStream;
writer.append(" BitRate: ").append(String.valueOf(view.ijkPlayer.getBitRate()/1000)).append("k\tFPS: ").append(String.valueOf(vStream.mFpsNum/(float)vStream.mFpsDen)).append(" (").append(String.valueOf(vStream.mFpsNum)).append("/").append(String.valueOf(vStream.mFpsDen)).append(")\n");
var tracks = view.ijkPlayer.getTrackInfo();
for(var track : tracks) writer.append(" ").append(track.getInfoInline()).append("\n");
writer.append(" Format: ").append(mediaInfo.mMeta.mFormat).append("\n");
writer.append("VideoDecoder: ").append(mediaInfo.mVideoDecoder).append(" ").append(mediaInfo.mVideoDecoderImpl).append(" (").append(String.valueOf(view.ijkPlayer.getVideoDecoder())).append(")\n");
writer.append("AudioDecoder: ").append(mediaInfo.mAudioDecoder).append(" ").append(mediaInfo.mAudioDecoderImpl).append("\n");
//writer.append("PROFILE: ").append(mediaInfo.mMeta.getString(IjkMediaMeta.IJKM_KEY_CODEC_PROFILE)).append("\n");
}
writer.append("\n");
} else if(src.view instanceof SrcWeather) {
var view = (SrcWeather) src.view;
writer.append("SrcWeather html: ").append(view.html).append("\n");
} else if(src.view instanceof WebView) {
var view = (WebView) src.view;
writer.append("Title: ").append(view.getTitle()).append("\n");
writer.append(" Url: ").append(view.getUrl()).append("\n");
2024-08-22 17:37:46 +08:00
writer.append("OriginUrl: ").append(view.getOriginalUrl()).append("\n");
2024-05-09 20:30:22 +08:00
writer.append("Progress: ").append(String.valueOf(view.getProgress())).append("\n");
}
} catch (Exception ignored) {
}
}
}
latch.countDown();
});
try {
latch.await();
} catch (InterruptedException ignored) {}
writer.flush();
} else if("GetLog".equals(_type)) {
out.write(Util.buf.toString().getBytes());
} else if("ListProgFiles".equals(_type)) {
var files = new File(Util.programDir).listFiles();
2024-07-04 17:45:56 +08:00
if(files!=null) {
2025-07-28 19:14:00 +08:00
Arrays.sort(files, (f1, f2) -> Long.signum(f2.lastModified() - f1.lastModified()));
2024-07-04 17:45:56 +08:00
var writer = new OutputStreamWriter(out);
for(var file : files) writer.append(fmt.format(new Date(file.lastModified()))).append(' ').append(file.getName()).append(' ').append(String.valueOf(file.length())).append('\n');
writer.flush();
}
2024-05-09 20:30:22 +08:00
} else if("GetFile".equals(_type)) {
var name = obj.str("name");
2024-06-06 22:11:01 +08:00
if(name==null) new JSMap("msg", "name is null").write(out);
else {
var file = new File(Util.programDir+"/"+name);
if(! file.isFile()) new JSMap("msg", "file not exist").write(out);
else {
new JSMap("len", file.length()).write(out);
IOs.writeCloseIn(out, new FileInputStream(file));
}
}
2024-07-22 17:42:12 +08:00
} else if("GetJsonWithFileInfo".equals(_type)) {
2024-08-22 17:37:46 +08:00
var inse = new File(Util.programDir+"/insert");
var files = new File(Util.programDir).listFiles();
if(inse.isFile()) {
2025-12-23 16:40:05 +08:00
var json = IOs.readStrClose(new FileInputStream(inse)).trim();
2024-08-22 17:37:46 +08:00
if(files!=null) for(var file : files) if(! "program".equals(file.getName())) json = json.replace("\""+file.getName()+"\"", "\""+file.getName()+"\"/*"+file.length()+" "+fmt.format(new Date(file.lastModified()))+"*/");
var writer = new OutputStreamWriter(out);
writer.append("insert:\n");
writer.append(json);
if(! json.endsWith("\n")) writer.append("\n");
writer.flush();
}
2024-07-22 17:42:12 +08:00
var prog = new File(Util.programDir+"/program");
if(! prog.isFile()) new JSMap("msg", "'program' file not exist").write(out);
else {
2025-12-23 16:40:05 +08:00
var json = IOs.readStrClose(new FileInputStream(prog)).trim();
2024-07-22 17:42:12 +08:00
if(files!=null) for(var file : files) if(! "program".equals(file.getName())) json = json.replace("\""+file.getName()+"\"", "\""+file.getName()+"\"/*"+file.length()+" "+fmt.format(new Date(file.lastModified()))+"*/");
var writer = new OutputStreamWriter(out);
2024-08-22 17:37:46 +08:00
writer.append("\nprogram:\n");
2024-07-22 17:42:12 +08:00
writer.append(json);
writer.flush();
}
2024-05-09 20:30:22 +08:00
}
out.flush();
Util.println("cmd end");
}
} catch (Throwable e) {
var emsg = e.getMessage();
2024-06-06 22:11:01 +08:00
if(e instanceof SocketTimeoutException || "Socket closed".equals(emsg) || (emsg!=null && emsg.endsWith("end-of-input"))) {
2024-05-09 20:30:22 +08:00
Util.println(emsg);
return;
}
2024-08-22 17:37:46 +08:00
if(main!=null) main.runOnUiThread(() -> Util.makeText(main, Util.toStr(e)).show());
2024-05-09 20:30:22 +08:00
Util.printStackTrace(e);
} finally {
Util.socketThreads.remove(this);
O.close(in, out, socket);
Util.println("conn end\n");
}
}
}