[Camera] Add DeviceConnectionChanged event (#3211)
authorHaesu Gwon <haesu.gwon@samsung.com>
Tue, 22 Jun 2021 02:48:49 +0000 (11:48 +0900)
committerGitHub <noreply@github.com>
Tue, 22 Jun 2021 02:48:49 +0000 (11:48 +0900)
* [Camera] Add DeviceConnectionChanged event

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

index 5da1962..99824fe 100644 (file)
@@ -272,13 +272,6 @@ namespace Tizen.Multimedia
             }
         }
 
-        /// <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 void RegisterCallbacks()
         {
             RegisterErrorCallback();
index 1b700d1..b1f0bde 100644 (file)
@@ -78,16 +78,15 @@ namespace Tizen.Multimedia
             try
             {
                 _cameraDeviceManager = new CameraDeviceManager();
-                var deviceInfo = _cameraDeviceManager.GetDeviceInfo();
+                var deviceInfo = _cameraDeviceManager.GetDeviceInformation();
                 Log.Info(CameraLog.Tag, deviceInfo.ToString());
 
                 cameraDeviceType = deviceInfo.First().Type;
-                _cameraDeviceManager.CameraDeviceListChanged += CameraDeviceListChanged;
             }
             catch (NotSupportedException e)
             {
                 Tizen.Log.Info(CameraLog.Tag,
-                    $"CameraDeviceManager is not supported. {e.Message}");
+                    $"CameraDeviceManager is not supported. {e.Message}. Not error.");
             }
 
             if (cameraDeviceType == CameraDeviceType.BuiltIn ||
diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraDeviceConnectionChangedEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceConnectionChangedEventArgs.cs
new file mode 100644 (file)
index 0000000..e1f5224
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.DeviceConnectionChanged"/> event.
+    /// </summary>
+    /// <since_tizen> 9 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class CameraDeviceConnectionChangedEventArgs : EventArgs
+    {
+        internal CameraDeviceConnectionChangedEventArgs(ref CameraDeviceStruct device, bool status)
+        {
+            CameraDeviceInformation = CameraDeviceManager.GetDeviceInformation(device);
+            IsConnected = status;
+        }
+
+        /// <summary>
+        /// Gets the camera device information.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CameraDeviceInformation CameraDeviceInformation { get; }
+
+        /// <summary>
+        /// Gets the status of camera device.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsConnected { get; }
+    }
+}
index 06e334f..3ee41df 100644 (file)
@@ -23,7 +23,7 @@ using static Interop.CameraDeviceManager;
 namespace Tizen.Multimedia
 {
     /// <summary>
-    /// Provides data for the <see cref="CameraDeviceManager.CameraDeviceListChanged"/> event.
+    /// Provides data for the <see cref="CameraDeviceManager.DeviceListChanged"/> event.
     /// </summary>
     /// <since_tizen> 9 </since_tizen>
     [EditorBrowsable(EditorBrowsableState.Never)]
@@ -31,7 +31,7 @@ namespace Tizen.Multimedia
     {
         internal CameraDeviceListChangedEventArgs(ref CameraDeviceListStruct deviceList)
         {
-            CameraDeviceInfo = CameraDeviceManager.GetDeviceInfo(deviceList);
+            CameraDeviceInfo = CameraDeviceManager.GetDeviceInformation(deviceList);
         }
 
         /// <summary>
@@ -39,6 +39,6 @@ namespace Tizen.Multimedia
         /// </summary>
         /// <since_tizen> 9 </since_tizen>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public ReadOnlyCollection<CameraDeviceInfo> CameraDeviceInfo { get; }
+        public ReadOnlyCollection<CameraDeviceInformation> CameraDeviceInfo { get; }
     }
 }
