parent
5209136174
commit
223fdb5c10
|
|
@ -218,6 +218,7 @@ dependencies {
|
||||||
|
|
||||||
val appCenter = "4.4.2"
|
val appCenter = "4.4.2"
|
||||||
debugImplementation("com.microsoft.appcenter:appcenter-crashes:${appCenter}")
|
debugImplementation("com.microsoft.appcenter:appcenter-crashes:${appCenter}")
|
||||||
|
debugImplementation("com.microsoft.appcenter:appcenter-analytics:${appCenter}")
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.all {
|
configurations.all {
|
||||||
|
|
|
||||||
|
|
@ -2,52 +2,66 @@ package org.lsposed.manager.util;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.microsoft.appcenter.AppCenter;
|
import com.microsoft.appcenter.AppCenter;
|
||||||
|
import com.microsoft.appcenter.analytics.Analytics;
|
||||||
import com.microsoft.appcenter.channel.AbstractChannelListener;
|
import com.microsoft.appcenter.channel.AbstractChannelListener;
|
||||||
import com.microsoft.appcenter.channel.Channel;
|
import com.microsoft.appcenter.channel.Channel;
|
||||||
import com.microsoft.appcenter.crashes.Crashes;
|
import com.microsoft.appcenter.crashes.Crashes;
|
||||||
|
import com.microsoft.appcenter.ingestion.models.Log;
|
||||||
|
|
||||||
import org.lsposed.manager.App;
|
import org.lsposed.manager.App;
|
||||||
import org.lsposed.manager.BuildConfig;
|
import org.lsposed.manager.BuildConfig;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class Telemetry {
|
public class Telemetry {
|
||||||
static Channel.Listener patchDeviceListener = new AbstractChannelListener() {
|
private static final Channel.Listener patchDeviceListener = new AbstractChannelListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPreparedLog(@NonNull com.microsoft.appcenter.ingestion.models.Log log, @NonNull String groupName, int flags) {
|
public void onPreparedLog(@NonNull Log log, @NonNull String groupName, int flags) {
|
||||||
var d = log.getDevice();
|
var device = log.getDevice();
|
||||||
d.setAppVersion(BuildConfig.VERSION_NAME);
|
device.setAppVersion(BuildConfig.VERSION_NAME);
|
||||||
d.setAppBuild(String.valueOf(BuildConfig.VERSION_CODE));
|
device.setAppBuild(String.valueOf(BuildConfig.VERSION_CODE));
|
||||||
d.setAppNamespace(BuildConfig.APPLICATION_ID);
|
|
||||||
log.setDevice(d);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void addPatchDeviceListener() {
|
private static void addPatchDeviceListener() {
|
||||||
try {
|
try {
|
||||||
var channel = AppCenter.class.getDeclaredField("mChannel");
|
var channelField = AppCenter.class.getDeclaredField("mChannel");
|
||||||
channel.setAccessible(true);
|
channelField.setAccessible(true);
|
||||||
((Channel) channel.get(AppCenter.getInstance())).addListener(patchDeviceListener);
|
var channel = (Channel) channelField.get(AppCenter.getInstance());
|
||||||
} catch (Throwable e) {
|
assert channel != null;
|
||||||
Log.e(App.TAG, "add listener", e);
|
channel.addListener(patchDeviceListener);
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
android.util.Log.e(App.TAG, "add listener", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void patchDevice() throws Throwable {
|
private static void patchDevice() {
|
||||||
var handle = AppCenter.class.getDeclaredField("mHandler");
|
try {
|
||||||
handle.setAccessible(true);
|
var handlerField = AppCenter.class.getDeclaredField("mHandler");
|
||||||
((Handler) handle.get(AppCenter.getInstance())).post(Telemetry::addPatchDeviceListener);
|
handlerField.setAccessible(true);
|
||||||
|
var handler = ((Handler) handlerField.get(AppCenter.getInstance()));
|
||||||
|
assert handler != null;
|
||||||
|
handler.post(Telemetry::addPatchDeviceListener);
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
android.util.Log.e(App.TAG, "patch device", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void start(Application app) {
|
public static void start(Application app) {
|
||||||
AppCenter.start(app, "eb3c4175-e879-4312-a72e-b0e64bca142c", Crashes.class);
|
AppCenter.start(app, "eb3c4175-e879-4312-a72e-b0e64bca142c",
|
||||||
try {
|
Analytics.class, Crashes.class);
|
||||||
patchDevice();
|
patchDevice();
|
||||||
} catch (Throwable e) {
|
}
|
||||||
Log.w(App.TAG, "patch device", e);
|
|
||||||
}
|
public static void trackEvent(String name, Map<String, String> properties) {
|
||||||
|
Analytics.trackEvent(name, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void trackError(Throwable throwable, Map<String, String> properties) {
|
||||||
|
Crashes.trackError(throwable, properties, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
package org.lsposed.manager;
|
package org.lsposed.manager;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.ActivityManager;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
@ -53,6 +54,7 @@ import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
@ -147,8 +149,22 @@ public class App extends Application {
|
||||||
@Override
|
@Override
|
||||||
protected void attachBaseContext(Context base) {
|
protected void attachBaseContext(Context base) {
|
||||||
super.attachBaseContext(base);
|
super.attachBaseContext(base);
|
||||||
if (BuildConfig.DEBUG) {
|
Telemetry.start(this);
|
||||||
Telemetry.start(this);
|
var map = new HashMap<String, String>(1);
|
||||||
|
map.put("isParasitic", String.valueOf(isParasitic()));
|
||||||
|
Telemetry.trackEvent("App start", map);
|
||||||
|
var am = getSystemService(ActivityManager.class);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
map.clear();
|
||||||
|
var reasons = am.getHistoricalProcessExitReasons(null, 0, 1);
|
||||||
|
if (reasons.size() == 1) {
|
||||||
|
map.put("description", reasons.get(0).getDescription());
|
||||||
|
map.put("importance", String.valueOf(reasons.get(0).getImportance()));
|
||||||
|
map.put("process", reasons.get(0).getProcessName());
|
||||||
|
map.put("reason", String.valueOf(reasons.get(0).getReason()));
|
||||||
|
map.put("status", String.valueOf(reasons.get(0).getStatus()));
|
||||||
|
Telemetry.trackEvent("Last exit reasons", map);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ import org.lsposed.manager.R;
|
||||||
import org.lsposed.manager.ui.dialog.BlurBehindDialogBuilder;
|
import org.lsposed.manager.ui.dialog.BlurBehindDialogBuilder;
|
||||||
import org.lsposed.manager.ui.dialog.FlashDialogBuilder;
|
import org.lsposed.manager.ui.dialog.FlashDialogBuilder;
|
||||||
import org.lsposed.manager.util.NavUtil;
|
import org.lsposed.manager.util.NavUtil;
|
||||||
|
import org.lsposed.manager.util.Telemetry;
|
||||||
import org.lsposed.manager.util.ThemeUtil;
|
import org.lsposed.manager.util.ThemeUtil;
|
||||||
import org.lsposed.manager.util.UpdateUtil;
|
import org.lsposed.manager.util.UpdateUtil;
|
||||||
|
|
||||||
|
|
@ -94,6 +95,12 @@ public class BaseActivity extends MaterialActivity {
|
||||||
setTaskDescription(new ActivityManager.TaskDescription(getTitle().toString(), icon));
|
setTaskDescription(new ActivityManager.TaskDescription(getTitle().toString(), icon));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
Telemetry.trackEvent("BaseActivity stop", null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onApplyUserThemeResource(@NonNull Resources.Theme theme, boolean isDecorView) {
|
public void onApplyUserThemeResource(@NonNull Resources.Theme theme, boolean isDecorView) {
|
||||||
theme.applyStyle(ThemeUtil.getNightThemeStyleRes(this), true);
|
theme.applyStyle(ThemeUtil.getNightThemeStyleRes(this), true);
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,13 @@ import org.lsposed.manager.ui.dialog.BlurBehindDialogBuilder;
|
||||||
import org.lsposed.manager.ui.dialog.FlashDialogBuilder;
|
import org.lsposed.manager.ui.dialog.FlashDialogBuilder;
|
||||||
import org.lsposed.manager.ui.dialog.ShortcutDialog;
|
import org.lsposed.manager.ui.dialog.ShortcutDialog;
|
||||||
import org.lsposed.manager.util.NavUtil;
|
import org.lsposed.manager.util.NavUtil;
|
||||||
|
import org.lsposed.manager.util.Telemetry;
|
||||||
import org.lsposed.manager.util.UpdateUtil;
|
import org.lsposed.manager.util.UpdateUtil;
|
||||||
import org.lsposed.manager.util.chrome.LinkTransformationMethod;
|
import org.lsposed.manager.util.chrome.LinkTransformationMethod;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import rikka.core.util.ClipboardUtils;
|
import rikka.core.util.ClipboardUtils;
|
||||||
import rikka.material.app.LocaleDelegate;
|
import rikka.material.app.LocaleDelegate;
|
||||||
|
|
||||||
|
|
@ -194,6 +198,12 @@ public class HomeFragment extends BaseFragment {
|
||||||
activity.getString(R.string.info_system_abi) +
|
activity.getString(R.string.info_system_abi) +
|
||||||
"\n" +
|
"\n" +
|
||||||
binding.systemAbi.getText();
|
binding.systemAbi.getText();
|
||||||
|
var map = new HashMap<String, String>();
|
||||||
|
map.put("apiVersion", binding.apiVersion.getText().toString());
|
||||||
|
map.put("api", binding.api.getText().toString());
|
||||||
|
map.put("frameworkVersion", binding.frameworkVersion.getText().toString());
|
||||||
|
map.put("systemAbi", Arrays.toString(Build.SUPPORTED_ABIS));
|
||||||
|
Telemetry.trackEvent("HomeFragment", map);
|
||||||
binding.copyInfo.setOnClickListener(v -> {
|
binding.copyInfo.setOnClickListener(v -> {
|
||||||
ClipboardUtils.put(activity, info);
|
ClipboardUtils.put(activity, info);
|
||||||
showHint(R.string.info_copied, false);
|
showHint(R.string.info_copied, false);
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ public class LogsFragment extends BaseFragment {
|
||||||
private OptionsItemSelectListener optionsItemSelectListener;
|
private OptionsItemSelectListener optionsItemSelectListener;
|
||||||
|
|
||||||
private final ActivityResultLauncher<String> saveLogsLauncher = registerForActivityResult(
|
private final ActivityResultLauncher<String> saveLogsLauncher = registerForActivityResult(
|
||||||
new ActivityResultContracts.CreateDocument(),
|
new ActivityResultContracts.CreateDocument("application/zip"),
|
||||||
uri -> {
|
uri -> {
|
||||||
if (uri == null) return;
|
if (uri == null) return;
|
||||||
runAsync(() -> {
|
runAsync(() -> {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,15 @@ package org.lsposed.manager.util;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class Telemetry {
|
public class Telemetry {
|
||||||
public static void start(Application application) {}
|
public static void start(Application application) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void trackEvent(String name, Map<String, String> properties) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void trackError(Throwable throwable, Map<String, String> properties) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue