[Camera] Add CameraDeviceManager (#3137)
authorHaesu Gwon <haesu.gwon@samsung.com>
Wed, 2 Jun 2021 03:06:41 +0000 (12:06 +0900)
committerGitHub <noreply@github.com>
Wed, 2 Jun 2021 03:06:41 +0000 (12:06 +0900)
* [Camera] Add CameraDeviceManager

src/Tizen.Multimedia.Camera/Camera/CameraDeviceListChangedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Camera/Camera/CameraDeviceManager.cs [new file with mode: 0644]
src/Tizen.Multimedia.Camera/Camera/CameraEnums.cs
src/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs

diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraDeviceListChangedEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceListChangedEventArgs.cs
new file mode 100644 (file)
index 0000000..06e334f
--- /dev/null
@@ -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
+{
+    /// <summary>
+    /// Provides data for the <see cref="CameraDeviceManager.CameraDeviceListChanged"/> event.
+    /// </summary>
+    /// <since_tizen> 9 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class CameraDeviceListChangedEventArgs : EventArgs
+    {
+        internal CameraDeviceListChangedEventArgs(ref CameraDeviceListStruct deviceList)
+        {
+            CameraDeviceInfo = CameraDeviceManager.GetDeviceInfo(deviceList);
+        }
+
+        /// <summary>
+        /// Gets the camera device info.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ReadOnlyCollection<CameraDeviceInfo> CameraDeviceInfo { get; }
+    }
+}
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraDeviceManager.cs b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceManager.cs
new file mode 100644 (file)
index 0000000..7f9ea33
--- /dev/null
@@ -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
+{
+    /// <summary>
+    /// This CameraDeviceManager class provides methods to control current camera devices and get its information.
+    /// </summary>
+    /// <since_tizen> 9 </since_tizen>
+    /// <feature> http://tizen.org/feature/camera </feature>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class CameraDeviceManager : IDisposable
+    {
+        private IntPtr _handle;
+        private bool _disposed;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CameraDeviceManager"/> class.
+        /// </summary>
+        /// <exception cref="InvalidOperationException">Invalid operation.</exception>
+        /// <exception cref="NotSupportedException">The camera feature is not supported.</exception>
+        /// <since_tizen> 9 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CameraDeviceManager()
+        {
+            Native.Initialize(out _handle).ThrowIfFailed("Failed to initialize CameraDeviceManager");
+
+            RegisterDeviceListCallback();
+        }
+
+        /// <summary>
+        /// Finalizes an instance of the Camera class.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        ~CameraDeviceManager()
+        {
+            Dispose(false);
+        }
+
+        /// <summary>
+        /// Gets the current camera device information.
+        /// </summary>
+        /// <returns></returns>
+        /// <since_tizen> 9 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ReadOnlyCollection<CameraDeviceInfo> GetDeviceInfo()
+        {
+            var deviceList = new Native.CameraDeviceListStruct();
+
+            Native.GetDeviceList(Handle, ref deviceList).
+                ThrowIfFailed("Failed to get camera device list");
+
+            return GetDeviceInfo(deviceList);
+        }
+
+        internal static ReadOnlyCollection<CameraDeviceInfo> GetDeviceInfo(Native.CameraDeviceListStruct deviceList)
+        {
+            var cameraDevice = deviceList.device;
+
+            var cameraDeviceList = new List<CameraDeviceInfo>();
+
+            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<CameraDeviceInfo>(cameraDeviceList);
+        }
+
+        private static string GetString(char[] word)
+        {
+            int length = 0;
+            while(word[length] != '\0')
+            {
+                length++;
+            }
+
+            return new String(word, 0, length);
+        }
+
+        /// <summary>
+        /// An event that occurs when there is a change in the camera device list.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<CameraDeviceListChangedEventArgs> 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
+        /// <summary>
+        /// Releases the unmanaged resources used by the camera.
+        /// </summary>
+        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
+        /// <since_tizen> 9 </since_tizen>
+        [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;
+            }
+        }
+
+        /// <summary>
+        /// Releases all resources used by the camera.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        [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
+    }
+
+    /// <summary>
+    /// Provides the ability to get camera device information.
+    /// </summary>
+    /// <since_tizen> 9 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class CameraDeviceInfo
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CameraDeviceInfo"/> class.
+        /// </summary>
+        /// <param name="type"><see cref="CameraDeviceType"/></param>
+        /// <param name="device"><see cref="CameraDevice"/></param>
+        /// <param name="name">The name of camera device</param>
+        /// <param name="id">The ID of camera device</param>
+        /// <exception cref="ArgumentException">Invalid enumeration of empty string.</exception>
+        /// <exception cref="ArgumentNullException">name of id is null.</exception>
+        /// <since_tizen> 9 </since_tizen>
+        [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;
+        }
+
+        /// <summary>
+        /// Gets the camera device type.
+        /// </summary>
+        /// <value><see cref="CameraDeviceType"/></value>
+        /// <since_tizen> 9 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CameraDeviceType Type { get; }
+
+        /// <summary>
+        /// Gets the <see cref="CameraDevice"/>.
+        /// </summary>
+        /// <value><see cref="CameraDevice"/></value>
+        /// <since_tizen> 9 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CameraDevice Device { get; }
+
+        /// <summary>
+        /// Gets the camera device name.
+        /// </summary>
+        /// <value>The camera device name</value>
+        /// <since_tizen> 9 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public string Name { get; }
+
+        /// <summary>
+        /// Gets the camera device Id.
+        /// </summary>
+        /// <value>The camera device id.</value>
+        /// <since_tizen> 9 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public string Id { get; }
+
+        /// <summary>
+        /// Returns a string that represents the current object.
+        /// </summary>
+        /// <returns>A string that represents the current object.</returns>
+        /// <since_tizen> 9 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override string ToString() =>
+            $"Type:{Type.ToString()}, Device:{Device.ToString()}, Name:{Name}, ID:{Id}";
+    }
+}
index 3f94a07..7c01ebf 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 using System;
+using System.ComponentModel;
 
 namespace Tizen.Multimedia
 {
@@ -927,4 +928,25 @@ namespace Tizen.Multimedia
         /// <since_tizen> 5 </since_tizen>
         RgbPlane
     }
+
+    /// <summary>
+    /// Enumeration for camera device type
+    /// </summary>
+    /// <since_tizen> 9 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum CameraDeviceType
+    {
+        /// <summary>
+        /// Built-in camera.
+        /// </summary>
+        BuiltIn,
+        /// <summary>
+        /// USB camera.
+        /// </summary>
+        Usb,
+        /// <summary>
+        /// Network camera.
+        /// </summary>
+        Network
+    }
 }
index 759269c..91f76be 100644 (file)
@@ -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