From f2b105a88dd071c283728439c82163a00ab481d9 Mon Sep 17 00:00:00 2001 From: Haesu Gwon Date: Wed, 2 Jun 2021 12:06:41 +0900 Subject: [PATCH] [Camera] Add CameraDeviceManager (#3137) * [Camera] Add CameraDeviceManager --- .../Camera/CameraDeviceListChangedEventArgs.cs | 44 ++++ .../Camera/CameraDeviceManager.cs | 264 +++++++++++++++++++++ src/Tizen.Multimedia.Camera/Camera/CameraEnums.cs | 22 ++ .../Interop/Interop.Camera.cs | 54 ++++- 4 files changed, 381 insertions(+), 3 deletions(-) create mode 100644 src/Tizen.Multimedia.Camera/Camera/CameraDeviceListChangedEventArgs.cs create mode 100644 src/Tizen.Multimedia.Camera/Camera/CameraDeviceManager.cs diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraDeviceListChangedEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceListChangedEventArgs.cs new file mode 100644 index 0000000..06e334f --- /dev/null +++ b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceListChangedEventArgs.cs @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using static Interop.CameraDeviceManager; + +namespace Tizen.Multimedia +{ + /// + /// Provides data for the event. + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public class CameraDeviceListChangedEventArgs : EventArgs + { + internal CameraDeviceListChangedEventArgs(ref CameraDeviceListStruct deviceList) + { + CameraDeviceInfo = CameraDeviceManager.GetDeviceInfo(deviceList); + } + + /// + /// Gets the camera device info. + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public ReadOnlyCollection CameraDeviceInfo { get; } + } +} diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraDeviceManager.cs b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceManager.cs new file mode 100644 index 0000000..7f9ea33 --- /dev/null +++ b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceManager.cs @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using Native = Interop.CameraDeviceManager; + +namespace Tizen.Multimedia +{ + /// + /// This CameraDeviceManager class provides methods to control current camera devices and get its information. + /// + /// 9 + /// http://tizen.org/feature/camera + [EditorBrowsable(EditorBrowsableState.Never)] + public class CameraDeviceManager : IDisposable + { + private IntPtr _handle; + private bool _disposed; + + /// + /// Initializes a new instance of the class. + /// + /// Invalid operation. + /// The camera feature is not supported. + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public CameraDeviceManager() + { + Native.Initialize(out _handle).ThrowIfFailed("Failed to initialize CameraDeviceManager"); + + RegisterDeviceListCallback(); + } + + /// + /// Finalizes an instance of the Camera class. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + ~CameraDeviceManager() + { + Dispose(false); + } + + /// + /// Gets the current camera device information. + /// + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public ReadOnlyCollection GetDeviceInfo() + { + var deviceList = new Native.CameraDeviceListStruct(); + + Native.GetDeviceList(Handle, ref deviceList). + ThrowIfFailed("Failed to get camera device list"); + + return GetDeviceInfo(deviceList); + } + + internal static ReadOnlyCollection GetDeviceInfo(Native.CameraDeviceListStruct deviceList) + { + var cameraDevice = deviceList.device; + + var cameraDeviceList = new List(); + + for (int i = 0 ; i < deviceList.count ; i++) + { + var deviceInfo = new CameraDeviceInfo(cameraDevice[i].Type, cameraDevice[i].device, + GetString(cameraDevice[i].name), GetString(cameraDevice[i].id)); + + cameraDeviceList.Add(deviceInfo); + + Log.Info(CameraLog.Tag, deviceInfo.ToString()); + } + + return new ReadOnlyCollection(cameraDeviceList); + } + + private static string GetString(char[] word) + { + int length = 0; + while(word[length] != '\0') + { + length++; + } + + return new String(word, 0, length); + } + + /// + /// An event that occurs when there is a change in the camera device list. + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public event EventHandler CameraDeviceListChanged; + + private IntPtr Handle + { + get + { + ValidateNotDisposed(); + return _handle; + } + } + + private int callbackId = 0; + private void RegisterDeviceListCallback() + { + Native.DeviceListChangedCallback callback = (ref Native.CameraDeviceListStruct deviceList, IntPtr userData) => + { + CameraDeviceListChanged?.Invoke(this, new CameraDeviceListChangedEventArgs(ref deviceList)); + }; + + Native.SetDeviceListChangedCallback(Handle, callback, IntPtr.Zero, out callbackId). + ThrowIfFailed("Failed to set device list changed callback"); + + Log.Info(CameraLog.Tag, $"callback Id : {callbackId}"); + } + + private void UnregisterDeviceListCallback() + { + Log.Info(CameraLog.Tag, $"callback Id : {callbackId}"); + + Native.UnsetDeviceListChangedCallback(Handle, callbackId). + ThrowIfFailed("Failed to unset device list changed callback"); + } + + #region Dispose support + /// + /// Releases the unmanaged resources used by the camera. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + // to be used if there are any other disposable objects + } + + if (_handle != IntPtr.Zero) + { + UnregisterDeviceListCallback(); + Native.Deinitialize(_handle); + _handle = IntPtr.Zero; + } + + _disposed = true; + } + } + + /// + /// Releases all resources used by the camera. + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + internal void ValidateNotDisposed() + { + if (_disposed) + { + Log.Error(CameraLog.Tag, "Camera handle is disposed."); + throw new ObjectDisposedException(nameof(Camera)); + } + } + #endregion Dispose support + } + + /// + /// Provides the ability to get camera device information. + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public class CameraDeviceInfo + { + /// + /// Initializes a new instance of the class. + /// + /// + /// + /// The name of camera device + /// The ID of camera device + /// Invalid enumeration of empty string. + /// name of id is null. + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public CameraDeviceInfo(CameraDeviceType type, CameraDevice device, string name, string id) + { + ValidationUtil.ValidateEnum(typeof(CameraDeviceType), type, nameof(type)); + ValidationUtil.ValidateEnum(typeof(CameraDevice), device, nameof(device)); + ValidationUtil.ValidateIsNullOrEmpty(name, nameof(name)); + ValidationUtil.ValidateIsNullOrEmpty(id, nameof(id)); + + Type = type; + Device = device; + Name = name; + Id = id; + } + + /// + /// Gets the camera device type. + /// + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public CameraDeviceType Type { get; } + + /// + /// Gets the . + /// + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public CameraDevice Device { get; } + + /// + /// Gets the camera device name. + /// + /// The camera device name + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public string Name { get; } + + /// + /// Gets the camera device Id. + /// + /// The camera device id. + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public string Id { get; } + + /// + /// Returns a string that represents the current object. + /// + /// A string that represents the current object. + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public override string ToString() => + $"Type:{Type.ToString()}, Device:{Device.ToString()}, Name:{Name}, ID:{Id}"; + } +} diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraEnums.cs b/src/Tizen.Multimedia.Camera/Camera/CameraEnums.cs index 3f94a07..7c01ebf 100644 --- a/src/Tizen.Multimedia.Camera/Camera/CameraEnums.cs +++ b/src/Tizen.Multimedia.Camera/Camera/CameraEnums.cs @@ -15,6 +15,7 @@ */ using System; +using System.ComponentModel; namespace Tizen.Multimedia { @@ -927,4 +928,25 @@ namespace Tizen.Multimedia /// 5 RgbPlane } + + /// + /// Enumeration for camera device type + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public enum CameraDeviceType + { + /// + /// Built-in camera. + /// + BuiltIn, + /// + /// USB camera. + /// + Usb, + /// + /// Network camera. + /// + Network + } } diff --git a/src/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs b/src/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs index 759269c..91f76be 100644 --- a/src/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs +++ b/src/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs @@ -169,12 +169,12 @@ internal static partial class Interop [DllImport(Libraries.Camera, EntryPoint = "camera_set_state_changed_cb")] internal static extern CameraError SetStateChangedCallback(IntPtr handle, StateChangedCallback callback, IntPtr userData = default); - [DllImport(Libraries.Camera, EntryPoint = "camera_add_device_state_changed_cb")] - internal static extern CameraError SetDeviceStateChangedCallback(DeviceStateChangedCallback callback, IntPtr userData, out int callbackId); - [DllImport(Libraries.Camera, EntryPoint = "camera_unset_state_changed_cb")] internal static extern CameraError UnsetStateChangedCallback(IntPtr handle); + [DllImport(Libraries.Camera, EntryPoint = "camera_add_device_state_changed_cb")] + internal static extern CameraError SetDeviceStateChangedCallback(DeviceStateChangedCallback callback, IntPtr userData, out int callbackId); + [DllImport(Libraries.Camera, EntryPoint = "camera_remove_device_state_changed_cb")] internal static extern CameraError UnsetDeviceStateChangedCallback(int cbId); @@ -311,4 +311,52 @@ internal static partial class Interop internal PreviewPlaneStruct Plane; } } + + internal static partial class CameraDeviceManager + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void DeviceListChangedCallback(ref CameraDeviceListStruct deviceList, IntPtr userData); + + + [DllImport(Libraries.Camera, EntryPoint = "camera_device_manager_initialize")] + internal static extern CameraError Initialize(out IntPtr handle); + + [DllImport(Libraries.Camera, EntryPoint = "camera_device_manager_deinitialize")] + internal static extern CameraError Deinitialize(IntPtr handle); + + [DllImport(Libraries.Camera, EntryPoint = "camera_device_manager_get_device_list")] + internal static extern CameraError GetDeviceList(IntPtr handle, ref CameraDeviceListStruct deviceList); + + [DllImport(Libraries.Camera, EntryPoint = "camera_device_manager_add_device_list_changed_cb")] + internal static extern CameraError SetDeviceListChangedCallback(IntPtr handle, DeviceListChangedCallback callback, IntPtr userData, out int id); + + [DllImport(Libraries.Camera, EntryPoint = "camera_device_manager_remove_device_list_changed_cb")] + internal static extern CameraError UnsetDeviceListChangedCallback(IntPtr handle, int id); + + + [NativeStruct("camera_device_s", Include="camera_internal.h", PkgConfig="capi-media-camera")] + [StructLayout(LayoutKind.Sequential)] + internal struct CameraDeviceStruct + { + internal CameraDeviceType Type; + + internal CameraDevice device; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + internal char[] name; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + internal char[] id; + } + + [NativeStruct("camera_device_list_s", Include="camera_internal.h", PkgConfig="capi-media-camera")] + [StructLayout(LayoutKind.Sequential)] + internal struct CameraDeviceListStruct + { + internal uint count; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + internal CameraDeviceStruct[] device; + } + } } \ No newline at end of file -- 2.7.4