2 * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 using System.Collections.Generic;
19 using System.ComponentModel;
21 using Native = Interop.CameraDeviceManager;
23 namespace Tizen.Multimedia
26 /// This CameraDeviceManager class provides methods to control current camera devices and get its information.
29 /// This supports the product infrastructure and is not intended to be used directly from 3rd party application code.
31 /// <since_tizen> 10 </since_tizen>
32 public class CameraDeviceManager : IDisposable
34 private IntPtr _handle;
35 private bool _disposed;
36 private Native.DeviceConnectionChangedCallback _deviceConnectionChangedCallback;
39 /// Initializes a new instance of the <see cref="CameraDeviceManager"/> class.
41 /// <exception cref="InvalidOperationException">Invalid operation.</exception>
42 /// <exception cref="NotSupportedException">The camera device manager is not supported.</exception>
43 /// <since_tizen> 10 </since_tizen>
44 public CameraDeviceManager()
46 Native.Initialize(out _handle).ThrowIfFailed("Failed to initialize CameraDeviceManager");
50 /// Finalizes an instance of the Camera class.
52 ~CameraDeviceManager()
58 /// Gets the status whether camera device(usb, network) is connected or not.
60 /// <returns>true if usb or network camera is connected.</returns>
61 /// <exception cref="ObjectDisposedException">The CameraDeviceManager already has been disposed.</exception>
62 /// <since_tizen> 10 </since_tizen>
63 public bool IsExternalCameraConnected =>
64 SupportedDevices.Where(d => d.Type == CameraDeviceType.Usb ||
65 d.Type == CameraDeviceType.Network)
69 /// Retrieves all the supported camera devices and returns its information.
72 /// if camera device exist, returns list of <see cref="CameraDeviceInformation"/>; otherwise returns Enumerable.Empty.
74 /// <exception cref="ArgumentException">Invalid enumeration.</exception>
75 /// <exception cref="ArgumentNullException">name or id is null.</exception>
76 /// <exception cref="ObjectDisposedException">The CameraDeviceManager already has been disposed.</exception>
77 /// <since_tizen> 10 </since_tizen>
78 public IEnumerable<CameraDeviceInformation> SupportedDevices
82 var deviceList = new List<CameraDeviceInformation>();
84 Exception caught = null;
86 Native.SupportedDeviceCallback callback = (ref Native.CameraDeviceStruct supportedDevice, IntPtr userData) =>
90 var deviceInfo = new CameraDeviceInformation(supportedDevice.type, supportedDevice.device, supportedDevice.name,
91 supportedDevice.id, supportedDevice.extraStreamNum);
92 Log.Debug(CameraLog.Tag, deviceInfo.ToString());
94 deviceList.Add(deviceInfo);
104 Native.SupportedDevices(Handle, callback, IntPtr.Zero).
105 ThrowIfFailed("failed to get supported devices");
112 return deviceList.Any() ? deviceList.AsReadOnly() : Enumerable.Empty<CameraDeviceInformation>();
117 /// Gets the current camera device information.
118 /// Retrieves all the supported camera devices and returns its information.
120 /// <remarks>This method is only for backward compatibility. Please use SupportedDevices instead.</remarks>
122 /// if camera device exist, returns list of <see cref="CameraDeviceInformation"/>; otherwise returns Enumerable.Empty.
124 /// <see also="WebRTCState"/>
125 [EditorBrowsable(EditorBrowsableState.Never)]
126 public IEnumerable<CameraDeviceInformation> GetDeviceInformation() => SupportedDevices;
128 private event EventHandler<CameraDeviceConnectionChangedEventArgs> _deviceConnectionChanged;
130 /// An event that occurs when camera device is connected or disconnected.
132 /// <exception cref="ObjectDisposedException">The CameraDeviceManager already has been disposed.</exception>
133 /// <since_tizen> 10 </since_tizen>
134 public event EventHandler<CameraDeviceConnectionChangedEventArgs> DeviceConnectionChanged
138 if (_deviceConnectionChanged == null)
140 RegisterDeviceConnectionChangedCallback();
143 _deviceConnectionChanged += value;
147 _deviceConnectionChanged -= value;
149 if (_deviceConnectionChanged == null)
151 UnregisterDeviceConnectionChangedCallback();
156 private IntPtr Handle
160 ValidateNotDisposed();
165 private int _connectionCallbackId = -1;
166 private void RegisterDeviceConnectionChangedCallback()
168 _deviceConnectionChangedCallback = (ref Native.CameraDeviceStruct supportedDevice, bool isConnected, IntPtr userData) =>
170 var deviceInfo = new CameraDeviceInformation(supportedDevice.type, supportedDevice.device, supportedDevice.name,
171 supportedDevice.id, supportedDevice.extraStreamNum);
172 Log.Debug(CameraLog.Tag, deviceInfo.ToString());
174 _deviceConnectionChanged?.Invoke(this, new CameraDeviceConnectionChangedEventArgs(deviceInfo, isConnected));
177 Native.SetDeviceConnectionChangedCallback(Handle, _deviceConnectionChangedCallback, IntPtr.Zero, out _connectionCallbackId).
178 ThrowIfFailed("Failed to set device connection changed callback");
180 Log.Debug(CameraLog.Tag, $"callbackId[{_connectionCallbackId}]");
183 private void UnregisterDeviceConnectionChangedCallback()
185 Log.Debug(CameraLog.Tag, $"callbackId[{_connectionCallbackId}]");
187 if (_connectionCallbackId >= 0)
189 Native.UnsetDeviceConnectionChangedCallback(Handle, _connectionCallbackId).
190 ThrowIfFailed("Failed to unset device connection changed callback");
194 #region Dispose support
196 /// Releases the unmanaged resources used by the camera.
198 /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
199 /// <since_tizen> 10 </since_tizen>
200 protected virtual void Dispose(bool disposing)
204 Log.Debug(CameraLog.Tag, $"Enter. disposing:{disposing.ToString()}");
208 // to be used if there are any other disposable objects
211 if (_handle != IntPtr.Zero)
213 UnregisterDeviceConnectionChangedCallback();
215 Native.Deinitialize(_handle);
216 _handle = IntPtr.Zero;
224 /// Releases all resources used by the camera.
226 /// <since_tizen> 10 </since_tizen>
227 public void Dispose()
230 GC.SuppressFinalize(this);
233 internal void ValidateNotDisposed()
237 Log.Error(CameraLog.Tag, "CameraDeviceManager handle is disposed.");
238 throw new ObjectDisposedException(nameof(Camera));
241 #endregion Dispose support
245 /// Provides the ability to get camera device information.
247 /// <since_tizen> 10 </since_tizen>
248 public struct CameraDeviceInformation
251 /// Initializes a new instance of the <see cref="CameraDeviceInformation"/> class.
253 /// <param name="type">The camera type</param>
254 /// <param name="device">The camera device</param>
255 /// <param name="name">The name of camera device</param>
256 /// <param name="id">The ID of camera device</param>
257 /// <param name="numberOfExtraStream">The number of extra streams</param>
258 /// <exception cref="ArgumentException">Invalid enumeration.</exception>
259 /// <exception cref="ArgumentNullException">name or id is null.</exception>
260 /// <since_tizen> 10 </since_tizen>
261 internal CameraDeviceInformation(CameraDeviceType type, CameraDevice device, string name, string id, int numberOfExtraStream)
263 ValidationUtil.ValidateEnum(typeof(CameraDeviceType), type, nameof(type));
264 ValidationUtil.ValidateEnum(typeof(CameraDevice), device, nameof(device));
268 Name = name ?? throw new ArgumentNullException(nameof(name), "name is null");
269 Id = id ?? throw new ArgumentNullException(nameof(id), "id is null");
270 NumberOfExtraStream = numberOfExtraStream;
272 Log.Debug(CameraLog.Tag, this.ToString());
276 /// Gets the camera device type.
278 /// <value><see cref="CameraDeviceType"/></value>
279 /// <since_tizen> 10 </since_tizen>
280 public CameraDeviceType Type { get; }
283 /// Gets the <see cref="CameraDevice"/>.
285 /// <value><see cref="CameraDevice"/></value>
286 /// <since_tizen> 10 </since_tizen>
287 public CameraDevice Device { get; }
290 /// Gets the camera device name.
292 /// <value>The camera device name</value>
293 /// <since_tizen> 10 </since_tizen>
294 public string Name { get; }
297 /// Gets the camera device ID.
299 /// <value>The camera device ID.</value>
300 /// <since_tizen> 10 </since_tizen>
301 public string Id { get; }
304 /// Gets the number of extra streams.
306 /// <value>The number of extra streams.</value>
307 /// <since_tizen> 10 </since_tizen>
308 public int NumberOfExtraStream { get; }
311 /// Returns a string that represents the current object.
313 /// <returns>A string that represents the current object.</returns>
314 /// <since_tizen> 10 </since_tizen>
315 public override string ToString() =>
316 $"Type:{Type.ToString()}, Device:{Device.ToString()}, Name:{Name}, Id:{Id}, NumberOfExtraStream:{NumberOfExtraStream}";