diff options
-rw-r--r-- | services/core/java/com/android/server/utils/AnrTimer.java | 31 | ||||
-rw-r--r-- | services/core/jni/com_android_server_utils_AnrTimer.cpp | 33 | ||||
-rw-r--r-- | services/core/jni/onload.cpp | 4 |
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); |