package mobi.acpm.inspeckage.log;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.channels.NotYetConnectedException;
import mobi.acpm.inspeckage.Module;
import mobi.acpm.inspeckage.util.Config;
/**
* Created by acpm on 14/03/16.
*/
public class LogService extends Service {
public static final String TAG = "Inspeckage_Log";
private boolean isStarted = false;
private String pid = "";
private Thread logThread;
private Thread pidThread;
private java.lang.Process logProcess;
private WSocketServer wss;
private SharedPreferences mPrefs;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Context context = getApplicationContext();
try {
int port = 8887;
String filter = "";
if (intent != null && intent.getExtras() != null) {
port = intent.getIntExtra("port", 8887);
filter = intent.getStringExtra("filter");
}
mPrefs = context.getSharedPreferences(Module.PREFS, context.MODE_WORLD_READABLE);
wss = new WSocketServer(port);
wss.start();
startLogger(filter);
Toast.makeText(this, "LogService started on port " + port, Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
if (wss != null)
try {
stopLogger();
wss.stop();
Toast.makeText(this, "LogService stopped", Toast.LENGTH_LONG).show();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
private void startLogger(final String filter) {
if (!isStarted) {
logThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Runtime.getRuntime().exec("su -c logcat -c");
String cmd = "su -c logcat |grep -v Xposed |grep -v Inspeckage |grep -v E/ |grep -v I/ |grep -v W/ |grep -v F/ |grep -v V/ |grep -v W/ |grep -v D/";
String[] filters = filter.split(",");
for (String filter1 : filters) {
if (cmd.contains(filter1 + "/")) {
cmd = cmd.replace("|grep -v " + filter1 + "/", "");
}
}
logProcess = Runtime.getRuntime().exec(cmd);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(logProcess.getInputStream()));
String line;
while (isStarted && (line = bufferedReader.readLine()) != null) {
if (pid.trim().length() > 2 && line.contains(pid.trim())) {
wss.sendToClient(line);
}
}
logProcess.destroy();
} catch (IOException | NotYetConnectedException e) {
Log.e(TAG, "LogService failed: " + e.getMessage());
}
}
}, "Logger_Thread");
logThread.start();
isStarted = true;
//---PID
pidThread = new Thread(new Runnable() {
@Override
public void run() {
try {
while (isStarted) {
String name = mPrefs.getString(Config.SP_PACKAGE, "null");
Process p = Runtime.getRuntime().exec("ps");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String var = "";
String psline;
while ((psline = br.readLine()) != null) {
if (psline.contains(" " + name)) {
var = psline;
}
}
if (var.length() > 10) {
String tmp = var.replaceAll("\\s+", " ");
pid = tmp.split(" ")[1];
}
synchronized (this) {
try {
wait(3000);
} catch (InterruptedException e) {
}
}
}
} catch (IOException | NotYetConnectedException e) {
Log.e(TAG, "LogService failed: " + e.getMessage());
}
}
}, "Logger_Thread");
pidThread.start();
}
}
public void stopLogger() {
if (isStarted) {
isStarted = false;
try {
logProcess.destroy();
pidThread.join();
logThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}