Loading core/java/android/app/ActivityManagerInternal.java +6 −0 Original line number Diff line number Diff line Loading @@ -538,4 +538,10 @@ public abstract class ActivityManagerInternal { * @return mBootTimeTempAllowlistDuration of ActivityManagerConstants. */ public abstract long getBootTimeTempAllowListDuration(); /** Register an {@link AnrController} to control the ANR dialog behavior */ public abstract void registerAnrController(AnrController controller); /** Unregister an {@link AnrController} */ public abstract void unregisterAnrController(AnrController controller); } core/java/android/app/AnrController.java 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 android.app; /** * Interface to control the ANR dialog within the activity manager * {@hide} */ public interface AnrController { /** * Returns the delay in milliseconds for an ANR dialog that is about to be shown for * {@code packageName}. */ long getAnrDelayMillis(String packageName, int uid); } services/core/java/com/android/server/am/ActivityManagerService.java +11 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,7 @@ import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManagerInternal; import android.app.ActivityTaskManager.RootTaskInfo; import android.app.ActivityThread; import android.app.AnrController; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.AppOpsManagerInternal.CheckOpsDelegate; Loading Loading @@ -15861,6 +15862,16 @@ public class ActivityManagerService extends IActivityManager.Stub // PackageManagerService. return mConstants.mBootTimeTempAllowlistDuration; } @Override public void registerAnrController(AnrController controller) { mActivityTaskManager.registerAnrController(controller); } @Override public void unregisterAnrController(AnrController controller) { mActivityTaskManager.unregisterAnrController(controller); } } long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { services/core/java/com/android/server/am/ProcessErrorStateRecord.java +9 −1 Original line number Diff line number Diff line Loading @@ -416,6 +416,14 @@ class ProcessErrorStateRecord { return; } // Retrieve max ANR delay from AnrControllers without the mService lock since the // controllers might in turn call into apps long anrDialogDelayMs = mService.mActivityTaskManager.getMaxAnrDelayMillis(aInfo); if (aInfo != null && aInfo.packageName != null && anrDialogDelayMs > 0) { Slog.i(TAG, "Delaying ANR dialog for " + aInfo.packageName + " for " + anrDialogDelayMs + "ms"); } synchronized (mService) { // mBatteryStatsService can be null if the AMS is constructed with injector only. This // will only happen in tests. Loading Loading @@ -447,7 +455,7 @@ class ProcessErrorStateRecord { msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG; msg.obj = new AppNotRespondingDialog.Data(mApp, aInfo, aboveSystem); mService.mUiHandler.sendMessage(msg); mService.mUiHandler.sendMessageDelayed(msg, anrDialogDelayMs); } } } Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +36 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,7 @@ import android.app.ActivityTaskManager; import android.app.ActivityTaskManager.RootTaskInfo; import android.app.ActivityThread; import android.app.AlertDialog; import android.app.AnrController; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.Dialog; Loading Loading @@ -494,6 +495,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ private volatile long mLastStopAppSwitchesTime; private final List<AnrController> mAnrController = new ArrayList<>(); IActivityController mController = null; boolean mControllerIsAMonkey = false; Loading Loading @@ -2058,6 +2060,40 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return mAppSwitchesAllowed; } /** Register an {@link AnrController} to control the ANR dialog behavior */ public void registerAnrController(AnrController controller) { synchronized (mGlobalLock) { mAnrController.add(controller); } } /** Unregister an {@link AnrController} */ public void unregisterAnrController(AnrController controller) { synchronized (mGlobalLock) { mAnrController.remove(controller); } } /** @return the max ANR delay from all registered {@link AnrController} instances */ public long getMaxAnrDelayMillis(ApplicationInfo info) { if (info == null || info.packageName == null) { return 0; } final ArrayList<AnrController> controllers; synchronized (mGlobalLock) { controllers = new ArrayList<>(mAnrController); } final String packageName = info.packageName; long maxDelayMs = 0; for (AnrController controller : controllers) { maxDelayMs = Math.max(maxDelayMs, controller.getAnrDelayMillis(packageName, info.uid)); } maxDelayMs = Math.max(maxDelayMs, 0); return maxDelayMs; } @Override public void setActivityController(IActivityController controller, boolean imAMonkey) { mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, Loading Loading
core/java/android/app/ActivityManagerInternal.java +6 −0 Original line number Diff line number Diff line Loading @@ -538,4 +538,10 @@ public abstract class ActivityManagerInternal { * @return mBootTimeTempAllowlistDuration of ActivityManagerConstants. */ public abstract long getBootTimeTempAllowListDuration(); /** Register an {@link AnrController} to control the ANR dialog behavior */ public abstract void registerAnrController(AnrController controller); /** Unregister an {@link AnrController} */ public abstract void unregisterAnrController(AnrController controller); }
core/java/android/app/AnrController.java 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 android.app; /** * Interface to control the ANR dialog within the activity manager * {@hide} */ public interface AnrController { /** * Returns the delay in milliseconds for an ANR dialog that is about to be shown for * {@code packageName}. */ long getAnrDelayMillis(String packageName, int uid); }
services/core/java/com/android/server/am/ActivityManagerService.java +11 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,7 @@ import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManagerInternal; import android.app.ActivityTaskManager.RootTaskInfo; import android.app.ActivityThread; import android.app.AnrController; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.AppOpsManagerInternal.CheckOpsDelegate; Loading Loading @@ -15861,6 +15862,16 @@ public class ActivityManagerService extends IActivityManager.Stub // PackageManagerService. return mConstants.mBootTimeTempAllowlistDuration; } @Override public void registerAnrController(AnrController controller) { mActivityTaskManager.registerAnrController(controller); } @Override public void unregisterAnrController(AnrController controller) { mActivityTaskManager.unregisterAnrController(controller); } } long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
services/core/java/com/android/server/am/ProcessErrorStateRecord.java +9 −1 Original line number Diff line number Diff line Loading @@ -416,6 +416,14 @@ class ProcessErrorStateRecord { return; } // Retrieve max ANR delay from AnrControllers without the mService lock since the // controllers might in turn call into apps long anrDialogDelayMs = mService.mActivityTaskManager.getMaxAnrDelayMillis(aInfo); if (aInfo != null && aInfo.packageName != null && anrDialogDelayMs > 0) { Slog.i(TAG, "Delaying ANR dialog for " + aInfo.packageName + " for " + anrDialogDelayMs + "ms"); } synchronized (mService) { // mBatteryStatsService can be null if the AMS is constructed with injector only. This // will only happen in tests. Loading Loading @@ -447,7 +455,7 @@ class ProcessErrorStateRecord { msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG; msg.obj = new AppNotRespondingDialog.Data(mApp, aInfo, aboveSystem); mService.mUiHandler.sendMessage(msg); mService.mUiHandler.sendMessageDelayed(msg, anrDialogDelayMs); } } } Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +36 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,7 @@ import android.app.ActivityTaskManager; import android.app.ActivityTaskManager.RootTaskInfo; import android.app.ActivityThread; import android.app.AlertDialog; import android.app.AnrController; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.Dialog; Loading Loading @@ -494,6 +495,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ private volatile long mLastStopAppSwitchesTime; private final List<AnrController> mAnrController = new ArrayList<>(); IActivityController mController = null; boolean mControllerIsAMonkey = false; Loading Loading @@ -2058,6 +2060,40 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return mAppSwitchesAllowed; } /** Register an {@link AnrController} to control the ANR dialog behavior */ public void registerAnrController(AnrController controller) { synchronized (mGlobalLock) { mAnrController.add(controller); } } /** Unregister an {@link AnrController} */ public void unregisterAnrController(AnrController controller) { synchronized (mGlobalLock) { mAnrController.remove(controller); } } /** @return the max ANR delay from all registered {@link AnrController} instances */ public long getMaxAnrDelayMillis(ApplicationInfo info) { if (info == null || info.packageName == null) { return 0; } final ArrayList<AnrController> controllers; synchronized (mGlobalLock) { controllers = new ArrayList<>(mAnrController); } final String packageName = info.packageName; long maxDelayMs = 0; for (AnrController controller : controllers) { maxDelayMs = Math.max(maxDelayMs, controller.getAnrDelayMillis(packageName, info.uid)); } maxDelayMs = Math.max(maxDelayMs, 0); return maxDelayMs; } @Override public void setActivityController(IActivityController controller, boolean imAMonkey) { mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, Loading