Merge "Add AnrController to control ANR dialog delay" into sc-dev

This commit is contained in:
Zimuzo Ezeozue
2021-02-08 11:12:50 +00:00
committed by Android (Google) Code Review
5 changed files with 91 additions and 1 deletions

View File

@@ -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);
}

View 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);
}

View File

@@ -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) {

View File

@@ -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);
}
}
}

View File

@@ -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,