package com.tencent.wstt.gt.log.logcat; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import android.os.AsyncTask; /** * Combines multipe buffered readers into a single reader that merges all input synchronously. */ public class MultipleLogcatReader extends AbsLogcatReader { private static final String DUMMY_NULL = new String(""); private List<ReaderThread> readerThreads = new LinkedList<ReaderThread>(); private BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1); public MultipleLogcatReader(boolean recordingMode, Map<String,String> lastLines) throws IOException { super(recordingMode); // read from all three buffers at once for (Entry<String,String> entry : lastLines.entrySet()) { String logBuffer = entry.getKey(); String lastLine = entry.getValue(); ReaderThread readerThread = new ReaderThread(logBuffer, lastLine); readerThread.start(); readerThreads.add(readerThread); } } public String readLine() throws IOException { try { String value = queue.take(); if (value != DUMMY_NULL) { return value; } } catch (InterruptedException e) { } return null; } @Override public boolean readyToRecord() { for (ReaderThread thread : readerThreads) { if (!thread.reader.readyToRecord()) { return false; } } return true; } @Override public void killQuietly() { for (ReaderThread thread : readerThreads) { thread.killed = true; } // do in background, because otherwise we might hang new AsyncTask<Void, Void, Void>(){ @Override protected Void doInBackground(Void... params) { for (ReaderThread thread : readerThreads) { thread.reader.killQuietly(); } queue.offer(DUMMY_NULL); return null; } }.execute((Void)null); } @Override public List<Process> getProcesses() { List<Process> result = new ArrayList<Process>(); for (ReaderThread thread : readerThreads) { result.addAll(thread.reader.getProcesses()); } return result; } private class ReaderThread extends Thread { SingleLogcatReader reader; private boolean killed; public ReaderThread(String logBuffer, String lastLine) throws IOException { this.reader = new SingleLogcatReader(recordingMode, logBuffer, lastLine); } @Override public void run() { String line; try { while (!killed && (line = reader.readLine()) != null && !killed) { queue.put(line); } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } }