Merge "Add AnrController to control ANR dialog delay" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a0735849df
@@ -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);
|
||||
}
|
||||
|
||||
29
core/java/android/app/AnrController.java
Normal file
29
core/java/android/app/AnrController.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user