Loading core/java/android/app/ActivityManagerInternal.java +7 −2 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ import android.os.WorkSource; import android.util.ArraySet; import android.util.Pair; import com.android.internal.os.TimeoutRecord; import java.util.ArrayList; import java.util.List; import java.util.Map; Loading Loading @@ -440,10 +442,13 @@ public abstract class ActivityManagerInternal { /** Input dispatch timeout to a window, start the ANR process. Return the timeout extension, * in milliseconds, or 0 to abort dispatch. */ public abstract long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason); public abstract long inputDispatchingTimedOut(int pid, boolean aboveSystem, TimeoutRecord timeoutRecord); public abstract boolean inputDispatchingTimedOut(Object proc, String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, Object parentProc, boolean aboveSystem, String reason); boolean aboveSystem, TimeoutRecord timeoutRecord); /** * App started responding to input events. This signal can be used to abort the ANR process and * hide the ANR dialog. Loading core/java/com/android/internal/os/TimeoutRecord.java 0 → 100644 +130 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.os; import android.annotation.IntDef; import android.annotation.NonNull; import android.os.SystemClock; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * A timeout that has triggered on the system. * * @hide */ public class TimeoutRecord { /** Kind of timeout, e.g. BROADCAST_RECEIVER, etc. */ @IntDef(value = { TimeoutKind.INPUT_DISPATCH_NO_FOCUSED_WINDOW, TimeoutKind.INPUT_DISPATCH_WINDOW_UNRESPONSIVE, TimeoutKind.BROADCAST_RECEIVER, TimeoutKind.SERVICE_START, TimeoutKind.SERVICE_EXEC, TimeoutKind.CONTENT_PROVIDER, TimeoutKind.APP_REGISTERED}) @Retention(RetentionPolicy.SOURCE) private @interface TimeoutKind { int INPUT_DISPATCH_NO_FOCUSED_WINDOW = 1; int INPUT_DISPATCH_WINDOW_UNRESPONSIVE = 2; int BROADCAST_RECEIVER = 3; int SERVICE_START = 4; int SERVICE_EXEC = 5; int CONTENT_PROVIDER = 6; int APP_REGISTERED = 7; } /** Kind of timeout, e.g. BROADCAST_RECEIVER, etc. */ @TimeoutKind public final int mKind; /** Reason for the timeout. */ public final String mReason; /** System uptime in millis when the timeout was triggered. */ public final long mEndUptimeMillis; /** * Was the end timestamp taken right after the timeout triggered, before any potentially * expensive operations such as taking locks? */ public final boolean mEndTakenBeforeLocks; private TimeoutRecord(@TimeoutKind int kind, @NonNull String reason, long endUptimeMillis, boolean endTakenBeforeLocks) { this.mKind = kind; this.mReason = reason; this.mEndUptimeMillis = endUptimeMillis; this.mEndTakenBeforeLocks = endTakenBeforeLocks; } private static TimeoutRecord endingNow(@TimeoutKind int kind, String reason) { long endUptimeMillis = SystemClock.uptimeMillis(); return new TimeoutRecord(kind, reason, endUptimeMillis, /* endTakenBeforeLocks */ true); } private static TimeoutRecord endingApproximatelyNow(@TimeoutKind int kind, String reason) { long endUptimeMillis = SystemClock.uptimeMillis(); return new TimeoutRecord(kind, reason, endUptimeMillis, /* endTakenBeforeLocks */ false); } /** Record for a broadcast receiver timeout. */ @NonNull public static TimeoutRecord forBroadcastReceiver(@NonNull String reason) { return TimeoutRecord.endingNow(TimeoutKind.BROADCAST_RECEIVER, reason); } /** Record for an input dispatch no focused window timeout */ @NonNull public static TimeoutRecord forInputDispatchNoFocusedWindow(@NonNull String reason) { return TimeoutRecord.endingNow(TimeoutKind.INPUT_DISPATCH_NO_FOCUSED_WINDOW, reason); } /** Record for an input dispatch window unresponsive timeout. */ @NonNull public static TimeoutRecord forInputDispatchWindowUnresponsive(@NonNull String reason) { return TimeoutRecord.endingNow(TimeoutKind.INPUT_DISPATCH_WINDOW_UNRESPONSIVE, reason); } /** Record for a service exec timeout. */ @NonNull public static TimeoutRecord forServiceExec(@NonNull String reason) { return TimeoutRecord.endingNow(TimeoutKind.SERVICE_EXEC, reason); } /** Record for a service start timeout. */ @NonNull public static TimeoutRecord forServiceStartWithEndTime(@NonNull String reason, long endUptimeMillis) { return new TimeoutRecord(TimeoutKind.SERVICE_START, reason, endUptimeMillis, /* endTakenBeforeLocks */ true); } /** Record for a content provider timeout. */ @NonNull public static TimeoutRecord forContentProvider(@NonNull String reason) { return TimeoutRecord.endingApproximatelyNow(TimeoutKind.CONTENT_PROVIDER, reason); } /** Record for an app registered timeout. */ @NonNull public static TimeoutRecord forApp(@NonNull String reason) { return TimeoutRecord.endingApproximatelyNow(TimeoutKind.APP_REGISTERED, reason); } } services/core/java/com/android/server/am/ActiveServices.java +13 −7 Original line number Diff line number Diff line Loading @@ -166,6 +166,7 @@ import com.android.internal.app.procstats.ServiceState; import com.android.internal.messages.nano.SystemMessageProto; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.SomeArgs; import com.android.internal.os.TimeoutRecord; import com.android.internal.os.TransferPipe; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastPrintWriter; Loading Loading @@ -5761,7 +5762,7 @@ public final class ActiveServices { } void serviceTimeout(ProcessRecord proc) { String anrMessage = null; TimeoutRecord timeoutRecord = null; synchronized(mAm) { if (proc.isDebugging()) { // The app's being debugged, ignore timeout. Loading Loading @@ -5796,7 +5797,8 @@ public final class ActiveServices { mLastAnrDump = sw.toString(); mAm.mHandler.removeCallbacks(mLastAnrDumpClearer); mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS); anrMessage = "executing service " + timeout.shortInstanceName; String anrMessage = "executing service " + timeout.shortInstanceName; timeoutRecord = TimeoutRecord.forServiceExec(anrMessage); } else { Message msg = mAm.mHandler.obtainMessage( ActivityManagerService.SERVICE_TIMEOUT_MSG); Loading @@ -5806,13 +5808,15 @@ public final class ActiveServices { } } if (anrMessage != null) { mAm.mAnrHelper.appNotResponding(proc, anrMessage); if (timeoutRecord != null) { mAm.mAnrHelper.appNotResponding(proc, timeoutRecord); } } void serviceForegroundTimeout(ServiceRecord r) { ProcessRecord app; // Grab a timestamp before lock is taken. long timeoutEndMs = SystemClock.uptimeMillis(); synchronized (mAm) { if (!r.fgRequired || !r.fgWaiting || r.destroying) { return; Loading @@ -5836,17 +5840,19 @@ public final class ActiveServices { + "Service.startForeground(): " + r; Message msg = mAm.mHandler.obtainMessage( ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_ANR_MSG); TimeoutRecord timeoutRecord = TimeoutRecord.forServiceStartWithEndTime(annotation, timeoutEndMs); SomeArgs args = SomeArgs.obtain(); args.arg1 = app; args.arg2 = annotation; args.arg2 = timeoutRecord; msg.obj = args; mAm.mHandler.sendMessageDelayed(msg, mAm.mConstants.mServiceStartForegroundAnrDelayMs); } } void serviceForegroundTimeoutANR(ProcessRecord app, String annotation) { mAm.mAnrHelper.appNotResponding(app, annotation); void serviceForegroundTimeoutANR(ProcessRecord app, TimeoutRecord timeoutRecord) { mAm.mAnrHelper.appNotResponding(app, timeoutRecord); } public void updateServiceApplicationInfoLocked(ApplicationInfo applicationInfo) { Loading services/core/java/com/android/server/am/ActivityManagerService.java +16 −19 Original line number Diff line number Diff line Loading @@ -357,6 +357,7 @@ import com.android.internal.os.ByteTransferPipe; import com.android.internal.os.IResultReceiver; import com.android.internal.os.ProcessCpuTracker; import com.android.internal.os.SomeArgs; import com.android.internal.os.TimeoutRecord; import com.android.internal.os.TransferPipe; import com.android.internal.os.Zygote; import com.android.internal.policy.AttributeCache; Loading Loading @@ -1700,7 +1701,7 @@ public class ActivityManagerService extends IActivityManager.Stub case SERVICE_FOREGROUND_TIMEOUT_ANR_MSG: { SomeArgs args = (SomeArgs) msg.obj; mServices.serviceForegroundTimeoutANR((ProcessRecord) args.arg1, (String) args.arg2); (TimeoutRecord) args.arg2); args.recycle(); } break; case SERVICE_FOREGROUND_CRASH_MSG: { Loading Loading @@ -6417,6 +6418,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void appNotResponding(final String reason) { TimeoutRecord timeoutRecord = TimeoutRecord.forApp("App requested: " + reason); final int callingPid = Binder.getCallingPid(); synchronized (mPidsSelfLocked) { Loading @@ -6426,7 +6428,7 @@ public class ActivityManagerService extends IActivityManager.Stub } mAnrHelper.appNotResponding(app, null, app.info, null, null, false, "App requested: " + reason); timeoutRecord); } } Loading Loading @@ -17172,18 +17174,19 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) { return ActivityManagerService.this.inputDispatchingTimedOut(pid, aboveSystem, reason); public long inputDispatchingTimedOut(int pid, boolean aboveSystem, TimeoutRecord timeoutRecord) { return ActivityManagerService.this.inputDispatchingTimedOut(pid, aboveSystem, timeoutRecord); } @Override public boolean inputDispatchingTimedOut(Object proc, String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, Object parentProc, boolean aboveSystem, String reason) { boolean aboveSystem, TimeoutRecord timeoutRecord) { return ActivityManagerService.this.inputDispatchingTimedOut((ProcessRecord) proc, activityShortComponentName, aInfo, parentShortComponentName, (WindowProcessController) parentProc, aboveSystem, reason); (WindowProcessController) parentProc, aboveSystem, timeoutRecord); } @Override Loading Loading @@ -17745,7 +17748,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { long inputDispatchingTimedOut(int pid, final boolean aboveSystem, TimeoutRecord timeoutRecord) { if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires permission " + FILTER_EVENTS); } Loading @@ -17756,7 +17759,7 @@ public class ActivityManagerService extends IActivityManager.Stub final long timeoutMillis = proc != null ? proc.getInputDispatchingTimeoutMillis() : DEFAULT_DISPATCHING_TIMEOUT_MILLIS; if (inputDispatchingTimedOut(proc, null, null, null, null, aboveSystem, reason)) { if (inputDispatchingTimedOut(proc, null, null, null, null, aboveSystem, timeoutRecord)) { return 0; } Loading @@ -17769,18 +17772,12 @@ public class ActivityManagerService extends IActivityManager.Stub */ boolean inputDispatchingTimedOut(ProcessRecord proc, String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, WindowProcessController parentProcess, boolean aboveSystem, String reason) { WindowProcessController parentProcess, boolean aboveSystem, TimeoutRecord timeoutRecord) { if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires permission " + FILTER_EVENTS); } final String annotation; if (reason == null) { annotation = "Input dispatching timed out"; } else { annotation = "Input dispatching timed out (" + reason + ")"; } if (proc != null) { synchronized (this) { if (proc.isDebugging()) { Loading @@ -17790,13 +17787,13 @@ public class ActivityManagerService extends IActivityManager.Stub if (proc.getActiveInstrumentation() != null) { Bundle info = new Bundle(); info.putString("shortMsg", "keyDispatchingTimedOut"); info.putString("longMsg", annotation); info.putString("longMsg", timeoutRecord.mReason); finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); return true; } } mAnrHelper.appNotResponding(proc, activityShortComponentName, aInfo, parentShortComponentName, parentProcess, aboveSystem, annotation); parentShortComponentName, parentProcess, aboveSystem, timeoutRecord); } return true; services/core/java/com/android/server/am/AnrHelper.java +16 −10 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.os.SystemClock; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.TimeoutRecord; import com.android.server.wm.WindowProcessController; import java.util.ArrayList; Loading Loading @@ -68,15 +69,16 @@ class AnrHelper { mService = service; } void appNotResponding(ProcessRecord anrProcess, String annotation) { void appNotResponding(ProcessRecord anrProcess, TimeoutRecord timeoutRecord) { appNotResponding(anrProcess, null /* activityShortComponentName */, null /* aInfo */, null /* parentShortComponentName */, null /* parentProcess */, false /* aboveSystem */, annotation); false /* aboveSystem */, timeoutRecord); } void appNotResponding(ProcessRecord anrProcess, String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, WindowProcessController parentProcess, boolean aboveSystem, String annotation) { WindowProcessController parentProcess, boolean aboveSystem, TimeoutRecord timeoutRecord) { final int incomingPid = anrProcess.mPid; synchronized (mAnrRecords) { if (incomingPid == 0) { Loading @@ -85,17 +87,19 @@ class AnrHelper { return; } if (mProcessingPid == incomingPid) { Slog.i(TAG, "Skip duplicated ANR, pid=" + incomingPid + " " + annotation); Slog.i(TAG, "Skip duplicated ANR, pid=" + incomingPid + " " + timeoutRecord.mReason); return; } for (int i = mAnrRecords.size() - 1; i >= 0; i--) { if (mAnrRecords.get(i).mPid == incomingPid) { Slog.i(TAG, "Skip queued ANR, pid=" + incomingPid + " " + annotation); Slog.i(TAG, "Skip queued ANR, pid=" + incomingPid + " " + timeoutRecord.mReason); return; } } mAnrRecords.add(new AnrRecord(anrProcess, activityShortComponentName, aInfo, parentShortComponentName, parentProcess, aboveSystem, annotation)); parentShortComponentName, parentProcess, aboveSystem, timeoutRecord)); } startAnrConsumerIfNeeded(); } Loading Loading @@ -175,7 +179,7 @@ class AnrHelper { final int mPid; final String mActivityShortComponentName; final String mParentShortComponentName; final String mAnnotation; final TimeoutRecord mTimeoutRecord; final ApplicationInfo mAppInfo; final WindowProcessController mParentProcess; final boolean mAboveSystem; Loading @@ -183,12 +187,13 @@ class AnrHelper { AnrRecord(ProcessRecord anrProcess, String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, WindowProcessController parentProcess, boolean aboveSystem, String annotation) { WindowProcessController parentProcess, boolean aboveSystem, TimeoutRecord timeoutRecord) { mApp = anrProcess; mPid = anrProcess.mPid; mActivityShortComponentName = activityShortComponentName; mParentShortComponentName = parentShortComponentName; mAnnotation = annotation; mTimeoutRecord = timeoutRecord; mAppInfo = aInfo; mParentProcess = parentProcess; mAboveSystem = aboveSystem; Loading @@ -196,7 +201,8 @@ class AnrHelper { void appNotResponding(boolean onlyDumpSelf) { mApp.mErrorState.appNotResponding(mActivityShortComponentName, mAppInfo, mParentShortComponentName, mParentProcess, mAboveSystem, mAnnotation, mParentShortComponentName, mParentProcess, mAboveSystem, mTimeoutRecord, onlyDumpSelf); } } Loading Loading
core/java/android/app/ActivityManagerInternal.java +7 −2 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ import android.os.WorkSource; import android.util.ArraySet; import android.util.Pair; import com.android.internal.os.TimeoutRecord; import java.util.ArrayList; import java.util.List; import java.util.Map; Loading Loading @@ -440,10 +442,13 @@ public abstract class ActivityManagerInternal { /** Input dispatch timeout to a window, start the ANR process. Return the timeout extension, * in milliseconds, or 0 to abort dispatch. */ public abstract long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason); public abstract long inputDispatchingTimedOut(int pid, boolean aboveSystem, TimeoutRecord timeoutRecord); public abstract boolean inputDispatchingTimedOut(Object proc, String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, Object parentProc, boolean aboveSystem, String reason); boolean aboveSystem, TimeoutRecord timeoutRecord); /** * App started responding to input events. This signal can be used to abort the ANR process and * hide the ANR dialog. Loading
core/java/com/android/internal/os/TimeoutRecord.java 0 → 100644 +130 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.os; import android.annotation.IntDef; import android.annotation.NonNull; import android.os.SystemClock; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * A timeout that has triggered on the system. * * @hide */ public class TimeoutRecord { /** Kind of timeout, e.g. BROADCAST_RECEIVER, etc. */ @IntDef(value = { TimeoutKind.INPUT_DISPATCH_NO_FOCUSED_WINDOW, TimeoutKind.INPUT_DISPATCH_WINDOW_UNRESPONSIVE, TimeoutKind.BROADCAST_RECEIVER, TimeoutKind.SERVICE_START, TimeoutKind.SERVICE_EXEC, TimeoutKind.CONTENT_PROVIDER, TimeoutKind.APP_REGISTERED}) @Retention(RetentionPolicy.SOURCE) private @interface TimeoutKind { int INPUT_DISPATCH_NO_FOCUSED_WINDOW = 1; int INPUT_DISPATCH_WINDOW_UNRESPONSIVE = 2; int BROADCAST_RECEIVER = 3; int SERVICE_START = 4; int SERVICE_EXEC = 5; int CONTENT_PROVIDER = 6; int APP_REGISTERED = 7; } /** Kind of timeout, e.g. BROADCAST_RECEIVER, etc. */ @TimeoutKind public final int mKind; /** Reason for the timeout. */ public final String mReason; /** System uptime in millis when the timeout was triggered. */ public final long mEndUptimeMillis; /** * Was the end timestamp taken right after the timeout triggered, before any potentially * expensive operations such as taking locks? */ public final boolean mEndTakenBeforeLocks; private TimeoutRecord(@TimeoutKind int kind, @NonNull String reason, long endUptimeMillis, boolean endTakenBeforeLocks) { this.mKind = kind; this.mReason = reason; this.mEndUptimeMillis = endUptimeMillis; this.mEndTakenBeforeLocks = endTakenBeforeLocks; } private static TimeoutRecord endingNow(@TimeoutKind int kind, String reason) { long endUptimeMillis = SystemClock.uptimeMillis(); return new TimeoutRecord(kind, reason, endUptimeMillis, /* endTakenBeforeLocks */ true); } private static TimeoutRecord endingApproximatelyNow(@TimeoutKind int kind, String reason) { long endUptimeMillis = SystemClock.uptimeMillis(); return new TimeoutRecord(kind, reason, endUptimeMillis, /* endTakenBeforeLocks */ false); } /** Record for a broadcast receiver timeout. */ @NonNull public static TimeoutRecord forBroadcastReceiver(@NonNull String reason) { return TimeoutRecord.endingNow(TimeoutKind.BROADCAST_RECEIVER, reason); } /** Record for an input dispatch no focused window timeout */ @NonNull public static TimeoutRecord forInputDispatchNoFocusedWindow(@NonNull String reason) { return TimeoutRecord.endingNow(TimeoutKind.INPUT_DISPATCH_NO_FOCUSED_WINDOW, reason); } /** Record for an input dispatch window unresponsive timeout. */ @NonNull public static TimeoutRecord forInputDispatchWindowUnresponsive(@NonNull String reason) { return TimeoutRecord.endingNow(TimeoutKind.INPUT_DISPATCH_WINDOW_UNRESPONSIVE, reason); } /** Record for a service exec timeout. */ @NonNull public static TimeoutRecord forServiceExec(@NonNull String reason) { return TimeoutRecord.endingNow(TimeoutKind.SERVICE_EXEC, reason); } /** Record for a service start timeout. */ @NonNull public static TimeoutRecord forServiceStartWithEndTime(@NonNull String reason, long endUptimeMillis) { return new TimeoutRecord(TimeoutKind.SERVICE_START, reason, endUptimeMillis, /* endTakenBeforeLocks */ true); } /** Record for a content provider timeout. */ @NonNull public static TimeoutRecord forContentProvider(@NonNull String reason) { return TimeoutRecord.endingApproximatelyNow(TimeoutKind.CONTENT_PROVIDER, reason); } /** Record for an app registered timeout. */ @NonNull public static TimeoutRecord forApp(@NonNull String reason) { return TimeoutRecord.endingApproximatelyNow(TimeoutKind.APP_REGISTERED, reason); } }
services/core/java/com/android/server/am/ActiveServices.java +13 −7 Original line number Diff line number Diff line Loading @@ -166,6 +166,7 @@ import com.android.internal.app.procstats.ServiceState; import com.android.internal.messages.nano.SystemMessageProto; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.SomeArgs; import com.android.internal.os.TimeoutRecord; import com.android.internal.os.TransferPipe; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastPrintWriter; Loading Loading @@ -5761,7 +5762,7 @@ public final class ActiveServices { } void serviceTimeout(ProcessRecord proc) { String anrMessage = null; TimeoutRecord timeoutRecord = null; synchronized(mAm) { if (proc.isDebugging()) { // The app's being debugged, ignore timeout. Loading Loading @@ -5796,7 +5797,8 @@ public final class ActiveServices { mLastAnrDump = sw.toString(); mAm.mHandler.removeCallbacks(mLastAnrDumpClearer); mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS); anrMessage = "executing service " + timeout.shortInstanceName; String anrMessage = "executing service " + timeout.shortInstanceName; timeoutRecord = TimeoutRecord.forServiceExec(anrMessage); } else { Message msg = mAm.mHandler.obtainMessage( ActivityManagerService.SERVICE_TIMEOUT_MSG); Loading @@ -5806,13 +5808,15 @@ public final class ActiveServices { } } if (anrMessage != null) { mAm.mAnrHelper.appNotResponding(proc, anrMessage); if (timeoutRecord != null) { mAm.mAnrHelper.appNotResponding(proc, timeoutRecord); } } void serviceForegroundTimeout(ServiceRecord r) { ProcessRecord app; // Grab a timestamp before lock is taken. long timeoutEndMs = SystemClock.uptimeMillis(); synchronized (mAm) { if (!r.fgRequired || !r.fgWaiting || r.destroying) { return; Loading @@ -5836,17 +5840,19 @@ public final class ActiveServices { + "Service.startForeground(): " + r; Message msg = mAm.mHandler.obtainMessage( ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_ANR_MSG); TimeoutRecord timeoutRecord = TimeoutRecord.forServiceStartWithEndTime(annotation, timeoutEndMs); SomeArgs args = SomeArgs.obtain(); args.arg1 = app; args.arg2 = annotation; args.arg2 = timeoutRecord; msg.obj = args; mAm.mHandler.sendMessageDelayed(msg, mAm.mConstants.mServiceStartForegroundAnrDelayMs); } } void serviceForegroundTimeoutANR(ProcessRecord app, String annotation) { mAm.mAnrHelper.appNotResponding(app, annotation); void serviceForegroundTimeoutANR(ProcessRecord app, TimeoutRecord timeoutRecord) { mAm.mAnrHelper.appNotResponding(app, timeoutRecord); } public void updateServiceApplicationInfoLocked(ApplicationInfo applicationInfo) { Loading
services/core/java/com/android/server/am/ActivityManagerService.java +16 −19 Original line number Diff line number Diff line Loading @@ -357,6 +357,7 @@ import com.android.internal.os.ByteTransferPipe; import com.android.internal.os.IResultReceiver; import com.android.internal.os.ProcessCpuTracker; import com.android.internal.os.SomeArgs; import com.android.internal.os.TimeoutRecord; import com.android.internal.os.TransferPipe; import com.android.internal.os.Zygote; import com.android.internal.policy.AttributeCache; Loading Loading @@ -1700,7 +1701,7 @@ public class ActivityManagerService extends IActivityManager.Stub case SERVICE_FOREGROUND_TIMEOUT_ANR_MSG: { SomeArgs args = (SomeArgs) msg.obj; mServices.serviceForegroundTimeoutANR((ProcessRecord) args.arg1, (String) args.arg2); (TimeoutRecord) args.arg2); args.recycle(); } break; case SERVICE_FOREGROUND_CRASH_MSG: { Loading Loading @@ -6417,6 +6418,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void appNotResponding(final String reason) { TimeoutRecord timeoutRecord = TimeoutRecord.forApp("App requested: " + reason); final int callingPid = Binder.getCallingPid(); synchronized (mPidsSelfLocked) { Loading @@ -6426,7 +6428,7 @@ public class ActivityManagerService extends IActivityManager.Stub } mAnrHelper.appNotResponding(app, null, app.info, null, null, false, "App requested: " + reason); timeoutRecord); } } Loading Loading @@ -17172,18 +17174,19 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) { return ActivityManagerService.this.inputDispatchingTimedOut(pid, aboveSystem, reason); public long inputDispatchingTimedOut(int pid, boolean aboveSystem, TimeoutRecord timeoutRecord) { return ActivityManagerService.this.inputDispatchingTimedOut(pid, aboveSystem, timeoutRecord); } @Override public boolean inputDispatchingTimedOut(Object proc, String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, Object parentProc, boolean aboveSystem, String reason) { boolean aboveSystem, TimeoutRecord timeoutRecord) { return ActivityManagerService.this.inputDispatchingTimedOut((ProcessRecord) proc, activityShortComponentName, aInfo, parentShortComponentName, (WindowProcessController) parentProc, aboveSystem, reason); (WindowProcessController) parentProc, aboveSystem, timeoutRecord); } @Override Loading Loading @@ -17745,7 +17748,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { long inputDispatchingTimedOut(int pid, final boolean aboveSystem, TimeoutRecord timeoutRecord) { if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires permission " + FILTER_EVENTS); } Loading @@ -17756,7 +17759,7 @@ public class ActivityManagerService extends IActivityManager.Stub final long timeoutMillis = proc != null ? proc.getInputDispatchingTimeoutMillis() : DEFAULT_DISPATCHING_TIMEOUT_MILLIS; if (inputDispatchingTimedOut(proc, null, null, null, null, aboveSystem, reason)) { if (inputDispatchingTimedOut(proc, null, null, null, null, aboveSystem, timeoutRecord)) { return 0; } Loading @@ -17769,18 +17772,12 @@ public class ActivityManagerService extends IActivityManager.Stub */ boolean inputDispatchingTimedOut(ProcessRecord proc, String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, WindowProcessController parentProcess, boolean aboveSystem, String reason) { WindowProcessController parentProcess, boolean aboveSystem, TimeoutRecord timeoutRecord) { if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires permission " + FILTER_EVENTS); } final String annotation; if (reason == null) { annotation = "Input dispatching timed out"; } else { annotation = "Input dispatching timed out (" + reason + ")"; } if (proc != null) { synchronized (this) { if (proc.isDebugging()) { Loading @@ -17790,13 +17787,13 @@ public class ActivityManagerService extends IActivityManager.Stub if (proc.getActiveInstrumentation() != null) { Bundle info = new Bundle(); info.putString("shortMsg", "keyDispatchingTimedOut"); info.putString("longMsg", annotation); info.putString("longMsg", timeoutRecord.mReason); finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); return true; } } mAnrHelper.appNotResponding(proc, activityShortComponentName, aInfo, parentShortComponentName, parentProcess, aboveSystem, annotation); parentShortComponentName, parentProcess, aboveSystem, timeoutRecord); } return true;
services/core/java/com/android/server/am/AnrHelper.java +16 −10 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.os.SystemClock; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.TimeoutRecord; import com.android.server.wm.WindowProcessController; import java.util.ArrayList; Loading Loading @@ -68,15 +69,16 @@ class AnrHelper { mService = service; } void appNotResponding(ProcessRecord anrProcess, String annotation) { void appNotResponding(ProcessRecord anrProcess, TimeoutRecord timeoutRecord) { appNotResponding(anrProcess, null /* activityShortComponentName */, null /* aInfo */, null /* parentShortComponentName */, null /* parentProcess */, false /* aboveSystem */, annotation); false /* aboveSystem */, timeoutRecord); } void appNotResponding(ProcessRecord anrProcess, String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, WindowProcessController parentProcess, boolean aboveSystem, String annotation) { WindowProcessController parentProcess, boolean aboveSystem, TimeoutRecord timeoutRecord) { final int incomingPid = anrProcess.mPid; synchronized (mAnrRecords) { if (incomingPid == 0) { Loading @@ -85,17 +87,19 @@ class AnrHelper { return; } if (mProcessingPid == incomingPid) { Slog.i(TAG, "Skip duplicated ANR, pid=" + incomingPid + " " + annotation); Slog.i(TAG, "Skip duplicated ANR, pid=" + incomingPid + " " + timeoutRecord.mReason); return; } for (int i = mAnrRecords.size() - 1; i >= 0; i--) { if (mAnrRecords.get(i).mPid == incomingPid) { Slog.i(TAG, "Skip queued ANR, pid=" + incomingPid + " " + annotation); Slog.i(TAG, "Skip queued ANR, pid=" + incomingPid + " " + timeoutRecord.mReason); return; } } mAnrRecords.add(new AnrRecord(anrProcess, activityShortComponentName, aInfo, parentShortComponentName, parentProcess, aboveSystem, annotation)); parentShortComponentName, parentProcess, aboveSystem, timeoutRecord)); } startAnrConsumerIfNeeded(); } Loading Loading @@ -175,7 +179,7 @@ class AnrHelper { final int mPid; final String mActivityShortComponentName; final String mParentShortComponentName; final String mAnnotation; final TimeoutRecord mTimeoutRecord; final ApplicationInfo mAppInfo; final WindowProcessController mParentProcess; final boolean mAboveSystem; Loading @@ -183,12 +187,13 @@ class AnrHelper { AnrRecord(ProcessRecord anrProcess, String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, WindowProcessController parentProcess, boolean aboveSystem, String annotation) { WindowProcessController parentProcess, boolean aboveSystem, TimeoutRecord timeoutRecord) { mApp = anrProcess; mPid = anrProcess.mPid; mActivityShortComponentName = activityShortComponentName; mParentShortComponentName = parentShortComponentName; mAnnotation = annotation; mTimeoutRecord = timeoutRecord; mAppInfo = aInfo; mParentProcess = parentProcess; mAboveSystem = aboveSystem; Loading @@ -196,7 +201,8 @@ class AnrHelper { void appNotResponding(boolean onlyDumpSelf) { mApp.mErrorState.appNotResponding(mActivityShortComponentName, mAppInfo, mParentShortComponentName, mParentProcess, mAboveSystem, mAnnotation, mParentShortComponentName, mParentProcess, mAboveSystem, mTimeoutRecord, onlyDumpSelf); } } Loading