package com.xixun.xixunplayer; import static android.view.View.VISIBLE; import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import android.graphics.BitmapFactory; import android.os.Environment; import android.os.StatFs; import android.view.WindowManager; import android.webkit.WebView; import net.lingala.zip4j.ZipFile; 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; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.HashSet; import java.util.TimeZone; 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; public class TCPThread extends Thread { 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(); } MainActivity main; Socket socket; InputStream in; OutputStream out; SimpleDateFormat fmt = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); public TCPThread(MainActivity main, Socket socket) { this.main = main; this.socket = socket; } public void run() { try { socket.setSoTimeout(600000); Util.socketThreads.add(this); in = socket.getInputStream(); out = socket.getOutputStream(); HashSet existed = null; ByteArrayOutputStream progJson = null; while(true) { var obj = JSMap.from(in); var _type = obj.stnn("_type"); Util.println("_type: "+_type); if("consult".equals(_type)) { JSList 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); if(file.isFile() && file.length()==fil.intg("size")) existed.add(name); } new JSMap("_type", _type, "existed", existed).write(out); } } else if("proStart".equals(_type)) { Util.downId = 0; Util.deleteFiles(obj.intg("proSize"), existed); } else if("fileStart".equals(_type)) { var size = obj.intg("size"); 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); try { IOs.write(fOut, in, size); fOut.flush(); fOut.getFD().sync(); fOut.close(); } catch(Throwable e) { fOut.close(); new File(Util.programDir + "/" + name).delete(); } } } else if("setBackImg".equals(_type) || "imgFileStart".equals(_type)) { var fout = new FileOutputStream(Util.backImgFile); IOs.write(fout, in, obj.intg("size")); fout.flush(); fout.getFD().sync(); fout.close(); var img = BitmapFactory.decodeFile(Util.backImgFile, Util.noScaled); if(main!=null) main.runOnUiThread(() -> { main.backView.cosImg = img; main.backView.invalidate(); }); new JSMap("success", true).write(out); } else if("proEnd".equals(_type)) { new JSMap("_type", "AckSuccess", "success", progJson!=null).write(out); if(progJson!=null) { var json = progJson.toByteArray(); progJson = null; var acti = MainActivity.ins; if(acti!=null) acti.runOnUiThread(() -> acti.initProg(json)); else { var fOut = new FileOutputStream(Util.programDir + "/program"); fOut.write(json); 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); } } if(MainService.ins!=null) { var intent = new Intent("com.xixun.AccessibilityService"); intent.putExtra("newProgram", "TCP"); MainService.ins.sendBroadcast(intent); } } } 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); if(main!=null) main.runOnUiThread(() -> Util.makeText(main, "No program File").show()); } else if(size==0) { Util.println("Zip Size is 0"); new JSMap("success", false, "msg", "Zip Size is 0").write(out); if(main!=null) main.runOnUiThread(() -> Util.makeText(main, "zip size is 0").show()); } 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(); var acti = MainActivity.ins; if(acti!=null) acti.runOnUiThread(()->acti.initProg(json)); else { var fOut = new FileOutputStream(Util.programDir + "/program"); fOut.write(json); 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); } } new JSMap("success", true).write(out); if(MainService.ins!=null) { var intent = new Intent("com.xixun.AccessibilityService"); intent.putExtra("newProgram", "TCP"); MainService.ins.sendBroadcast(intent); } } } catch (Exception e) { Util.printStackTrace(e); new JSMap("success", false).write(out); if(main!=null) main.runOnUiThread(() -> Util.makeText(main, Util.toStr(e)).show()); } } else if("DelPrograms".equals(_type)) { Util.downId = 0; var ok = new AtomicBoolean(false); if(main!=null) { var latch = new CountDownLatch(1); main.runOnUiThread(() -> { ok.set(main.delProgFile()); latch.countDown(); }); try { latch.await(); } catch (InterruptedException ignored) {} } new JSMap("success", ok.get()).write(out); } 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); } } 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); } 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); } else if("getPlayerState".equals(_type)) { var state = main==null ? 8 : main.state; var descs = Util.getState(state); new JSMap( "code", state, "des_en", descs[0], "des", descs[1] ).write(out); } else if("GetInfo".equals(_type)) { var writer = new OutputStreamWriter(out); var fmt = new SimpleDateFormat("yy-MM-dd HH:mm:ss.SSS"); var dur = 0; if(main==null) writer.append("\nAPP is Closed\n"); else { try { var packageInfo = main.getPackageManager().getPackageInfo(main.getPackageName(), 0); writer.append("ver: ").append(packageInfo.versionName).append("\n"); } catch (Exception ignored) {} 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"); writer.append(" Sync: ").append(fmt.format(main.syncMs)).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"); } writer.append(" Current: ").append(fmt.format(System.currentTimeMillis())).append(" ").append(String.valueOf(TimeZone.getDefault().getRawOffset()/3600000f)).append(" ").append(TimeZone.getDefault().getDisplayName()).append("\n"); 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"); } 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"); 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"); } 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"); writer.append("Server URL "+Util.serverURL); writer.append("\n\n"); writer.append(Util.cfg.toStr()); writer.append("\n\n"); var latch = new CountDownLatch(1); if(main!=null) main.runOnUiThread(() -> { if(! main.avas.isEmpty()) { var page = main.avas.get(main.curAva); for(var layer : page.layers) for(var src : layer.srcs) if(src.view.getVisibility()==VISIBLE) { try { if(src.view instanceof SrcVideo) { 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"); writer.append("OriginUrl: ").append(view.getOriginalUrl()).append("\n"); 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(); if(files!=null) { Arrays.sort(files, (f1, f2) -> Long.signum(f2.lastModified() - f1.lastModified())); 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(); } } else if("GetFile".equals(_type)) { var name = obj.str("name"); 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)); } } } else if("GetJsonWithFileInfo".equals(_type)) { var inse = new File(Util.programDir+"/insert"); var files = new File(Util.programDir).listFiles(); if(inse.isFile()) { var json = IOs.readStrClose(new FileInputStream(inse)); 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(); } var prog = new File(Util.programDir+"/program"); if(! prog.isFile()) new JSMap("msg", "'program' file not exist").write(out); else { var json = IOs.readStrClose(new FileInputStream(prog)); 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("\nprogram:\n"); writer.append(json); writer.flush(); } } out.flush(); Util.println("cmd end"); } } catch (Throwable e) { var emsg = e.getMessage(); if(e instanceof SocketTimeoutException || "Socket closed".equals(emsg) || (emsg!=null && emsg.endsWith("end-of-input"))) { Util.println(emsg); return; } if(main!=null) main.runOnUiThread(() -> Util.makeText(main, Util.toStr(e)).show()); Util.printStackTrace(e); } finally { Util.socketThreads.remove(this); O.close(in, out, socket); Util.println("conn end\n"); } } }