Android12 支持发送ANR和ACTION_APP_ERROR广播

文章介绍了Android12系统新增的功能,当发生ANR(应用程序无响应)事件时,系统会发送android.intent.action.ANR广播,包含发生ANR的应用包名。同时,在应用崩溃时,会发送Intent.ACTION_APP_ERROR广播,附带应用的Crash信息。更新的代码实现了这些功能,包括发送错误广播和构建错误报告的过程。
摘要由CSDN通过智能技术生成

Android12 支持发送ANR和ACTION_APP_ERROR广播

一、需求说明
  1. 在系统发生ANR事件时发送:android.intent.action.ANR通知上层日志服务。对应的广播内容:

    KeyValueType
    actionandroid.intent.action.ANR
    packageName发生ANR的应用包名String
  2. 在有应用奔溃时发送Intent.ACTION_APP_ERROR广播通知上层日志服务。对应的广播内容:

    KeyValueType
    actionIntent.ACTION_APP_ERROR
    Intent.EXTRA_BUG_REPORT应用的Crash信息ApplicationErrorReport.CrashInfo
二、实现代码
diff --git a/frameworks/base/services/core/java/com/android/server/am/AppErrors.java b/frameworks/base/services/core/java/com/android/server/am/AppErrors.java
index 8debf9d7a18..2c7fa682203 100644
--- a/frameworks/base/services/core/java/com/android/server/am/AppErrors.java
+++ b/frameworks/base/services/core/java/com/android/server/am/AppErrors.java
@@ -70,6 +70,10 @@ import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -70,6 +70,10 @@ import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.Collections;
 import java.util.List;
+import android.content.Intent;
+import android.app.AppOpsManager;
+import android.os.UserHandle;
+import static android.app.AppOpsManager.OP_NONE;
 
 /**
  * Controls error conditions in applications.
@@ -564,6 +568,9 @@ class AppErrors {
 
     private void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo,
             int callingPid, int callingUid) {
         long timeMillis = System.currentTimeMillis();
         String shortMsg = crashInfo.exceptionClassName;
         String longMsg = crashInfo.exceptionMessage;
@@ -629,7 +636,9 @@ class AppErrors {
             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) {
                 return;
             }
-
+            
+            CrashMonitor.sendCrashBroadcast(mContext,r,timeMillis,crashInfo);
             final Message msg = Message.obtain();
             msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG;
 
@@ -1083,6 +1092,18 @@ class AppErrors {
             if (!proc.isPersistent()) {
                 packageList = proc.getPackageListWithVersionCode();
             }
+
+            Intent intent = new Intent("android.intent.action.ANR");
+            intent.putExtra("packageName", proc.info.packageName);
+            if (!mService.mProcessesReady) {
+                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                        | Intent.FLAG_RECEIVER_FOREGROUND);
+            }
+            mService.broadcastIntentLocked(null, null, null,intent, null, null, 0, null, null, null,null, AppOpsManager.OP_NONE,
+                    null, false, false, MY_PID, Process.SYSTEM_UID, Binder.getCallingUid(),
+                        Binder.getCallingPid(), UserHandle.USER_ALL);
+
             if (errState.getDialogController().hasAnrDialogs()) {
                 Slog.e(TAG, "App already has anr dialog: " + proc);
                 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
diff --git a/frameworks/base/services/core/java/com/android/server/am/CrashMonitor.java b/frameworks/base/services/core/java/com/android/server/am/CrashMonitor.java
new file mode 100644
index 00000000000..38d76eb273a
--- /dev/null
+++ b/frameworks/base/services/core/java/com/android/server/am/CrashMonitor.java
@@ -0,0 +1,47 @@
+package com.android.server.am;
+
+import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
+
+import android.os.UserHandle;
+import android.app.ApplicationErrorReport;
+import android.content.Context;
+import android.content.Intent;
+
+class CrashMonitor {
+    private static final String TAG = "CrashMonitor";
+    private static Intent getCrashIntent(ProcessRecord r,
+            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
+        ApplicationErrorReport report = new ApplicationErrorReport();
+        report.packageName = r.info.packageName;
+        if (r.mErrorState.getErrorReportReceiver() != null) {
+            report.installerPackageName = r.mErrorState.getErrorReportReceiver().getPackageName();
+        }
+        report.processName = r.processName;
+        report.time = timeMillis;
+        report.systemApp = (r.info.flags & FLAG_SYSTEM) != 0;
+        if (r.mErrorState.isCrashing() || r.mErrorState.isForceCrashReport()) {
+            report.type = ApplicationErrorReport.TYPE_CRASH;
+            report.crashInfo = crashInfo;
+        } else if(r.mErrorState.isNotResponding()) {
+            report.type = ApplicationErrorReport.TYPE_ANR;
+            report.anrInfo = new ApplicationErrorReport.AnrInfo();
+            report.anrInfo.activity = r.mErrorState.getNotRespondingReport().tag;
+            report.anrInfo.cause = r.mErrorState.getNotRespondingReport().shortMsg;
+            report.anrInfo.info = r.mErrorState.getNotRespondingReport().longMsg;
+        }
+
+        Intent result = new Intent(Intent.ACTION_APP_ERROR);
+        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
+        return result;
+    }
+
+
+    public static void sendCrashBroadcast(Context context, ProcessRecord r,
+            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
+        Intent intent = getCrashIntent(r, timeMillis, crashInfo);
+        context.sendBroadcastAsUser(intent, UserHandle.ALL);
+    }
+}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值