[Storage] Added base implementation
authorDinesh Dwivedi <dinesh.d@samsung.com>
Wed, 18 May 2016 11:54:11 +0000 (17:24 +0530)
committerDinesh Dwivedi <dinesh.d@samsung.com>
Wed, 18 May 2016 11:59:05 +0000 (17:29 +0530)
Change-Id: I35d1db19be2b6d2c1b094d137ca472d592a442da
Signed-off-by: Dinesh Dwivedi <dinesh.d@samsung.com>
Tizen.System/Interop/Interop.Libraries.cs
Tizen.System/Interop/Interop.Storage.cs [new file with mode: 0644]
Tizen.System/Storage/DirectoryType.cs [new file with mode: 0644]
Tizen.System/Storage/Storage.cs [new file with mode: 0644]
Tizen.System/Storage/StorageArea.cs [new file with mode: 0644]
Tizen.System/Storage/StorageManager.cs [new file with mode: 0644]
Tizen.System/Storage/StorageState.cs [new file with mode: 0644]
Tizen.System/Tizen.System.csproj
packaging/csapi-tizen.system.spec

index 93a287c..ab50290 100644 (file)
@@ -11,6 +11,7 @@ internal static partial class Interop
     internal static partial class Libraries
     {
         internal const string RuntimeInfo = "libcapi-system-runtime-info.so.0";
+        internal const string Storage = "libstorage.so.0.1";
         internal const string SystemInfo = "libcapi-system-info.so.0";
     }
 }
