blob: cf3ff8d98fd53485315ad2a5b56a64eec5b483f6 [file] [log] [blame]
/*
* Copyright (C) 2016 Fairphone B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fairphone.hiccup.app;
import android.content.Context;
import android.support.annotation.Nullable;
import android.system.ErrnoException;
import android.system.Os;
import com.fairphone.hiccup.HiccupdService;
import com.fairphone.hiccup.LogFile;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class LogfileArchive {
private final static SimpleDateFormat dirNameDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
static private final String logFileDirectory = "/crashreport_logfiles/";
private Date date;
private String logfilePath;
private LogfileArchive(String path) throws CrashReportFormatException {
File file = new File(path);
try {
date = dirNameDateFormat.parse(file.getName().replaceFirst("crashreport_", "").replaceAll(".zip", ""));
} catch (ParseException e) {
throw new CrashReportFormatException();
}
logfilePath = path;
}
/**
* This generates a new Crashreport. It will create a new directory i
*/
static public LogfileArchive fetchCrashReportLogfiles(Context ctx, HiccupSettings.IncludeLogFilesConfiguration conf) {
List<LogFile> logFiles = getLogFiles(conf);
if (logFiles.isEmpty()) return null;
return createLogfilesArchive(ctx, logFiles);
}
@Nullable
private static LogfileArchive createLogfilesArchive(Context ctx, List<LogFile> logFiles) {
Date date = new Date();
String basePath = ctx.getFilesDir().getAbsolutePath();
new File(basePath + logFileDirectory).mkdirs();
String tmpZipName = basePath + logFileDirectory + "/.INCOMPLETE_" + getCrashReportName(date) + ".zip";
String zipName = basePath + logFileDirectory + '/' + getCrashReportName(date) + ".zip";
writeZipFile(logFiles, tmpZipName);
try {
Os.rename(tmpZipName, zipName);
} catch (ErrnoException e) {
e.printStackTrace();
}
try {
return new LogfileArchive(zipName);
} catch (CrashReportFormatException e) {
e.printStackTrace();
return null;
}
}
private static List<LogFile> getLogFiles(HiccupSettings.IncludeLogFilesConfiguration conf) {
List<LogFile> logFiles= null;
try {
switch (conf) {
case NONE:
break;
case LAST_KMSG:
logFiles = getLastKmesg();
break;
case ALL:
logFiles = getAllLogFiles();
break;
}
} catch (Exception e) {
HiccupUtil.LOG("error talking to Hiccupd\n" + e.toString());
}
if (logFiles != null) {
HiccupUtil.LOG("Received " + String.valueOf(logFiles.size()) + " Logfiles");
} else {
HiccupUtil.LOG("Empty list received...");
}
return logFiles;
}
private static List<LogFile> getAllLogFiles() {
List<LogFile> logFiles = new ArrayList<LogFile>();
HiccupdService hiccupd = HiccupdService.getInstance();
hiccupd.stopLogging();
logFiles = hiccupd.getLogs();
hiccupd.cleanLogs();
hiccupd.startLogging();
return logFiles;
}
private static List<LogFile> getLastKmesg() {
List<LogFile> logFiles = new ArrayList<LogFile>();
HiccupdService hiccupd = HiccupdService.getInstance();
logFiles = hiccupd.getLastKmsg();
return logFiles;
}
static private void writeZipFile(List<LogFile> logFiles, String path) {
FileOutputStream dest;
try {
dest = new FileOutputStream(path);
ZipOutputStream out = new ZipOutputStream(new
BufferedOutputStream(dest));
for (LogFile logFile : logFiles) {
try {
dumpLogfile(out, logFile);
} catch (IOException e) {
HiccupUtil.LOG("skipping " + logFile.getFileName() + ": " + e.toString());
}
}
out.close();
dest.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
static private void dumpLogfile(ZipOutputStream zipOutputStream, LogFile logFile) throws IOException {
FileInputStream inputStream = new FileInputStream(logFile.getFileDescriptor());
final int BUFFER = 2048;
int count;
byte data[] = new byte[BUFFER];
ZipEntry entry = new ZipEntry(logFile.getFileName());
zipOutputStream.putNextEntry(entry);
while ((count = inputStream.read(data, 0,
BUFFER)) != -1) {
zipOutputStream.write(data, 0, count);
}
inputStream.close();
}
static private String getCrashReportName(Date date) {
SimpleDateFormat df = dirNameDateFormat;
return "crashreport_" + df.format(date);
}
public void delete() {
File dir = new File(logfilePath);
if (dir.isDirectory()) {
String[] children = dir.list();
for (String aChildren : children) {
new File(dir, aChildren).delete();
}
}
dir.delete();
}
public File getCrashReportFile() {
return new File(logfilePath);
}
private String getCrashReportName() {
SimpleDateFormat df = dirNameDateFormat;
return "crashreport_" + df.format(date);
}
private class CrashReportFormatException extends Exception {
}
}