Loading core/java/com/android/internal/os/TimeoutRecord.java +11 −3 Original line number Diff line number Diff line Loading @@ -202,17 +202,25 @@ public class TimeoutRecord { return TimeoutRecord.endingNow(TimeoutKind.APP_START, reason); } /** Record the ID of the timer that expired. */ /** * Record the timer that expired. The argument is an opaque handle. If an expired timer had * already been set, close it now. */ @NonNull public TimeoutRecord setExpiredTimer(@Nullable AutoCloseable handle) { // Close the current value of mExpiredTimer, if it not null. closeExpiredTimer(); mExpiredTimer = handle; return this; } /** Close the ExpiredTimer, if one is present. */ /** Close the ExpiredTimer, if one is present. getExpiredTimer will return null after this. */ public void closeExpiredTimer() { try { if (mExpiredTimer != null) mExpiredTimer.close(); if (mExpiredTimer != null) { mExpiredTimer.close(); mExpiredTimer = null; } } catch (Exception e) { // mExpiredTimer.close() should never, ever throw. If it does, just rethrow as a // RuntimeException. Loading services/core/java/com/android/server/am/ActiveServices.java +4 −4 Original line number Diff line number Diff line Loading @@ -3727,7 +3727,7 @@ public final class ActiveServices { mShortFGSAnrTimer.discard(sr); return; } mShortFGSAnrTimer.accept(sr); mShortFGSAnrTimer.accept(sr, tr); final String message = "Short FGS ANR'ed: " + sr; if (DEBUG_SHORT_SERVICE) { Loading Loading @@ -7574,7 +7574,6 @@ public final class ActiveServices { } } if (timeout != null && mAm.mProcessList.isInLruListLOSP(proc)) { final AutoCloseable timer = mActiveServiceAnrTimer.accept(proc); Slog.w(TAG, "Timeout executing service: " + timeout); StringWriter sw = new StringWriter(); PrintWriter pw = new FastPrintWriter(sw, false, 1024); Loading @@ -7587,7 +7586,8 @@ public final class ActiveServices { LAST_ANR_LIFETIME_DURATION_MSECS); long waitedMillis = now - timeout.executingStart; timeoutRecord = TimeoutRecord.forServiceExec(timeout.shortInstanceName, waitedMillis).setExpiredTimer(timer); waitedMillis); mActiveServiceAnrTimer.accept(proc, timeoutRecord); } else { mActiveServiceAnrTimer.discard(proc); final long delay = psr.shouldExecServicesFg() Loading Loading @@ -7631,7 +7631,7 @@ public final class ActiveServices { return; } mServiceFGAnrTimer.accept(r); mServiceFGAnrTimer.accept(r, timeoutRecord); if (DEBUG_BACKGROUND_CHECK) { Slog.i(TAG, "Service foreground-required timeout for " + r); Loading services/core/java/com/android/server/am/BroadcastQueueImpl.java +2 −2 Original line number Diff line number Diff line Loading @@ -1431,11 +1431,11 @@ class BroadcastQueueImpl extends BroadcastQueue { if (deliveryState == BroadcastRecord.DELIVERY_TIMEOUT) { r.anrCount++; if (app != null && !app.isDebugging()) { final AutoCloseable timer = mAnrTimer.accept(queue); final String packageName = getReceiverPackageName(receiver); final String className = getReceiverClassName(receiver); TimeoutRecord tr = TimeoutRecord.forBroadcastReceiver(r.intent, packageName, className).setExpiredTimer(timer); className); mAnrTimer.accept(queue, tr); mService.appNotResponding(queue.app, tr); } else { mAnrTimer.discard(queue); Loading services/core/java/com/android/server/utils/AnrTimer.java +9 −11 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.Keep; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.TimeoutRecord; import com.android.internal.util.RingBuffer; import java.lang.ref.WeakReference; Loading Loading @@ -684,21 +685,18 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** * Accept the expired timer associated with arg. This indicates that the caller considers the * timer expiration to be a true ANR. (See {@link #discard} for an alternate response.) The * function returns a {@link TimerLock} if an expired timer was found and null otherwise. * After this call, the timer does not exist. It is an error to accept a running timer, * however, the running timer will be canceled. * function stores a {@link TimerLock} in the {@link TimeoutRecord} argument. The TimerLock * records information about the expired timer for retrieval during ANR report generation. * After this call, the timer does not exist. * * If a non-null TimerLock is returned, the TimerLock must be closed before the target process * is dumped (for an ANR report) or continued. * * Note: the return value is always null if the feature is not enabled. * It is a protocol error to accept a running timer, however, the running timer will be * canceled. * * @param arg The key by which the timer is known. This is never examined or modified. * @return A TimerLock if an expired timer was accepted. * @param timeoutRecord The TimeoutRecord that will hold information about the expired timer. */ @Nullable public TimerLock accept(@NonNull V arg) { return mFeature.accept(arg); public void accept(@NonNull V arg, @NonNull TimeoutRecord timeoutRecord) { timeoutRecord.setExpiredTimer(mFeature.accept(arg)); } /** Loading Loading
core/java/com/android/internal/os/TimeoutRecord.java +11 −3 Original line number Diff line number Diff line Loading @@ -202,17 +202,25 @@ public class TimeoutRecord { return TimeoutRecord.endingNow(TimeoutKind.APP_START, reason); } /** Record the ID of the timer that expired. */ /** * Record the timer that expired. The argument is an opaque handle. If an expired timer had * already been set, close it now. */ @NonNull public TimeoutRecord setExpiredTimer(@Nullable AutoCloseable handle) { // Close the current value of mExpiredTimer, if it not null. closeExpiredTimer(); mExpiredTimer = handle; return this; } /** Close the ExpiredTimer, if one is present. */ /** Close the ExpiredTimer, if one is present. getExpiredTimer will return null after this. */ public void closeExpiredTimer() { try { if (mExpiredTimer != null) mExpiredTimer.close(); if (mExpiredTimer != null) { mExpiredTimer.close(); mExpiredTimer = null; } } catch (Exception e) { // mExpiredTimer.close() should never, ever throw. If it does, just rethrow as a // RuntimeException. Loading
services/core/java/com/android/server/am/ActiveServices.java +4 −4 Original line number Diff line number Diff line Loading @@ -3727,7 +3727,7 @@ public final class ActiveServices { mShortFGSAnrTimer.discard(sr); return; } mShortFGSAnrTimer.accept(sr); mShortFGSAnrTimer.accept(sr, tr); final String message = "Short FGS ANR'ed: " + sr; if (DEBUG_SHORT_SERVICE) { Loading Loading @@ -7574,7 +7574,6 @@ public final class ActiveServices { } } if (timeout != null && mAm.mProcessList.isInLruListLOSP(proc)) { final AutoCloseable timer = mActiveServiceAnrTimer.accept(proc); Slog.w(TAG, "Timeout executing service: " + timeout); StringWriter sw = new StringWriter(); PrintWriter pw = new FastPrintWriter(sw, false, 1024); Loading @@ -7587,7 +7586,8 @@ public final class ActiveServices { LAST_ANR_LIFETIME_DURATION_MSECS); long waitedMillis = now - timeout.executingStart; timeoutRecord = TimeoutRecord.forServiceExec(timeout.shortInstanceName, waitedMillis).setExpiredTimer(timer); waitedMillis); mActiveServiceAnrTimer.accept(proc, timeoutRecord); } else { mActiveServiceAnrTimer.discard(proc); final long delay = psr.shouldExecServicesFg() Loading Loading @@ -7631,7 +7631,7 @@ public final class ActiveServices { return; } mServiceFGAnrTimer.accept(r); mServiceFGAnrTimer.accept(r, timeoutRecord); if (DEBUG_BACKGROUND_CHECK) { Slog.i(TAG, "Service foreground-required timeout for " + r); Loading
services/core/java/com/android/server/am/BroadcastQueueImpl.java +2 −2 Original line number Diff line number Diff line Loading @@ -1431,11 +1431,11 @@ class BroadcastQueueImpl extends BroadcastQueue { if (deliveryState == BroadcastRecord.DELIVERY_TIMEOUT) { r.anrCount++; if (app != null && !app.isDebugging()) { final AutoCloseable timer = mAnrTimer.accept(queue); final String packageName = getReceiverPackageName(receiver); final String className = getReceiverClassName(receiver); TimeoutRecord tr = TimeoutRecord.forBroadcastReceiver(r.intent, packageName, className).setExpiredTimer(timer); className); mAnrTimer.accept(queue, tr); mService.appNotResponding(queue.app, tr); } else { mAnrTimer.discard(queue); Loading
services/core/java/com/android/server/utils/AnrTimer.java +9 −11 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.Keep; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.TimeoutRecord; import com.android.internal.util.RingBuffer; import java.lang.ref.WeakReference; Loading Loading @@ -684,21 +685,18 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** * Accept the expired timer associated with arg. This indicates that the caller considers the * timer expiration to be a true ANR. (See {@link #discard} for an alternate response.) The * function returns a {@link TimerLock} if an expired timer was found and null otherwise. * After this call, the timer does not exist. It is an error to accept a running timer, * however, the running timer will be canceled. * function stores a {@link TimerLock} in the {@link TimeoutRecord} argument. The TimerLock * records information about the expired timer for retrieval during ANR report generation. * After this call, the timer does not exist. * * If a non-null TimerLock is returned, the TimerLock must be closed before the target process * is dumped (for an ANR report) or continued. * * Note: the return value is always null if the feature is not enabled. * It is a protocol error to accept a running timer, however, the running timer will be * canceled. * * @param arg The key by which the timer is known. This is never examined or modified. * @return A TimerLock if an expired timer was accepted. * @param timeoutRecord The TimeoutRecord that will hold information about the expired timer. */ @Nullable public TimerLock accept(@NonNull V arg) { return mFeature.accept(arg); public void accept(@NonNull V arg, @NonNull TimeoutRecord timeoutRecord) { timeoutRecord.setExpiredTimer(mFeature.accept(arg)); } /** Loading