diff --git a/Tizen.System/Interop/Interop.Storage.cs b/Tizen.System/Interop/Interop.Storage.cs
new file mode 100644 (file)
index 0000000..094320b
--- /dev/null
@@ -0,0 +1,101 @@
+// 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;
+
+internal static partial class Interop
+{
+    internal static partial class Storage
+    {
+        internal enum ErrorCode
+        {
+            None = Tizen.Internals.Errors.ErrorCode.None,
+            InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+            OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+            NotSupported = Tizen.Internals.Errors.ErrorCode.NoSuchDevice,
+            OperationFailed = -0x00020000 | 0x12,
+        }
+
+        // Any change here might require changes in Tizen.System.StorageArea enum
+        internal enum StorageArea
+        {
+            Internal = 0,
+            External = 1,
+        }
+
+        // Any change here might require changes in Tizen.System.StorageState enum
+        internal enum StorageState
+        {
+            Unmountable = -2,
+            Removed = -1,
+            Mounted = 0,
+            MountedReadOnly = 1,
+        }
+
+        // Any change here might require changes in Tizen.System.directoryType enum
+        internal enum DirectoryType
+        {
+            Images = 0,
+            Sounds = 1,
+            Videos = 2,
+            Camera = 3,
+            Downloads = 4,
+            Music = 5,
+            Documents = 6,
+            Others = 7,
+            Ringtones = 8,
+        }
+
+        [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+        internal delegate void StorageStateChangedCallback(int id, StorageState state, IntPtr userData);
+
+        [DllImport(Libraries.Storage, EntryPoint = "storage_get_root_directory")]
+        internal static extern ErrorCode StorageGetRootDirectory(int id, out string path);
+
+        [DllImport(Libraries.Storage, EntryPoint = "storage_get_directory")]
+        internal static extern ErrorCode StorageGetAbsoluteDirectory(int id, DirectoryType type, out string path);
+
+        [DllImport(Libraries.Storage, EntryPoint = "storage_get_state")]
+        internal static extern ErrorCode StorageGetState(int id, out StorageState state);
+
+        [DllImport(Libraries.Storage, EntryPoint = "storage_get_type")]
+        internal static extern ErrorCode StorageGetType(int id, out StorageArea type);
+
+        [DllImport(Libraries.Storage, EntryPoint = "storage_set_state_changed_cb")]
+        internal static extern ErrorCode StorageSetStateChanged(int id, StorageStateChangedCallback callback, IntPtr userData);
+
+        [DllImport(Libraries.Storage, EntryPoint = "storage_unset_state_changed_cb")]
+        internal static extern ErrorCode StorageUnsetStateChanged(int id, StorageStateChangedCallback callback);
+
+        [DllImport(Libraries.Storage, EntryPoint = "storage_get_total_space")]
+        internal static extern ErrorCode StorageGetTotalSpace(int id, out ulong bytes);
+
+        [DllImport(Libraries.Storage, EntryPoint = "storage_get_available_space")]
+        internal static extern ErrorCode StorageGetAvailableSpace(int id, out ulong bytes);
+
+        [StructLayout(LayoutKind.Sequential)]
+        public struct FileSystemInfo
+        {
+            public uint BlockSize;
+            public uint FragmentSize;
+            public uint BlockCount;
+            public uint FreeBlocks;
+            public uint BlockAvailable;
+
+            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
+            public uint[] vals;
+        }
+
+        [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
+        internal delegate bool StorageDeviceSupportedCallback(int storageID, StorageArea type, StorageState state, string rootDirectory, IntPtr userData);
+
+        [DllImport(Libraries.Storage, EntryPoint = "storage_foreach_device_supported")]
+        public static extern ErrorCode StorageManagerGetForeachDeviceSupported(StorageDeviceSupportedCallback callback, IntPtr userData);
+    }
+}
diff --git a/Tizen.System/Storage/DirectoryType.cs b/Tizen.System/Storage/DirectoryType.cs
new file mode 100644 (file)
index 0000000..fdb2f85
--- /dev/null
@@ -0,0 +1,53 @@
+// 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.
+
+namespace Tizen.System.Storage
+{
+    /// <summary>
+    /// Enumeration of the storage directory types.
+    /// </summary>
+    public enum DirectoryType
+    {
+        /// <summary>
+        /// Image directory
+        /// </summary>
+        Images = Interop.Storage.DirectoryType.Images,
+        /// <summary>
+        /// Sounds directory
+        /// </summary>
+        Sounds = Interop.Storage.DirectoryType.Sounds,
+        /// <summary>
+        /// Videos directory
+        /// </summary>
+        Videos = Interop.Storage.DirectoryType.Videos,
+        /// <summary>
+        /// Camera directory
+        /// </summary>
+        Camera = Interop.Storage.DirectoryType.Camera,
+        /// <summary>
+        /// Downloads directory
+        /// </summary>
+        Downloads = Interop.Storage.DirectoryType.Downloads,
+        /// <summary>
+        /// Music directory
+        /// </summary>
+        Music = Interop.Storage.DirectoryType.Music,
+        /// <summary>
+        /// Documents directory
+        /// </summary>
+        Documents = Interop.Storage.DirectoryType.Documents,
+        /// <summary>
+        /// Others directory
+        /// </summary>
+        Others = Interop.Storage.DirectoryType.Others,
+        /// <summary>
+        /// System ringtones directory. Only available for internal storage.
+        /// </summary>
+        Ringtones = Interop.Storage.DirectoryType.Ringtones,
+    }
+}
\ No newline at end of file
diff --git a/Tizen.System/Storage/Storage.cs b/Tizen.System/Storage/Storage.cs
new file mode 100644 (file)
index 0000000..25ba441
--- /dev/null
@@ -0,0 +1,208 @@
+// 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;
+
+namespace Tizen.System.Storage
+{
+    /// <summary>
+    /// class to access storage device information
+    /// </summary>
+    public class Storage
+    {
+        private const string LogTag = "Tizen.System";
+        private Interop.Storage.StorageState _state;
+        private ulong _totalSpace;
+
+        internal Storage(int storageID, Interop.Storage.StorageArea storageType, Interop.Storage.StorageState storagestate, string rootDirectory)
+        {
+            Id = storageID;
+            StorageType = (StorageArea)storageType;
+            RootDirectory = rootDirectory;
+            _state = storagestate;
+
+            Interop.Storage.ErrorCode err = Interop.Storage.StorageGetTotalSpace(Id, out _totalSpace);
+            if (err != Interop.Storage.ErrorCode.None)
+            {
+                Log.Warn(LogTag, string.Format("Failed to get total storage space for storage Id: {0}. err = {1}", Id, err));
+            }
+
+            s_stateChangedEventCallback = (id, state, userData) =>
+            {
+                if (id == Id)
+                {
+                    _state = state;
+                    s_stateChangedEventHandler?.Invoke(this, EventArgs.Empty);
+                }
+            };
+        }
+
+        private EventHandler s_stateChangedEventHandler;
+        private Interop.Storage.StorageStateChangedCallback s_stateChangedEventCallback;
+
+        private void RegisterStateChangedEvent()
+        {
+            Interop.Storage.ErrorCode err = Interop.Storage.StorageSetStateChanged(Id, s_stateChangedEventCallback, IntPtr.Zero);
+            if (err != Interop.Storage.ErrorCode.None)
+            {
+                Log.Warn(LogTag, string.Format("Failed to Register state changed event callback for storage Id: {0}. err = {1}", Id, err));
+            }
+        }
+
+        private void UnregisterStateChangedEvent()
+        {
+            Interop.Storage.ErrorCode err = Interop.Storage.StorageUnsetStateChanged(Id, s_stateChangedEventCallback);
+            if (err != Interop.Storage.ErrorCode.None)
+            {
+                Log.Warn(LogTag, string.Format("Failed to Register state changed event callback for storage Id: {0}. err = {1}", Id, err));
+            }
+        }
+
+        /// <summary>
+        /// StorageStateChanged event. This event is occurred when a storage state changes.
+        /// </summary>
+        /// <remarks>
+        /// Storage state will be updated before calling event handler.
+        /// </remarks>
+        /// <example>
+        /// <code>
+        /// myStorage.StorageStateChanged += (s, e) =>
+        /// {
+        ///     var storage = s as Storage;
+        ///     Console.WriteLine(string.Format("State Changed to {0}", storage.State));
+        /// }
+        /// </code>
+        /// </example>
+        public event EventHandler StorageStateChanged
+        {
+            add
+            {
+                if (s_stateChangedEventHandler == null)
+                {
+                    _state = (Interop.Storage.StorageState)State;
+                    RegisterStateChangedEvent();
+                }
+                s_stateChangedEventHandler += value;
+            }
+            remove
+            {
+                if (s_stateChangedEventHandler != null)
+                {
+                    s_stateChangedEventHandler -= value;
+                    if (s_stateChangedEventHandler == null)
+                    {
+                        UnregisterStateChangedEvent();
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Storage ID
+        /// </summary>
+        public readonly int Id;
+        /// <summary>
+        /// Type of the storage
+        /// </summary>
+        public readonly StorageArea StorageType;
+        /// <summary>
+        /// Root directory for the storage
+        /// </summary>
+        public readonly string RootDirectory;
+        /// <summary>
+        /// Total storage size in bytes
+        /// </summary>
+        public ulong TotalSpace { get { return _totalSpace; } }
+
+        /// <summary>
+        /// Storage state
+        /// </summary>
+        public StorageState State
+        {
+            get
+            {
+                if (s_stateChangedEventHandler == null)
+                {
+                    Interop.Storage.ErrorCode err = Interop.Storage.StorageGetState(Id, out _state);
+                    if (err != Interop.Storage.ErrorCode.None)
+                    {
+                        Log.Warn(LogTag, string.Format("Failed to get storage state for storage Id: {0}. err = {1}", Id, err));
+                    }
+                }
+                return (StorageState)_state;
+            }
+        }
+
+        /// <summary>
+        /// Available storage size in bytes
+        /// </summary>
+        public ulong AvaliableSpace
+        {
+            get
+            {
+                ulong available;
+                Interop.Storage.ErrorCode err = Interop.Storage.StorageGetAvailableSpace(Id, out available);
+                if (err != Interop.Storage.ErrorCode.None)
+                {
+                    Log.Warn(LogTag, string.Format("Failed to get available storage stace for storage Id: {0}. err = {1}", Id, err));
+                }
+
+                return available;
+            }
+        }
+
+        /// <summary>
+        /// Absolute path for given directory type in storage
+        /// </summary>
+        /// <remarks>
+        /// returned directory path may not exist, so you must make sure that it exists before using it.
+        /// For accessing internal storage except Ringtones directory, app should have http://tizen.org/privilege/mediastorage privilege.
+        /// For accessing Ringtones directory, app should have http://tizen.org/privilege/systemsettings privilege.
+        /// For accessing external storage, app should have http://tizen.org/privilege/externalstorage privilege.
+        /// </remarks>
+        /// <param name="dirType">Directory type</param>
+        /// <returns>Absolute path for given directory type in storage</returns>
+        /// <exception cref="ArgumentException">Thrown when failed because of a invalid arguament</exception>
+        /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory exception</exception>
+        /// <exception cref="NotSupportedException">Thrown when failed if storage is not supported or app does not have permission to access directory path</exception>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/systemsettings</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <example>
+        /// <code>
+        /// // To get video directories for all supported storage,
+        /// var storageList = StorageManager.Storages as List&lt;Storage&gt;;
+        /// foreach (var storage in storageList)
+        /// {
+        ///     string pathForVideoDir = storage.GetAbsolutePath(DirectoryType.Videos);
+        /// }
+        /// </code>
+        /// </example>
+        public string GetAbsolutePath(DirectoryType dirType)
+        {
+            string path = string.Empty;
+            Interop.Storage.ErrorCode err = Interop.Storage.StorageGetAbsoluteDirectory(Id, (Interop.Storage.DirectoryType)dirType, out path);
+            if (err != Interop.Storage.ErrorCode.None)
+            {
+                Log.Warn(LogTag, string.Format("Failed to get package Id. err = {0}", err));
+                switch (err)
+                {
+                    case Interop.Storage.ErrorCode.InvalidParameter:
+                        throw new ArgumentException("Invalid Arguments");
+                    case Interop.Storage.ErrorCode.OutOfMemory:
+                        throw new OutOfMemoryException("Out of Memory");
+                    case Interop.Storage.ErrorCode.NotSupported:
+                        throw new NotSupportedException("Operation Not Supported");
+                    default:
+                        throw new InvalidOperationException("Error = " + err);
+                }
+            }
+            return path;
+        }
+    }
+}
diff --git a/Tizen.System/Storage/StorageArea.cs b/Tizen.System/Storage/StorageArea.cs
new file mode 100644 (file)
index 0000000..f1e2cbf
--- /dev/null
@@ -0,0 +1,25 @@
+// 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.
+
+namespace Tizen.System.Storage
+{
+    /// <summary>
+    /// Enumeration for storage area types.
+    /// </summary>
+    public enum StorageArea
+    {
+        /// <summary>
+        /// Internal device storage (built-in storage in a device, non-removable)
+        /// </summary>
+        Internal = Interop.Storage.StorageArea.Internal,
+        /// <summary>
+        /// External storage
+        /// </summary>
+        External = Interop.Storage.StorageArea.External,
+    }
+}
\ No newline at end of file
diff --git a/Tizen.System/Storage/StorageManager.cs b/Tizen.System/Storage/StorageManager.cs
new file mode 100644 (file)
index 0000000..8a400c7
--- /dev/null
@@ -0,0 +1,44 @@
+// 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.Collections.Generic;
+
+namespace Tizen.System.Storage
+{
+    /// <summary>
+    /// Storage Manager, provides properties/ methods to access storage in the device.
+    /// </summary>
+    public static class StorageManager
+    {
+        private const string LogTag = "Tizen.System";
+
+        /// <summary>
+        /// List of all storage in the device
+        /// </summary>
+        public static IEnumerable<Storage> Storages
+        {
+            get
+            {
+                List<Storage> storageList = new List<Storage>();
+                Interop.Storage.StorageDeviceSupportedCallback cb = (int storageID, Interop.Storage.StorageArea type, Interop.Storage.StorageState state, string rootDirectory, IntPtr userData) =>
+                {
+                    storageList.Add(new Storage(storageID, type, state, rootDirectory));
+                    return true;
+                };
+
+                Interop.Storage.ErrorCode err = Interop.Storage.StorageManagerGetForeachDeviceSupported(cb, IntPtr.Zero);
+                if (err != Interop.Storage.ErrorCode.None)
+                {
+                    Log.Warn(LogTag, string.Format("Failed to get storage list. err = {0}", err));
+                }
+                return storageList;
+            }
+        }
+    }
+}
diff --git a/Tizen.System/Storage/StorageState.cs b/Tizen.System/Storage/StorageState.cs
new file mode 100644 (file)
index 0000000..db02ccc
--- /dev/null
@@ -0,0 +1,33 @@
+// 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.
+
+namespace Tizen.System.Storage
+{
+    /// <summary>
+    /// Enumeration for the state of storage devices.
+    /// </summary>
+    public enum StorageState
+    {
+        /// <summary>
+        /// Storage is present but cannot be mounted. Typically it happens if the file system of the storage is corrupted
+        /// </summary>
+        Unmountable = Interop.Storage.StorageState.Unmountable,
+        /// <summary>
+        /// Storage is not present or removed
+        /// </summary>
+        Removed = Interop.Storage.StorageState.Removed,
+        /// <summary>
+        /// Storage is mounted with read/write access
+        /// </summary>
+        Mounted = Interop.Storage.StorageState.Mounted,
+        /// <summary>
+        /// Storage is mounted with read only access
+        /// </summary>
+        MountedReadOnly = Interop.Storage.StorageState.MountedReadOnly,
+    }
+}
\ No newline at end of file
index 194e3dc..b4a29b4 100644 (file)
@@ -66,6 +66,7 @@
     <Compile Include="Interop\Interop.Device.cs" />
     <Compile Include="Interop\Interop.RuntimeInfo.cs" />
     <Compile Include="Interop\Interop.Libraries.cs" />
+    <Compile Include="Interop\Interop.Storage.cs" />
     <Compile Include="Interop\Interop.SystemInfo.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="RuntimeInfo\CpuUsage.cs" />
     <Compile Include="RuntimeInfo\RuntimeInformation.cs" />
     <Compile Include="RuntimeInfo\RuntimeKeyStatusChangedEventArgs.cs" />
     <Compile Include="RuntimeInfo\MemoryInformation.cs" />
+    <Compile Include="Storage\DirectoryType.cs" />
+    <Compile Include="Storage\Storage.cs" />
+    <Compile Include="Storage\StorageArea.cs" />
+    <Compile Include="Storage\StorageManager.cs" />
+    <Compile Include="Storage\StorageState.cs" />
     <Compile Include="SystemInfo\SystemInfo.cs" />
   </ItemGroup>
   <ItemGroup>
index 987d2ff..82b5ed7 100755 (executable)
@@ -20,6 +20,7 @@ BuildRequires: pkgconfig(csapi-tizen)
 BuildRequires: pkgconfig(capi-system-device)
 BuildRequires: pkgconfig(capi-system-runtime-info)
 BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(storage)
 
 # P/Invoke Runtime Dependencies
 # TODO: It should be removed after fix tizen-rpm-config
@@ -27,6 +28,7 @@ BuildRequires: pkgconfig(capi-system-info)
 Requires: capi-system-device
 Requires: capi-system-runtime-info
 Requires: capi-system-info
+Requires: storage
 #BuildRequires: ...
 
 %description