summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/utils/AnrTimer.java31
-rw-r--r--services/core/jni/com_android_server_utils_AnrTimer.cpp33
-rw-r--r--services/core/jni/onload.cpp4
3 files changed, 26 insertions, 42 deletions
diff --git a/services/core/java/com/android/server/utils/AnrTimer.java b/services/core/java/com/android/server/utils/AnrTimer.java
index 053ffbc00a5c..e3aba0f6bc6f 100644
--- a/services/core/java/com/android/server/utils/AnrTimer.java
+++ b/services/core/java/com/android/server/utils/AnrTimer.java
@@ -36,8 +36,6 @@ import com.android.internal.annotations.Keep;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.RingBuffer;
-import libcore.util.NativeAllocationRegistry;
-
import java.lang.ref.WeakReference;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -419,14 +417,6 @@ public class AnrTimer<V> implements AutoCloseable {
new LongSparseArray<>();
/**
- * The manager of native pointers.
- */
- private static final NativeAllocationRegistry sNativeRegistry =
- NativeAllocationRegistry.createMalloced(
- AnrTimer.FeatureEnabled.class.getClassLoader(),
- nativeAnrTimerGetFinalizer());
-
- /**
* The FeatureEnabled class enables the AnrTimer logic. It is used when the AnrTimer service
* is enabled via Flags.anrTimerServiceEnabled.
*/
@@ -438,14 +428,10 @@ public class AnrTimer<V> implements AutoCloseable {
*/
private long mNative = 0;
- /** The Runnable that frees the native pointer. */
- private final Runnable mFreeNative;
-
/** Fetch the native tag (an integer) for the given label. */
FeatureEnabled() {
mNative = nativeAnrTimerCreate(mLabel);
if (mNative == 0) throw new IllegalArgumentException("unable to create native timer");
- mFreeNative = sNativeRegistry.registerNativeAllocation(this, mNative);
synchronized (sAnrTimerList) {
sAnrTimerList.put(mNative, new WeakReference(AnrTimer.this));
}
@@ -556,7 +542,7 @@ public class AnrTimer<V> implements AutoCloseable {
sAnrTimerList.remove(mNative);
}
synchronized (mLock) {
- if (mNative != 0) mFreeNative.run();
+ if (mNative != 0) nativeAnrTimerClose(mNative);
mNative = 0;
}
}
@@ -673,6 +659,17 @@ public class AnrTimer<V> implements AutoCloseable {
}
/**
+ * Ensure any native resources are freed when the object is GC'ed. Best practice is to close
+ * the object explicitly, but overriding finalize() avoids accidental leaks.
+ */
+ @SuppressWarnings("Finalize")
+ @Override
+ protected void finalize() throws Throwable {
+ close();
+ super.finalize();
+ }
+
+ /**
* Dump a single AnrTimer.
*/
private void dump(IndentingPrintWriter pw) {
@@ -797,8 +794,8 @@ public class AnrTimer<V> implements AutoCloseable {
*/
private native long nativeAnrTimerCreate(String name);
- /** Return the finalizer for the native resources. */
- private static native long nativeAnrTimerGetFinalizer();
+ /** 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,
diff --git a/services/core/jni/com_android_server_utils_AnrTimer.cpp b/services/core/jni/com_android_server_utils_AnrTimer.cpp
index b7f7a7507531..97b18fac91f4 100644
--- a/services/core/jni/com_android_server_utils_AnrTimer.cpp
+++ b/services/core/jni/com_android_server_utils_AnrTimer.cpp
@@ -486,11 +486,9 @@ class AnrTimerService::Ticker {
void remove(AnrTimerService const* service) {
AutoMutex _l(lock_);
timer_id_t front = headTimerId();
- for (auto i = running_.begin(); i != running_.end(); ) {
+ for (auto i = running_.begin(); i != running_.end(); i++) {
if (i->service == service) {
- i = running_.erase(i);
- } else {
- i++;
+ running_.erase(i);
}
}
if (front != headTimerId()) restartLocked();
@@ -810,7 +808,7 @@ static bool anrNotify(AnrTimerService::timer_id_t timerId, int pid, int uid,
AnrArgs* target = reinterpret_cast<AnrArgs* >(cookie);
JNIEnv *env;
if (target->vm->AttachCurrentThread(&env, 0) != JNI_OK) {
- ALOGE("anrNotify failed to attach thread to JavaVM");
+ ALOGE("failed to attach thread to JavaVM");
return false;
}
jboolean r = false;
@@ -846,29 +844,18 @@ AnrTimerService *toService(jlong pointer) {
return reinterpret_cast<AnrTimerService*>(pointer);
}
-AnrTimerService *toService(void* pointer) {
- return reinterpret_cast<AnrTimerService*>(pointer);
-}
-
-void anrTimerDelete(void *ptr) {
- if (ptr == 0) return;
+jint anrTimerClose(JNIEnv* env, jclass, jlong ptr) {
+ if (!nativeSupportEnabled) return -1;
+ if (ptr == 0) return -1;
AutoMutex _l(gAnrLock);
- AnrTimerService* s = toService(ptr);
- JNIEnv *env;
- if (gAnrArgs.vm->AttachCurrentThread(&env, 0) == JNI_OK) {
- env->DeleteWeakGlobalRef(s->jtimer());
- } else {
- ALOGE("anrTimerDelete failed to attach thread to JavaVM");
- }
+ AnrTimerService *s = toService(ptr);
+ env->DeleteWeakGlobalRef(s->jtimer());
delete s;
if (--gAnrArgs.tickerUseCount <= 0) {
delete gAnrArgs.ticker;
gAnrArgs.ticker = nullptr;
}
-}
-
-jlong anrTimerGetFinalizer(JNIEnv*, jclass) {
- return static_cast<jlong>(reinterpret_cast<uintptr_t>(&anrTimerDelete));
+ return 0;
}
jint anrTimerStart(JNIEnv* env, jclass, jlong ptr,
@@ -903,7 +890,7 @@ jint anrTimerDump(JNIEnv *env, jclass, jlong ptr, jboolean verbose) {
static const JNINativeMethod methods[] = {
{"nativeAnrTimerSupported", "()Z", (void*) anrTimerSupported},
{"nativeAnrTimerCreate", "(Ljava/lang/String;)J", (void*) anrTimerCreate},
- {"nativeAnrTimerGetFinalizer", "()J", (void*) anrTimerGetFinalizer},
+ {"nativeAnrTimerClose", "(J)I", (void*) anrTimerClose},
{"nativeAnrTimerStart", "(JIIJZ)I", (void*) anrTimerStart},
{"nativeAnrTimerCancel", "(JI)Z", (void*) anrTimerCancel},
{"nativeAnrTimerAccept", "(JI)Z", (void*) anrTimerAccept},
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 5d1eb496903b..f3158d11b9a4 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -52,10 +52,10 @@ int register_android_server_Watchdog(JNIEnv* env);
int register_android_server_HardwarePropertiesManagerService(JNIEnv* env);
int register_android_server_SyntheticPasswordManager(JNIEnv* env);
int register_android_hardware_display_DisplayViewport(JNIEnv* env);
+int register_android_server_utils_AnrTimer(JNIEnv *env);
int register_android_server_am_OomConnection(JNIEnv* env);
int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
int register_android_server_am_LowMemDetector(JNIEnv* env);
-int register_android_server_utils_AnrTimer(JNIEnv *env);
int register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(JNIEnv* env);
int register_com_android_server_soundtrigger_middleware_ExternalCaptureStateTracker(JNIEnv* env);
int register_android_server_com_android_server_pm_PackageManagerShellCommandDataLoader(JNIEnv* env);
@@ -114,10 +114,10 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_storage_AppFuse(env);
register_android_server_SyntheticPasswordManager(env);
register_android_hardware_display_DisplayViewport(env);
+ register_android_server_utils_AnrTimer(env);
register_android_server_am_OomConnection(env);
register_android_server_am_CachedAppOptimizer(env);
register_android_server_am_LowMemDetector(env);
- register_android_server_utils_AnrTimer(env);
register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(env);
register_com_android_server_soundtrigger_middleware_ExternalCaptureStateTracker(env);
register_android_server_com_android_server_pm_PackageManagerShellCommandDataLoader(env);