Loading services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +2 −1 Original line number Diff line number Diff line Loading @@ -1336,7 +1336,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue { private class BroadcastAnrTimer extends AnrTimer<BroadcastProcessQueue> { BroadcastAnrTimer(@NonNull Handler handler) { super(Objects.requireNonNull(handler), MSG_DELIVERY_TIMEOUT, "BROADCAST_TIMEOUT", true); MSG_DELIVERY_TIMEOUT, "BROADCAST_TIMEOUT", new AnrTimer.Args().extend(true)); } @Override Loading services/core/java/com/android/server/utils/AnrTimer.java +38 −46 Original line number Diff line number Diff line Loading @@ -139,6 +139,29 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** The default injector. */ private static final Injector sDefaultInjector = new Injector(); /** * This class provides build-style arguments to an AnrTimer constructor. This simplifies the * number of AnrTimer constructors needed, especially as new options are added. */ public static class Args { /** The Injector (used only for testing). */ private Injector mInjector = AnrTimer.sDefaultInjector; /** Grant timer extensions when the system is heavily loaded. */ private boolean mExtend = false; // This is only used for testing, so it is limited to package visibility. Args injector(@NonNull Injector injector) { mInjector = injector; return this; } public Args extend(boolean flag) { mExtend = flag; return this; } } /** * An error is defined by its issue, the operation that detected the error, the tag of the * affected service, a short stack of the bad call, and the stringified arg associated with Loading Loading @@ -229,11 +252,8 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** A label that identifies the AnrTimer associated with a Timer in log messages. */ private final String mLabel; /** Whether this timer instance supports extending timeouts. */ private final boolean mExtend; /** The injector used to create this instance. This is only used for testing. */ private final Injector mInjector; /** The configuration for this instance. */ private final Args mArgs; /** The top-level switch for the feature enabled or disabled. */ private final FeatureSwitch mFeature; Loading @@ -254,18 +274,14 @@ public abstract class AnrTimer<V> implements AutoCloseable { * @param handler The handler to which the expiration message will be delivered. * @param what The "what" parameter for the expiration message. * @param label A name for this instance. * @param extend A flag to indicate if expired timers can be granted extensions. * @param injector An injector to provide overrides for testing. * @param args Configuration information for this instance. */ @VisibleForTesting AnrTimer(@NonNull Handler handler, int what, @NonNull String label, boolean extend, @NonNull Injector injector) { public AnrTimer(@NonNull Handler handler, int what, @NonNull String label, @NonNull Args args) { mHandler = handler; mWhat = what; mLabel = label; mExtend = extend; mInjector = injector; boolean enabled = mInjector.anrTimerServiceEnabled() && nativeTimersSupported(); mArgs = args; boolean enabled = args.mInjector.anrTimerServiceEnabled() && nativeTimersSupported(); mFeature = createFeatureSwitch(enabled); } Loading @@ -288,29 +304,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { } /** * Create one AnrTimer instance. The instance is given a handler and a "what". Individual * timers are started with {@link #start}. If a timer expires, then a {@link Message} is sent * immediately to the handler with {@link Message.what} set to what and {@link Message.obj} set * to the timer key. * * AnrTimer instances have a label, which must be unique. The label is used for reporting and * debug. * * If an individual timer expires internally, and the "extend" parameter is true, then the * AnrTimer may extend the individual timer rather than immediately delivering the timeout to * the client. The extension policy is not part of the instance. * * @param handler The handler to which the expiration message will be delivered. * @param what The "what" parameter for the expiration message. * @param label A name for this instance. * @param extend A flag to indicate if expired timers can be granted extensions. */ public AnrTimer(@NonNull Handler handler, int what, @NonNull String label, boolean extend) { this(handler, what, label, extend, sDefaultInjector); } /** * Create an AnrTimer instance with the default {@link #Injector} and with extensions disabled. * Create an AnrTimer instance with the default {@link #Injector} and the default configuration. * See {@link AnrTimer(Handler, int, String, boolean, Injector} for a functional description. * * @param handler The handler to which the expiration message will be delivered. Loading @@ -318,7 +312,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { * @param label A name for this instance. */ public AnrTimer(@NonNull Handler handler, int what, @NonNull String label) { this(handler, what, label, false); this(handler, what, label, new Args()); } /** Loading Loading @@ -449,7 +443,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** Fetch the native tag (an integer) for the given label. */ FeatureEnabled() { mNative = nativeAnrTimerCreate(mLabel); mNative = nativeAnrTimerCreate(mLabel, mArgs.mExtend); if (mNative == 0) throw new IllegalArgumentException("unable to create native timer"); synchronized (sAnrTimerList) { sAnrTimerList.put(mNative, new WeakReference(AnrTimer.this)); Loading @@ -466,7 +460,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { // exist. if (cancel(arg)) mTotalRestarted++; int timerId = nativeAnrTimerStart(mNative, pid, uid, timeoutMs, mExtend); int timerId = nativeAnrTimerStart(mNative, pid, uid, timeoutMs); if (timerId > 0) { mTimerIdMap.put(arg, timerId); mTimerArgMap.put(timerId, arg); Loading Loading @@ -828,19 +822,17 @@ public abstract class AnrTimer<V> implements AutoCloseable { private static native boolean nativeAnrTimerSupported(); /** * Create a new native timer with the given key and name. The key is not used by the native * code but it is returned to the Java layer in the expiration handler. The name is only for * logging. Unlike the other methods, this is an instance method: the "this" parameter is * passed into the native layer. * Create a new native timer with the given name and flags. The name is only for logging. * Unlike the other methods, this is an instance method: the "this" parameter is passed into * the native layer. */ private native long nativeAnrTimerCreate(String name); private native long nativeAnrTimerCreate(String name, boolean extend); /** Release the native resources. No further operations are premitted. */ private static native int nativeAnrTimerClose(long service); /** Start a timer and return its ID. Zero is returned on error. */ private static native int nativeAnrTimerStart(long service, int pid, int uid, long timeoutMs, boolean extend); private static native int nativeAnrTimerStart(long service, int pid, int uid, long timeoutMs); /** * Cancel a timer by ID. Return true if the timer was running and canceled. Return false if Loading services/core/jni/com_android_server_utils_AnrTimer.cpp +26 −25 Original line number Diff line number Diff line Loading @@ -130,7 +130,8 @@ class AnrTimerService { * constructor is also given the notifier callback, and two cookies for the callback: the * traditional void* and an int. */ AnrTimerService(char const* label, notifier_t notifier, void* cookie, jweak jtimer, Ticker*); AnrTimerService(char const* label, notifier_t notifier, void* cookie, jweak jtimer, Ticker*, bool extend); // Delete the service and clean up memory. ~AnrTimerService(); Loading @@ -138,7 +139,7 @@ class AnrTimerService { // Start a timer and return the associated timer ID. It does not matter if the same pid/uid // are already in the running list. Once start() is called, one of cancel(), accept(), or // discard() must be called to clean up the internal data structures. timer_id_t start(int pid, int uid, nsecs_t timeout, bool extend); timer_id_t start(int pid, int uid, nsecs_t timeout); // Cancel a timer and remove it from all lists. This is called when the event being timed // has occurred. If the timer was Running, the function returns true. The other Loading Loading @@ -192,6 +193,9 @@ class AnrTimerService { void* notifierCookie_; jweak notifierObject_; // True if extensions can be granted to expired timers. const bool extend_; // The global lock mutable Mutex lock_; Loading Loading @@ -636,12 +640,13 @@ class AnrTimerService::Ticker { std::atomic<size_t> AnrTimerService::Ticker::idGen_; AnrTimerService::AnrTimerService(char const* label, notifier_t notifier, void* cookie, jweak jtimer, Ticker* ticker) : AnrTimerService::AnrTimerService(char const* label, notifier_t notifier, void* cookie, jweak jtimer, Ticker* ticker, bool extend) : label_(label), notifier_(notifier), notifierCookie_(cookie), notifierObject_(jtimer), extend_(extend), ticker_(ticker) { // Zero the statistics Loading @@ -666,11 +671,10 @@ char const *AnrTimerService::statusString(Status s) { return "unknown"; } AnrTimerService::timer_id_t AnrTimerService::start(int pid, int uid, nsecs_t timeout, bool extend) { AnrTimerService::timer_id_t AnrTimerService::start(int pid, int uid, nsecs_t timeout) { ALOGI_IF(DEBUG, "starting"); AutoMutex _l(lock_); Timer t(pid, uid, timeout, extend); Timer t(pid, uid, timeout, extend_); insert(t); counters_.started++; Loading Loading @@ -826,7 +830,8 @@ bool nativeSupportEnabled = false; /** * Singleton/globals for the anr timer. Among other things, this includes a Ticker* and a use * count. The JNI layer creates a single Ticker for all operational AnrTimers. The Ticker is * created when the first AnrTimer is created, and is deleted when the last AnrTimer is closed. * created when the first AnrTimer is created; this means that the Ticker is only created if * native anr timers are used. */ static Mutex gAnrLock; struct AnrArgs { Loading @@ -834,7 +839,6 @@ struct AnrArgs { jmethodID func = NULL; JavaVM* vm = NULL; AnrTimerService::Ticker* ticker = nullptr; int tickerUseCount = 0;; }; static AnrArgs gAnrArgs; Loading Loading @@ -863,18 +867,17 @@ jboolean anrTimerSupported(JNIEnv* env, jclass) { return nativeSupportEnabled; } jlong anrTimerCreate(JNIEnv* env, jobject jtimer, jstring jname) { jlong anrTimerCreate(JNIEnv* env, jobject jtimer, jstring jname, jboolean extend) { if (!nativeSupportEnabled) return 0; AutoMutex _l(gAnrLock); if (!gAnrArgs.ticker) { if (gAnrArgs.ticker == nullptr) { gAnrArgs.ticker = new AnrTimerService::Ticker(); } gAnrArgs.tickerUseCount++; ScopedUtfChars name(env, jname); jobject timer = env->NewWeakGlobalRef(jtimer); AnrTimerService* service = new AnrTimerService(name.c_str(), anrNotify, &gAnrArgs, timer, gAnrArgs.ticker); AnrTimerService* service = new AnrTimerService(name.c_str(), anrNotify, &gAnrArgs, timer, gAnrArgs.ticker, extend); return reinterpret_cast<jlong>(service); } Loading @@ -889,19 +892,14 @@ jint anrTimerClose(JNIEnv* env, jclass, jlong ptr) { AnrTimerService *s = toService(ptr); env->DeleteWeakGlobalRef(s->jtimer()); delete s; if (--gAnrArgs.tickerUseCount <= 0) { delete gAnrArgs.ticker; gAnrArgs.ticker = nullptr; } return 0; } jint anrTimerStart(JNIEnv* env, jclass, jlong ptr, jint pid, jint uid, jlong timeout, jboolean extend) { jint anrTimerStart(JNIEnv* env, jclass, jlong ptr, jint pid, jint uid, jlong timeout) { if (!nativeSupportEnabled) return 0; // On the Java side, timeouts are expressed in milliseconds and must be converted to // nanoseconds before being passed to the library code. return toService(ptr)->start(pid, uid, milliseconds_to_nanoseconds(timeout), extend); return toService(ptr)->start(pid, uid, milliseconds_to_nanoseconds(timeout)); } jboolean anrTimerCancel(JNIEnv* env, jclass, jlong ptr, jint timerId) { Loading Loading @@ -932,9 +930,9 @@ jobjectArray anrTimerDump(JNIEnv *env, jclass, jlong ptr) { static const JNINativeMethod methods[] = { {"nativeAnrTimerSupported", "()Z", (void*) anrTimerSupported}, {"nativeAnrTimerCreate", "(Ljava/lang/String;)J", (void*) anrTimerCreate}, {"nativeAnrTimerCreate", "(Ljava/lang/String;Z)J", (void*) anrTimerCreate}, {"nativeAnrTimerClose", "(J)I", (void*) anrTimerClose}, {"nativeAnrTimerStart", "(JIIJZ)I", (void*) anrTimerStart}, {"nativeAnrTimerStart", "(JIIJ)I", (void*) anrTimerStart}, {"nativeAnrTimerCancel", "(JI)Z", (void*) anrTimerCancel}, {"nativeAnrTimerAccept", "(JI)Z", (void*) anrTimerAccept}, {"nativeAnrTimerDiscard", "(JI)Z", (void*) anrTimerDiscard}, Loading @@ -948,13 +946,16 @@ int register_android_server_utils_AnrTimer(JNIEnv* env) static const char *className = "com/android/server/utils/AnrTimer"; jniRegisterNativeMethods(env, className, methods, NELEM(methods)); nativeSupportEnabled = NATIVE_SUPPORT; // Do not perform any further initialization if native support is not enabled. if (!nativeSupportEnabled) return 0; jclass service = FindClassOrDie(env, className); gAnrArgs.clazz = MakeGlobalRefOrDie(env, service); gAnrArgs.func = env->GetMethodID(gAnrArgs.clazz, "expire", "(IIIJ)Z"); env->GetJavaVM(&gAnrArgs.vm); nativeSupportEnabled = NATIVE_SUPPORT; return 0; } Loading services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -129,7 +129,7 @@ public class AnrTimerTest { */ private class TestAnrTimer extends AnrTimer<TestArg> { private TestAnrTimer(Handler h, int key, String tag) { super(h, key, tag, false, new TestInjector()); super(h, key, tag, new AnrTimer.Args().injector(new TestInjector())); } TestAnrTimer(Helper helper) { Loading Loading
services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +2 −1 Original line number Diff line number Diff line Loading @@ -1336,7 +1336,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue { private class BroadcastAnrTimer extends AnrTimer<BroadcastProcessQueue> { BroadcastAnrTimer(@NonNull Handler handler) { super(Objects.requireNonNull(handler), MSG_DELIVERY_TIMEOUT, "BROADCAST_TIMEOUT", true); MSG_DELIVERY_TIMEOUT, "BROADCAST_TIMEOUT", new AnrTimer.Args().extend(true)); } @Override Loading
services/core/java/com/android/server/utils/AnrTimer.java +38 −46 Original line number Diff line number Diff line Loading @@ -139,6 +139,29 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** The default injector. */ private static final Injector sDefaultInjector = new Injector(); /** * This class provides build-style arguments to an AnrTimer constructor. This simplifies the * number of AnrTimer constructors needed, especially as new options are added. */ public static class Args { /** The Injector (used only for testing). */ private Injector mInjector = AnrTimer.sDefaultInjector; /** Grant timer extensions when the system is heavily loaded. */ private boolean mExtend = false; // This is only used for testing, so it is limited to package visibility. Args injector(@NonNull Injector injector) { mInjector = injector; return this; } public Args extend(boolean flag) { mExtend = flag; return this; } } /** * An error is defined by its issue, the operation that detected the error, the tag of the * affected service, a short stack of the bad call, and the stringified arg associated with Loading Loading @@ -229,11 +252,8 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** A label that identifies the AnrTimer associated with a Timer in log messages. */ private final String mLabel; /** Whether this timer instance supports extending timeouts. */ private final boolean mExtend; /** The injector used to create this instance. This is only used for testing. */ private final Injector mInjector; /** The configuration for this instance. */ private final Args mArgs; /** The top-level switch for the feature enabled or disabled. */ private final FeatureSwitch mFeature; Loading @@ -254,18 +274,14 @@ public abstract class AnrTimer<V> implements AutoCloseable { * @param handler The handler to which the expiration message will be delivered. * @param what The "what" parameter for the expiration message. * @param label A name for this instance. * @param extend A flag to indicate if expired timers can be granted extensions. * @param injector An injector to provide overrides for testing. * @param args Configuration information for this instance. */ @VisibleForTesting AnrTimer(@NonNull Handler handler, int what, @NonNull String label, boolean extend, @NonNull Injector injector) { public AnrTimer(@NonNull Handler handler, int what, @NonNull String label, @NonNull Args args) { mHandler = handler; mWhat = what; mLabel = label; mExtend = extend; mInjector = injector; boolean enabled = mInjector.anrTimerServiceEnabled() && nativeTimersSupported(); mArgs = args; boolean enabled = args.mInjector.anrTimerServiceEnabled() && nativeTimersSupported(); mFeature = createFeatureSwitch(enabled); } Loading @@ -288,29 +304,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { } /** * Create one AnrTimer instance. The instance is given a handler and a "what". Individual * timers are started with {@link #start}. If a timer expires, then a {@link Message} is sent * immediately to the handler with {@link Message.what} set to what and {@link Message.obj} set * to the timer key. * * AnrTimer instances have a label, which must be unique. The label is used for reporting and * debug. * * If an individual timer expires internally, and the "extend" parameter is true, then the * AnrTimer may extend the individual timer rather than immediately delivering the timeout to * the client. The extension policy is not part of the instance. * * @param handler The handler to which the expiration message will be delivered. * @param what The "what" parameter for the expiration message. * @param label A name for this instance. * @param extend A flag to indicate if expired timers can be granted extensions. */ public AnrTimer(@NonNull Handler handler, int what, @NonNull String label, boolean extend) { this(handler, what, label, extend, sDefaultInjector); } /** * Create an AnrTimer instance with the default {@link #Injector} and with extensions disabled. * Create an AnrTimer instance with the default {@link #Injector} and the default configuration. * See {@link AnrTimer(Handler, int, String, boolean, Injector} for a functional description. * * @param handler The handler to which the expiration message will be delivered. Loading @@ -318,7 +312,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { * @param label A name for this instance. */ public AnrTimer(@NonNull Handler handler, int what, @NonNull String label) { this(handler, what, label, false); this(handler, what, label, new Args()); } /** Loading Loading @@ -449,7 +443,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** Fetch the native tag (an integer) for the given label. */ FeatureEnabled() { mNative = nativeAnrTimerCreate(mLabel); mNative = nativeAnrTimerCreate(mLabel, mArgs.mExtend); if (mNative == 0) throw new IllegalArgumentException("unable to create native timer"); synchronized (sAnrTimerList) { sAnrTimerList.put(mNative, new WeakReference(AnrTimer.this)); Loading @@ -466,7 +460,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { // exist. if (cancel(arg)) mTotalRestarted++; int timerId = nativeAnrTimerStart(mNative, pid, uid, timeoutMs, mExtend); int timerId = nativeAnrTimerStart(mNative, pid, uid, timeoutMs); if (timerId > 0) { mTimerIdMap.put(arg, timerId); mTimerArgMap.put(timerId, arg); Loading Loading @@ -828,19 +822,17 @@ public abstract class AnrTimer<V> implements AutoCloseable { private static native boolean nativeAnrTimerSupported(); /** * Create a new native timer with the given key and name. The key is not used by the native * code but it is returned to the Java layer in the expiration handler. The name is only for * logging. Unlike the other methods, this is an instance method: the "this" parameter is * passed into the native layer. * Create a new native timer with the given name and flags. The name is only for logging. * Unlike the other methods, this is an instance method: the "this" parameter is passed into * the native layer. */ private native long nativeAnrTimerCreate(String name); private native long nativeAnrTimerCreate(String name, boolean extend); /** Release the native resources. No further operations are premitted. */ private static native int nativeAnrTimerClose(long service); /** Start a timer and return its ID. Zero is returned on error. */ private static native int nativeAnrTimerStart(long service, int pid, int uid, long timeoutMs, boolean extend); private static native int nativeAnrTimerStart(long service, int pid, int uid, long timeoutMs); /** * Cancel a timer by ID. Return true if the timer was running and canceled. Return false if Loading
services/core/jni/com_android_server_utils_AnrTimer.cpp +26 −25 Original line number Diff line number Diff line Loading @@ -130,7 +130,8 @@ class AnrTimerService { * constructor is also given the notifier callback, and two cookies for the callback: the * traditional void* and an int. */ AnrTimerService(char const* label, notifier_t notifier, void* cookie, jweak jtimer, Ticker*); AnrTimerService(char const* label, notifier_t notifier, void* cookie, jweak jtimer, Ticker*, bool extend); // Delete the service and clean up memory. ~AnrTimerService(); Loading @@ -138,7 +139,7 @@ class AnrTimerService { // Start a timer and return the associated timer ID. It does not matter if the same pid/uid // are already in the running list. Once start() is called, one of cancel(), accept(), or // discard() must be called to clean up the internal data structures. timer_id_t start(int pid, int uid, nsecs_t timeout, bool extend); timer_id_t start(int pid, int uid, nsecs_t timeout); // Cancel a timer and remove it from all lists. This is called when the event being timed // has occurred. If the timer was Running, the function returns true. The other Loading Loading @@ -192,6 +193,9 @@ class AnrTimerService { void* notifierCookie_; jweak notifierObject_; // True if extensions can be granted to expired timers. const bool extend_; // The global lock mutable Mutex lock_; Loading Loading @@ -636,12 +640,13 @@ class AnrTimerService::Ticker { std::atomic<size_t> AnrTimerService::Ticker::idGen_; AnrTimerService::AnrTimerService(char const* label, notifier_t notifier, void* cookie, jweak jtimer, Ticker* ticker) : AnrTimerService::AnrTimerService(char const* label, notifier_t notifier, void* cookie, jweak jtimer, Ticker* ticker, bool extend) : label_(label), notifier_(notifier), notifierCookie_(cookie), notifierObject_(jtimer), extend_(extend), ticker_(ticker) { // Zero the statistics Loading @@ -666,11 +671,10 @@ char const *AnrTimerService::statusString(Status s) { return "unknown"; } AnrTimerService::timer_id_t AnrTimerService::start(int pid, int uid, nsecs_t timeout, bool extend) { AnrTimerService::timer_id_t AnrTimerService::start(int pid, int uid, nsecs_t timeout) { ALOGI_IF(DEBUG, "starting"); AutoMutex _l(lock_); Timer t(pid, uid, timeout, extend); Timer t(pid, uid, timeout, extend_); insert(t); counters_.started++; Loading Loading @@ -826,7 +830,8 @@ bool nativeSupportEnabled = false; /** * Singleton/globals for the anr timer. Among other things, this includes a Ticker* and a use * count. The JNI layer creates a single Ticker for all operational AnrTimers. The Ticker is * created when the first AnrTimer is created, and is deleted when the last AnrTimer is closed. * created when the first AnrTimer is created; this means that the Ticker is only created if * native anr timers are used. */ static Mutex gAnrLock; struct AnrArgs { Loading @@ -834,7 +839,6 @@ struct AnrArgs { jmethodID func = NULL; JavaVM* vm = NULL; AnrTimerService::Ticker* ticker = nullptr; int tickerUseCount = 0;; }; static AnrArgs gAnrArgs; Loading Loading @@ -863,18 +867,17 @@ jboolean anrTimerSupported(JNIEnv* env, jclass) { return nativeSupportEnabled; } jlong anrTimerCreate(JNIEnv* env, jobject jtimer, jstring jname) { jlong anrTimerCreate(JNIEnv* env, jobject jtimer, jstring jname, jboolean extend) { if (!nativeSupportEnabled) return 0; AutoMutex _l(gAnrLock); if (!gAnrArgs.ticker) { if (gAnrArgs.ticker == nullptr) { gAnrArgs.ticker = new AnrTimerService::Ticker(); } gAnrArgs.tickerUseCount++; ScopedUtfChars name(env, jname); jobject timer = env->NewWeakGlobalRef(jtimer); AnrTimerService* service = new AnrTimerService(name.c_str(), anrNotify, &gAnrArgs, timer, gAnrArgs.ticker); AnrTimerService* service = new AnrTimerService(name.c_str(), anrNotify, &gAnrArgs, timer, gAnrArgs.ticker, extend); return reinterpret_cast<jlong>(service); } Loading @@ -889,19 +892,14 @@ jint anrTimerClose(JNIEnv* env, jclass, jlong ptr) { AnrTimerService *s = toService(ptr); env->DeleteWeakGlobalRef(s->jtimer()); delete s; if (--gAnrArgs.tickerUseCount <= 0) { delete gAnrArgs.ticker; gAnrArgs.ticker = nullptr; } return 0; } jint anrTimerStart(JNIEnv* env, jclass, jlong ptr, jint pid, jint uid, jlong timeout, jboolean extend) { jint anrTimerStart(JNIEnv* env, jclass, jlong ptr, jint pid, jint uid, jlong timeout) { if (!nativeSupportEnabled) return 0; // On the Java side, timeouts are expressed in milliseconds and must be converted to // nanoseconds before being passed to the library code. return toService(ptr)->start(pid, uid, milliseconds_to_nanoseconds(timeout), extend); return toService(ptr)->start(pid, uid, milliseconds_to_nanoseconds(timeout)); } jboolean anrTimerCancel(JNIEnv* env, jclass, jlong ptr, jint timerId) { Loading Loading @@ -932,9 +930,9 @@ jobjectArray anrTimerDump(JNIEnv *env, jclass, jlong ptr) { static const JNINativeMethod methods[] = { {"nativeAnrTimerSupported", "()Z", (void*) anrTimerSupported}, {"nativeAnrTimerCreate", "(Ljava/lang/String;)J", (void*) anrTimerCreate}, {"nativeAnrTimerCreate", "(Ljava/lang/String;Z)J", (void*) anrTimerCreate}, {"nativeAnrTimerClose", "(J)I", (void*) anrTimerClose}, {"nativeAnrTimerStart", "(JIIJZ)I", (void*) anrTimerStart}, {"nativeAnrTimerStart", "(JIIJ)I", (void*) anrTimerStart}, {"nativeAnrTimerCancel", "(JI)Z", (void*) anrTimerCancel}, {"nativeAnrTimerAccept", "(JI)Z", (void*) anrTimerAccept}, {"nativeAnrTimerDiscard", "(JI)Z", (void*) anrTimerDiscard}, Loading @@ -948,13 +946,16 @@ int register_android_server_utils_AnrTimer(JNIEnv* env) static const char *className = "com/android/server/utils/AnrTimer"; jniRegisterNativeMethods(env, className, methods, NELEM(methods)); nativeSupportEnabled = NATIVE_SUPPORT; // Do not perform any further initialization if native support is not enabled. if (!nativeSupportEnabled) return 0; jclass service = FindClassOrDie(env, className); gAnrArgs.clazz = MakeGlobalRefOrDie(env, service); gAnrArgs.func = env->GetMethodID(gAnrArgs.clazz, "expire", "(IIIJ)Z"); env->GetJavaVM(&gAnrArgs.vm); nativeSupportEnabled = NATIVE_SUPPORT; return 0; } Loading
services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -129,7 +129,7 @@ public class AnrTimerTest { */ private class TestAnrTimer extends AnrTimer<TestArg> { private TestAnrTimer(Handler h, int key, String tag) { super(h, key, tag, false, new TestInjector()); super(h, key, tag, new AnrTimer.Args().injector(new TestInjector())); } TestAnrTimer(Helper helper) { Loading