Loading core/java/android/app/AnrController.java +23 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,29 @@ package android.app; public interface AnrController { /** * Returns the delay in milliseconds for an ANR dialog that is about to be shown for * {@code packageName}. * {@code packageName} with {@code uid}. * * Implementations should only return a positive value if they actually expect the * {@code packageName} to be delayed due to them. * If there are multiple controllers registered, the controller with the max delay will * be selected and will receive an {@link #onAnrDelayStarted} callback at the start of the * delay and an {@link #onAnrDelayCompleted} at the end of the delay. */ long getAnrDelayMillis(String packageName, int uid); /** * Notifies the controller at the start of the ANR dialog delay for {@code packageName} with * {@code uid}. The controller can decide to show a progress UI after this notification. */ void onAnrDelayStarted(String packageName, int uid); /** * Notifies the controller at the end of the ANR dialog delay for {@code packageName} with * {@code uid}. * * @return whether the ANR dialog should be shown or cancelled. {@code true} if the * ANR dialog should be shown, {@code false} if it should be cancelled. */ boolean onAnrDelayCompleted(String packageName, int uid); } services/core/java/com/android/server/StorageManagerService.java +24 −8 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.AnrController; import android.app.AppOpsManager; import android.app.IActivityManager; import android.app.KeyguardManager; Loading Loading @@ -938,14 +939,29 @@ class StorageManagerService extends IStorageManager.Stub if (transcodeEnabled) { LocalServices.getService(ActivityManagerInternal.class) .registerAnrController((packageName, uid) -> { try { return mStorageSessionController.getAnrDelayMillis(packageName, uid); } catch (ExternalStorageServiceException e) { Log.e(TAG, "Failed to get ANR delay for " + packageName, e); return 0; .registerAnrController(new ExternalStorageServiceAnrController()); } }); } // TODO(b/170486601): Check transcoding status based on events pushed from the MediaProvider private class ExternalStorageServiceAnrController implements AnrController { @Override public long getAnrDelayMillis(String packageName, int uid) { int delay = SystemProperties.getInt("sys.fuse.transcode_anr_delay", 0); Log.d(TAG, "getAnrDelayMillis: " + packageName + ". Delaying for " + delay + "ms"); return delay; } @Override public void onAnrDelayStarted(String packageName, int uid) { Log.d(TAG, "onAnrDelayStarted: " + packageName); } @Override public boolean onAnrDelayCompleted(String packageName, int uid) { boolean show = SystemProperties.getBoolean("sys.fuse.transcode_anr_dialog_show", true); Log.d(TAG, "onAnrDelayCompleted: " + packageName + ". Show: " + show); return show; } } Loading services/core/java/com/android/server/am/AppErrors.java +21 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_N import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.AnrController; import android.app.ApplicationErrorReport; import android.app.ApplicationExitInfo; import android.content.ActivityNotFoundException; Loading Loading @@ -1058,7 +1059,26 @@ class AppErrors { Settings.Secure.ANR_SHOW_BACKGROUND, 0, mService.mUserController.getCurrentUserId()) != 0; if (mService.mAtmInternal.canShowErrorDialogs() || showBackground) { AnrController anrController = errState.getDialogController().getAnrController(); if (anrController == null) { errState.getDialogController().showAnrDialogs(data); } else { String packageName = proc.info.packageName; int uid = proc.info.uid; boolean showDialog = anrController.onAnrDelayCompleted(packageName, uid); if (showDialog) { Slog.d(TAG, "ANR delay completed. Showing ANR dialog for package: " + packageName); errState.getDialogController().showAnrDialogs(data); } else { Slog.d(TAG, "ANR delay completed. Cancelling ANR dialog for package: " + packageName); errState.setNotResponding(false); errState.setNotRespondingReport(null); errState.getDialogController().clearAnrDialogs(); } } } else { MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, AppNotRespondingDialog.CANT_SHOW); Loading services/core/java/com/android/server/am/ErrorDialogController.java +21 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.am; import android.annotation.Nullable; import android.app.AnrController; import android.app.Dialog; import android.content.Context; Loading Loading @@ -57,6 +59,13 @@ final class ErrorDialogController { @GuardedBy("mProcLock") private AppWaitingForDebuggerDialog mWaitDialog; /** * ANR dialog controller */ @GuardedBy("mProcLock") @Nullable private AnrController mAnrController; @GuardedBy("mProcLock") boolean hasCrashDialogs() { return mCrashDialogs != null; Loading Loading @@ -118,6 +127,7 @@ final class ErrorDialogController { } forAllDialogs(mAnrDialogs, Dialog::dismiss); mAnrDialogs = null; mAnrController = null; } @GuardedBy("mProcLock") Loading Loading @@ -220,6 +230,17 @@ final class ErrorDialogController { }); } @GuardedBy("mProcLock") @Nullable AnrController getAnrController() { return mAnrController; } @GuardedBy("mProcLock") void setAnrController(AnrController controller) { mAnrController = controller; } /** * Helper function to collect contexts from crashed app located displays. * Loading services/core/java/com/android/server/am/ProcessErrorStateRecord.java +12 −4 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.server.am.ActivityManagerService.MY_PID; import static com.android.server.am.ProcessRecord.TAG; import android.app.ActivityManager; import android.app.AnrController; import android.app.ApplicationErrorReport; import android.app.ApplicationExitInfo; import android.content.ComponentName; Loading Loading @@ -418,10 +419,16 @@ class ProcessErrorStateRecord { // 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"); AnrController anrController = mService.mActivityTaskManager.getAnrController(aInfo); long anrDialogDelayMs = 0; if (anrController != null) { String packageName = aInfo.packageName; int uid = aInfo.uid; anrDialogDelayMs = anrController.getAnrDelayMillis(packageName, uid); // Might execute an async binder call to a system app to show an interim // ANR progress UI anrController.onAnrDelayStarted(packageName, uid); Slog.i(TAG, "ANR delay of " + anrDialogDelayMs + "ms started for " + packageName); } synchronized (mService) { Loading @@ -440,6 +447,7 @@ class ProcessErrorStateRecord { // Set the app's notResponding state, and look up the errorReportReceiver makeAppNotRespondingLSP(activityShortComponentName, annotation != null ? "ANR " + annotation : "ANR", info.toString()); mDialogController.setAnrController(anrController); } // Notify package manager service to possibly update package state Loading Loading
core/java/android/app/AnrController.java +23 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,29 @@ package android.app; public interface AnrController { /** * Returns the delay in milliseconds for an ANR dialog that is about to be shown for * {@code packageName}. * {@code packageName} with {@code uid}. * * Implementations should only return a positive value if they actually expect the * {@code packageName} to be delayed due to them. * If there are multiple controllers registered, the controller with the max delay will * be selected and will receive an {@link #onAnrDelayStarted} callback at the start of the * delay and an {@link #onAnrDelayCompleted} at the end of the delay. */ long getAnrDelayMillis(String packageName, int uid); /** * Notifies the controller at the start of the ANR dialog delay for {@code packageName} with * {@code uid}. The controller can decide to show a progress UI after this notification. */ void onAnrDelayStarted(String packageName, int uid); /** * Notifies the controller at the end of the ANR dialog delay for {@code packageName} with * {@code uid}. * * @return whether the ANR dialog should be shown or cancelled. {@code true} if the * ANR dialog should be shown, {@code false} if it should be cancelled. */ boolean onAnrDelayCompleted(String packageName, int uid); }
services/core/java/com/android/server/StorageManagerService.java +24 −8 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.AnrController; import android.app.AppOpsManager; import android.app.IActivityManager; import android.app.KeyguardManager; Loading Loading @@ -938,14 +939,29 @@ class StorageManagerService extends IStorageManager.Stub if (transcodeEnabled) { LocalServices.getService(ActivityManagerInternal.class) .registerAnrController((packageName, uid) -> { try { return mStorageSessionController.getAnrDelayMillis(packageName, uid); } catch (ExternalStorageServiceException e) { Log.e(TAG, "Failed to get ANR delay for " + packageName, e); return 0; .registerAnrController(new ExternalStorageServiceAnrController()); } }); } // TODO(b/170486601): Check transcoding status based on events pushed from the MediaProvider private class ExternalStorageServiceAnrController implements AnrController { @Override public long getAnrDelayMillis(String packageName, int uid) { int delay = SystemProperties.getInt("sys.fuse.transcode_anr_delay", 0); Log.d(TAG, "getAnrDelayMillis: " + packageName + ". Delaying for " + delay + "ms"); return delay; } @Override public void onAnrDelayStarted(String packageName, int uid) { Log.d(TAG, "onAnrDelayStarted: " + packageName); } @Override public boolean onAnrDelayCompleted(String packageName, int uid) { boolean show = SystemProperties.getBoolean("sys.fuse.transcode_anr_dialog_show", true); Log.d(TAG, "onAnrDelayCompleted: " + packageName + ". Show: " + show); return show; } } Loading
services/core/java/com/android/server/am/AppErrors.java +21 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_N import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.AnrController; import android.app.ApplicationErrorReport; import android.app.ApplicationExitInfo; import android.content.ActivityNotFoundException; Loading Loading @@ -1058,7 +1059,26 @@ class AppErrors { Settings.Secure.ANR_SHOW_BACKGROUND, 0, mService.mUserController.getCurrentUserId()) != 0; if (mService.mAtmInternal.canShowErrorDialogs() || showBackground) { AnrController anrController = errState.getDialogController().getAnrController(); if (anrController == null) { errState.getDialogController().showAnrDialogs(data); } else { String packageName = proc.info.packageName; int uid = proc.info.uid; boolean showDialog = anrController.onAnrDelayCompleted(packageName, uid); if (showDialog) { Slog.d(TAG, "ANR delay completed. Showing ANR dialog for package: " + packageName); errState.getDialogController().showAnrDialogs(data); } else { Slog.d(TAG, "ANR delay completed. Cancelling ANR dialog for package: " + packageName); errState.setNotResponding(false); errState.setNotRespondingReport(null); errState.getDialogController().clearAnrDialogs(); } } } else { MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, AppNotRespondingDialog.CANT_SHOW); Loading
services/core/java/com/android/server/am/ErrorDialogController.java +21 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.am; import android.annotation.Nullable; import android.app.AnrController; import android.app.Dialog; import android.content.Context; Loading Loading @@ -57,6 +59,13 @@ final class ErrorDialogController { @GuardedBy("mProcLock") private AppWaitingForDebuggerDialog mWaitDialog; /** * ANR dialog controller */ @GuardedBy("mProcLock") @Nullable private AnrController mAnrController; @GuardedBy("mProcLock") boolean hasCrashDialogs() { return mCrashDialogs != null; Loading Loading @@ -118,6 +127,7 @@ final class ErrorDialogController { } forAllDialogs(mAnrDialogs, Dialog::dismiss); mAnrDialogs = null; mAnrController = null; } @GuardedBy("mProcLock") Loading Loading @@ -220,6 +230,17 @@ final class ErrorDialogController { }); } @GuardedBy("mProcLock") @Nullable AnrController getAnrController() { return mAnrController; } @GuardedBy("mProcLock") void setAnrController(AnrController controller) { mAnrController = controller; } /** * Helper function to collect contexts from crashed app located displays. * Loading
services/core/java/com/android/server/am/ProcessErrorStateRecord.java +12 −4 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.server.am.ActivityManagerService.MY_PID; import static com.android.server.am.ProcessRecord.TAG; import android.app.ActivityManager; import android.app.AnrController; import android.app.ApplicationErrorReport; import android.app.ApplicationExitInfo; import android.content.ComponentName; Loading Loading @@ -418,10 +419,16 @@ class ProcessErrorStateRecord { // 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"); AnrController anrController = mService.mActivityTaskManager.getAnrController(aInfo); long anrDialogDelayMs = 0; if (anrController != null) { String packageName = aInfo.packageName; int uid = aInfo.uid; anrDialogDelayMs = anrController.getAnrDelayMillis(packageName, uid); // Might execute an async binder call to a system app to show an interim // ANR progress UI anrController.onAnrDelayStarted(packageName, uid); Slog.i(TAG, "ANR delay of " + anrDialogDelayMs + "ms started for " + packageName); } synchronized (mService) { Loading @@ -440,6 +447,7 @@ class ProcessErrorStateRecord { // Set the app's notResponding state, and look up the errorReportReceiver makeAppNotRespondingLSP(activityShortComponentName, annotation != null ? "ANR " + annotation : "ANR", info.toString()); mDialogController.setAnrController(anrController); } // Notify package manager service to possibly update package state Loading