Save crash to file (#2460)
This commit is contained in:
parent
4190bfb9e6
commit
8792e62df8
|
|
@ -56,9 +56,6 @@
|
||||||
android:name="android.app.shortcuts"
|
android:name="android.app.shortcuts"
|
||||||
android:resource="@xml/shortcuts" />
|
android:resource="@xml/shortcuts" />
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
|
||||||
android:name=".ui.activity.CrashReportActivity"
|
|
||||||
android:process=":error" />
|
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.startup.InitializationProvider"
|
android:name="androidx.startup.InitializationProvider"
|
||||||
|
|
|
||||||
|
|
@ -20,18 +20,20 @@
|
||||||
|
|
||||||
package org.lsposed.manager;
|
package org.lsposed.manager;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
|
import android.provider.MediaStore;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.system.Os;
|
import android.system.Os;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
@ -43,8 +45,8 @@ import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
import org.lsposed.hiddenapibypass.HiddenApiBypass;
|
import org.lsposed.hiddenapibypass.HiddenApiBypass;
|
||||||
import org.lsposed.manager.adapters.AppHelper;
|
import org.lsposed.manager.adapters.AppHelper;
|
||||||
|
import org.lsposed.manager.receivers.LSPManagerServiceHolder;
|
||||||
import org.lsposed.manager.repo.RepoLoader;
|
import org.lsposed.manager.repo.RepoLoader;
|
||||||
import org.lsposed.manager.ui.activity.CrashReportActivity;
|
|
||||||
import org.lsposed.manager.util.CloudflareDNS;
|
import org.lsposed.manager.util.CloudflareDNS;
|
||||||
import org.lsposed.manager.util.ModuleUtil;
|
import org.lsposed.manager.util.ModuleUtil;
|
||||||
import org.lsposed.manager.util.Telemetry;
|
import org.lsposed.manager.util.Telemetry;
|
||||||
|
|
@ -55,8 +57,8 @@ import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
@ -96,23 +98,12 @@ public class App extends Application {
|
||||||
var list = AppHelper.getAppList(false);
|
var list = AppHelper.getAppList(false);
|
||||||
var pm = App.getInstance().getPackageManager();
|
var pm = App.getInstance().getPackageManager();
|
||||||
list.parallelStream().forEach(i -> AppHelper.getAppLabel(i, pm));
|
list.parallelStream().forEach(i -> AppHelper.getAppLabel(i, pm));
|
||||||
|
AppHelper.getDenyList(false);
|
||||||
|
ModuleUtil.getInstance();
|
||||||
|
RepoLoader.getInstance();
|
||||||
});
|
});
|
||||||
return false;
|
App.getExecutorService().submit(HTML_TEMPLATE);
|
||||||
});
|
App.getExecutorService().submit(HTML_TEMPLATE_DARK);
|
||||||
|
|
||||||
Looper.myQueue().addIdleHandler(() -> {
|
|
||||||
if (App.getInstance() == null || App.getExecutorService() == null) return true;
|
|
||||||
App.getExecutorService().submit(() -> AppHelper.getDenyList(false));
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
Looper.myQueue().addIdleHandler(() -> {
|
|
||||||
if (App.getInstance() == null || App.getExecutorService() == null) return true;
|
|
||||||
App.getExecutorService().submit(ModuleUtil::getInstance);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
Looper.myQueue().addIdleHandler(() -> {
|
|
||||||
if (App.getInstance() == null || App.getExecutorService() == null) return true;
|
|
||||||
App.getExecutorService().submit(RepoLoader::getInstance);
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -169,41 +160,47 @@ public class App extends Application {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("WrongConstant")
|
|
||||||
private void setCrashReport() {
|
private void setCrashReport() {
|
||||||
|
var handler = Thread.getDefaultUncaughtExceptionHandler();
|
||||||
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
|
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
|
||||||
|
var time = OffsetDateTime.now();
|
||||||
StringWriter sw = new StringWriter();
|
var dir = new File(getCacheDir(), "crash");
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
//noinspection ResultOfMethodCallIgnored
|
||||||
throwable.printStackTrace(pw);
|
dir.mkdir();
|
||||||
String stackTraceString = sw.toString();
|
var file = new File(dir, time.toEpochSecond() + ".log");
|
||||||
|
try (var pw = new PrintWriter(file)) {
|
||||||
//Reduce data to 128KB so we don't get a TransactionTooLargeException when sending the intent.
|
pw.println(BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")");
|
||||||
//The limit is 1MB on Android but some devices seem to have it lower.
|
pw.println(time);
|
||||||
//See: http://developer.android.com/reference/android/os/TransactionTooLargeException.html
|
pw.println("pid: " + Os.getpid() + " uid: " + Os.getuid());
|
||||||
//And: http://stackoverflow.com/questions/11451393/what-to-do-on-transactiontoolargeexception#comment46697371_12809171
|
throwable.printStackTrace(pw);
|
||||||
if (stackTraceString.length() > 131071) {
|
} catch (IOException ignored) {
|
||||||
String disclaimer = " [stack trace too large]";
|
}
|
||||||
stackTraceString = stackTraceString.substring(0, 131071 - disclaimer.length()) + disclaimer;
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
var table = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
|
||||||
|
var values = new ContentValues();
|
||||||
|
values.put(MediaStore.Downloads.DISPLAY_NAME, "LSPosed_crash_report" + time.toEpochSecond() + ".zip");
|
||||||
|
values.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS);
|
||||||
|
var cr = getContentResolver();
|
||||||
|
var uri = cr.insert(table, values);
|
||||||
|
if (uri == null) return;
|
||||||
|
try (var zipFd = cr.openFileDescriptor(uri, "wt")) {
|
||||||
|
LSPManagerServiceHolder.getService().getLogs(zipFd);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
cr.delete(uri, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (handler != null) {
|
||||||
|
handler.uncaughtException(thread, throwable);
|
||||||
}
|
}
|
||||||
Intent intent = new Intent(App.this, CrashReportActivity.class);
|
|
||||||
intent.putExtra(BuildConfig.APPLICATION_ID + ".EXTRA_STACK_TRACE", stackTraceString);
|
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
|
||||||
App.this.startActivity(intent);
|
|
||||||
System.exit(10);
|
|
||||||
Process.killProcess(Os.getpid());
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
if (!BuildConfig.DEBUG && !isParasitic) {
|
|
||||||
setCrashReport();
|
|
||||||
}
|
|
||||||
|
|
||||||
instance = this;
|
instance = this;
|
||||||
|
|
||||||
|
setCrashReport();
|
||||||
pref = PreferenceManager.getDefaultSharedPreferences(this);
|
pref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
if (!pref.contains("doh")) {
|
if (!pref.contains("doh")) {
|
||||||
var name = "private_dns_mode";
|
var name = "private_dns_mode";
|
||||||
|
|
@ -256,17 +253,14 @@ public class App extends Application {
|
||||||
}, intentFilter, Context.RECEIVER_NOT_EXPORTED);
|
}, intentFilter, Context.RECEIVER_NOT_EXPORTED);
|
||||||
|
|
||||||
UpdateUtil.loadRemoteVersion();
|
UpdateUtil.loadRemoteVersion();
|
||||||
|
|
||||||
executorService.submit(HTML_TEMPLATE);
|
|
||||||
executorService.submit(HTML_TEMPLATE_DARK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static OkHttpClient getOkHttpClient() {
|
public static OkHttpClient getOkHttpClient() {
|
||||||
if (okHttpClient != null) return okHttpClient;
|
if (okHttpClient != null) return okHttpClient;
|
||||||
var builder = new OkHttpClient.Builder()
|
var builder = new OkHttpClient.Builder()
|
||||||
.cache(getOkHttpCache())
|
.cache(getOkHttpCache())
|
||||||
.dns(new CloudflareDNS());
|
.dns(new CloudflareDNS());
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
var log = new HttpLoggingInterceptor();
|
var log = new HttpLoggingInterceptor();
|
||||||
log.setLevel(HttpLoggingInterceptor.Level.HEADERS);
|
log.setLevel(HttpLoggingInterceptor.Level.HEADERS);
|
||||||
|
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of LSPosed.
|
|
||||||
*
|
|
||||||
* LSPosed 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.
|
|
||||||
*
|
|
||||||
* LSPosed 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 LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 EdXposed Contributors
|
|
||||||
* Copyright (C) 2021 LSPosed Contributors
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.lsposed.manager.ui.activity;
|
|
||||||
|
|
||||||
import android.content.ClipData;
|
|
||||||
import android.content.ClipboardManager;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.google.android.material.color.DynamicColors;
|
|
||||||
|
|
||||||
import org.lsposed.manager.BuildConfig;
|
|
||||||
import org.lsposed.manager.R;
|
|
||||||
import org.lsposed.manager.databinding.ActivityCrashReportBinding;
|
|
||||||
import org.lsposed.manager.util.NavUtil;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import rikka.material.app.LocaleDelegate;
|
|
||||||
import rikka.material.app.MaterialActivity;
|
|
||||||
|
|
||||||
public class CrashReportActivity extends MaterialActivity {
|
|
||||||
ActivityCrashReportBinding binding;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
setTheme(R.style.AppTheme);
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
binding = ActivityCrashReportBinding.inflate(getLayoutInflater());
|
|
||||||
setContentView(binding.getRoot());
|
|
||||||
binding.sendLogs.setOnClickListener(view -> {
|
|
||||||
Intent sendIntent = new Intent();
|
|
||||||
sendIntent.setAction(Intent.ACTION_SEND);
|
|
||||||
sendIntent.putExtra(Intent.EXTRA_TEXT, getAllErrorDetailsFromIntent(getIntent()));
|
|
||||||
sendIntent.setType("text/plain");
|
|
||||||
startActivity(Intent.createChooser(sendIntent, null));
|
|
||||||
});
|
|
||||||
binding.reportIssue.setOnClickListener(view -> {
|
|
||||||
var clipboard = getSystemService(ClipboardManager.class);
|
|
||||||
//Are there any devices without clipboard...?
|
|
||||||
if (clipboard != null) {
|
|
||||||
ClipData clip = ClipData.newPlainText("LSPManagerCrashInfo",
|
|
||||||
getAllErrorDetailsFromIntent(getIntent()));
|
|
||||||
clipboard.setPrimaryClip(clip);
|
|
||||||
Toast.makeText(this, R.string.crash_info_copied, Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
NavUtil.startURL(this, "https://github.com/LSPosed/LSPosed/issues");
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onApplyUserThemeResource(@NonNull Resources.Theme theme, boolean isDecorView) {
|
|
||||||
if (!DynamicColors.isDynamicColorAvailable())
|
|
||||||
theme.applyStyle(R.style.ThemeOverlay_MaterialBlue, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAllErrorDetailsFromIntent(@NonNull Intent intent) {
|
|
||||||
String versionName = String.format(LocaleDelegate.getDefaultLocale(), "%s (%d)", BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE);
|
|
||||||
|
|
||||||
return "Build version: " + versionName + " \n" +
|
|
||||||
"Current date: " + LocalDateTime.now() + " \n" +
|
|
||||||
"Device: " + getDeviceModelName() + " \n" +
|
|
||||||
"Fingerprint: " + getFingerprint() + " \n \n" +
|
|
||||||
"SDK: " + Build.VERSION.SDK_INT + " \n \n" +
|
|
||||||
"Stack trace: \n" +
|
|
||||||
getStackTraceFromIntent(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getFingerprint() {
|
|
||||||
return Build.BRAND + '/' +
|
|
||||||
Build.PRODUCT + '/' +
|
|
||||||
Build.DEVICE + ':' +
|
|
||||||
Build.VERSION.RELEASE + '/' +
|
|
||||||
Build.ID + '/' +
|
|
||||||
Build.VERSION.INCREMENTAL + ':' +
|
|
||||||
Build.TYPE + '/' +
|
|
||||||
Build.TAGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getDeviceModelName() {
|
|
||||||
String manufacturer = Build.MANUFACTURER;
|
|
||||||
String model = Build.MODEL;
|
|
||||||
if (model.startsWith(manufacturer)) {
|
|
||||||
return capitalize(model);
|
|
||||||
} else {
|
|
||||||
return capitalize(manufacturer) + " " + model;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String capitalize(@Nullable String s) {
|
|
||||||
if (s == null || s.length() == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
char first = s.charAt(0);
|
|
||||||
if (Character.isUpperCase(first)) {
|
|
||||||
return s;
|
|
||||||
} else {
|
|
||||||
return Character.toUpperCase(first) + s.substring(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStackTraceFromIntent(@NonNull Intent intent) {
|
|
||||||
return intent.getStringExtra(BuildConfig.APPLICATION_ID + ".EXTRA_STACK_TRACE");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?><!--
|
|
||||||
~ This file is part of LSPosed.
|
|
||||||
~
|
|
||||||
~ LSPosed 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.
|
|
||||||
~
|
|
||||||
~ LSPosed 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 LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
~
|
|
||||||
~ Copyright (C) 2020 EdXposed Contributors
|
|
||||||
~ Copyright (C) 2021 LSPosed Contributors
|
|
||||||
-->
|
|
||||||
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:clipChildren="false">
|
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
|
||||||
style="?materialCardViewElevatedStyle"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:minHeight="148dp"
|
|
||||||
android:outlineAmbientShadowColor="@color/home_secondary_outline_ambient_shadow_color"
|
|
||||||
android:outlineSpotShadowColor="@color/home_secondary_outline_spot_shadow_color"
|
|
||||||
app:cardElevation="@dimen/home_secondary_elevation">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:paddingBottom="8dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_weight="1.0"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingTop="8dp">
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
style="?attr/textAppearanceHeadline5"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/manager_crashed" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
|
||||||
android:layout_width="80dp"
|
|
||||||
android:layout_height="80dp"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:background="@android:color/transparent"
|
|
||||||
android:tint="@color/material_amber_500"
|
|
||||||
app:srcCompat="@drawable/ic_round_warning_24" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="8dp">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/send_logs"
|
|
||||||
style="?attr/borderlessButtonStyle"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:minWidth="0dp"
|
|
||||||
android:text="@string/send_crash_info"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:tooltipText="@string/send_crash_info"
|
|
||||||
app:icon="@drawable/ic_round_send_24" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/report_issue"
|
|
||||||
style="?attr/borderlessButtonStyle"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:minWidth="0dp"
|
|
||||||
android:text="@string/report_issue"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:tooltipText="@string/report_issue"
|
|
||||||
app:icon="@drawable/ic_round_bug_report_24" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
@ -24,6 +24,7 @@ import static org.lsposed.lspd.service.ServiceManager.toGlobalNamespace;
|
||||||
|
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
|
@ -69,6 +70,7 @@ import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.util.zip.Deflater;
|
import java.util.zip.Deflater;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
|
|
@ -248,6 +250,11 @@ public class ConfigFileManager {
|
||||||
zipAddDir(os, oldLogDirPath);
|
zipAddDir(os, oldLogDirPath);
|
||||||
zipAddDir(os, Paths.get("/data/tombstones"));
|
zipAddDir(os, Paths.get("/data/tombstones"));
|
||||||
zipAddDir(os, Paths.get("/data/anr"));
|
zipAddDir(os, Paths.get("/data/anr"));
|
||||||
|
var data = Paths.get("/data/data");
|
||||||
|
var app1 = data.resolve(BuildConfig.MANAGER_INJECTED_PKG_NAME + "/cache/crash");
|
||||||
|
var app2 = data.resolve(BuildConfig.DEFAULT_MANAGER_PACKAGE_NAME + "/cache/crash");
|
||||||
|
zipAddDir(os, app1);
|
||||||
|
zipAddDir(os, app2);
|
||||||
zipAddProcOutput(os, "full.log", "logcat", "-b", "all", "-d");
|
zipAddProcOutput(os, "full.log", "logcat", "-b", "all", "-d");
|
||||||
zipAddProcOutput(os, "dmesg.log", "dmesg");
|
zipAddProcOutput(os, "dmesg.log", "dmesg");
|
||||||
var magiskDataDir = Paths.get("/data/adb");
|
var magiskDataDir = Paths.get("/data/adb");
|
||||||
|
|
@ -261,6 +268,14 @@ public class ConfigFileManager {
|
||||||
zipAddFile(os, p.resolve("sepolicy.rule"), magiskDataDir);
|
zipAddFile(os, p.resolve("sepolicy.rule"), magiskDataDir);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
var proc = Paths.get("/proc");
|
||||||
|
for (var pid : new String[]{"self", String.valueOf(Binder.getCallingPid())}) {
|
||||||
|
var pidPath = proc.resolve(pid);
|
||||||
|
zipAddFile(os, pidPath.resolve("maps"), proc);
|
||||||
|
zipAddFile(os, pidPath.resolve("mountinfo"), proc);
|
||||||
|
zipAddFile(os, pidPath.resolve("status"), proc);
|
||||||
|
}
|
||||||
|
zipAddFile(os, dbPath.toPath(), configDirPath);
|
||||||
ConfigManager.getInstance().exportScopes(os);
|
ConfigManager.getInstance().exportScopes(os);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Log.w(TAG, "get log", e);
|
Log.w(TAG, "get log", e);
|
||||||
|
|
@ -299,6 +314,7 @@ public class ConfigFileManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void zipAddDir(ZipOutputStream os, Path path) throws IOException {
|
private static void zipAddDir(ZipOutputStream os, Path path) throws IOException {
|
||||||
|
if (!Files.isDirectory(path)) return;
|
||||||
Files.walkFileTree(path, new SimpleFileVisitor<>() {
|
Files.walkFileTree(path, new SimpleFileVisitor<>() {
|
||||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
|
||||||
if (Files.isRegularFile(file)) {
|
if (Files.isRegularFile(file)) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue