3 * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 using System.Collections.Generic;
20 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> 9 </since_tizen>
32 /// <feature> http://tizen.org/feature/camera </feature>
33 [EditorBrowsable(EditorBrowsableState.Never)]
34 public class CameraDeviceManager : IDisposable
36 private IntPtr _handle;
37 private bool _disposed;
38 private Native.DeviceConnectionChangedCallback _deviceConnectionChangedCallback;
41 /// Initializes a new instance of the <see cref="CameraDeviceManager"/> class.
43 /// <exception cref="InvalidOperationException">Invalid operation.</exception>
44 /// <exception cref="NotSupportedException">The camera device manager is not supported.</exception>
45 /// <since_tizen> 9 </since_tizen>
46 [EditorBrowsable(EditorBrowsableState.Never)]
47 public CameraDeviceManager()
49 Native.Initialize(out _handle).ThrowIfFailed("Failed to initialize CameraDeviceManager");
53 /// Finalizes an instance of the Camera class.
55 [EditorBrowsable(EditorBrowsableState.Never)]
56 ~CameraDeviceManager()
62 /// Gets the status whether camera device(usb, network) is connected or not.
64 [EditorBrowsable(EditorBrowsableState.Never)]
65 public bool IsExternalCameraConnected =>
66 GetDeviceInformation().Where(d => d.Type == CameraDeviceType.Usb ||
67 d.Type == CameraDeviceType.Network)
71 /// Gets the current camera device information.
73 /// <returns></returns>
74 /// <since_tizen> 9 </since_tizen>
75 [EditorBrowsable(EditorBrowsableState.Never)]
76 public IEnumerable<CameraDeviceInformation> GetDeviceInformation()
78 var deviceList = new Native.CameraDeviceListStruct();
80 Native.GetDeviceList(Handle, ref deviceList).
81 ThrowIfFailed("Failed to get camera device list");
83 return GetDeviceInformation(deviceList);
86 internal static bool IsSupported
92 using (var cameraDeviceManager = new CameraDeviceManager())
97 catch (NotSupportedException)
99 Log.Info(CameraLog.Tag,
100 $"CameraDeviceManager is not supported. Not error.");
106 internal static IEnumerable<CameraDeviceInformation> GetDeviceInformation(Native.CameraDeviceListStruct list)
110 return Enumerable.Empty<CameraDeviceInformation>();
113 var deviceList = new List<CameraDeviceInformation>();
115 for (int i = 0 ; i < list.count ; i++)
117 deviceList.Add(GetDeviceInformation(list.device[i]));
120 return deviceList.AsReadOnly();
123 internal static CameraDeviceInformation GetDeviceInformation(Native.CameraDeviceStruct device) =>
124 new CameraDeviceInformation(device.Type, device.device, device.name, device.id, device.extraStreamNum);
126 private event EventHandler<CameraDeviceConnectionChangedEventArgs> _deviceConnectionChanged;
128 /// An event that occurs when camera device is connected or disconnected.
130 /// <since_tizen> 9 </since_tizen>
131 [EditorBrowsable(EditorBrowsableState.Never)]
132 public event EventHandler<CameraDeviceConnectionChangedEventArgs> DeviceConnectionChanged
136 if (_deviceConnectionChanged == null)
138 RegisterDeviceConnectionChangedCallback();
141 _deviceConnectionChanged += value;
145 _deviceConnectionChanged -= value;
147 if (_deviceConnectionChanged == null)
149 UnregisterDeviceConnectionChangedCallback();
154 private IntPtr Handle
158 ValidateNotDisposed();
163 private int _connectionCallbackId = -1;
164 private void RegisterDeviceConnectionChangedCallback()
166 Log.Debug(CameraLog.Tag, "Enter");
168 _deviceConnectionChangedCallback = (ref Native.CameraDeviceStruct device, bool status, IntPtr userData) =>
170 Log.Debug(CameraLog.Tag, "Invoke DeviceConnectionChanged event");
171 _deviceConnectionChanged?.Invoke(this, new CameraDeviceConnectionChangedEventArgs(ref device, status));
174 Native.SetDeviceConnectionChangedCallback(Handle, _deviceConnectionChangedCallback, IntPtr.Zero, out _connectionCallbackId).
175 ThrowIfFailed("Failed to set device connection changed callback");
177 Log.Debug(CameraLog.Tag, $"Leave. callbackId[{_connectionCallbackId}]");
180 private void UnregisterDeviceConnectionChangedCallback()
182 Log.Debug(CameraLog.Tag, $"Enter. callbackId[{_connectionCallbackId}]");
184 if (_connectionCallbackId >= 0)
186 Native.UnsetDeviceConnectionChangedCallback(Handle, _connectionCallbackId).
187 ThrowIfFailed("Failed to unset device connection changed callback");
191 #region Dispose support
193 /// Releases the unmanaged resources used by the camera.
195 /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
196 /// <since_tizen> 9 </since_tizen>
197 [EditorBrowsable(EditorBrowsableState.Never)]
198 protected virtual void Dispose(bool disposing)
202 Log.Debug(CameraLog.Tag, $"Enter. disposing:{disposing.ToString()}");
206 // to be used if there are any other disposable objects
209 if (_handle != IntPtr.Zero)
211 UnregisterDeviceConnectionChangedCallback();
213 Native.Deinitialize(_handle);
214 _handle = IntPtr.Zero;
222 /// Releases all resources used by the camera.
224 /// <since_tizen> 9 </since_tizen>
225 [EditorBrowsable(EditorBrowsableState.Never)]
226 public void Dispose()
229 GC.SuppressFinalize(this);
232 internal void ValidateNotDisposed()
236 Log.Error(CameraLog.Tag, "CameraDeviceManager handle is disposed.");
237 throw new ObjectDisposedException(nameof(Camera));
240 #endregion Dispose support
244 /// Provides the ability to get camera device information.
246 /// <since_tizen> 9 </since_tizen>
247 [EditorBrowsable(EditorBrowsableState.Never)]
248 public struct CameraDeviceInformation
251 /// Initializes a new instance of the <see cref="CameraDeviceInformation"/> class.
253 /// <param name="type"><see cref="CameraDeviceType"/></param>
254 /// <param name="device"><see cref="CameraDevice"/></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 stream</param>
258 /// <exception cref="ArgumentException">Invalid enumeration.</exception>
259 /// <exception cref="ArgumentNullException">name or id is null.</exception>
260 /// <since_tizen> 9 </since_tizen>
261 [EditorBrowsable(EditorBrowsableState.Never)]
262 internal CameraDeviceInformation(CameraDeviceType type, CameraDevice device, string name, string id, int numberOfExtraStream)
264 ValidationUtil.ValidateEnum(typeof(CameraDeviceType), type, nameof(type));
265 ValidationUtil.ValidateEnum(typeof(CameraDevice), device, nameof(device));
269 Name = name ?? throw new ArgumentNullException(nameof(name), "name is null");
270 Id = id ?? throw new ArgumentNullException(nameof(id), "id is null");
271 NumberOfExtraStream = numberOfExtraStream;
273 Log.Debug(CameraLog.Tag, this.ToString());
277 /// Gets the camera device type.
279 /// <value><see cref="CameraDeviceType"/></value>
280 /// <since_tizen> 9 </since_tizen>
281 [EditorBrowsable(EditorBrowsableState.Never)]
282 public CameraDeviceType Type { get; }
285 /// Gets the <see cref="CameraDevice"/>.
287 /// <value><see cref="CameraDevice"/></value>
288 /// <since_tizen> 9 </since_tizen>
289 [EditorBrowsable(EditorBrowsableState.Never)]
290 public CameraDevice Device { get; }
293 /// Gets the camera device name.
295 /// <value>The camera device name</value>
296 /// <since_tizen> 9 </since_tizen>
297 [EditorBrowsable(EditorBrowsableState.Never)]
298 public string Name { get; }
301 /// Gets the camera device Id.
303 /// <value>The camera device id.</value>
304 /// <since_tizen> 9 </since_tizen>
305 [EditorBrowsable(EditorBrowsableState.Never)]
306 public string Id { get; }
309 /// Gets the number of extra stream.
311 /// <value>The number of extra stream.</value>
312 /// <since_tizen> 9 </since_tizen>
313 [EditorBrowsable(EditorBrowsableState.Never)]
314 public int NumberOfExtraStream { get; }
317 /// Returns a string that represents the current object.
319 /// <returns>A string that represents the current object.</returns>
320 /// <since_tizen> 9 </since_tizen>
321 [EditorBrowsable(EditorBrowsableState.Never)]
322 public override string ToString() =>
323 $"Type:{Type.ToString()}, Device:{Device.ToString()}, Name:{Name}, Id:{Id}, NumberOfExtraStream:{NumberOfExtraStream}";