diff options
author | 2025-03-23 00:10:19 -0700 | |
---|---|---|
committer | 2025-03-25 19:40:53 -0700 | |
commit | 931522948072130050e18db575f6ec1af1d03aa1 (patch) | |
tree | c170cc06c4d1a50c1fd84ec67cceec0368e22d54 /services | |
parent | 98f765ed453890cd01865a548db2c56d945c1309 (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.java | 107 |
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); + } } |