package com.stardust.scriptdroid.ui.console; import android.content.Context; import android.content.Intent; import android.support.annotation.NonNull; import android.view.WindowManager; import com.stardust.autojs.runtime.ScriptInterface; import com.stardust.autojs.runtime.ScriptInterruptedException; import com.stardust.autojs.runtime.api.AbstractConsole; import com.stardust.autojs.runtime.api.Console; import com.stardust.enhancedfloaty.FloatyService; import com.stardust.enhancedfloaty.ResizableExpandableFloatyWindow; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.external.floatingwindow.FloatingWindowManger; import com.stardust.util.UiHandler; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; /** * Created by Stardust on 2017/5/2. */ public class StardustConsole extends AbstractConsole { public static class Log { public int level; public CharSequence content; public Log(int level, CharSequence content) { this.level = level; this.content = content; } } public interface LogListener { void onNewLog(Log log); void onLogClear(); } private final Console GLOBAL_CONSOLE = AutoJs.getInstance().getScriptEngineService().getGlobalConsole(); private List<Log> mLogs = new ArrayList<>(); private ResizableExpandableFloatyWindow mFloatyWindow; private ConsoleFloaty mConsoleFloaty; private LogListener mLogListener; private UiHandler mUiHandler; private BlockingQueue<String> mInput = new ArrayBlockingQueue<>(1); private ConsoleView mConsoleView; private volatile boolean mShown = false; public StardustConsole(UiHandler uiHandler) { mUiHandler = uiHandler; mConsoleFloaty = new ConsoleFloaty(this); mFloatyWindow = new ResizableExpandableFloatyWindow(mConsoleFloaty); } public void setConsoleView(ConsoleView consoleView) { mConsoleView = consoleView; setLogListener(consoleView); synchronized (this) { this.notify(); } } public void setLogListener(LogListener logListener) { mLogListener = logListener; } public List<Log> getLogs() { return mLogs; } @Override public void println(int level, CharSequence charSequence) { Log log = new Log(level, charSequence + "\n"); mLogs.add(log); GLOBAL_CONSOLE.println(level, charSequence); if (mLogListener != null) { mLogListener.onNewLog(log); } } @Override public void write(int level, CharSequence charSequence) { Log log = new Log(level, charSequence); mLogs.add(log); GLOBAL_CONSOLE.print(level, charSequence); if (mLogListener != null) { mLogListener.onNewLog(log); } } @Override public void clear() { mLogs.clear(); if (mLogListener != null) { mLogListener.onLogClear(); } } @Override public void show() { if (!FloatingWindowManger.hasFloatingWindowPermission(mUiHandler.getContext())) { FloatingWindowManger.goToFloatingWindowPermissionSetting(); mUiHandler.toast(R.string.text_no_floating_window_permission); } startFloatyService(); mUiHandler.post(new Runnable() { @Override public void run() { try { FloatyService.addWindow(mFloatyWindow); } catch (WindowManager.BadTokenException e) { e.printStackTrace(); mUiHandler.toast(R.string.text_no_floating_window_permission); } } }); mShown = true; } private void startFloatyService() { Context context = mUiHandler.getContext(); context.startService(new Intent(context, FloatyService.class)); } @Override public void hide() { try { mFloatyWindow.close(); } catch (IllegalArgumentException ignored) { } mShown = false; } @ScriptInterface public String rawInput() { if (mConsoleView == null) { if (!mShown) { show(); } waitConsoleView(); } mConsoleView.showEditText(); try { return mInput.take(); } catch (InterruptedException e) { throw new ScriptInterruptedException(); } } private void waitConsoleView() { synchronized (this) { try { this.wait(); } catch (InterruptedException e) { throw new ScriptInterruptedException(); } } } @ScriptInterface public String rawInput(Object data, Object... param) { log(data, param); return rawInput(); } boolean submitInput(@NonNull CharSequence input) { return mInput.offer(input.toString()); } @Override public void setTitle(CharSequence title) { mConsoleFloaty.setTitle(title); } }