Loading core/java/android/hardware/camera2/CameraManager.java +65 −10 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.os.SystemProperties; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; Loading @@ -80,6 +81,7 @@ import com.android.internal.camera.flags.Flags; import com.android.internal.util.ArrayUtils; import java.lang.ref.WeakReference; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; Loading Loading @@ -2157,6 +2159,12 @@ public final class CameraManager { private final Set<Set<DeviceCameraInfo>> mConcurrentCameraIdCombinations = new ArraySet<>(); // Diagnostic messages for ArrayIndexOutOfBoundsException in extractCameraIdListLocked // b/367649718 private static final int DEVICE_STATUS_ARRAY_SIZE = 10; private final ArrayDeque<String> mDeviceStatusHistory = new ArrayDeque<>(DEVICE_STATUS_ARRAY_SIZE); // Registered availability callbacks and their executors private final ArrayMap<AvailabilityCallback, Executor> mCallbackMap = new ArrayMap<>(); Loading Loading @@ -2274,6 +2282,10 @@ public final class CameraManager { } try { addDeviceStatusHistoryLocked(TextUtils.formatSimple( "connectCameraServiceLocked(E): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); CameraStatus[] cameraStatuses = cameraService.addListener(this); for (CameraStatus cameraStatus : cameraStatuses) { DeviceCameraInfo info = new DeviceCameraInfo(cameraStatus.cameraId, Loading @@ -2296,6 +2308,10 @@ public final class CameraManager { } } mCameraService = cameraService; addDeviceStatusHistoryLocked(TextUtils.formatSimple( "connectCameraServiceLocked(X): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); } catch (ServiceSpecificException e) { // Unexpected failure throw new IllegalStateException("Failed to register a camera service listener", e); Loading Loading @@ -2349,6 +2365,10 @@ public final class CameraManager { } private String[] extractCameraIdListLocked(int deviceId, int devicePolicy) { addDeviceStatusHistoryLocked(TextUtils.formatSimple( "extractCameraIdListLocked(E): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); try { List<String> cameraIds = new ArrayList<>(); for (int i = 0; i < mDeviceStatus.size(); i++) { int status = mDeviceStatus.valueAt(i); Loading @@ -2361,6 +2381,12 @@ public final class CameraManager { cameraIds.add(info.mCameraId); } return cameraIds.toArray(new String[0]); } catch (ArrayIndexOutOfBoundsException e) { String message = e.getMessage(); String messageWithHistory = message + ": {" + String.join(" -> ", mDeviceStatusHistory) + "}"; throw new ArrayIndexOutOfBoundsException(messageWithHistory); } } private Set<Set<String>> extractConcurrentCameraIdListLocked(int deviceId, Loading Loading @@ -2488,6 +2514,10 @@ public final class CameraManager { synchronized (mLock) { connectCameraServiceLocked(); try { addDeviceStatusHistoryLocked(TextUtils.formatSimple( "getCameraIdListNoLazy(E): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); // The purpose of the addListener, removeListener pair here is to get a fresh // list of camera ids from cameraserver. We do this since for in test processes, // changes can happen w.r.t non-changeable permissions (eg: SYSTEM_CAMERA Loading Loading @@ -2521,6 +2551,9 @@ public final class CameraManager { onStatusChangedLocked(ICameraServiceListener.STATUS_NOT_PRESENT, info); mTorchStatus.remove(info); } addDeviceStatusHistoryLocked(TextUtils.formatSimple( "getCameraIdListNoLazy(X): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); } catch (ServiceSpecificException e) { // Unexpected failure throw new IllegalStateException("Failed to register a camera service listener", Loading Loading @@ -3209,7 +3242,13 @@ public final class CameraManager { public void onStatusChanged(int status, String cameraId, int deviceId) throws RemoteException { synchronized(mLock) { addDeviceStatusHistoryLocked( TextUtils.formatSimple("onStatusChanged(E): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); onStatusChangedLocked(status, new DeviceCameraInfo(cameraId, deviceId)); addDeviceStatusHistoryLocked( TextUtils.formatSimple("onStatusChanged(X): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); } } Loading Loading @@ -3352,6 +3391,10 @@ public final class CameraManager { */ public void binderDied() { synchronized(mLock) { addDeviceStatusHistoryLocked( TextUtils.formatSimple("binderDied(E): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); // Only do this once per service death if (mCameraService == null) return; Loading Loading @@ -3380,6 +3423,10 @@ public final class CameraManager { mConcurrentCameraIdCombinations.clear(); scheduleCameraServiceReconnectionLocked(); addDeviceStatusHistoryLocked( TextUtils.formatSimple("binderDied(X): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); } } Loading Loading @@ -3409,5 +3456,13 @@ public final class CameraManager { return Objects.hash(mCameraId, mDeviceId); } } private void addDeviceStatusHistoryLocked(String log) { if (mDeviceStatusHistory.size() == DEVICE_STATUS_ARRAY_SIZE) { mDeviceStatusHistory.removeFirst(); } mDeviceStatusHistory.addLast(log); } } // CameraManagerGlobal } // CameraManager Loading
core/java/android/hardware/camera2/CameraManager.java +65 −10 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.os.SystemProperties; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; Loading @@ -80,6 +81,7 @@ import com.android.internal.camera.flags.Flags; import com.android.internal.util.ArrayUtils; import java.lang.ref.WeakReference; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; Loading Loading @@ -2157,6 +2159,12 @@ public final class CameraManager { private final Set<Set<DeviceCameraInfo>> mConcurrentCameraIdCombinations = new ArraySet<>(); // Diagnostic messages for ArrayIndexOutOfBoundsException in extractCameraIdListLocked // b/367649718 private static final int DEVICE_STATUS_ARRAY_SIZE = 10; private final ArrayDeque<String> mDeviceStatusHistory = new ArrayDeque<>(DEVICE_STATUS_ARRAY_SIZE); // Registered availability callbacks and their executors private final ArrayMap<AvailabilityCallback, Executor> mCallbackMap = new ArrayMap<>(); Loading Loading @@ -2274,6 +2282,10 @@ public final class CameraManager { } try { addDeviceStatusHistoryLocked(TextUtils.formatSimple( "connectCameraServiceLocked(E): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); CameraStatus[] cameraStatuses = cameraService.addListener(this); for (CameraStatus cameraStatus : cameraStatuses) { DeviceCameraInfo info = new DeviceCameraInfo(cameraStatus.cameraId, Loading @@ -2296,6 +2308,10 @@ public final class CameraManager { } } mCameraService = cameraService; addDeviceStatusHistoryLocked(TextUtils.formatSimple( "connectCameraServiceLocked(X): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); } catch (ServiceSpecificException e) { // Unexpected failure throw new IllegalStateException("Failed to register a camera service listener", e); Loading Loading @@ -2349,6 +2365,10 @@ public final class CameraManager { } private String[] extractCameraIdListLocked(int deviceId, int devicePolicy) { addDeviceStatusHistoryLocked(TextUtils.formatSimple( "extractCameraIdListLocked(E): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); try { List<String> cameraIds = new ArrayList<>(); for (int i = 0; i < mDeviceStatus.size(); i++) { int status = mDeviceStatus.valueAt(i); Loading @@ -2361,6 +2381,12 @@ public final class CameraManager { cameraIds.add(info.mCameraId); } return cameraIds.toArray(new String[0]); } catch (ArrayIndexOutOfBoundsException e) { String message = e.getMessage(); String messageWithHistory = message + ": {" + String.join(" -> ", mDeviceStatusHistory) + "}"; throw new ArrayIndexOutOfBoundsException(messageWithHistory); } } private Set<Set<String>> extractConcurrentCameraIdListLocked(int deviceId, Loading Loading @@ -2488,6 +2514,10 @@ public final class CameraManager { synchronized (mLock) { connectCameraServiceLocked(); try { addDeviceStatusHistoryLocked(TextUtils.formatSimple( "getCameraIdListNoLazy(E): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); // The purpose of the addListener, removeListener pair here is to get a fresh // list of camera ids from cameraserver. We do this since for in test processes, // changes can happen w.r.t non-changeable permissions (eg: SYSTEM_CAMERA Loading Loading @@ -2521,6 +2551,9 @@ public final class CameraManager { onStatusChangedLocked(ICameraServiceListener.STATUS_NOT_PRESENT, info); mTorchStatus.remove(info); } addDeviceStatusHistoryLocked(TextUtils.formatSimple( "getCameraIdListNoLazy(X): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); } catch (ServiceSpecificException e) { // Unexpected failure throw new IllegalStateException("Failed to register a camera service listener", Loading Loading @@ -3209,7 +3242,13 @@ public final class CameraManager { public void onStatusChanged(int status, String cameraId, int deviceId) throws RemoteException { synchronized(mLock) { addDeviceStatusHistoryLocked( TextUtils.formatSimple("onStatusChanged(E): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); onStatusChangedLocked(status, new DeviceCameraInfo(cameraId, deviceId)); addDeviceStatusHistoryLocked( TextUtils.formatSimple("onStatusChanged(X): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); } } Loading Loading @@ -3352,6 +3391,10 @@ public final class CameraManager { */ public void binderDied() { synchronized(mLock) { addDeviceStatusHistoryLocked( TextUtils.formatSimple("binderDied(E): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); // Only do this once per service death if (mCameraService == null) return; Loading Loading @@ -3380,6 +3423,10 @@ public final class CameraManager { mConcurrentCameraIdCombinations.clear(); scheduleCameraServiceReconnectionLocked(); addDeviceStatusHistoryLocked( TextUtils.formatSimple("binderDied(X): tid(%d): mDeviceStatus size %d", Thread.currentThread().getId(), mDeviceStatus.size())); } } Loading Loading @@ -3409,5 +3456,13 @@ public final class CameraManager { return Objects.hash(mCameraId, mDeviceId); } } private void addDeviceStatusHistoryLocked(String log) { if (mDeviceStatusHistory.size() == DEVICE_STATUS_ARRAY_SIZE) { mDeviceStatusHistory.removeFirst(); } mDeviceStatusHistory.addLast(log); } } // CameraManagerGlobal } // CameraManager