package cn.hikyson.godeye.monitor; import android.annotation.SuppressLint; import android.content.Context; import android.net.wifi.WifiManager; import android.util.Log; import androidx.annotation.Keep; import com.koushikdutta.async.http.WebSocket; import com.koushikdutta.async.http.server.AsyncHttpServerRequest; import com.koushikdutta.async.http.server.AsyncHttpServerResponse; import java.util.List; import java.util.Locale; import cn.hikyson.godeye.core.internal.notification.NotificationObserverManager; import cn.hikyson.godeye.core.utils.L; import cn.hikyson.godeye.core.utils.ThreadUtil; import cn.hikyson.godeye.monitor.notification.MonitorNotificationListener; import cn.hikyson.godeye.monitor.server.GodEyeMonitorServer; import cn.hikyson.godeye.monitor.server.HttpStaticProcessor; import cn.hikyson.godeye.monitor.server.ModuleDriver; import cn.hikyson.godeye.monitor.server.WebSocketBizProcessor; /** * Created by kysonchao on 2017/11/27. */ @Keep public class GodEyeMonitor { private static boolean sIsWorking = false; private static final String MONITOR_LOGCAT = "AndroidGodEye monitor is running at port [%s]"; private static GodEyeMonitorServer sGodEyeMonitorServer; /** * monitor start work */ @Keep static synchronized void work(Context context, int port) { if (sIsWorking) { return; } sIsWorking = true; if (context == null) { throw new IllegalStateException("context can not be null."); } Context applicationContext = context.getApplicationContext(); sGodEyeMonitorServer = new GodEyeMonitorServer(port); final HttpStaticProcessor httpStaticProcessor = new HttpStaticProcessor(applicationContext); final WebSocketBizProcessor webSocketBizProcessor = new WebSocketBizProcessor(); sGodEyeMonitorServer.setMonitorServerCallback(new GodEyeMonitorServer.MonitorServerCallback() { @Override public void onClientAdded(List<WebSocket> webSockets, WebSocket added) { ModuleDriver.instance().start(sGodEyeMonitorServer); NotificationObserverManager.installNotificationListener("MONITOR", new MonitorNotificationListener(sGodEyeMonitorServer)); } @Override public void onClientRemoved(List<WebSocket> webSockets, WebSocket removed) { if (webSockets == null || webSockets.isEmpty()) { ModuleDriver.instance().stop(); NotificationObserverManager.uninstallNotificationListener("MONITOR"); } } @Override public void onHttpRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) { ThreadUtil.ensureWorkThread("AndroidGodEyeOnHttpRequest"); try { httpStaticProcessor.process(request, response); } catch (Throwable throwable) { L.e(String.valueOf(throwable)); } } @Override public void onWebSocketRequest(WebSocket webSocket, String messageFromClient) { ThreadUtil.ensureWorkThread("AndroidGodEyeOnWebSocketRequest"); webSocketBizProcessor.process(webSocket, messageFromClient); } }); sGodEyeMonitorServer.start(); Log.d(L.DEFAULT_TAG, String.format(MONITOR_LOGCAT, port)); L.d(getAddressLog(context, port)); } /** * monitor stop work */ @Keep static synchronized void shutDown() { if (sGodEyeMonitorServer != null) { sGodEyeMonitorServer.stop(); sGodEyeMonitorServer = null; } ModuleDriver.instance().stop(); NotificationObserverManager.uninstallNotificationListener("MONITOR"); sIsWorking = false; L.d("GodEye monitor stopped."); } private static String getAddressLog(Context context, int port) { @SuppressLint("WifiManagerPotentialLeak") WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); int ipAddress = wifiManager != null ? wifiManager.getConnectionInfo().getIpAddress() : 0; final String formattedIpAddress = String.format(Locale.US, "%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff)); return "Open AndroidGodEye dashboard [ http://localhost:" + port + "/index.html ] or [ http://" + formattedIpAddress + ":" + port + "/index.html ] in your browser"; } }