package org.witness.informacam.intake;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Vector;
import org.witness.informacam.Debug;
import org.witness.informacam.InformaCam;
import org.witness.informacam.models.j3m.IDCIMDescriptor;
import org.witness.informacam.utils.Constants.App.Storage;
import org.witness.informacam.utils.Constants.Logger;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.FileObserver;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
public class DCIMObserver extends BroadcastReceiver {
private final static String LOG = Storage.LOG;
public static IDCIMDescriptor dcimDescriptor;
public ComponentName cameraComponent;
List<ContentObserver> observers;
InformaCam informaCam = InformaCam.getInstance();
Handler h;
private Context mContext;
private FileMonitor fileMonitor;
private int raPID = -1;
private boolean debug = false;
public DCIMObserver () {}
public DCIMObserver(Context context, String parentId, ComponentName cameraComponent) {
mContext = context;
this.cameraComponent = cameraComponent;
if (cameraComponent != null)
{
List<RunningAppProcessInfo> running = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getRunningAppProcesses();
for(RunningAppProcessInfo r : running) {
if(r.processName.equals(cameraComponent.getPackageName())) {
raPID = r.pid;
break;
}
}
}
h = new Handler();
fileMonitor = new FileMonitor();
observers = new Vector<ContentObserver>();
observers.add(new Observer(h, MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
observers.add(new Observer(h, MediaStore.Images.Media.INTERNAL_CONTENT_URI));
observers.add(new Observer(h, MediaStore.Video.Media.EXTERNAL_CONTENT_URI));
observers.add(new Observer(h, MediaStore.Video.Media.INTERNAL_CONTENT_URI));
observers.add(new Observer(h, MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI));
observers.add(new Observer(h, MediaStore.Images.Thumbnails.INTERNAL_CONTENT_URI));
observers.add(new Observer(h, MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI));
observers.add(new Observer(h, MediaStore.Video.Thumbnails.INTERNAL_CONTENT_URI));
for(ContentObserver o : observers) {
mContext.getContentResolver().registerContentObserver(((Observer) o).authority, false, o);
}
dcimDescriptor = new IDCIMDescriptor(parentId, cameraComponent);
fileMonitor.start();
dcimDescriptor.startSession();
//Log.d(LOG, "DCIM OBSERVER INITED");
}
public void destroy() {
dcimDescriptor.stopSession();
dcimDescriptor = null;
for(ContentObserver o : observers) {
mContext.getContentResolver().unregisterContentObserver(o);
}
fileMonitor.stop();
Log.d(LOG, "DCIM OBSERVER STOPPED");
}
class FileMonitor extends FileObserver {
public FileMonitor() {
super(Storage.DCIM);
Log.d(LOG, "STARTING FILE OBSERVER ON PATH: " + Storage.DCIM);
}
public void start() {
startWatching();
}
public void stop() {
stopWatching();
}
@SuppressWarnings("unused")
private void lsof() {
lsof(true, null);
}
private void lsof(boolean mask, String fileToWatch) {
String line;
Process check;
try {
check = Runtime.getRuntime().exec(String.format("lsof -r1 %s/*", Storage.DCIM));
BufferedReader br = new BufferedReader(new InputStreamReader(check.getInputStream()));
while((line = br.readLine()) != null) {
if(fileToWatch != null) {
if(!line.contains(fileToWatch)) {
continue;
}
}
if(!mask || line.contains(String.valueOf(raPID))) {
Log.d(LOG, line);
}
}
} catch (IOException e) {
Logger.e(LOG, e);
}
}
private void ls(String fileToWatch) {
String line;
Process check;
try {
check = Runtime.getRuntime().exec(String.format("ls -la %s", fileToWatch));
BufferedReader br = new BufferedReader(new InputStreamReader(check.getInputStream()));
while((line = br.readLine()) != null) {
Log.d(LOG, line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onEvent(int event, String path) {
path = (Storage.DCIM + "/" + path);
if(debug) {
switch (event) {
case FileObserver.ACCESS:
Log.d(LOG, "FILE OBSERVER: ACCESS");
break;
case FileObserver.MODIFY:
Log.d(LOG, "FILE OBSERVER: MODIFY");
break;
case FileObserver.ATTRIB:
Log.d(LOG, "FILE OBSERVER: ATTRIB");
ls(path);
break;
case FileObserver.CLOSE_WRITE:
Log.d(LOG, "FILE OBSERVER: CLOSE_WRITE");
ls(path);
break;
case FileObserver.CLOSE_NOWRITE:
Log.d(LOG, "FILE OBSERVER: CLOSE_NOWRITE");
break;
case FileObserver.OPEN:
Log.d(LOG, "FILE OBSERVER: OPEN");
lsof(false, path);
break;
case FileObserver.MOVED_FROM:
Log.d(LOG, "FILE OBSERVER: MOVED_FROM");
break;
case FileObserver.MOVED_TO:
Log.d(LOG, "FILE OBSERVER: MOVED_TO");
break;
case FileObserver.CREATE:
Log.d(LOG, "FILE OBSERVER: CREATE");
// WHICH PROCESS THOUGH???!!!
lsof(false, null);
ls(path);
break;
case FileObserver.DELETE:
Log.d(LOG, "FILE OBSERVER: DELETE");
break;
case FileObserver.DELETE_SELF:
Log.d(LOG, "FILE OBSERVER: DELETE_SELF");
break;
case FileObserver.MOVE_SELF:
Log.d(LOG, "FILE OBSERVER: MOVE_SELF");
break;
default:
Log.d(LOG, "FILE OBSERVER: UNKNOWN");
lsof(false, path);
break;
}
Log.d(LOG, "THE FILE OBSERVER SAW EVT: " + event + " on path " + path);
}
}
}
class Observer extends ContentObserver {
Uri authority;
public Observer(Handler handler, Uri authority) {
super(handler);
this.authority = authority;
}
@Override
public void onChange(boolean selfChange) {
Log.d(LOG, "ON CHANGE CALLED (no URI)");
onChange(selfChange, null);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
boolean isThumbnail = false;
if(Debug.DEBUG) {
Logger.d(LOG, "AUTHORITY: " + authority.toString());
if(uri != null) {
//Log.d(LOG, "ON CHANGE CALLED (with URI!)");
Logger.d(LOG, "URI: " + uri.toString());
}
}
if(
authority.equals(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI) ||
authority.equals(MediaStore.Images.Thumbnails.INTERNAL_CONTENT_URI) ||
authority.equals(MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI) ||
authority.equals(MediaStore.Video.Thumbnails.INTERNAL_CONTENT_URI)
) {
isThumbnail = true;
}
try
{
dcimDescriptor.addEntry(authority.toString(), isThumbnail,Storage.Type.FILE_SYSTEM);
}
catch (Exception e)
{
//Logger.d(LOG,"unable to add thumbnail");
Logger.e(LOG, e);
}
}
@Override
public boolean deliverSelfNotifications() {
return true;
}
}
@Override
public void onReceive(Context context, Intent intent) {
Cursor cursor = context.getContentResolver().query(intent.getData(), null,null, null, null);
cursor.moveToFirst();
String media_path = cursor.getString(cursor.getColumnIndex("_data"));
cursor.close();
if (dcimDescriptor != null)
{
try
{
dcimDescriptor.addEntry(media_path, false, Storage.Type.FILE_SYSTEM);
}
catch (Exception e)
{
//Logger.d(LOG,"unable to add thumbnail");
Logger.e(LOG, e);
}
}
}
}