2024-05-09 20:30:22 +08:00
package com.xixun.xixunplayer ;
import static android.view.View.VISIBLE ;
import android.app.ActivityManager ;
import android.graphics.BitmapFactory ;
import android.os.Environment ;
import android.os.StatFs ;
import android.webkit.WebView ;
import androidx.annotation.OptIn ;
import androidx.media3.common.util.UnstableApi ;
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.FileReader ;
import java.io.InputStream ;
import java.io.OutputStream ;
import java.io.OutputStreamWriter ;
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 ;
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 SocketThread extends Thread {
MainActivity main ;
Socket socket ;
InputStream in ;
OutputStream out ;
2024-06-06 22:11:01 +08:00
SimpleDateFormat fmt = new SimpleDateFormat ( " MM-dd HH:mm:ss " ) ;
2024-05-09 20:30:22 +08:00
public SocketThread ( MainActivity main , Socket socket ) {
this . main = main ;
this . socket = socket ;
}
@OptIn ( markerClass = UnstableApi . class ) @Override
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 ) ;
if ( file . isFile ( ) & & file . length ( ) = = fil . intg ( " size " ) ) existed . add ( name ) ;
}
new JSMap ( " _type " , _type , " existed " , existed ) . write ( out ) ;
2024-05-09 20:30:22 +08:00
}
} else if ( " proStart " . equals ( _type ) ) {
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 ) ) {
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 ) ;
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
}
} else if ( " imgFileStart " . equals ( _type ) ) {
var size = obj . intg ( " size " ) ;
var fout = new FileOutputStream ( Util . backImgFile ) ;
IOs . write ( fout , in , size ) ;
fout . flush ( ) ;
fout . getFD ( ) . sync ( ) ;
fout . close ( ) ;
main . runOnUiThread ( ( ) - > {
2024-05-11 21:12:39 +08:00
main . backView . cosImg = BitmapFactory . decodeFile ( Util . backImgFile , Util . noScaled ) ;
2024-05-09 20:30:22 +08:00
main . backView . invalidate ( ) ;
} ) ;
} else if ( " imgFileEnd " . equals ( _type ) ) {
new JSMap ( " success " , true ) . write ( out ) ;
} else if ( " proEnd " . equals ( _type ) ) {
new JSMap ( " success " , progJson ! = null ) . write ( out ) ;
if ( progJson ! = null ) {
var json = progJson . toByteArray ( ) ;
progJson = null ;
main . runOnUiThread ( ( ) - > main . initProg ( json ) ) ;
}
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 ) ;
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 ) ;
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 ( ) ;
main . runOnUiThread ( ( ) - > main . initProg ( json ) ) ;
Util . println ( " Succeed " ) ;
new JSMap ( " success " , true ) . write ( out ) ;
}
} catch ( Exception e ) {
Util . printStackTrace ( e ) ;
new JSMap ( " success " , false ) . write ( out ) ;
main . runOnUiThread ( ( ) - > Util . makeText ( main , Util . toStr ( e ) ) . show ( ) ) ;
}
2024-05-09 20:30:22 +08:00
} else if ( " DelPrograms " . equals ( _type ) ) {
var latch = new CountDownLatch ( 1 ) ;
var ok = new AtomicBoolean ( false ) ;
main . runOnUiThread ( ( ) - > {
ok . set ( main . delProgFile ( ) ) ;
latch . countDown ( ) ;
} ) ;
try {
latch . await ( ) ;
} catch ( InterruptedException ignored ) { }
new JSMap ( " success " , ok . get ( ) ) . 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 ( " getPlayerState " . equals ( _type ) ) {
var descs = Util . getState ( main . state ) ;
new JSMap (
" code " , main . 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 . progView ! = null ) for ( var page : main . progView . pages ) dur + = page . tDur ;
2024-06-06 22:11:01 +08:00
writer . append ( " ProgSend: " ) . append ( Fmt . format ( new File ( Util . programDir + " /program " ) . lastModified ( ) ) ) . append ( " ProgDur: " ) . append ( String . valueOf ( dur ) ) . append ( " ms " ) ;
if ( main . progView ! = null ) writer . append ( " Size Avas: " ) . append ( String . valueOf ( main . progView . avas . size ( ) ) ) . append ( " Pages: " ) . append ( String . valueOf ( main . progView . pages . size ( ) ) ) ;
2024-05-09 20:30:22 +08:00
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 . progView = = null ) writer . append ( " ProgView is Null \ n " ) ;
else if ( main . progView . avas . isEmpty ( ) ) writer . append ( " No Avas \ n " ) ;
else writer . append ( " Page End: " ) . append ( Fmt . format ( main . progView . curAva ( ) . endMilli ) ) . append ( " CurPage: " ) . append ( String . valueOf ( main . progView . curAva ) ) . append ( " / " ) . append ( String . valueOf ( main . progView . avas . get ( main . progView . curAva ) ) ) . append ( " \ n " ) ;
writer . append ( " Current: " ) . append ( Fmt . format ( System . currentTimeMillis ( ) ) ) . 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 " ) ;
var actManager = ( ActivityManager ) main . getSystemService ( main . 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 " ) ;
var latch = new CountDownLatch ( 1 ) ;
main . runOnUiThread ( ( ) - > {
if ( main . progView ! = null & & ! main . progView . avas . isEmpty ( ) ) {
var page = main . progView . 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");
} else if ( view . exoPlayer ! = null ) {
writer . append ( " VideoPlaying: " ) . append ( String . valueOf ( view . exoPlayer . isPlaying ( ) ) ) . append ( " " ) . append ( String . valueOf ( view . exoPlayer . getCurrentPosition ( ) ) ) . append ( " / " ) . append ( String . valueOf ( view . exoPlayer . getDuration ( ) ) ) . append ( " \ n " ) ;
writer . append ( " BitRate: " ) . append ( String . valueOf ( view . bitRate / 1000 ) ) . append ( " k \ n " ) ;
writer . append ( " PlaybackStat: " ) . append ( view . getState ( ) ) . append ( " \ n " ) ;
writer . append ( " PlayerError: " ) . append ( String . valueOf ( view . exoPlayer . getPlayerError ( ) ) ) . append ( " \ n " ) ;
writer . append ( " VideoFormat: " ) . append ( String . valueOf ( view . exoPlayer . getVideoFormat ( ) ) ) . append ( " \ n " ) ;
var cnt = view . exoPlayer . getRendererCount ( ) ;
for ( int rr = 0 ; rr < cnt ; rr + + ) writer . append ( " Renderer: " ) . append ( String . valueOf ( view . exoPlayer . getRendererType ( rr ) ) ) . append ( " " ) . append ( String . valueOf ( view . exoPlayer . getRenderer ( rr ) ) ) . append ( " \ n " ) ;
writer . append ( " getPlaybackParameters: " ) . append ( String . valueOf ( view . exoPlayer . getPlaybackParameters ( ) ) ) . 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 ( " OrUrl: " ) . 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 ( ) ;
2024-07-04 17:45:56 +08:00
if ( files ! = null ) {
Arrays . sort ( files , ( f1 , f2 ) - > ( int ) ( 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 . 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-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 ;
}
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 " ) ;
}
}
}