Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
QtCameraAvailabilityListener.java
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4package org.qtproject.qt.android.multimedia;
5
6import android.app.Activity;
7import android.hardware.camera2.CameraManager;
8import android.os.Handler;
9import android.util.Log;
10
11import org.qtproject.qt.android.UsedFromNativeCode;
12
13import java.util.concurrent.CountDownLatch;
14
15// This class implements the camera-device availability callbacks for Android CameraManager.
16// This class should only be used with QAndroidVideoDevices.
17// In the future it might make sense to a central QtVideoDeviceManager that everything references,
18// and to build this class' functionality into that.
19class QtCameraAvailabilityListener extends CameraManager.AvailabilityCallback {
20
21 static final String LOG_TAG = "QtCameraAvailabilityListener";
22
23 CameraManager mCameraManager = null;
24 // Holds the pointer to the QAndroidVideoDevices instance.
25 long mVideoDevicesNativePtr = 0;
26
27 Handler mAvailabilityCallbackHandler = null;
28
29 @UsedFromNativeCode
30 QtCameraAvailabilityListener(Activity activity, long videoDevicesNativePtr) {
31 mCameraManager = (CameraManager)activity.getSystemService(Activity.CAMERA_SERVICE);
32 mVideoDevicesNativePtr = videoDevicesNativePtr;
33
34 // We use the Android main UI thread for receiving callbacks.
35 mAvailabilityCallbackHandler = new Handler(activity.getMainLooper());
36
37 // TODO: This will call C++ updateNativeVideoDevices() for each currently available
38 // camera when registered, possibly leading to us enumerating video-devices unncessarily
39 // often, and also signalling QMediaDevices::videoInputsChanged more than necessary.
40 // This should generally not be a problem assuming the multimedia backend is initialized
41 // before user-code.
42 //
43 // A future solution could be to post a job on the handler and wait for it, or
44 // to dynamically add/remove devices from an internal list which is then returned in
45 // QAndroidVideoDevices::findVideoInputs()
46 mCameraManager.registerAvailabilityCallback(this, mAvailabilityCallbackHandler);
47 }
48
49 @UsedFromNativeCode
50 void cleanup() {
51 // Perform cleanup on the same thread that we receive callbacks, then wait for cleanup job
52 // to finish. No need for locks.
53 final CountDownLatch latch = new CountDownLatch(1);
54 final boolean postSuccess = mAvailabilityCallbackHandler.post(() -> {
55 mCameraManager.unregisterAvailabilityCallback(this);
56 mVideoDevicesNativePtr = 0;
57 latch.countDown(); // Signal that the task is done
58 });
59
60 if (!postSuccess) {
61 Log.w(
62 LOG_TAG,
63 "Unable to post cleanup job to corresponding thread during " +
64 "QAndroidVideoDevices cleanup.");
65 return;
66 }
67
68 try {
69 latch.await();
70 } catch (InterruptedException e) {
71 Log.w(
72 LOG_TAG,
73 "Unable to wait for cleanup job to finish on corresponding thread during" +
74 "QAndroidVideoDevices cleanup.");
75 }
76
77 // After waiting, QAndroidVideoDevices can now be safely destroyed.
78 }
79
80 native void onCameraAvailableNative(long videoDevicesNativePtr);
81
82 // Will be called once for each connected camera device when availability-listener
83 // is attached to the Android CameraManager.
84 @Override
85 public void onCameraAvailable(String cameraId) {
86 assert(mVideoDevicesNativePtr != 0);
87 onCameraAvailableNative(mVideoDevicesNativePtr);
88 }
89
90 native void onCameraUnavailableNative(long videoDevicesNativePtr);
91
92 @Override
93 public void onCameraUnavailable(String cameraId) {
94 assert(mVideoDevicesNativePtr != 0);
95 onCameraUnavailableNative(mVideoDevicesNativePtr);
96 }
97
98 @Override
99 public void onCameraAccessPrioritiesChanged() {
100 // TODO: In the future we should handle camera priorities, such as when the camera-device
101 // is connected but is in use by another application, making the current application unable
102 // to use it until the device is released by the other application.
103 }
104}
Q_CORE_EXPORT QtJniTypes::Activity activity()
#define assert
@ Handler
void cleanup()