/** * Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr) * This file is part of CSipSimple. * * CSipSimple is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * If you own a pjsip commercial license you can also redistribute it * and/or modify it under the terms of the GNU Lesser General Public License * as an android library. * * CSipSimple is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with CSipSimple. If not, see <http://www.gnu.org/licenses/>. */ package com.csipsimple.utils; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; public class CollectLogs { private static final Object LINE_SEPARATOR = "\n"; private static final String THIS_FILE = "Collect Logs"; private static class LogResult { public StringBuilder head; public File file; public LogResult(StringBuilder aHead, File aFile) { head = aHead; file = aFile; } }; /*Usage: logcat [options] [filterspecs] options include: -s Set default filter to silent. Like specifying filterspec '*:s' -f <filename> Log to file. Default to stdout -r [<kbytes>] Rotate log every kbytes. (16 if unspecified). Requires -f -n <count> Sets max number of rotated logs to <count>, default 4 -v <format> Sets the log print format, where <format> is one of: brief process tag thread raw time threadtime long -c clear (flush) the entire log and exit -d dump the log and then exit (don't block) -g get the size of the log's ring buffer and exit -b <buffer> request alternate ring buffer ('main' (default), 'radio', 'events') -B output the log in binary filterspecs are a series of <tag>[:priority] where <tag> is a log component tag (or * for all) and priority is: V Verbose D Debug I Info W Warn E Error F Fatal S Silent (supress all output) '*' means '*:d' and <tag> by itself means <tag>:v If not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS. If no filterspec is found, filter defaults to '*:I' If not specified with -v, format is set from ANDROID_PRINTF_LOG or defaults to "brief"*/ public final static LogResult getLogs(Context ctxt) { //Clear old files PreferencesWrapper.cleanLogsFiles(ctxt); final StringBuilder log = new StringBuilder(); File outFile = null; try{ ArrayList<String> commandLine = new ArrayList<String>(); commandLine.add("logcat"); outFile = PreferencesWrapper.getLogsFile(ctxt, false); if( outFile != null) { commandLine.add("-f"); commandLine.add(outFile.getAbsolutePath()); } commandLine.add("-d"); commandLine.add("D"); Process process = Runtime.getRuntime().exec(commandLine.toArray(new String[0])); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line ; while ((line = bufferedReader.readLine()) != null){ log.append(line); log.append(LINE_SEPARATOR); } } catch (IOException e){ Log.e(THIS_FILE, "Collect logs failed : ", e);//$NON-NLS-1$ log.append("Unable to get logs : " + e.toString()); } return new LogResult(log, outFile); } public final static StringBuilder getDeviceInfo() { final StringBuilder log = new StringBuilder(); log.append( "Here are important informations about Device : "); log.append(LINE_SEPARATOR); log.append("android.os.Build.BOARD : " + android.os.Build.BOARD ); log.append(LINE_SEPARATOR); log.append("android.os.Build.BRAND : " + android.os.Build.BRAND ); log.append(LINE_SEPARATOR); log.append("android.os.Build.DEVICE : " + android.os.Build.DEVICE ); log.append(LINE_SEPARATOR); log.append("android.os.Build.ID : " + android.os.Build.ID ); log.append(LINE_SEPARATOR); log.append("android.os.Build.MODEL : " + android.os.Build.MODEL ); log.append(LINE_SEPARATOR); log.append("android.os.Build.PRODUCT : " + android.os.Build.PRODUCT ); log.append(LINE_SEPARATOR); log.append("android.os.Build.TAGS : " + android.os.Build.TAGS ); log.append(LINE_SEPARATOR); log.append("android.os.Build.CPU_ABI : " + android.os.Build.CPU_ABI ); log.append(LINE_SEPARATOR); log.append("android.os.Build.VERSION.INCREMENTAL : " + android.os.Build.VERSION.INCREMENTAL ); log.append(LINE_SEPARATOR); log.append("android.os.Build.VERSION.RELEASE : " + android.os.Build.VERSION.RELEASE ); log.append(LINE_SEPARATOR); log.append("android.os.Build.VERSION.SDK_INT : " + android.os.Build.VERSION.SDK_INT ); log.append(LINE_SEPARATOR); return log; } public final static String getApplicationInfo(Context ctx) { String result = ""; PackageManager pm = ctx.getPackageManager(); result += "Based on GPL application "; result += ctx.getApplicationInfo().loadLabel(pm); result += " version : "; PackageInfo pinfo = PreferencesProviderWrapper.getCurrentPackageInfos(ctx); if(pinfo != null) { result += pinfo.versionName + " r" + pinfo.versionCode; } return result; } public static Intent getLogReportIntent(String userComment, Context ctx) { LogResult logs = getLogs(ctx); Intent sendIntent = new Intent(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_SUBJECT, "CSipSimple Error-Log report"); sendIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { CustomDistribution.getSupportEmail() }); StringBuilder log = new StringBuilder(); log.append(userComment); log.append(LINE_SEPARATOR); log.append(LINE_SEPARATOR); log.append(getApplicationInfo(ctx)); log.append(LINE_SEPARATOR); log.append(getDeviceInfo()); log.append(LINE_SEPARATOR); log.append(logs.head); if(logs.file != null) { sendIntent.putExtra( Intent.EXTRA_STREAM, Uri.fromFile(logs.file) ); /* BufferedReader buf; String line; try { buf = new BufferedReader(new FileReader(logs.second)); while( (line = buf.readLine()) != null ) { log.append(line); } } catch (FileNotFoundException e) { Log.e(THIS_FILE, "Impossible to open log file", e); } catch (IOException e) { Log.e(THIS_FILE, "Impossible to read log file", e); } */ } log.append(LINE_SEPARATOR); log.append(LINE_SEPARATOR); log.append(userComment); sendIntent.setType("message/rfc822"); sendIntent.putExtra(Intent.EXTRA_TEXT, log.toString()); return sendIntent; } }