From: Dinesh Dwivedi Date: Wed, 18 May 2016 11:54:11 +0000 (+0530) Subject: [Storage] Added base implementation X-Git-Tag: submit/tizen/20161214.063015~40^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d9f5cd7ea2c19673cb30839dab884e95d736c77c;p=platform%2Fcore%2Fcsapi%2Fsystem.git [Storage] Added base implementation Change-Id: I35d1db19be2b6d2c1b094d137ca472d592a442da Signed-off-by: Dinesh Dwivedi --- diff --git a/Tizen.System/Interop/Interop.Libraries.cs b/Tizen.System/Interop/Interop.Libraries.cs index 93a287c..ab50290 100644 --- a/Tizen.System/Interop/Interop.Libraries.cs +++ b/Tizen.System/Interop/Interop.Libraries.cs @@ -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 index 0000000..094320b --- /dev/null +++ b/Tizen.System/Interop/Interop.Storage.cs @@ -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 index 0000000..fdb2f85 --- /dev/null +++ b/Tizen.System/Storage/DirectoryType.cs @@ -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 +{ + /// + /// Enumeration of the storage directory types. + /// + public enum DirectoryType + { + /// + /// Image directory + /// + Images = Interop.Storage.DirectoryType.Images, + /// + /// Sounds directory + /// + Sounds = Interop.Storage.DirectoryType.Sounds, + /// + /// Videos directory + /// + Videos = Interop.Storage.DirectoryType.Videos, + /// + /// Camera directory + /// + Camera = Interop.Storage.DirectoryType.Camera, + /// + /// Downloads directory + /// + Downloads = Interop.Storage.DirectoryType.Downloads, + /// + /// Music directory + /// + Music = Interop.Storage.DirectoryType.Music, + /// + /// Documents directory + /// + Documents = Interop.Storage.DirectoryType.Documents, + /// + /// Others directory + /// + Others = Interop.Storage.DirectoryType.Others, + /// + /// System ringtones directory. Only available for internal storage. + /// + 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 index 0000000..25ba441 --- /dev/null +++ b/Tizen.System/Storage/Storage.cs @@ -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 +{ + /// + /// class to access storage device information + /// + 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)); + } + } + + /// + /// StorageStateChanged event. This event is occurred when a storage state changes. + /// + /// + /// Storage state will be updated before calling event handler. + /// + /// + /// + /// myStorage.StorageStateChanged += (s, e) => + /// { + /// var storage = s as Storage; + /// Console.WriteLine(string.Format("State Changed to {0}", storage.State)); + /// } + /// + /// + 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(); + } + } + } + } + + /// + /// Storage ID + /// + public readonly int Id; + /// + /// Type of the storage + /// + public readonly StorageArea StorageType; + /// + /// Root directory for the storage + /// + public readonly string RootDirectory; + /// + /// Total storage size in bytes + /// + public ulong TotalSpace { get { return _totalSpace; } } + + /// + /// Storage state + /// + 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; + } + } + + /// + /// Available storage size in bytes + /// + 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; + } + } + + /// + /// Absolute path for given directory type in storage + /// + /// + /// 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. + /// + /// Directory type + /// Absolute path for given directory type in storage + /// Thrown when failed because of a invalid arguament + /// Thrown when failed due to out of memory exception + /// Thrown when failed if storage is not supported or app does not have permission to access directory path + /// http://tizen.org/privilege/mediastorage + /// http://tizen.org/privilege/systemsettings + /// http://tizen.org/privilege/externalstorage + /// + /// + /// // To get video directories for all supported storage, + /// var storageList = StorageManager.Storages as List<Storage>; + /// foreach (var storage in storageList) + /// { + /// string pathForVideoDir = storage.GetAbsolutePath(DirectoryType.Videos); + /// } + /// + /// + 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 index 0000000..f1e2cbf --- /dev/null +++ b/Tizen.System/Storage/StorageArea.cs @@ -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 +{ + /// + /// Enumeration for storage area types. + /// + public enum StorageArea + { + /// + /// Internal device storage (built-in storage in a device, non-removable) + /// + Internal = Interop.Storage.StorageArea.Internal, + /// + /// External storage + /// + 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 index 0000000..8a400c7 --- /dev/null +++ b/Tizen.System/Storage/StorageManager.cs @@ -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 +{ + /// + /// Storage Manager, provides properties/ methods to access storage in the device. + /// + public static class StorageManager + { + private const string LogTag = "Tizen.System"; + + /// + /// List of all storage in the device + /// + public static IEnumerable Storages + { + get + { + List storageList = new List(); + 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 index 0000000..db02ccc --- /dev/null +++ b/Tizen.System/Storage/StorageState.cs @@ -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 +{ + /// + /// Enumeration for the state of storage devices. + /// + public enum StorageState + { + /// + /// Storage is present but cannot be mounted. Typically it happens if the file system of the storage is corrupted + /// + Unmountable = Interop.Storage.StorageState.Unmountable, + /// + /// Storage is not present or removed + /// + Removed = Interop.Storage.StorageState.Removed, + /// + /// Storage is mounted with read/write access + /// + Mounted = Interop.Storage.StorageState.Mounted, + /// + /// Storage is mounted with read only access + /// + MountedReadOnly = Interop.Storage.StorageState.MountedReadOnly, + } +} \ No newline at end of file diff --git a/Tizen.System/Tizen.System.csproj b/Tizen.System/Tizen.System.csproj index 194e3dc..b4a29b4 100644 --- a/Tizen.System/Tizen.System.csproj +++ b/Tizen.System/Tizen.System.csproj @@ -66,6 +66,7 @@ + @@ -74,6 +75,11 @@ + + + + + diff --git a/packaging/csapi-tizen.system.spec b/packaging/csapi-tizen.system.spec index 987d2ff..82b5ed7 100755 --- a/packaging/csapi-tizen.system.spec +++ b/packaging/csapi-tizen.system.spec @@ -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