/** Copyright (C) 2013 Louis Teboul (a.k.a Androguide) * * admin@pimpmyrom.org || louisteboul@gmail.com * http://pimpmyrom.org || http://androguide.fr * 71 quai Clémenceau, 69300 Caluire-et-Cuire, FRANCE. * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. **/ package com.secupwn.aimsicd.utils; import android.os.Parcel; import android.os.Parcelable; import java.io.File; import java.io.FileWriter; import java.io.IOException; import io.freefair.android.util.logging.AndroidLogger; import io.freefair.android.util.logging.Logger; import lombok.Getter; @SuppressWarnings("AccessOfSystemProperties") public class CommandResult implements Parcelable { private final Logger log = AndroidLogger.forClass(CommandResult.class); private long startTime; @Getter private int exitValue; @Getter private String stdOut; @Getter private String stdErr; private long endTime; public CommandResult(long startTime, int exitValue, String stdout, String stderr, long endTime) { this.startTime = startTime; this.exitValue = exitValue; this.stdOut = stdout; this.stdErr = stderr; this.endTime = endTime; log.debug("Time to execute: " + (this.endTime - this.startTime) + " ns (nanoseconds)"); // this is set last so log from here checkForErrors(); } // pretty much just forward the constructor from parcelable to our main // loading constructor @SuppressWarnings("CastToConcreteClass") public CommandResult(Parcel inParcel) { this(inParcel.readLong(), inParcel.readInt(), inParcel.readString(), inParcel.readString(), inParcel.readLong()); } public boolean success() { return (exitValue == 0); } @SuppressWarnings("UnnecessaryExplicitNumericCast") private void checkForErrors() { if (exitValue != 0 || !stdErr.trim().isEmpty()) { // don't log the commands that failed // because the cpu was offline boolean skipOfflineCpu = // if core is off locking fails stdErr.contains("chmod: /sys/devices/system/cpu/cpu") // if core is off applying cpu freqs fails || stdErr.contains(": can't create /sys/devices/system/cpu/cpu"); String lineEnding = System.getProperty("line.separator"); FileWriter errorWriter = null; try { File errorLogFile = new File(RealmHelper.mExternalFilesDirPath + "error.txt"); if (!errorLogFile.exists()) { errorLogFile.createNewFile(); } errorWriter = new FileWriter(errorLogFile, true); // only log the cpu state as offline while writing if (skipOfflineCpu) { errorWriter.write(lineEnding); errorWriter.write("Attempted to write to an offline cpu core (ignore me)."); } else { errorWriter.write("shell error detected!"); errorWriter.write(lineEnding); errorWriter.write("CommandResult {" + this.toString() + '}'); errorWriter.write(lineEnding); } errorWriter.write(lineEnding); } catch (IOException e) { log.error("Failed to write command result to error file", e); } finally { if (errorWriter != null) { try { errorWriter.close(); } catch (IOException ignored) { log.error("Failed to close error writer", ignored); } } } } } // implement parcelable @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeLong(startTime); parcel.writeInt(exitValue); parcel.writeString(stdOut); parcel.writeString(stdErr); parcel.writeLong(endTime); } @Override public String toString() { return "CommandResult{" + ", startTime=" + startTime + ", exitValue=" + exitValue + ", stdout='" + stdOut + "'" + ", stderr='" + stdErr + "'" + ", endTime=" + endTime + '}'; } public static final Parcelable.Creator<CommandResult> CREATOR = new Parcelable.Creator<CommandResult>() { public CommandResult createFromParcel(Parcel in) { return new CommandResult(in); } public CommandResult[] newArray(int size) { return new CommandResult[size]; } }; @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof CommandResult)) { return false; } CommandResult that = (CommandResult) o; return (startTime == that.startTime && exitValue == that.exitValue && stdOut.equals(that.stdOut) && stdErr.equals(that.stdErr) && endTime == that.endTime); } @Override public int hashCode() { int result = 0; result = 31 * result + (int) (startTime ^ (startTime >>> 32)); result = 31 * result + exitValue; result = 31 * result + (stdOut != null ? stdOut.hashCode() : 0); result = 31 * result + (stdErr != null ? stdErr.hashCode() : 0); result = 31 * result + (int) (endTime ^ (endTime >>> 32)); return result; } }