summaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
author Shuzhen Wang <shuzhenwang@google.com> 2025-03-23 00:10:19 -0700
committer Android Build Coastguard Worker <android-build-coastguard-worker@google.com> 2025-03-25 19:40:53 -0700
commit931522948072130050e18db575f6ec1af1d03aa1 (patch)
treec170cc06c4d1a50c1fd84ec67cceec0368e22d54 /services
parent98f765ed453890cd01865a548db2c56d945c1309 (diff)
Camera: Dump stack traces at cameraserver watchdog
Before cameraserver watchdog, trigger CameraServiceProxy to dump the client, cameraserver, and HAL processes stack traces. Test: Camera CTS; manually force a camera close watchdog Flag: EXEMPT bugfix Bug: 392953059 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4c2f2a6f89180f833b224b1e9558d6581ee54b84) Merged-In: I22aae54f7308ef4d2f82dd5685406585ead5e33b Change-Id: I22aae54f7308ef4d2f82dd5685406585ead5e33b
Diffstat (limited to 'services')
-rw-r--r--services/core/java/com/android/server/camera/CameraServiceProxy.java107
1 files changed, 107 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index c2500c8ae7fa..a38cd229e904 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -57,6 +57,7 @@ import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
import android.hardware.display.DisplayManager;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
+import android.hidl.manager.V1_0.IServiceManager;
import android.media.AudioManager;
import android.nfc.NfcAdapter;
import android.nfc.NfcManager;
@@ -68,6 +69,8 @@ import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
+import android.os.ServiceDebugInfo;
+import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.ShellCommand;
import android.os.SystemClock;
@@ -93,6 +96,7 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
+import com.android.server.am.StackTracesDumpHelper;
import com.android.server.wm.WindowManagerInternal;
import java.io.FileDescriptor;
@@ -103,8 +107,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -895,6 +901,11 @@ public class CameraServiceProxy extends SystemService
}
@Override
+ public void notifyWatchdog(int pid, boolean isNativePid) {
+ dumpStackTraces(pid, isNativePid);
+ }
+
+ @Override
public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
String[] args, ShellCallback callback, ResultReceiver resultReceiver)
throws RemoteException {
@@ -1563,4 +1574,100 @@ public class CameraServiceProxy extends SystemService
return combinationStr.toString();
}
+
+ // Which native services to dump into dropbox's stack traces
+ private static final String[] NATIVE_SERVICES_OF_INTEREST = new String[] {
+ "/system/bin/cameraserver",
+ };
+
+ // Which AIDL interfaces to dump into dropbox's stack traces
+ private static final String[] AIDL_INTERFACE_PREFIXES_OF_INTEREST = new String[] {
+ "android.hardware.camera.provider.ICameraProvider/",
+ };
+
+ // Which HIDL interfaces to dump into dropbox's stack traces
+ public static final List<String> HIDL_INTERFACES_OF_INTEREST = Arrays.asList(
+ "android.hardware.camera.provider@2.4::ICameraProvider"
+ );
+
+ private static void addHidlInterfacesOfInterest(Set<Integer> pids) {
+ try {
+ IServiceManager serviceManager = IServiceManager.getService();
+ ArrayList<IServiceManager.InstanceDebugInfo> dump =
+ serviceManager.debugDump();
+ for (IServiceManager.InstanceDebugInfo info : dump) {
+ if (info.pid == IServiceManager.PidConstant.NO_PID) {
+ continue;
+ }
+
+ if (HIDL_INTERFACES_OF_INTEREST.contains(info.interfaceName)) {
+ pids.add(info.pid);
+ }
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Remote exception while querying HIDL service manager", e);
+ }
+ }
+
+ private static boolean matchesAidlInterfacePrefixes(
+ String[] interfacePrefixes, String interfaceName) {
+ for (String prefix : interfacePrefixes) {
+ if (interfaceName.startsWith(prefix)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static void addAidlInterfacesOfInterest(Set<Integer> pids) {
+ ServiceDebugInfo[] infos = ServiceManager.getServiceDebugInfo();
+ if (infos == null) return;
+
+ for (ServiceDebugInfo info : infos) {
+ if (matchesAidlInterfacePrefixes(
+ AIDL_INTERFACE_PREFIXES_OF_INTEREST, info.name)) {
+ pids.add(info.debugPid);
+ }
+ }
+ }
+
+ /**
+ * Find the camera native Pids to dump stack traces.
+ */
+ private static Set<Integer> getRelevantNativePids() {
+ HashSet<Integer> pids = new HashSet<Integer>();
+ addHidlInterfacesOfInterest(pids);
+ addAidlInterfacesOfInterest(pids);
+
+ int[] nativePids = Process.getPidsForCommands(NATIVE_SERVICES_OF_INTEREST);
+ if (nativePids != null) {
+ for (int i : nativePids) {
+ pids.add(i);
+ }
+ }
+
+ return pids;
+ }
+
+ /**
+ * A helper function to call StackTracesDumpHelper.dumpStackTraces().
+ */
+ private static void dumpStackTraces(int pid, boolean isNativePid) {
+ ArrayList<Integer> dalvikPids = new ArrayList<>();
+ ArrayList<Integer> nativePids = new ArrayList<>();
+ if (isNativePid) {
+ nativePids.add(pid);
+ } else {
+ dalvikPids.add(pid);
+ }
+
+ nativePids.addAll(getRelevantNativePids());
+
+ StackTracesDumpHelper.dumpStackTraces(dalvikPids,
+ /* processCpuTracker= */null, /* lastPids= */null,
+ CompletableFuture.completedFuture(nativePids),
+ /* logExceptionCreatingFile= */null, /* subject= */null,
+ /* criticalEventSection= */null, /* extraHeaders= */ null,
+ Runnable::run, /* latencyTracker= */null);
+ }
}