index e3431cd..9d6441a 100644 (file)
@@ -1,3 +1,4 @@
+using System.Linq;
 /*
  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
  *
@@ -25,10 +26,13 @@ namespace Tizen.Multimedia
     /// <summary>
     /// This CameraDeviceManager class provides methods to control current camera devices and get its information.
     /// </summary>
+    /// <remarks>
+    /// This supports the product infrastructure and is not intended to be used directly from 3rd party application code.
+    /// </remarks>
     /// <since_tizen> 9 </since_tizen>
     /// <feature> http://tizen.org/feature/camera </feature>
     [EditorBrowsable(EditorBrowsableState.Never)]
-    internal class CameraDeviceManager : IDisposable
+    public class CameraDeviceManager : IDisposable
     {
         private IntPtr _handle;
         private bool _disposed;
@@ -37,14 +41,14 @@ namespace Tizen.Multimedia
         /// 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>
+        /// <exception cref="NotSupportedException">The camera device manager is not supported.</exception>
         /// <since_tizen> 9 </since_tizen>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        internal CameraDeviceManager()
+        public CameraDeviceManager()
         {
             Native.Initialize(out _handle).ThrowIfFailed("Failed to initialize CameraDeviceManager");
 
-            RegisterDeviceListCallback();
+            RegisterCallbacks();
         }
 
         /// <summary>
@@ -57,40 +61,49 @@ namespace Tizen.Multimedia
         }
 
         /// <summary>
+        /// Gets the status whether camera device(usb, network) is connected or not.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsExternalCameraConnected =>
+            GetDeviceInformation().Where(d => d.Type == CameraDeviceType.Usb ||
+                                              d.Type == CameraDeviceType.Network)
+                                  .Any();
+
+        /// <summary>
         /// Gets the current camera device information.
         /// </summary>
         /// <returns></returns>
         /// <since_tizen> 9 </since_tizen>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        internal ReadOnlyCollection<CameraDeviceInfo> GetDeviceInfo()
+        public ReadOnlyCollection<CameraDeviceInformation> GetDeviceInformation()
         {
             var deviceList = new Native.CameraDeviceListStruct();
 
             Native.GetDeviceList(Handle, ref deviceList).
                 ThrowIfFailed("Failed to get camera device list");
 
-            return GetDeviceInfo(deviceList);
+            return GetDeviceInformation(deviceList);
         }
 
-        internal static ReadOnlyCollection<CameraDeviceInfo> GetDeviceInfo(Native.CameraDeviceListStruct deviceList)
+        internal static ReadOnlyCollection<CameraDeviceInformation> GetDeviceInformation(Native.CameraDeviceListStruct list)
         {
-            var cameraDevice = deviceList.device;
+            var devices = list.device;
+            var deviceList = new List<CameraDeviceInformation>();
 
-            var cameraDeviceList = new List<CameraDeviceInfo>();
-
-            for (int i = 0 ; i < deviceList.count ; i++)
+            for (int i = 0 ; i < list.count ; i++)
             {
-                var deviceInfo = new CameraDeviceInfo(cameraDevice[i].Type, cameraDevice[i].device,
-                    GetString(cameraDevice[i].name), GetString(cameraDevice[i].id));
-
-                cameraDeviceList.Add(deviceInfo);
+                var deviceInfo = GetDeviceInformation(devices[i]);
+                deviceList.Add(deviceInfo);
 
                 Log.Info(CameraLog.Tag, deviceInfo.ToString());
             }
 
-            return new ReadOnlyCollection<CameraDeviceInfo>(cameraDeviceList);
+            return new ReadOnlyCollection<CameraDeviceInformation>(deviceList);
         }
 
+        internal static CameraDeviceInformation GetDeviceInformation(Native.CameraDeviceStruct device) =>
+            new CameraDeviceInformation(device.Type, device.device, GetString(device.name), GetString(device.id));
+
         private static string GetString(char[] word)
         {
             int length = 0;
@@ -107,7 +120,14 @@ namespace Tizen.Multimedia
         /// </summary>
         /// <since_tizen> 9 </since_tizen>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        internal event EventHandler<CameraDeviceListChangedEventArgs> CameraDeviceListChanged;
+        public event EventHandler<CameraDeviceListChangedEventArgs> DeviceListChanged;
+
+        /// <summary>
+        /// An event that occurs when camera device is connected or disconnected.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<CameraDeviceConnectionChangedEventArgs> DeviceConnectionChanged;
 
         private IntPtr Handle
         {
@@ -118,28 +138,52 @@ namespace Tizen.Multimedia
             }
         }
 
-        private int callbackId = 0;
-        private void RegisterDeviceListCallback()
+        private void RegisterCallbacks()
+        {
+            RegisterDeviceListChangedCallback();
+            RegisterDeviceConnectionChangedCallback();
+        }
+
+        private int listCallbackId = 0;
+        private void RegisterDeviceListChangedCallback()
         {
             Native.DeviceListChangedCallback callback = (ref Native.CameraDeviceListStruct deviceList, IntPtr userData) =>
             {
-                CameraDeviceListChanged?.Invoke(this, new CameraDeviceListChangedEventArgs(ref deviceList));
+                DeviceListChanged?.Invoke(this, new CameraDeviceListChangedEventArgs(ref deviceList));
             };
 
-            Native.SetDeviceListChangedCallback(Handle, callback, IntPtr.Zero, out callbackId).
+            Native.SetDeviceListChangedCallback(Handle, callback, IntPtr.Zero, out listCallbackId).
                 ThrowIfFailed("Failed to set device list changed callback");
 
-            Log.Info(CameraLog.Tag, $"callback Id : {callbackId}");
+            Log.Info(CameraLog.Tag, $"callback Id : {listCallbackId}");
         }
 
-        private void UnregisterDeviceListCallback()
+        private void UnregisterDeviceListChangedCallback()
         {
-            Log.Info(CameraLog.Tag, $"callback Id : {callbackId}");
+            Log.Info(CameraLog.Tag, $"callback Id : {listCallbackId}");
 
-            Native.UnsetDeviceListChangedCallback(Handle, callbackId).
+            Native.UnsetDeviceListChangedCallback(Handle, listCallbackId).
                 ThrowIfFailed("Failed to unset device list changed callback");
         }
 
+        private int connectionCallbackId = 0;
+        private void RegisterDeviceConnectionChangedCallback()
+        {
+            Native.DeviceConnectionChangedCallback callback = (ref Native.CameraDeviceStruct device, bool status, IntPtr userData) =>
+            {
+                DeviceConnectionChanged?.Invoke(this, new CameraDeviceConnectionChangedEventArgs(ref device, status));
+            };
+
+            Native.SetDeviceConnectionChangedCallback(Handle, callback, IntPtr.Zero, out connectionCallbackId).
+                ThrowIfFailed("Failed to set device connection changed callback");
+        }
+
+        private void UnregisterDeviceConnectionChangedCallback()
+        {
+            Native.UnsetDeviceConnectionChangedCallback(Handle, connectionCallbackId).
+                ThrowIfFailed("Failed to unset device connection changed callback");
+        }
+
         #region Dispose support
         /// <summary>
         /// Releases the unmanaged resources used by the camera.
@@ -158,7 +202,9 @@ namespace Tizen.Multimedia
 
                 if (_handle != IntPtr.Zero)
                 {
-                    UnregisterDeviceListCallback();
+                    UnregisterDeviceListChangedCallback();
+                    UnregisterDeviceConnectionChangedCallback();
+
                     Native.Deinitialize(_handle);
                     _handle = IntPtr.Zero;
                 }
@@ -194,10 +240,10 @@ namespace Tizen.Multimedia
     /// </summary>
     /// <since_tizen> 9 </since_tizen>
     [EditorBrowsable(EditorBrowsableState.Never)]
-    public class CameraDeviceInfo
+    public class CameraDeviceInformation
     {
         /// <summary>
-        /// Initializes a new instance of the <see cref="CameraDeviceInfo"/> class.
+        /// Initializes a new instance of the <see cref="CameraDeviceInformation"/> class.
         /// </summary>
         /// <param name="type"><see cref="CameraDeviceType"/></param>
         /// <param name="device"><see cref="CameraDevice"/></param>
@@ -207,7 +253,7 @@ namespace Tizen.Multimedia
         /// <exception cref="ArgumentNullException">name or id is null.</exception>
         /// <since_tizen> 9 </since_tizen>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        internal CameraDeviceInfo(CameraDeviceType type, CameraDevice device, string name, string id)
+        internal CameraDeviceInformation(CameraDeviceType type, CameraDevice device, string name, string id)
         {
             ValidationUtil.ValidateEnum(typeof(CameraDeviceType), type, nameof(type));
             ValidationUtil.ValidateEnum(typeof(CameraDevice), device, nameof(device));
index 50b884e..e8a9afa 100644 (file)
@@ -318,6 +318,9 @@ internal static partial class Interop
     internal static partial class CameraDeviceManager
     {
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void DeviceConnectionChangedCallback(ref CameraDeviceStruct device, bool status, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void DeviceListChangedCallback(ref CameraDeviceListStruct deviceList, IntPtr userData);
 
 
@@ -336,6 +339,12 @@ internal static partial class Interop
         [DllImport(Libraries.Camera, EntryPoint = "camera_device_manager_remove_device_list_changed_cb")]
         internal static extern CameraError UnsetDeviceListChangedCallback(IntPtr handle, int id);
 
+        [DllImport(Libraries.Camera, EntryPoint = "camera_device_manager_add_device_connection_changed_cb")]
+        internal static extern CameraError SetDeviceConnectionChangedCallback(IntPtr handle, DeviceConnectionChangedCallback callback, IntPtr userData, out int id);
+
+        [DllImport(Libraries.Camera, EntryPoint = "camera_device_manager_remove_device_connection_changed_cb")]
+        internal static extern CameraError UnsetDeviceConnectionChangedCallback(IntPtr handle, int id);
+
 
         [NativeStruct("camera_device_s", Include="camera_internal.h", PkgConfig="capi-media-camera")]
         [StructLayout(LayoutKind.Sequential)]