From 169845046e685d41c834e6022f279dc66b6cb03a Mon Sep 17 00:00:00 2001 From: WonYoung Choi Date: Thu, 18 Aug 2016 15:00:29 +0900 Subject: [PATCH] Add SafeBundleHandle for creating Bundle object from native Change-Id: I3da8c2f6d3fcf5c9d9cbdaa46af3d7c44519fe70 --- Tizen.Applications/Interop/Interop.Bundle.cs | 28 ++++----- Tizen.Applications/Interop/Interop.MessagePort.cs | 6 +- .../Tizen.Applications.Messages/MessagePort.cs | 6 +- Tizen.Applications/Tizen.Applications.csproj | 1 + .../Tizen.Applications/AppControl.cs | 5 ++ Tizen.Applications/Tizen.Applications/Bundle.cs | 67 ++++++++++------------ .../Tizen.Applications/SafeAppControlHandle.cs | 8 +++ .../Tizen.Applications/SafeBundleHandle.cs | 55 ++++++++++++++++++ 8 files changed, 120 insertions(+), 56 deletions(-) mode change 100755 => 100644 Tizen.Applications/Interop/Interop.Bundle.cs mode change 100755 => 100644 Tizen.Applications/Interop/Interop.MessagePort.cs mode change 100755 => 100644 Tizen.Applications/Tizen.Applications.Messages/MessagePort.cs create mode 100644 Tizen.Applications/Tizen.Applications/SafeBundleHandle.cs diff --git a/Tizen.Applications/Interop/Interop.Bundle.cs b/Tizen.Applications/Interop/Interop.Bundle.cs old mode 100755 new mode 100644 index 9668b00..64b0d64 --- a/Tizen.Applications/Interop/Interop.Bundle.cs +++ b/Tizen.Applications/Interop/Interop.Bundle.cs @@ -9,6 +9,8 @@ using System; using System.Runtime.InteropServices; +using Tizen.Applications; + internal static partial class Interop { internal static partial class Bundle @@ -17,44 +19,44 @@ internal static partial class Interop internal delegate void Iterator(string key, int type, IntPtr keyval, IntPtr userData); [DllImport(Libraries.Bundle, EntryPoint = "bundle_create")] - internal static extern IntPtr Create(); + internal static extern SafeBundleHandle Create(); [DllImport(Libraries.Bundle, EntryPoint = "bundle_free")] - internal static extern int Free(IntPtr handle); + internal static extern int DangerousFree(IntPtr handle); [DllImport(Libraries.Bundle, EntryPoint = "bundle_del")] - internal static extern int RemoveItem(IntPtr handle, string key); + internal static extern int RemoveItem(SafeBundleHandle handle, string key); [DllImport(Libraries.Bundle, EntryPoint = "bundle_add_str")] - internal static extern int AddString(IntPtr handle, string key, string value); + internal static extern int AddString(SafeBundleHandle handle, string key, string value); [DllImport(Libraries.Bundle, EntryPoint = "bundle_get_type")] - internal static extern int GetType(IntPtr handle, string key); + internal static extern int GetType(SafeBundleHandle handle, string key); [DllImport(Libraries.Bundle, EntryPoint = "bundle_get_str")] - internal static extern int GetString(IntPtr handle, string key, out IntPtr value); + internal static extern int GetString(SafeBundleHandle handle, string key, out IntPtr value); [DllImport(Libraries.Bundle, EntryPoint = "bundle_add_byte")] - internal static extern unsafe int AddByte(IntPtr handle, string key, byte* value, int size); + internal static extern unsafe int AddByte(SafeBundleHandle handle, string key, byte* value, int size); [DllImport(Libraries.Bundle, EntryPoint = "bundle_get_byte")] - internal static extern int GetByte(IntPtr handle, string key, out IntPtr value, out int size); + internal static extern int GetByte(SafeBundleHandle handle, string key, out IntPtr value, out int size); [DllImport(Libraries.Bundle, EntryPoint = "bundle_add_str_array")] - internal static extern int AddStringArray(IntPtr handle, string key, string[] value, int size); + internal static extern int AddStringArray(SafeBundleHandle handle, string key, string[] value, int size); [DllImport(Libraries.Bundle, EntryPoint = "bundle_get_str_array")] - internal static extern IntPtr GetStringArray(IntPtr handle, string key, out int size); + internal static extern IntPtr GetStringArray(SafeBundleHandle handle, string key, out int size); [DllImport(Libraries.Bundle, EntryPoint = "bundle_foreach")] - internal static extern void Foreach(IntPtr handle, Iterator iterator, IntPtr userData); + internal static extern void Foreach(SafeBundleHandle handle, Iterator iterator, IntPtr userData); [DllImport(Libraries.Bundle, EntryPoint = "bundle_dup")] - internal static extern IntPtr Clone(IntPtr handle); + internal static extern SafeBundleHandle DangerousClone(IntPtr handle); internal static class UnsafeCode { - internal static unsafe int AddItem(IntPtr handle, string key, byte[] value, int offset, int count) + internal static unsafe int AddItem(SafeBundleHandle handle, string key, byte[] value, int offset, int count) { fixed (byte* pointer = value) { diff --git a/Tizen.Applications/Interop/Interop.MessagePort.cs b/Tizen.Applications/Interop/Interop.MessagePort.cs old mode 100755 new mode 100644 index 0d35250..f84a70a --- a/Tizen.Applications/Interop/Interop.MessagePort.cs +++ b/Tizen.Applications/Interop/Interop.MessagePort.cs @@ -9,6 +9,8 @@ using System; using System.Runtime.InteropServices; +using Tizen.Applications; + internal static partial class Interop { internal static partial class MessagePort @@ -26,10 +28,10 @@ internal static partial class Interop internal static extern int UnregisterTrustedPort(int trusted_local_port_id); [DllImport(Libraries.MessagePort, EntryPoint = "message_port_send_message_with_local_port", CallingConvention = CallingConvention.Cdecl)] - internal static extern int SendMessageWithLocalPort(string remote_app_id, string remote_port, IntPtr message, int local_port_id); + internal static extern int SendMessageWithLocalPort(string remote_app_id, string remote_port, SafeBundleHandle message, int local_port_id); [DllImport(Libraries.MessagePort, EntryPoint = "message_port_send_trusted_message_with_local_port", CallingConvention = CallingConvention.Cdecl)] - internal static extern int SendTrustedMessageWithLocalPort(string remote_app_id, string remote_port, IntPtr message, int local_port_id); + internal static extern int SendTrustedMessageWithLocalPort(string remote_app_id, string remote_port, SafeBundleHandle message, int local_port_id); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void message_port_message_cb(int local_port_id, string remote_app_id, string remote_port, bool trusted_remote_port, IntPtr message, IntPtr userData); diff --git a/Tizen.Applications/Tizen.Applications.Messages/MessagePort.cs b/Tizen.Applications/Tizen.Applications.Messages/MessagePort.cs old mode 100755 new mode 100644 index 2624dc7..bc082fa --- a/Tizen.Applications/Tizen.Applications.Messages/MessagePort.cs +++ b/Tizen.Applications/Tizen.Applications.Messages/MessagePort.cs @@ -134,7 +134,7 @@ namespace Tizen.Applications.Messages { MessageReceivedEventArgs args = new MessageReceivedEventArgs() { - Message = Bundle.MakeRetainedBundle(message) + Message = new Bundle(new SafeBundleHandle(message, false)) }; if (!String.IsNullOrEmpty(remotePortName) && !String.IsNullOrEmpty(remoteAppId)) @@ -253,8 +253,8 @@ namespace Tizen.Applications.Messages throw new ArgumentNullException("message"); } int ret = trusted ? - Interop.MessagePort.SendTrustedMessageWithLocalPort(remoteAppId, remotePortName, message.Handle, _portId) : - Interop.MessagePort.SendMessageWithLocalPort(remoteAppId, remotePortName, message.Handle, _portId); + Interop.MessagePort.SendTrustedMessageWithLocalPort(remoteAppId, remotePortName, message.SafeBundleHandle, _portId) : + Interop.MessagePort.SendMessageWithLocalPort(remoteAppId, remotePortName, message.SafeBundleHandle, _portId); if (ret != (int)MessagePortError.None) { diff --git a/Tizen.Applications/Tizen.Applications.csproj b/Tizen.Applications/Tizen.Applications.csproj index 513d52a..a2dcec9 100644 --- a/Tizen.Applications/Tizen.Applications.csproj +++ b/Tizen.Applications/Tizen.Applications.csproj @@ -101,6 +101,7 @@ + diff --git a/Tizen.Applications/Tizen.Applications/AppControl.cs b/Tizen.Applications/Tizen.Applications/AppControl.cs index 124e28a..c434fc4 100644 --- a/Tizen.Applications/Tizen.Applications/AppControl.cs +++ b/Tizen.Applications/Tizen.Applications/AppControl.cs @@ -67,6 +67,11 @@ namespace Tizen.Applications /// public AppControl(SafeAppControlHandle handle) { + if (handle == null) + { + throw new ArgumentNullException("handle"); + } + Interop.AppControl.ErrorCode err = Interop.AppControl.DangerousClone(out _handle, handle.DangerousGetHandle()); if (err != Interop.AppControl.ErrorCode.None) { diff --git a/Tizen.Applications/Tizen.Applications/Bundle.cs b/Tizen.Applications/Tizen.Applications/Bundle.cs index 5f54a2d..0a5bc68 100644 --- a/Tizen.Applications/Tizen.Applications/Bundle.cs +++ b/Tizen.Applications/Tizen.Applications/Bundle.cs @@ -24,7 +24,7 @@ namespace Tizen.Applications /// public class Bundle : IDisposable { - private IntPtr _handle; + private SafeBundleHandle _handle; private bool _disposed = false; private readonly HashSet _keys; @@ -42,28 +42,29 @@ namespace Tizen.Applications _keys = new HashSet(); } - internal Bundle(IntPtr handle, bool ownership = false) + /// + /// The Bundle constructor. + /// + /// The SafeBundleHandle instance. + /// Thrown when the handle is null or invalid. + public Bundle(SafeBundleHandle handle) { - if (handle != IntPtr.Zero) + if (handle == null || handle.IsInvalid) { - _handle = handle; - if (!ownership) - _disposed = true; - _keys = new HashSet(); - Interop.Bundle.Iterator iterator = (string key, int type, IntPtr keyval, IntPtr userData) => - { - _keys.Add(key); - }; - - Interop.Bundle.Foreach(_handle, iterator, IntPtr.Zero); - if ((BundleErrorFactory.BundleError)ErrorFacts.GetLastResult() == BundleErrorFactory.BundleError.InvalidParameter) - { - throw new ArgumentException("Invalid parameter - cannot create bundle instance"); - } + throw new ArgumentNullException("handle"); } - else + + _handle = Interop.Bundle.DangerousClone(handle.DangerousGetHandle()); + _keys = new HashSet(); + Interop.Bundle.Iterator iterator = (string key, int type, IntPtr keyval, IntPtr userData) => { - throw new ArgumentNullException("handle"); + _keys.Add(key); + }; + + Interop.Bundle.Foreach(_handle, iterator, IntPtr.Zero); + if ((BundleErrorFactory.BundleError)ErrorFacts.GetLastResult() == BundleErrorFactory.BundleError.InvalidParameter) + { + throw new ArgumentException("Invalid parameter - cannot create bundle instance"); } } @@ -122,12 +123,12 @@ namespace Tizen.Applications } } - internal IntPtr Handle + /// + /// Gets the SafeBundleHandle instance. + /// + public SafeBundleHandle SafeBundleHandle { - get - { - return _handle; - } + get { return _handle; } } /// @@ -576,12 +577,6 @@ namespace Tizen.Applications } } - static internal Bundle MakeRetainedBundle(IntPtr handle) - { - IntPtr clonedHandle = Interop.Bundle.Clone(handle); - return new Bundle(clonedHandle, true); - } - /// /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects. /// @@ -592,12 +587,8 @@ namespace Tizen.Applications { if (disposing) { - // to be used if there are any other disposable objects - } - if (_handle != IntPtr.Zero) - { - Interop.Bundle.Free(_handle); - _handle = IntPtr.Zero; + if (_handle != null && !_handle.IsInvalid) + _handle.Dispose(); } _disposed = true; @@ -637,7 +628,7 @@ namespace Tizen.Applications KeyExists = -0x01180000 | 0x01 } - static internal void CheckAndThrowException(int error, IntPtr handle) + static internal void CheckAndThrowException(int error, SafeBundleHandle handle) { if ((BundleError)error == BundleError.None) { @@ -649,7 +640,7 @@ namespace Tizen.Applications } else if ((BundleError)error == BundleError.InvalidParameter) { - if (handle == IntPtr.Zero) + if (handle.IsInvalid) { throw new InvalidOperationException("Invalid bundle instance (object may have been disposed or released)"); } diff --git a/Tizen.Applications/Tizen.Applications/SafeAppControlHandle.cs b/Tizen.Applications/Tizen.Applications/SafeAppControlHandle.cs index 1740190..58264fa 100644 --- a/Tizen.Applications/Tizen.Applications/SafeAppControlHandle.cs +++ b/Tizen.Applications/Tizen.Applications/SafeAppControlHandle.cs @@ -1,3 +1,11 @@ +// Copyright 2016 by Samsung Electronics, Inc., +// +// This software is the confidential and proprietary information +// of Samsung Electronics, Inc. ("Confidential Information"). You +// shall not disclose such Confidential Information and shall use +// it only in accordance with the terms of the license agreement +// you entered into with Samsung. + using System; using System.Runtime.InteropServices; diff --git a/Tizen.Applications/Tizen.Applications/SafeBundleHandle.cs b/Tizen.Applications/Tizen.Applications/SafeBundleHandle.cs new file mode 100644 index 0000000..28be52c --- /dev/null +++ b/Tizen.Applications/Tizen.Applications/SafeBundleHandle.cs @@ -0,0 +1,55 @@ +// Copyright 2016 by Samsung Electronics, Inc., +// +// This software is the confidential and proprietary information +// of Samsung Electronics, Inc. ("Confidential Information"). You +// shall not disclose such Confidential Information and shall use +// it only in accordance with the terms of the license agreement +// you entered into with Samsung. + +using System; +using System.Runtime.InteropServices; + +namespace Tizen.Applications +{ + /// + /// Represents a wrapper class for a unmanaged Bundle handle. + /// + public sealed class SafeBundleHandle : SafeHandle + { + /// + /// Initializes a new instance of the SafeBundleHandle class. + /// + public SafeBundleHandle() : base(IntPtr.Zero, true) + { + } + + /// + /// Initializes a new instance of the SafeBundleHandle class. + /// + /// An IntPtr object that represents the pre-existing handle to use. + /// true to reliably release the handle during the finalization phase; false to prevent reliable release. + public SafeBundleHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle) + { + SetHandle(existingHandle); + } + + /// + /// Gets a value that indicates whether the handle is invalid. + /// + public override bool IsInvalid + { + get { return this.handle == IntPtr.Zero; } + } + + /// + /// When overridden in a derived class, executes the code required to free the handle. + /// + /// true if the handle is released successfully + protected override bool ReleaseHandle() + { + Interop.Bundle.DangerousFree(this.handle); + this.SetHandle(IntPtr.Zero); + return true; + } + } +} -- 2.7.4