package com.basic.security.utils.socket.outdoor; import android.os.SystemClock; import com.basic.security.base.BaseApplication; import com.basic.security.manager.DeviceManager; import com.basic.security.model.GuestMessage; import com.basic.security.model.ModelAdapter; import com.basic.security.utils.CompareFeatureResult; import com.basic.security.utils.Constants; import com.basic.security.utils.DetectedResult; import com.basic.security.utils.ObjectUtil; import com.basic.security.utils.SocketUtil; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class OutdoorGuestSocketServer { private static final int MAX_BUFFER = 1; public static List acceptedClientList = new ArrayList<>(); public static Lock acceptedClientListLock = new ReentrantLock(); public static boolean startServer = false; static long lastSetDetectedResult = 0; static DetectedResult prevDetectedResult; public static void setCameraData(byte[] cameraData) { acceptedClientListLock.lock(); for (GuestAcceptedClient acceptedClient : acceptedClientList) { acceptedClient.setCameraData(cameraData); } acceptedClientListLock.unlock(); } public static boolean detectedResultChangedByTrackId(DetectedResult detectedResult) { try { if (prevDetectedResult != null && detectedResult != null) { if (prevDetectedResult.facePositions.size() == 1 && detectedResult.facePositions.size() == 1) { boolean trackerIdEquals = prevDetectedResult.facePositions.get(0).trackerId == detectedResult.facePositions.get(0).trackerId; CompareFeatureResult compareFeatureResult1 = prevDetectedResult.facePositions.get(0).compareFeatureResult; CompareFeatureResult compareFeatureResult2 = detectedResult.facePositions.get(0).compareFeatureResult; boolean compareFeatureResultEqual = false; if (compareFeatureResult1 == null) { if (compareFeatureResult2 == null) { compareFeatureResultEqual = true; } else { compareFeatureResultEqual = false; } } else { if (compareFeatureResult2 == null) { compareFeatureResultEqual = false; } else { compareFeatureResultEqual = ObjectUtil.stringEquals(compareFeatureResult1.personId, compareFeatureResult2.personId); } } return !trackerIdEquals || !compareFeatureResultEqual; } if (prevDetectedResult.facePositions.size() != detectedResult.facePositions.size()) { return true; } } } catch (Exception e) { e.printStackTrace(); } return false; } public static void setDetectedResult(DetectedResult detectedResult) { boolean detectedResultChangedByTrackId = detectedResultChangedByTrackId(detectedResult); if (System.currentTimeMillis() - lastSetDetectedResult > 3 * 1000 || detectedResultChangedByTrackId) { if (Constants.indoorOutdoorInOne) { // System1.out.println("GuestAcceptedClient.setDetectedResult"); BaseApplication.getApplication().activity.fragment_guest_mode.addGuestListS(detectedResult); } acceptedClientListLock.lock(); for (GuestAcceptedClient acceptedClient : acceptedClientList) { acceptedClient.setDetectedResult(detectedResult); } acceptedClientListLock.unlock(); lastSetDetectedResult = System.currentTimeMillis(); prevDetectedResult = detectedResult; } } public static void startServer() { if (startServer) { return; } startServer = true; BaseApplication.getApplication().executorService.execute(() -> { ServerSocket server = null; try { server = new ServerSocket(Constants.guestServerPort); } catch (Exception e) { e.printStackTrace(); } while (true) { try { if (server == null) { break; } Socket client = server.accept(); GuestAcceptedClient guestAcceptedSocketClient = new GuestAcceptedClient(client); guestAcceptedSocketClient.start(); } catch (Exception e) { e.printStackTrace(); } finally { SystemClock.sleep(1000); } } }); } public static void setIdCardVerifiedPerson(ModelAdapter person) { } public static class GuestAcceptedClient extends Thread { private final LinkedList detectedResultQueue = new LinkedList<>(); private final LinkedList cameraDataQueue = new LinkedList(); Socket mSocket; public GuestAcceptedClient(Socket client) { mSocket = client; } public DetectedResult getDetectedResult() { DetectedResult mLastFrame = null; synchronized (detectedResultQueue) { if (detectedResultQueue.size() > 0) { mLastFrame = detectedResultQueue.poll(); } } // System1.out.println("GuestAcceptedClient.getDetectedResult " + mLastFrame); return mLastFrame; } public void setDetectedResult(DetectedResult detectedResult) { synchronized (detectedResultQueue) { if (detectedResultQueue.size() == MAX_BUFFER) { detectedResultQueue.poll(); } detectedResultQueue.add(detectedResult); } } public byte[] getCameraData() { byte[] cameraData = null; synchronized (cameraDataQueue) { if (cameraDataQueue.size() > 0) { cameraData = cameraDataQueue.poll(); } } return cameraData; } public void setCameraData(byte[] cameraData) { synchronized (cameraDataQueue) { if (cameraDataQueue.size() == MAX_BUFFER) { cameraDataQueue.poll(); } cameraDataQueue.add(cameraData); } } public void run() { acceptedClientListLock.lock(); acceptedClientList.add(this); acceptedClientListLock.unlock(); SocketUtil socketUtil = new SocketUtil(); try { socketUtil.setSocket(mSocket); while (true) { if (socketUtil.writeBitmapHeader()) { while (!Thread.currentThread().isInterrupted()) { Map map = new HashMap<>(); Map requestMap = socketUtil.readMap(); boolean isRequestFrame = Constants.TRUE.equals(requestMap.get(GuestMessage.requestFrame)); boolean isTransferVideo = Constants.TRUE.equals(requestMap.get(GuestMessage.transferVideo)); String hasFrameData = Constants.FALSE; byte[] frameData = null; map.put(GuestMessage.faceUpdateTime, null); byte[] featureArray = null; String frameJpgOrYuv = ""; boolean allowed = false; if (socketUtil.remoteIpAllowed(map)) { allowed = true; if (isTransferVideo) { if (isRequestFrame) { frameData = getCameraData(); if (frameData != null && frameData.length > 1000) { hasFrameData = Constants.TRUE; frameJpgOrYuv = GuestMessage.YUV; } else { SystemClock.sleep(500); } } else { SystemClock.sleep(500); } DetectedResult detectedResult = getDetectedResult(); if (detectedResult != null) { frameData = detectedResult.frameJpgData; hasFrameData = Constants.TRUE; frameJpgOrYuv = GuestMessage.JPG; map.put(GuestMessage.faceUpdateTime, System.currentTimeMillis() + ""); map.put(GuestMessage.facePositions, detectedResult.facePositionsJson()); featureArray = detectedResult.featureByteArrayOutputStream.toByteArray(); } } else { DetectedResult detectedResult = getDetectedResult(); if (detectedResult != null) { map.put(GuestMessage.faceUpdateTime, System.currentTimeMillis() + ""); map.put(GuestMessage.facePositions, detectedResult.facePositionsJson()); frameData = detectedResult.frameJpgData; featureArray = detectedResult.featureByteArrayOutputStream.toByteArray(); if (detectedResult.originalCameraDataChanged || !isRequestFrame) { hasFrameData = Constants.TRUE; frameJpgOrYuv = GuestMessage.JPG; } } } } else { SystemClock.sleep(1000); } int frameJpgLength = 0; if (frameData != null) { frameJpgLength = frameData.length; } map.put(GuestMessage.featureLength, featureArray == null ? "0" : featureArray.length + ""); map.put(GuestMessage.frameJpgOrYuv, frameJpgOrYuv); map.put(GuestMessage.frameJpgLength, frameJpgLength + ""); map.put(GuestMessage.hasFrameData, hasFrameData); // map.put(Constants.webRtcClientConnected, WebRtcBroadCastReceiver.webRtcClientConnected ? Constants.TRUE : Constants.FALSE); // map.put(Constants.webRtcServerStarted, allowed && WebRtcBroadCastReceiver.webRtcServerStarted ? Constants.TRUE : Constants.FALSE); map.put(GuestMessage.deviceId, DeviceManager.getDeviceId()); socketUtil.writeMap(map); if (Constants.TRUE.equals(hasFrameData)) { if (featureArray != null && featureArray.length > 0) { socketUtil.writeByteArray(featureArray); } socketUtil.writeByteArray(frameData); } SystemClock.sleep(200); } } else { SystemClock.sleep(2 * 1000); } } } catch (Exception e) { e.printStackTrace(); } finally { socketUtil.close(); } acceptedClientListLock.lock(); acceptedClientList.remove(this); acceptedClientListLock.unlock(); } } }