Fix log save (#1605)
This commit is contained in:
parent
a885818a4d
commit
74c55e9947
|
|
@ -63,6 +63,7 @@ import java.util.concurrent.FutureTask;
|
|||
import okhttp3.Cache;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
import rikka.core.os.FileUtils;
|
||||
import rikka.material.app.DayNightDelegate;
|
||||
import rikka.material.app.LocaleDelegate;
|
||||
|
||||
|
|
@ -74,10 +75,7 @@ public class App extends Application {
|
|||
try {
|
||||
var input = App.getInstance().getAssets().open("webview/" + name);
|
||||
var result = new ByteArrayOutputStream(1024);
|
||||
var buffer = new byte[1024];
|
||||
for (int length; (length = input.read(buffer)) != -1; ) {
|
||||
result.write(buffer, 0, length);
|
||||
}
|
||||
FileUtils.copy(input, result);
|
||||
return result.toString(StandardCharsets.UTF_8.name());
|
||||
} catch (IOException e) {
|
||||
Log.e(App.TAG, "read webview HTML", e);
|
||||
|
|
|
|||
|
|
@ -314,15 +314,6 @@ public class ConfigManager {
|
|||
}
|
||||
}
|
||||
|
||||
public static Map<String, ParcelFileDescriptor> getLogs() {
|
||||
try {
|
||||
return LSPManagerServiceHolder.getService().getLogs();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(App.TAG, Log.getStackTraceString(e));
|
||||
return new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
public static String getApi() {
|
||||
try {
|
||||
return LSPManagerServiceHolder.getService().getApi();
|
||||
|
|
|
|||
|
|
@ -50,11 +50,11 @@ import org.lsposed.manager.R;
|
|||
import org.lsposed.manager.databinding.FragmentPagerBinding;
|
||||
import org.lsposed.manager.databinding.ItemLogTextviewBinding;
|
||||
import org.lsposed.manager.databinding.SwiperefreshRecyclerviewBinding;
|
||||
import org.lsposed.manager.receivers.LSPManagerServiceHolder;
|
||||
import org.lsposed.manager.ui.widget.EmptyStateRecyclerView;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -62,11 +62,7 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import rikka.core.os.FileUtils;
|
||||
import rikka.material.app.LocaleDelegate;
|
||||
import rikka.recyclerview.RecyclerViewKt;
|
||||
|
||||
|
|
@ -89,11 +85,9 @@ public class LogsFragment extends BaseFragment {
|
|||
runAsync(() -> {
|
||||
var context = requireContext();
|
||||
var contentResolver = context.getContentResolver();
|
||||
try (var os = new ZipOutputStream(contentResolver.openOutputStream(uri))) {
|
||||
os.setLevel(Deflater.BEST_COMPRESSION);
|
||||
zipLogs(os);
|
||||
os.finish();
|
||||
} catch (IOException e) {
|
||||
try (var zipFd = contentResolver.openFileDescriptor(uri, "wt")) {
|
||||
LSPManagerServiceHolder.getService().getLogs(zipFd);
|
||||
} catch (Throwable e) {
|
||||
var text = context.getString(R.string.logs_save_failed2, e.getMessage());
|
||||
showHint(text, false);
|
||||
Log.w(App.TAG, "save log", e);
|
||||
|
|
@ -171,29 +165,6 @@ public class LogsFragment extends BaseFragment {
|
|||
saveLogsLauncher.launch(filename);
|
||||
}
|
||||
|
||||
private static void zipLogs(ZipOutputStream os) {
|
||||
var logs = ConfigManager.getLogs();
|
||||
logs.forEach((name, fd) -> {
|
||||
try (var is = new FileInputStream(fd.getFileDescriptor())) {
|
||||
os.putNextEntry(new ZipEntry(name));
|
||||
FileUtils.copy(is, os);
|
||||
os.closeEntry();
|
||||
} catch (IOException e) {
|
||||
Log.w(App.TAG, name, e);
|
||||
}
|
||||
});
|
||||
|
||||
var now = LocalDateTime.now();
|
||||
var name = "app_" + now.toString() + ".log";
|
||||
try (var is = new ProcessBuilder("logcat", "-d").start().getInputStream()) {
|
||||
os.putNextEntry(new ZipEntry(name));
|
||||
FileUtils.copy(is, os);
|
||||
os.closeEntry();
|
||||
} catch (IOException e) {
|
||||
Log.w(App.TAG, name, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
|
|
|
|||
|
|
@ -29,12 +29,15 @@ import org.lsposed.manager.App;
|
|||
import org.lsposed.manager.ConfigManager;
|
||||
import org.lsposed.manager.adapters.ScopeAdapter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import rikka.core.os.FileUtils;
|
||||
|
||||
public class BackupUtils {
|
||||
private static final int VERSION = 2;
|
||||
|
||||
|
|
@ -79,10 +82,9 @@ public class BackupUtils {
|
|||
public static void restore(Uri uri, String packageName) throws IOException, JSONException {
|
||||
try (GZIPInputStream gzipInputStream = new GZIPInputStream(App.getInstance().getContentResolver().openInputStream(uri), 32)) {
|
||||
StringBuilder string = new StringBuilder();
|
||||
byte[] data = new byte[32];
|
||||
int bytesRead;
|
||||
while ((bytesRead = gzipInputStream.read(data)) != -1) {
|
||||
string.append(new String(data, 0, bytesRead));
|
||||
try (var os = new ByteArrayOutputStream()) {
|
||||
FileUtils.copy(gzipInputStream, os);
|
||||
string.append(os);
|
||||
}
|
||||
gzipInputStream.close();
|
||||
JSONObject rootObject = new JSONObject(string.toString());
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ private:
|
|||
|
||||
inline void Log(std::string_view str);
|
||||
|
||||
void OnCrash();
|
||||
void OnCrash(int err);
|
||||
|
||||
void ProcessBuffer(struct log_msg *buf);
|
||||
|
||||
|
|
@ -191,7 +191,8 @@ inline void Logcat::Log(std::string_view str) {
|
|||
fflush(modules_file_.get());
|
||||
}
|
||||
|
||||
void Logcat::OnCrash() {
|
||||
void Logcat::OnCrash(int err) {
|
||||
using namespace std::string_literals;
|
||||
constexpr size_t max_restart_logd_wait = 1U << 10;
|
||||
static size_t kLogdCrashCount = 0;
|
||||
static size_t kLogdRestartWait = 1 << 3;
|
||||
|
|
@ -204,7 +205,7 @@ void Logcat::OnCrash() {
|
|||
kLogdCrashCount = 0;
|
||||
}
|
||||
} else {
|
||||
Log("\nLogd maybe crashed, retrying in 1s...\n");
|
||||
Log("\nLogd maybe crashed (err="s + strerror(err) + "), retrying in 1s...\n");
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(1s);
|
||||
|
|
@ -317,7 +318,7 @@ void Logcat::Run() {
|
|||
if (modules_print_count_ >= kMaxLogSize) [[unlikely]] RefreshFd(false);
|
||||
}
|
||||
|
||||
OnCrash();
|
||||
OnCrash(errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import android.content.res.AssetManager;
|
|||
import android.content.res.Resources;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SELinux;
|
||||
import android.os.SharedMemory;
|
||||
import android.system.ErrnoException;
|
||||
|
|
@ -22,8 +23,12 @@ import org.lsposed.lspd.util.Utils;
|
|||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
|
@ -45,7 +50,9 @@ import java.util.HashSet;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import hidden.HiddenApiBridge;
|
||||
|
||||
|
|
@ -77,6 +84,15 @@ public class ConfigFileManager {
|
|||
}
|
||||
}
|
||||
|
||||
public static void transfer(InputStream in, OutputStream out) throws IOException {
|
||||
int size = 8192;
|
||||
var buffer = new byte[size];
|
||||
int read;
|
||||
while ((read = in.read(buffer, 0, size)) >= 0) {
|
||||
out.write(buffer, 0, read);
|
||||
}
|
||||
}
|
||||
|
||||
private static void createLogDirPath() throws IOException {
|
||||
if (!Files.isDirectory(logDirPath, LinkOption.NOFOLLOW_LINKS)) {
|
||||
Files.deleteIfExists(logDirPath);
|
||||
|
|
@ -194,17 +210,42 @@ public class ConfigFileManager {
|
|||
return logDirPath.resolve("props.txt").toFile();
|
||||
}
|
||||
|
||||
static Map<String, ParcelFileDescriptor> getLogs() {
|
||||
var map = new LinkedHashMap<String, ParcelFileDescriptor>();
|
||||
try {
|
||||
putFds(map, logDirPath);
|
||||
putFds(map, oldLogDirPath);
|
||||
putFds(map, Paths.get("/data/tombstones"));
|
||||
putFds(map, Paths.get("/data/anr"));
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "getLogs", e);
|
||||
static void getLogs(ParcelFileDescriptor zipFd) throws RemoteException {
|
||||
var logs = new LinkedHashMap<String, ParcelFileDescriptor>();
|
||||
try (var os = new ZipOutputStream(new FileOutputStream(zipFd.getFileDescriptor()))) {
|
||||
putFds(logs, logDirPath);
|
||||
putFds(logs, oldLogDirPath);
|
||||
putFds(logs, Paths.get("/data/tombstones"));
|
||||
putFds(logs, Paths.get("/data/anr"));
|
||||
logs.forEach((name, fd) -> {
|
||||
try (var is = new FileInputStream(fd.getFileDescriptor())) {
|
||||
os.putNextEntry(new ZipEntry(name));
|
||||
transfer(is, os);
|
||||
os.closeEntry();
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, name, e);
|
||||
}
|
||||
});
|
||||
var name = "full.log";
|
||||
try (var is = new ProcessBuilder("logcat", "-d").start().getInputStream()) {
|
||||
os.putNextEntry(new ZipEntry(name));
|
||||
transfer(is, os);
|
||||
os.closeEntry();
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, name, e);
|
||||
}
|
||||
name = "dmesg.log";
|
||||
try (var is = new ProcessBuilder("dmesg").start().getInputStream()) {
|
||||
os.putNextEntry(new ZipEntry(name));
|
||||
transfer(is, os);
|
||||
os.closeEntry();
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, name, e);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Log.w(TAG, "get log", e);
|
||||
throw new RemoteException(Log.getStackTraceString(e));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static void putFds(Map<String, ParcelFileDescriptor> map, Path path) throws IOException {
|
||||
|
|
|
|||
|
|
@ -711,8 +711,8 @@ public class LSPManagerService extends ILSPManagerService.Stub {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ParcelFileDescriptor> getLogs() {
|
||||
return ConfigFileManager.getLogs();
|
||||
public void getLogs(ParcelFileDescriptor zipFd) throws RemoteException {
|
||||
ConfigFileManager.getLogs(zipFd);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ interface ILSPManagerService {
|
|||
|
||||
void setHiddenIcon(boolean hide) = 33;
|
||||
|
||||
Map<String,ParcelFileDescriptor> getLogs() = 34;
|
||||
void getLogs(in ParcelFileDescriptor zipFd) = 34;
|
||||
|
||||
void restartFor(in Intent intent) = 35;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue