[core] clear logs will refresh fd (#1020)
This commit is contained in:
parent
6e07bfb71e
commit
bc765d3cdd
|
|
@ -21,7 +21,6 @@
|
||||||
package org.lsposed.manager.ui.fragment;
|
package org.lsposed.manager.ui.fragment;
|
||||||
|
|
||||||
import static org.lsposed.manager.App.TAG;
|
import static org.lsposed.manager.App.TAG;
|
||||||
|
|
||||||
import static java.lang.Math.max;
|
import static java.lang.Math.max;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
|
@ -193,7 +192,7 @@ public class LogsFragment extends BaseFragment {
|
||||||
private void clear() {
|
private void clear() {
|
||||||
if (ConfigManager.clearLogs(verbose)) {
|
if (ConfigManager.clearLogs(verbose)) {
|
||||||
Snackbar.make(binding.snackbar, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();
|
Snackbar.make(binding.snackbar, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();
|
||||||
reloadErrorLog();
|
adapter.clearLogs();
|
||||||
} else {
|
} else {
|
||||||
Snackbar.make(binding.snackbar, R.string.logs_clear_failed_2, Snackbar.LENGTH_SHORT).show();
|
Snackbar.make(binding.snackbar, R.string.logs_clear_failed_2, Snackbar.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
@ -324,6 +323,11 @@ public class LogsFragment extends BaseFragment {
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clearLogs() {
|
||||||
|
logs.clear();
|
||||||
|
notifyItemRangeRemoved(0, logs.size());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return logs.size();
|
return logs.size();
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ private:
|
||||||
JNIEnv *env_;
|
JNIEnv *env_;
|
||||||
jobject thiz_;
|
jobject thiz_;
|
||||||
jmethodID refresh_fd_method_;
|
jmethodID refresh_fd_method_;
|
||||||
std::string id_ = "0";
|
|
||||||
|
|
||||||
UniqueFile modules_file_{};
|
UniqueFile modules_file_{};
|
||||||
size_t modules_file_part_ = 0;
|
size_t modules_file_part_ = 0;
|
||||||
|
|
@ -59,8 +58,10 @@ private:
|
||||||
|
|
||||||
bool verbose_ = true;
|
bool verbose_ = true;
|
||||||
|
|
||||||
const std::string start_verbose_inst_ = "!!start_verbose!!";
|
constexpr inline static auto start_verbose_inst_ = "!!start_verbose!!";
|
||||||
const std::string stop_verbose_inst_ = "!!stop_verbose!!";
|
constexpr inline static auto stop_verbose_inst_ = "!!stop_verbose!!";
|
||||||
|
constexpr inline static auto refresh_verbose_inst_ = "!!refresh_verbose!!";
|
||||||
|
constexpr inline static auto refresh_modules_inst_ = "!!refresh_modules!!";
|
||||||
};
|
};
|
||||||
|
|
||||||
int Logcat::PrintLogLine(const AndroidLogEntry &entry, FILE *out) {
|
int Logcat::PrintLogLine(const AndroidLogEntry &entry, FILE *out) {
|
||||||
|
|
@ -90,18 +91,20 @@ int Logcat::PrintLogLine(const AndroidLogEntry &entry, FILE *out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logcat::RefreshFd(bool is_verbose) {
|
void Logcat::RefreshFd(bool is_verbose) {
|
||||||
|
constexpr auto start = "----part %zu start----\n";
|
||||||
|
constexpr auto end = "-----part %zu end----\n";
|
||||||
if (is_verbose) {
|
if (is_verbose) {
|
||||||
verbose_print_count_ = 0;
|
verbose_print_count_ = 0;
|
||||||
fprintf(verbose_file_.get(), "----%s-%zu end----\n", id_.data(), verbose_file_part_);
|
fprintf(verbose_file_.get(), end, verbose_file_part_);
|
||||||
verbose_file_ = UniqueFile(env_->CallIntMethod(thiz_, refresh_fd_method_, JNI_TRUE), "a");
|
verbose_file_ = UniqueFile(env_->CallIntMethod(thiz_, refresh_fd_method_, JNI_TRUE), "a");
|
||||||
verbose_file_part_++;
|
verbose_file_part_++;
|
||||||
fprintf(verbose_file_.get(), "----%s-%zu start----\n", id_.data(), verbose_file_part_);
|
fprintf(verbose_file_.get(), start, verbose_file_part_);
|
||||||
} else {
|
} else {
|
||||||
modules_print_count_ = 0;
|
modules_print_count_ = 0;
|
||||||
fprintf(modules_file_.get(), "----%zu end----\n", modules_file_part_);
|
fprintf(modules_file_.get(), end, modules_file_part_);
|
||||||
modules_file_ = UniqueFile(env_->CallIntMethod(thiz_, refresh_fd_method_, JNI_FALSE), "a");
|
modules_file_ = UniqueFile(env_->CallIntMethod(thiz_, refresh_fd_method_, JNI_FALSE), "a");
|
||||||
modules_file_part_++;
|
modules_file_part_++;
|
||||||
fprintf(modules_file_.get(), "----%zu start----\n", modules_file_part_);
|
fprintf(modules_file_.get(), start, modules_file_part_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,7 +112,7 @@ void Logcat::ProcessBuffer(struct log_msg *buf) {
|
||||||
AndroidLogEntry entry;
|
AndroidLogEntry entry;
|
||||||
if (android_log_processLogBuffer(&buf->entry, &entry) < 0) return;
|
if (android_log_processLogBuffer(&buf->entry, &entry) < 0) return;
|
||||||
|
|
||||||
std::string_view tag(entry.tag);
|
std::string_view tag(entry.tag, entry.tagLen);
|
||||||
bool shortcut = false;
|
bool shortcut = false;
|
||||||
if (tag == "LSPosed-Bridge" || tag == "XSharedPreferences") [[unlikely]] {
|
if (tag == "LSPosed-Bridge" || tag == "XSharedPreferences") [[unlikely]] {
|
||||||
modules_print_count_ += PrintLogLine(entry, modules_file_.get());
|
modules_print_count_ += PrintLogLine(entry, modules_file_.get());
|
||||||
|
|
@ -122,12 +125,16 @@ void Logcat::ProcessBuffer(struct log_msg *buf) {
|
||||||
verbose_print_count_ += PrintLogLine(entry, verbose_file_.get());
|
verbose_print_count_ += PrintLogLine(entry, verbose_file_.get());
|
||||||
}
|
}
|
||||||
if (entry.pid == getpid() && tag == "LSPosedLogcat") [[unlikely]] {
|
if (entry.pid == getpid() && tag == "LSPosedLogcat") [[unlikely]] {
|
||||||
if (std::string_view(entry.message).starts_with(start_verbose_inst_)) {
|
std::string_view msg(entry.message, entry.messageLen);
|
||||||
|
if (msg == start_verbose_inst_) {
|
||||||
verbose_ = true;
|
verbose_ = true;
|
||||||
id_ = std::string(entry.message, start_verbose_inst_.length(), std::string::npos);
|
|
||||||
verbose_print_count_ += PrintLogLine(entry, verbose_file_.get());
|
verbose_print_count_ += PrintLogLine(entry, verbose_file_.get());
|
||||||
} else if (std::string_view(entry.message) == stop_verbose_inst_ + id_) {
|
} else if (msg == stop_verbose_inst_) {
|
||||||
verbose_ = false;
|
verbose_ = false;
|
||||||
|
} else if (msg == refresh_modules_inst_) {
|
||||||
|
RefreshFd(false);
|
||||||
|
} else if (msg == refresh_verbose_inst_) {
|
||||||
|
RefreshFd(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,21 +34,12 @@ import android.os.Parcel;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.util.ArrayMap;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.server.LocalServices;
|
|
||||||
import com.android.server.SystemService;
|
|
||||||
import com.android.server.SystemServiceManager;
|
|
||||||
import com.android.server.am.ActivityManagerService;
|
|
||||||
import com.android.server.am.ProcessRecord;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class BridgeService {
|
public class BridgeService {
|
||||||
|
|
@ -75,12 +66,12 @@ public class BridgeService {
|
||||||
Log.i(TAG, "service " + SERVICE_NAME + " is dead. ");
|
Log.i(TAG, "service " + SERVICE_NAME + " is dead. ");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//noinspection JavaReflectionMemberAccess
|
//noinspection JavaReflectionMemberAccess DiscouragedPrivateApi
|
||||||
Field field = ServiceManager.class.getDeclaredField("sServiceManager");
|
Field field = ServiceManager.class.getDeclaredField("sServiceManager");
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
field.set(null, null);
|
field.set(null, null);
|
||||||
|
|
||||||
//noinspection JavaReflectionMemberAccess
|
//noinspection JavaReflectionMemberAccess DiscouragedPrivateApi
|
||||||
field = ServiceManager.class.getDeclaredField("sCache");
|
field = ServiceManager.class.getDeclaredField("sCache");
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
Object sCache = field.get(null);
|
Object sCache = field.get(null);
|
||||||
|
|
@ -318,60 +309,4 @@ public class BridgeService {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void tryGetActivityManagerServiceInstance() {
|
|
||||||
try {
|
|
||||||
Log.e(TAG, "Trying to get the ams");
|
|
||||||
Field localServiceField = LocalServices.class.getDeclaredField("sLocalServiceObjects");
|
|
||||||
localServiceField.setAccessible(true);
|
|
||||||
ArrayMap<Class<?>, Object> localServiceMap = (ArrayMap<Class<?>, Object>) localServiceField.get(null);
|
|
||||||
Class<?> systemServiceManagerClass = null;
|
|
||||||
for (Class<?> clazz : localServiceMap.keySet()) {
|
|
||||||
if (clazz.getName().equals("com.android.server.SystemServiceManager")) {
|
|
||||||
systemServiceManagerClass = clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Field parentField = ClassLoader.class.getDeclaredField("parent");
|
|
||||||
parentField.setAccessible(true);
|
|
||||||
parentField.set(BridgeService.class.getClassLoader(), systemServiceManagerClass.getClassLoader());
|
|
||||||
SystemServiceManager systemServiceManager = LocalServices.getService(SystemServiceManager.class);
|
|
||||||
ArrayList<SystemService> services;
|
|
||||||
try {
|
|
||||||
Field servicesField = systemServiceManagerClass.getDeclaredField("mServices");
|
|
||||||
servicesField.setAccessible(true);
|
|
||||||
services = (ArrayList<SystemService>) servicesField.get(systemServiceManager);
|
|
||||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(e));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ActivityManagerService.Lifecycle lifecycle = null;
|
|
||||||
|
|
||||||
for (SystemService service : services) {
|
|
||||||
if (service instanceof ActivityManagerService.Lifecycle) {
|
|
||||||
lifecycle = (ActivityManagerService.Lifecycle) service;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lifecycle == null) {
|
|
||||||
Log.e(TAG, "I cannot get the lifecycle...");
|
|
||||||
}
|
|
||||||
ActivityManagerService activityManagerService = lifecycle.getService();
|
|
||||||
if (activityManagerService != null) {
|
|
||||||
Log.e(TAG, "I got the ams!!!: " + activityManagerService);
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "I cannot get the ams");
|
|
||||||
}
|
|
||||||
Method findProcessLockedMethod = ActivityManagerService.class.getDeclaredMethod("findProcessLocked", String.class, int.class, String.class);
|
|
||||||
findProcessLockedMethod.setAccessible(true);
|
|
||||||
ProcessRecord record = (ProcessRecord) findProcessLockedMethod.invoke(activityManagerService, String.valueOf(Binder.getCallingPid()), 0, "LSPosed");
|
|
||||||
Field processNameField = ProcessRecord.class.getDeclaredField("processName");
|
|
||||||
processNameField.setAccessible(true);
|
|
||||||
if (record != null) {
|
|
||||||
Log.e(TAG, "I got the record!!!: " + record);
|
|
||||||
Log.e(TAG, "I got the process name: " + processNameField.get(record));
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,8 @@ import org.lsposed.lspd.models.PreLoadedApk;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.nio.file.FileVisitResult;
|
import java.nio.file.FileVisitResult;
|
||||||
|
|
@ -866,17 +864,8 @@ public class ConfigManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean clearLogs(boolean verbose) {
|
public boolean clearLogs(boolean verbose) {
|
||||||
var logcatService = ServiceManager.getLogcatService();
|
ServiceManager.getLogcatService().refresh(verbose);
|
||||||
File logFile = verbose ? logcatService.getVerboseLog() : logcatService.getModulesLog();
|
|
||||||
if (logFile == null) return true;
|
|
||||||
try {
|
|
||||||
OutputStream os = new FileOutputStream(logFile);
|
|
||||||
os.close();
|
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(e));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isManager(String packageName) {
|
public boolean isManager(String packageName) {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import static org.lsposed.lspd.service.ServiceManager.TAG;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.ParcelFileDescriptor;
|
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@ import android.annotation.SuppressLint;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
@ -18,7 +16,6 @@ public class LogcatService implements Runnable {
|
||||||
private File modulesLog = null;
|
private File modulesLog = null;
|
||||||
private File verboseLog = null;
|
private File verboseLog = null;
|
||||||
private Thread thread = null;
|
private Thread thread = null;
|
||||||
private int id = 0;
|
|
||||||
|
|
||||||
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
||||||
public LogcatService() {
|
public LogcatService() {
|
||||||
|
|
@ -72,12 +69,19 @@ public class LogcatService implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startVerbose() {
|
public void startVerbose() {
|
||||||
Log.i(TAG, "!!start_verbose!!" + id);
|
Log.i(TAG, "!!start_verbose!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopVerbose() {
|
public void stopVerbose() {
|
||||||
Log.i(TAG, "!!stop_verbose!!" + id);
|
Log.i(TAG, "!!stop_verbose!!");
|
||||||
id++;
|
}
|
||||||
|
|
||||||
|
public void refresh(boolean isVerboseLog) {
|
||||||
|
if (isVerboseLog) {
|
||||||
|
Log.i(TAG, "!!refresh_verbose!!");
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "!!refresh_modules!!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getVerboseLog() {
|
public File getVerboseLog() {
|
||||||
|
|
|
||||||
|
|
@ -29,14 +29,13 @@ import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class UserService {
|
public class UserService {
|
||||||
private static IUserManager um = null;
|
private static IUserManager um = null;
|
||||||
private static IBinder binder = null;
|
private static IBinder binder = null;
|
||||||
private static IBinder.DeathRecipient recipient = new IBinder.DeathRecipient() {
|
private static final IBinder.DeathRecipient recipient = new IBinder.DeathRecipient() {
|
||||||
@Override
|
@Override
|
||||||
public void binderDied() {
|
public void binderDied() {
|
||||||
Log.w(TAG, "um is dead");
|
Log.w(TAG, "um is dead");
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.Looper;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.android.apksig.ApkVerifier;
|
import com.android.apksig.ApkVerifier;
|
||||||
|
|
@ -68,7 +69,7 @@ public class InstallerVerifier {
|
||||||
Utils.logW("showErrorToast: ", t);
|
Utils.logW("showErrorToast: ", t);
|
||||||
Toast.makeText((Context) param.thisObject, str, Toast.LENGTH_LONG).show();
|
Toast.makeText((Context) param.thisObject, str, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
new Handler().postDelayed(() -> System.exit(0), 50);
|
new Handler(Looper.getMainLooper()).postDelayed(() -> System.exit(0), 1000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue