From bfc579774b6c2c561f7c0898e517bf4f945f9943 Mon Sep 17 00:00:00 2001 From: Haesu Gwon Date: Tue, 22 Jun 2021 11:48:49 +0900 Subject: [PATCH] [Camera] Add DeviceConnectionChanged event (#3211) * [Camera] Add DeviceConnectionChanged event --- .../Camera/Camera.Events.cs | 7 -- src/Tizen.Multimedia.Camera/Camera/Camera.cs | 5 +- .../CameraDeviceConnectionChangedEventArgs.cs | 52 +++++++++++ .../Camera/CameraDeviceListChangedEventArgs.cs | 6 +- .../Camera/CameraDeviceManager.cs | 104 +++++++++++++++------ .../Interop/Interop.Camera.cs | 9 ++ 6 files changed, 141 insertions(+), 42 deletions(-) create mode 100644 src/Tizen.Multimedia.Camera/Camera/CameraDeviceConnectionChangedEventArgs.cs diff --git a/src/Tizen.Multimedia.Camera/Camera/Camera.Events.cs b/src/Tizen.Multimedia.Camera/Camera/Camera.Events.cs index 5da1962..99824fe 100644 --- a/src/Tizen.Multimedia.Camera/Camera/Camera.Events.cs +++ b/src/Tizen.Multimedia.Camera/Camera/Camera.Events.cs @@ -272,13 +272,6 @@ namespace Tizen.Multimedia } } - /// - /// An event that occurs when there is a change in the camera device list. - /// - /// 9 - [EditorBrowsable(EditorBrowsableState.Never)] - public event EventHandler CameraDeviceListChanged; - private void RegisterCallbacks() { RegisterErrorCallback(); diff --git a/src/Tizen.Multimedia.Camera/Camera/Camera.cs b/src/Tizen.Multimedia.Camera/Camera/Camera.cs index 1b700d1..b1f0bde 100644 --- a/src/Tizen.Multimedia.Camera/Camera/Camera.cs +++ b/src/Tizen.Multimedia.Camera/Camera/Camera.cs @@ -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 index 0000000..e1f5224 --- /dev/null +++ b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceConnectionChangedEventArgs.cs @@ -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 +{ + /// + /// Provides data for the event. + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public class CameraDeviceConnectionChangedEventArgs : EventArgs + { + internal CameraDeviceConnectionChangedEventArgs(ref CameraDeviceStruct device, bool status) + { + CameraDeviceInformation = CameraDeviceManager.GetDeviceInformation(device); + IsConnected = status; + } + + /// + /// Gets the camera device information. + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public CameraDeviceInformation CameraDeviceInformation { get; } + + /// + /// Gets the status of camera device. + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public bool IsConnected { get; } + } +} diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraDeviceListChangedEventArgs.cs b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceListChangedEventArgs.cs index 06e334f..3ee41df 100644 --- a/src/Tizen.Multimedia.Camera/Camera/CameraDeviceListChangedEventArgs.cs +++ b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceListChangedEventArgs.cs @@ -23,7 +23,7 @@ using static Interop.CameraDeviceManager; namespace Tizen.Multimedia { /// - /// Provides data for the event. + /// Provides data for the event. /// /// 9 [EditorBrowsable(EditorBrowsableState.Never)] @@ -31,7 +31,7 @@ namespace Tizen.Multimedia { internal CameraDeviceListChangedEventArgs(ref CameraDeviceListStruct deviceList) { - CameraDeviceInfo = CameraDeviceManager.GetDeviceInfo(deviceList); + CameraDeviceInfo = CameraDeviceManager.GetDeviceInformation(deviceList); } /// @@ -39,6 +39,6 @@ namespace Tizen.Multimedia /// /// 9 [EditorBrowsable(EditorBrowsableState.Never)] - public ReadOnlyCollection CameraDeviceInfo { get; } + public ReadOnlyCollection CameraDeviceInfo { get; } } } diff --git a/src/Tizen.Multimedia.Camera/Camera/CameraDeviceManager.cs b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceManager.cs index e3431cd..9d6441a 100644 --- a/src/Tizen.Multimedia.Camera/Camera/CameraDeviceManager.cs +++ b/src/Tizen.Multimedia.Camera/Camera/CameraDeviceManager.cs @@ -1,3 +1,4 @@ +using System.Linq; /* * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved * @@ -25,10 +26,13 @@ namespace Tizen.Multimedia /// /// This CameraDeviceManager class provides methods to control current camera devices and get its information. /// + /// + /// This supports the product infrastructure and is not intended to be used directly from 3rd party application code. + /// /// 9 /// http://tizen.org/feature/camera [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 class. /// /// Invalid operation. - /// The camera feature is not supported. + /// The camera device manager is not supported. /// 9 [EditorBrowsable(EditorBrowsableState.Never)] - internal CameraDeviceManager() + public CameraDeviceManager() { Native.Initialize(out _handle).ThrowIfFailed("Failed to initialize CameraDeviceManager"); - RegisterDeviceListCallback(); + RegisterCallbacks(); } /// @@ -57,40 +61,49 @@ namespace Tizen.Multimedia } /// + /// Gets the status whether camera device(usb, network) is connected or not. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool IsExternalCameraConnected => + GetDeviceInformation().Where(d => d.Type == CameraDeviceType.Usb || + d.Type == CameraDeviceType.Network) + .Any(); + + /// /// Gets the current camera device information. /// /// /// 9 [EditorBrowsable(EditorBrowsableState.Never)] - internal ReadOnlyCollection GetDeviceInfo() + public ReadOnlyCollection 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 GetDeviceInfo(Native.CameraDeviceListStruct deviceList) + internal static ReadOnlyCollection GetDeviceInformation(Native.CameraDeviceListStruct list) { - var cameraDevice = deviceList.device; + var devices = list.device; + var deviceList = new List(); - var cameraDeviceList = new List(); - - 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(cameraDeviceList); + return new ReadOnlyCollection(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 /// /// 9 [EditorBrowsable(EditorBrowsableState.Never)] - internal event EventHandler CameraDeviceListChanged; + public event EventHandler DeviceListChanged; + + /// + /// An event that occurs when camera device is connected or disconnected. + /// + /// 9 + [EditorBrowsable(EditorBrowsableState.Never)] + public event EventHandler 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 /// /// 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 /// /// 9 [EditorBrowsable(EditorBrowsableState.Never)] - public class CameraDeviceInfo + public class CameraDeviceInformation { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// @@ -207,7 +253,7 @@ namespace Tizen.Multimedia /// name or id is null. /// 9 [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)); diff --git a/src/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs b/src/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs index 50b884e..e8a9afa 100644 --- a/src/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs +++ b/src/Tizen.Multimedia.Camera/Interop/Interop.Camera.cs @@ -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)] -- 2.7.4