Merge remote-tracking branch 'origin/dev_robotaxi-d_231031_6.2.0' into dev_robotaxi-d_231031_6.2.0
This commit is contained in:
@@ -6,6 +6,7 @@ import java.text.SimpleDateFormat
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
apply from: rootProject.file('gradle/bytex/bytex.gradle')
|
||||
|
||||
@@ -214,6 +215,15 @@ dependencies {
|
||||
// releaseImplementation rootProject.ext.dependencies.releaseleakcanary
|
||||
implementation rootProject.ext.dependencies.android_start_up
|
||||
implementation rootProject.ext.dependencies.lancetx_runtime
|
||||
implementation rootProject.ext.dependencies.lancetx_compiler_lib
|
||||
kapt rootProject.ext.dependencies.lancetx_compiler
|
||||
|
||||
annotationProcessor rootProject.ext.dependencies.lancetx_compiler
|
||||
annotationProcessor rootProject.ext.dependencies.google_auto_service
|
||||
kapt rootProject.ext.dependencies.google_auto_service
|
||||
compileOnly rootProject.ext.dependencies.google_auto_service
|
||||
|
||||
|
||||
// implementation rootProject.ext.dependencies.mogocustommap
|
||||
implementation project(':libraries:mapmodule')
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
[package]
|
||||
-keeppackage com/mogo/thread/opt/core/
|
||||
-keeppackage com/mogo/eagle/core/function/main/threadopt/
|
||||
-keeppackage com/knightboost/lancet/api/synchronized_lock/
|
||||
-keeppackage com/mogo/core/lancetx/compiler/lib
|
||||
-keeppackage com/mogo/eagle/core/lancetx/generated/
|
||||
-keeppackage com/mogo/launcher/lancet/jank/spi/
|
||||
-keeppackage com/mogo/launcher
|
||||
-keeppackage com/rousetime/android_startup/
|
||||
-keeppackage com/mogo/systrace/
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
package com.mogo.launcher.lancet
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.*
|
||||
import android.view.View
|
||||
import androidx.annotation.*
|
||||
import com.knightboost.lancet.api.*
|
||||
import com.knightboost.lancet.api.Scope.ALL
|
||||
import com.knightboost.lancet.api.annotations.*
|
||||
import com.knightboost.lancet.api.annotations.Weaver
|
||||
import com.mogo.eagle.core.utilcode.util.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Runnable
|
||||
|
||||
@Keep
|
||||
@Weaver
|
||||
@Group("anr_fix")
|
||||
class ANRFix {
|
||||
|
||||
companion object {
|
||||
|
||||
// @JvmStatic
|
||||
// @TargetClass(value = "android.os.Handler", scope = ALL)
|
||||
// @TargetMethod(methodName = "post")
|
||||
// @ReplaceInvoke
|
||||
// fun handlerPostProxy(handler: Handler, action: Runnable): Boolean {
|
||||
// if (Looper.getMainLooper() != handler.looper) {
|
||||
// return handler.post(action)
|
||||
// }
|
||||
// val what = ObjectHashCodeUtils.getHashCodeIfNeed(action)
|
||||
// handler.removeMessages(what)
|
||||
// val msg = Message.obtain(handler, action)
|
||||
// msg.what = what
|
||||
// return handler.sendMessage(msg)
|
||||
// }
|
||||
//
|
||||
// @JvmStatic
|
||||
// @TargetClass(value = "android.os.Handler", scope = ALL)
|
||||
// @TargetMethod(methodName = "postDelayed")
|
||||
// @ReplaceInvoke
|
||||
// fun handlerPostDelayProxy(handler: Handler, action: Runnable, delayMillis: Long): Boolean {
|
||||
// if (Looper.getMainLooper() != handler.looper) {
|
||||
// return handler.postDelayed(action, delayMillis)
|
||||
// }
|
||||
// val what = ObjectHashCodeUtils.getHashCodeIfNeed(action)
|
||||
// handler.removeMessages(what)
|
||||
// val msg = Message.obtain(handler, action)
|
||||
// msg.what = what
|
||||
// return handler.sendMessageDelayed(msg, delayMillis)
|
||||
// }
|
||||
//
|
||||
// @JvmStatic
|
||||
// @TargetClass(value = "android.app.Activity", scope = ALL)
|
||||
// @TargetMethod(methodName = "post")
|
||||
// @ReplaceInvoke
|
||||
// fun runOnUiThreadOfActivityProxy(activity: Activity, action: Runnable) {
|
||||
// if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
// UiThreadHandler.post(action)
|
||||
// } else {
|
||||
// activity.runOnUiThread(action)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @JvmStatic
|
||||
// @TargetClass(value = "android.view.View", scope = ALL)
|
||||
// @TargetMethod(methodName = "post")
|
||||
// @ReplaceInvoke
|
||||
// fun postOfViewProxy(view: View, action: Runnable): Boolean {
|
||||
// return if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
// UiThreadHandler.post(action)
|
||||
// } else {
|
||||
// view.post(action)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @JvmStatic
|
||||
// @TargetClass(value = "android.view.View", scope = ALL)
|
||||
// @TargetMethod(methodName = "postDelayed")
|
||||
// @ReplaceInvoke
|
||||
// fun postDelayedOfViewProxy(view: View, action: Runnable, delayMillis: Long): Boolean {
|
||||
// return if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
// UiThreadHandler.postDelayed(action, delayMillis)
|
||||
// } else {
|
||||
// view.postDelayed(action, delayMillis)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
package com.mogo.launcher.lancet;
|
||||
package com.mogo.launcher.lancet.jank;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.knightboost.lancet.api.Scope;
|
||||
import com.knightboost.lancet.api.annotations.Group;
|
||||
@@ -19,11 +18,6 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import kotlin.coroutines.CoroutineContext;
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
import kotlinx.coroutines.MainCoroutineDispatcher;
|
||||
|
||||
|
||||
@Keep
|
||||
@Weaver
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.mogo.launcher.lancet
|
||||
package com.mogo.launcher.lancet.jank
|
||||
|
||||
import android.app.*
|
||||
import android.content.*
|
||||
@@ -515,7 +515,9 @@ class MainBlockCheck {
|
||||
return handler.removeCallbacks(action, token)
|
||||
}
|
||||
val what = ObjectHashCodeUtils.getHashCodeIfNeed(handler, action)
|
||||
getHandler(asyncHandlersMap.getOrPut(handler.hashCode()) { computeIsAsyncHandler(handler) }).removeMessages(what, if (token != null) { synchronized(tokens) { tokens.remove(token.hashCode())?.get() } } else null)
|
||||
getHandler(asyncHandlersMap.getOrPut(handler.hashCode()) { computeIsAsyncHandler(handler) }).removeMessages(what, if (token != null) { synchronized(
|
||||
tokens
|
||||
) { tokens.remove(token.hashCode())?.get() } } else null)
|
||||
remove(what)
|
||||
}
|
||||
|
||||
@@ -550,7 +552,9 @@ class MainBlockCheck {
|
||||
if (Looper.getMainLooper() != handler.looper) {
|
||||
return handler.removeMessages(what, token)
|
||||
}
|
||||
getHandler(asyncHandlersMap.getOrPut(handler.hashCode()) { computeIsAsyncHandler(handler) }).removeMessages(what, if (token != null) synchronized(tokens) { tokens.remove(token.hashCode())?.get() } else null)
|
||||
getHandler(asyncHandlersMap.getOrPut(handler.hashCode()) { computeIsAsyncHandler(handler) }).removeMessages(what, if (token != null) synchronized(
|
||||
tokens
|
||||
) { tokens.remove(token.hashCode())?.get() } else null)
|
||||
remove(what)
|
||||
}
|
||||
|
||||
@@ -559,30 +563,30 @@ class MainBlockCheck {
|
||||
}
|
||||
|
||||
fun insert(what: Int, holder: Holder) {
|
||||
val action = getAction()
|
||||
action.type = 0
|
||||
action.what = what
|
||||
action.holder = holder
|
||||
pool.execute(action)
|
||||
// val action = getAction()
|
||||
// action.type = 0
|
||||
// action.what = what
|
||||
// action.holder = holder
|
||||
// pool.execute(action)
|
||||
}
|
||||
|
||||
private fun remove(what: Int) {
|
||||
val action = getAction()
|
||||
action.type = 1
|
||||
action.what = what
|
||||
pool.execute(action)
|
||||
// val action = getAction()
|
||||
// action.type = 1
|
||||
// action.what = what
|
||||
// pool.execute(action)
|
||||
}
|
||||
|
||||
fun recycle(holder: Holder, elapsedTime: Long, duration: Long) {
|
||||
val action = getAction()
|
||||
action.type = 2
|
||||
action.holder = holder
|
||||
action.elapsedTime = elapsedTime
|
||||
action.duration = duration
|
||||
pool.execute(action)
|
||||
private fun recycle(holder: Holder, elapsedTime: Long, duration: Long) {
|
||||
// val action = getAction()
|
||||
// action.type = 2
|
||||
// action.holder = holder
|
||||
// action.elapsedTime = elapsedTime
|
||||
// action.duration = duration
|
||||
// pool.execute(action)
|
||||
}
|
||||
|
||||
fun getHandler(isAsync: Boolean): Handler {
|
||||
private fun getHandler(isAsync: Boolean): Handler {
|
||||
return if (isAsync) {
|
||||
ASYNC_HANDLER
|
||||
} else {
|
||||
@@ -591,114 +595,26 @@ class MainBlockCheck {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@TargetClass(value = "android.view.View", scope = LEAF)
|
||||
@Insert(mayCreateSuper = true)
|
||||
@TargetMethod(methodName = "onMeasure")
|
||||
fun proxyViewOnMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
val holder = Holder.acquire(handler = null, obj = "View[${This.get().javaClass.name}]:onMeasure")
|
||||
pool.execute {
|
||||
getRecorder()?.insert(holder)
|
||||
}
|
||||
val now = now()
|
||||
try {
|
||||
Origin.callVoid()
|
||||
} catch (t: Throwable) {
|
||||
throw t
|
||||
} finally {
|
||||
val spend = now() - now
|
||||
pool.execute {
|
||||
getRecorder()?.recycle(holder.id, 0, spend)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TargetClass(value = "android.view.View", scope = LEAF)
|
||||
@Insert(mayCreateSuper = true)
|
||||
@TargetMethod(methodName = "onLayout")
|
||||
fun proxyViewOnLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
||||
val holder = Holder.acquire(handler = null, obj = "View[${This.get().javaClass.name}]:onLayout")
|
||||
insert(-1, holder)
|
||||
val now = now()
|
||||
try {
|
||||
Origin.callVoid()
|
||||
} catch (t: Throwable) {
|
||||
throw t
|
||||
} finally {
|
||||
val spend = now() - now
|
||||
recycle(holder, 0, spend)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@TargetClass(value = "android.view.View", scope = LEAF)
|
||||
@Insert(mayCreateSuper = true)
|
||||
@TargetMethod(methodName = "onDraw")
|
||||
fun proxyViewOnDraw(canvas: Canvas) {
|
||||
val holder = Holder.acquire(handler = null, obj = "View[${This.get().javaClass.name}]:onDraw")
|
||||
insert(-1, holder)
|
||||
val now = now()
|
||||
try {
|
||||
Origin.callVoid()
|
||||
} catch (t: Throwable) {
|
||||
throw t
|
||||
} finally {
|
||||
val spend = now() - now
|
||||
recycle(holder, 0, spend)
|
||||
}
|
||||
}
|
||||
|
||||
@TargetClass(value = "android.app.Activity", scope = LEAF)
|
||||
@Insert(mayCreateSuper = true)
|
||||
@TargetMethod(methodName = "onCreate")
|
||||
fun proxyActivityOnCreate(savedInstanceState: Bundle?) {
|
||||
val holder = Holder.acquire(handler = null, obj = "Activity[${This.get().javaClass.name}]:onCreate")
|
||||
insert(-1, holder)
|
||||
val now = now()
|
||||
try {
|
||||
Origin.callVoid()
|
||||
} catch (t: Throwable) {
|
||||
throw t
|
||||
} finally {
|
||||
val spend = now() - now
|
||||
CallerDevaToolsManager.block()?.monitor((This.get() as Activity).window)
|
||||
recycle(holder, 0, spend)
|
||||
}
|
||||
}
|
||||
|
||||
@TargetClass(value = "android.app.Activity", scope = LEAF)
|
||||
@Insert(mayCreateSuper = true)
|
||||
@TargetMethod(methodName = "onStart")
|
||||
fun proxyActivityOnStart() {
|
||||
val holder = Holder.acquire(handler = null, obj = "Activity[${This.get().javaClass.name}]:onStart")
|
||||
insert(-1, holder)
|
||||
val now = now()
|
||||
try {
|
||||
Origin.callVoid()
|
||||
} catch (t: Throwable) {
|
||||
throw t
|
||||
} finally {
|
||||
val spend = now() - now
|
||||
recycle(holder, 0, spend)
|
||||
}
|
||||
}
|
||||
|
||||
@TargetClass(value = "android.app.Activity", scope = LEAF)
|
||||
@Insert(mayCreateSuper = true)
|
||||
@TargetMethod(methodName = "onResume")
|
||||
fun proxyActivityOnResume() {
|
||||
val holder = Holder.acquire(handler = null, obj = "Activity[${This.get().javaClass.name}]:onResume")
|
||||
insert(-1, holder)
|
||||
val now = now()
|
||||
CallerDevaToolsManager.block()?.resume((This.get() as Activity).window)
|
||||
try {
|
||||
Origin.callVoid()
|
||||
} catch (t: Throwable) {
|
||||
throw t
|
||||
} finally {
|
||||
val spend = now() - now
|
||||
recycle(holder, 0, spend)
|
||||
CallerDevaToolsManager.block()?.resume((This.get() as Activity).window)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -706,17 +622,10 @@ class MainBlockCheck {
|
||||
@Insert(mayCreateSuper = true)
|
||||
@TargetMethod(methodName = "onPause")
|
||||
fun proxyActivityOnPause() {
|
||||
val holder = Holder.acquire(handler = null, obj = "Activity[${This.get().javaClass.name}]:onPause")
|
||||
insert(-1, holder)
|
||||
CallerDevaToolsManager.block()?.pause((This.get() as Activity).window)
|
||||
val now = now()
|
||||
try {
|
||||
Origin.callVoid()
|
||||
} catch (t: Throwable) {
|
||||
throw t
|
||||
} finally {
|
||||
val spend = now() - now
|
||||
recycle(holder, 0, spend)
|
||||
CallerDevaToolsManager.block()?.pause((This.get() as Activity).window)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -724,79 +633,10 @@ class MainBlockCheck {
|
||||
@Insert(mayCreateSuper = true)
|
||||
@TargetMethod(methodName = "onDestroy")
|
||||
fun proxyActivityOnDestroy() {
|
||||
CallerDevaToolsManager.block()?.pop((This.get() as Activity).window)
|
||||
try {
|
||||
Origin.callVoid()
|
||||
} catch (t: Throwable) {
|
||||
throw t
|
||||
}
|
||||
}
|
||||
|
||||
@TargetClass(value = "androidx.fragment.app.Fragment", scope = LEAF)
|
||||
@Insert(mayCreateSuper = true)
|
||||
@TargetMethod(methodName = "onCreateView")
|
||||
fun proxyFragmentOnCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?) {
|
||||
val holder = Holder.acquire(handler = null, obj = "Fragment[${This.get().javaClass.name}]:onCreateView")
|
||||
insert(-1, holder)
|
||||
val startTime = now()
|
||||
try {
|
||||
Origin.callVoid()
|
||||
} catch (t: Throwable) {
|
||||
throw t
|
||||
} finally {
|
||||
val spend = now() - startTime
|
||||
recycle(holder, 0, spend)
|
||||
}
|
||||
}
|
||||
|
||||
@TargetClass(value = "androidx.fragment.app.Fragment", scope = LEAF)
|
||||
@Insert(mayCreateSuper = true)
|
||||
@TargetMethod(methodName = "onCreate")
|
||||
fun proxyFragmentOnCreate(savedInstanceState: Bundle?) {
|
||||
val holder = Holder.acquire(handler = null, obj = "Fragment[${This.get().javaClass.name}]:onCreate")
|
||||
insert(-1, holder)
|
||||
val startTime = now()
|
||||
try {
|
||||
Origin.callVoid()
|
||||
} catch (t: Throwable) {
|
||||
throw t
|
||||
} finally {
|
||||
val spend = now() - startTime
|
||||
recycle(holder, 0, spend)
|
||||
}
|
||||
}
|
||||
|
||||
@TargetClass(value = "androidx.fragment.app.Fragment", scope = LEAF)
|
||||
@Insert(mayCreateSuper = true)
|
||||
@TargetMethod(methodName = "onViewCreated")
|
||||
fun proxyFragmentOnViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
val holder = Holder.acquire(handler = null, obj = "Fragment[${This.get().javaClass.name}]:onViewCreated")
|
||||
insert(-1, holder)
|
||||
val startTime = now()
|
||||
try {
|
||||
Origin.callVoid()
|
||||
} catch (t: Throwable) {
|
||||
throw t
|
||||
} finally {
|
||||
val spend = now() - startTime
|
||||
recycle(holder, 0, spend)
|
||||
}
|
||||
}
|
||||
|
||||
@TargetClass(value = "android.content.BroadcastReceiver", scope = LEAF)
|
||||
@Insert(mayCreateSuper = true)
|
||||
@TargetMethod(methodName = "onReceive")
|
||||
fun proxyBroadcastReceiver(ctx: Context?, intent: Intent?) {
|
||||
val holder = Holder.acquire(handler = null, obj = "Receiver[${This.get().javaClass.name}]:onReceive")
|
||||
insert(-1, holder)
|
||||
val startTime = now()
|
||||
try {
|
||||
Origin.callVoid()
|
||||
} catch (t: Throwable) {
|
||||
throw t
|
||||
} finally {
|
||||
val spend = now() - startTime
|
||||
recycle(holder, 0, spend)
|
||||
CallerDevaToolsManager.block()?.pop((This.get() as Activity).window)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package com.mogo.launcher.lancet.jank.compiler;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Fragment;
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentProvider;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.SystemClock;
|
||||
import android.view.View;
|
||||
|
||||
import com.knightboost.lancet.api.synchronized_lock.ISynchronizedLockHooker;
|
||||
import com.mogo.core.lancetx.compiler.lib.annotations.LancetXGenerator;
|
||||
import com.mogo.core.lancetx.compiler.lib.generator.HookType;
|
||||
import com.mogo.core.lancetx.compiler.lib.generator.Scope;
|
||||
import com.mogo.core.lancetx.compiler.lib.generator.Type;
|
||||
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
class JankPointAutoGenerator {
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.IPC,
|
||||
hookAllPublicMethods = true,
|
||||
excludeHookMethodNames = { "toString", "hashCode" },
|
||||
excludeHookMethodDescs = { "()Ljava/lang/String;", "()I" }
|
||||
)
|
||||
private ActivityManager am;
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.IPC,
|
||||
hookAllPublicMethods = true,
|
||||
excludeHookMethodNames = { "toString", "hashCode" },
|
||||
excludeHookMethodDescs = { "()Ljava/lang/String;", "()I" }
|
||||
)
|
||||
private PackageManager pm;
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.ACTIVITY,
|
||||
mayCreateSuper = true,
|
||||
hookAllPublicMethods = true,
|
||||
scope = Scope.LEAF,
|
||||
hookType = HookType.AROUND,
|
||||
excludeHookMethodNames = { "runOnUiThread", "toString", "hashCode" },
|
||||
excludeHookMethodDescs = { "(Ljava/lang/Runnable;)V", "()Ljava/lang/String;", "()I" }
|
||||
)
|
||||
private Activity activity;
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.BROADCAST_RECEIVER,
|
||||
mayCreateSuper = true,
|
||||
hookType = HookType.AROUND,
|
||||
hookAllPublicMethods = true,
|
||||
scope = Scope.LEAF,
|
||||
excludeHookMethodNames = { "toString", "hashCode" },
|
||||
excludeHookMethodDescs = { "()Ljava/lang/String;", "()I" }
|
||||
)
|
||||
private BroadcastReceiver receiver;
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.CONTENT_PROVIDER,
|
||||
mayCreateSuper = true,
|
||||
hookType = HookType.AROUND,
|
||||
hookAllPublicMethods = true,
|
||||
scope = Scope.LEAF,
|
||||
excludeHookMethodNames = { "toString", "hashCode" },
|
||||
excludeHookMethodDescs = { "()Ljava/lang/String;", "()I" }
|
||||
)
|
||||
private ContentProvider provider;
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.SERVICE,
|
||||
hookAllPublicMethods = true,
|
||||
mayCreateSuper = true,
|
||||
hookType = HookType.AROUND,
|
||||
scope = Scope.LEAF,
|
||||
excludeHookMethodNames = { "toString", "hashCode" },
|
||||
excludeHookMethodDescs = { "()Ljava/lang/String;", "()I" }
|
||||
)
|
||||
private Service service;
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.AQS_LOCK,
|
||||
hookAllPublicMethods = true,
|
||||
scope = Scope.ALL,
|
||||
excludeHookMethodNames = { "toString", "hashCode" },
|
||||
excludeHookMethodDescs = { "()Ljava/lang/String;", "()I" }
|
||||
)
|
||||
private Lock lock;
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.SLEEP,
|
||||
scope = Scope.ALL,
|
||||
onlyHookMethodNames = { "sleep", "sleep"},
|
||||
onlyHookMethodDescs = { "(J)V", "(JI)V"},
|
||||
excludeHookMethodNames = { "toString", "hashCode" },
|
||||
excludeHookMethodDescs = { "()Ljava/lang/String;", "()I" }
|
||||
)
|
||||
private Thread thread;
|
||||
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.SYNCHRONIZED_LOCK,
|
||||
hookType = HookType.AROUND,
|
||||
scope = Scope.LEAF,
|
||||
mayCreateSuper = true,
|
||||
hookAllPublicMethods = true,
|
||||
excludeHookMethodNames = { "toString", "hashCode" },
|
||||
excludeHookMethodDescs = { "()Ljava/lang/String;", "()I" }
|
||||
)
|
||||
private ISynchronizedLockHooker synchronizedLock;
|
||||
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.PARK,
|
||||
scope = Scope.ALL,
|
||||
hookAllPublicMethods = true,
|
||||
excludeHookMethodNames = { "unpark", "getBlocker", "toString", "hashCode" },
|
||||
excludeHookMethodDescs = { "(Ljava/lang/Thread;)V", "(Ljava/lang/Thread;)Ljava/lang/Object;", "()Ljava/lang/String;", "()I"}
|
||||
)
|
||||
private LockSupport park;
|
||||
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.SLEEP,
|
||||
scope = Scope.ALL,
|
||||
onlyHookMethodNames = { "sleep" },
|
||||
onlyHookMethodDescs = { "(J)V" }
|
||||
)
|
||||
private SystemClock systemClockSleep;
|
||||
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.VIEW,
|
||||
scope = Scope.LEAF,
|
||||
hookType = HookType.AROUND,
|
||||
mayCreateSuper = true,
|
||||
onlyHookMethodNames = { "onMeasure", "onLayout", "onDraw", "draw" },
|
||||
onlyHookMethodDescs = { "(II)V", "(ZIIII)V", "(Landroid/graphics/Canvas;)V", "(Landroid/graphics/Canvas;)V" }
|
||||
)
|
||||
private View view;
|
||||
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.FRAGMENT,
|
||||
scope = Scope.LEAF,
|
||||
hookType = HookType.AROUND,
|
||||
mayCreateSuper = true,
|
||||
hookAllPublicMethods = true,
|
||||
excludeHookMethodNames = { "toString", "hashCode" },
|
||||
excludeHookMethodDescs = { "()Ljava/lang/String;", "()I" }
|
||||
|
||||
)
|
||||
private Fragment systemFragment;
|
||||
|
||||
@LancetXGenerator(
|
||||
group = "main_block_check",
|
||||
type = Type.FRAGMENT,
|
||||
scope = Scope.LEAF,
|
||||
hookType = HookType.AROUND,
|
||||
mayCreateSuper = true,
|
||||
hookAllPublicMethods = true,
|
||||
excludeHookMethodNames = { "toString", "hashCode" },
|
||||
excludeHookMethodDescs = { "()Ljava/lang/String;", "()I" }
|
||||
)
|
||||
private androidx.fragment.app.Fragment androidxFragment;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.mogo.launcher.lancet.jank.spi;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.mogo.core.lancetx.compiler.lib.generator.Type;
|
||||
import com.mogo.core.lancetx.compiler.lib.hook.IHookInvoker;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
||||
@AutoService(IHookInvoker.class)
|
||||
public class HookHandler implements IHookInvoker {
|
||||
|
||||
private final Looper mainLooper = Looper.getMainLooper();
|
||||
|
||||
|
||||
private final AtomicLong startTime = new AtomicLong(0L);
|
||||
|
||||
private final ThreadLocal<StringBuilder> message = new ThreadLocal<>();
|
||||
|
||||
@Override
|
||||
public void i(@NonNull Type type, Object caller, @NonNull String methodName, @NonNull Object... objects) {
|
||||
if (Looper.myLooper() == mainLooper) {
|
||||
startTime.set(SystemClock.elapsedRealtime());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void o(@NonNull Type type, Object caller, @NonNull String methodName, @NonNull Object... objects) {
|
||||
if (Looper.myLooper() == mainLooper) {
|
||||
long startTime = this.startTime.get();
|
||||
if (startTime > 0) {
|
||||
long delta = SystemClock.elapsedRealtime() - startTime;
|
||||
if (delta >= 10) {
|
||||
StringBuilder builder = message.get();
|
||||
if (builder == null) {
|
||||
builder = new StringBuilder();
|
||||
message.set(builder);
|
||||
}
|
||||
if (builder.length() > 0) {
|
||||
builder.setLength(0);
|
||||
}
|
||||
builder
|
||||
.append(type)
|
||||
.append("#")
|
||||
.append(caller == null ? "caller is null" : caller.getClass().getSimpleName())
|
||||
.append("#")
|
||||
.append(methodName);
|
||||
if (objects.length > 0) {
|
||||
builder.append("#(");
|
||||
}
|
||||
for (Object o : objects) {
|
||||
if (o == null) {
|
||||
continue;
|
||||
}
|
||||
builder.append(o.getClass().getSimpleName())
|
||||
.append(",");
|
||||
}
|
||||
|
||||
if (objects.length > 0) {
|
||||
builder.setLength(builder.length() - 1);
|
||||
builder.append(")");
|
||||
}
|
||||
if (type == Type.SYNCHRONIZED_LOCK || type == Type.AQS_LOCK) {
|
||||
builder.append("\n");
|
||||
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
|
||||
for (StackTraceElement trace: stackTrace) {
|
||||
if ("dalvik.system.VMStack".equals(trace.getClassName()) && "getThreadStackTrace".equals(trace.getMethodName())) {
|
||||
continue;
|
||||
}
|
||||
if ("java.lang.Thread".equals(trace.getClassName()) && "getStackTrace".equals(trace.getMethodName())) {
|
||||
continue;
|
||||
}
|
||||
builder.append(trace.getClassName()).append("#").append(trace.getMethodName()).append("#").append(trace.getLineNumber()).append("\n");
|
||||
}
|
||||
builder.setLength(builder.length() - 1);
|
||||
}
|
||||
Log.w("HookHandler", "jank detected:" + builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -34,7 +34,7 @@ buildscript {
|
||||
classpath "com.mogo.cloud:systrace:${plugin_version}"
|
||||
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.18'
|
||||
classpath "com.mogo.sticky:service:${plugin_version}"
|
||||
classpath "io.github.knight-zxw:lancet-plugin:${lancetx_plugin_version}"
|
||||
classpath "io.github.knight-zxw:lancet-plugin:10.1.0"
|
||||
classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.15.0"
|
||||
classpath 'com.mogo.cloud:matrix:1.0.0'
|
||||
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.4.0.2513'
|
||||
|
||||
@@ -208,7 +208,11 @@ ext {
|
||||
|
||||
|
||||
//========================= LancetX ===================
|
||||
lancetx_runtime : "io.github.knight-zxw:lancet-runtime:0.0.4_mogo",
|
||||
lancetx_runtime : "io.github.knight-zxw:lancet-runtime:10.2.0",
|
||||
|
||||
lancetx_compiler : "com.mogo.eagle.core.lancetx:compiler:1.0.0",
|
||||
|
||||
lancetx_compiler_lib : "com.mogo.eagle.core.lancetx:runtime:1.0.0",
|
||||
|
||||
//========================= autosize ======================
|
||||
androidautoSize : 'com.github.JessYanCoding:AndroidAutoSize:v1.2.1',
|
||||
@@ -225,7 +229,10 @@ ext {
|
||||
passport_secret : "com.zhidaoauto:sdk-java:1.0.5-SNAPSHOT",
|
||||
|
||||
// 主线程卡顿监测
|
||||
block_detector : "com.mogo.eagle.core.block:runtime:10.0.21"
|
||||
block_detector : "com.mogo.eagle.core.block:runtime:10.0.21",
|
||||
|
||||
//======================== google auto-service ===============
|
||||
google_auto_service : "com.google.auto.service:auto-service:1.0-rc7"
|
||||
]
|
||||
android = [
|
||||
fLauncherApplicationId : "com.mogo.launcher.f",
|
||||
|
||||
@@ -2,10 +2,11 @@ apply plugin: 'LancetX'
|
||||
LancetX {
|
||||
enable true
|
||||
enableInDebug true
|
||||
synchronizedLock {
|
||||
enabled true
|
||||
}
|
||||
weaveGroup {
|
||||
anr_fix {
|
||||
enable true
|
||||
}
|
||||
|
||||
crash_fix {
|
||||
enable true
|
||||
}
|
||||
@@ -19,7 +20,7 @@ LancetX {
|
||||
enable true
|
||||
}
|
||||
main_block_check {
|
||||
enable false
|
||||
enable true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user