Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.System.Storage / Storage / Storage.cs
1 /*
2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 using System;
18
19 namespace Tizen.System
20 {
21     /// <summary>
22     /// The class to access the storage device information.
23     /// </summary>
24     public class Storage
25     {
26         private const string LogTag = "Tizen.System";
27         private Interop.Storage.StorageState _state;
28         private ulong _totalSpace;
29
30         internal Storage(int storageID, Interop.Storage.StorageArea storageType, Interop.Storage.StorageState storagestate, string rootDirectory)
31         {
32             Id = storageID;
33             StorageType = (StorageArea)storageType;
34             RootDirectory = rootDirectory;
35             _state = storagestate;
36
37             Interop.Storage.ErrorCode err = Interop.Storage.StorageGetTotalSpace(Id, out _totalSpace);
38             if (err != Interop.Storage.ErrorCode.None)
39             {
40                 Log.Warn(LogTag, string.Format("Failed to get total storage space for storage Id: {0}. err = {1}", Id, err));
41             }
42
43             s_stateChangedEventCallback = (id, state, userData) =>
44             {
45                 if (id == Id)
46                 {
47                     _state = state;
48                     s_stateChangedEventHandler?.Invoke(this, EventArgs.Empty);
49                 }
50             };
51         }
52
53         private EventHandler s_stateChangedEventHandler;
54         private Interop.Storage.StorageStateChangedCallback s_stateChangedEventCallback;
55
56         private void RegisterStateChangedEvent()
57         {
58             Interop.Storage.ErrorCode err = Interop.Storage.StorageSetStateChanged(Id, s_stateChangedEventCallback, IntPtr.Zero);
59             if (err != Interop.Storage.ErrorCode.None)
60             {
61                 Log.Warn(LogTag, string.Format("Failed to Register state changed event callback for storage Id: {0}. err = {1}", Id, err));
62             }
63         }
64
65         private void UnregisterStateChangedEvent()
66         {
67             Interop.Storage.ErrorCode err = Interop.Storage.StorageUnsetStateChanged(Id, s_stateChangedEventCallback);
68             if (err != Interop.Storage.ErrorCode.None)
69             {
70                 Log.Warn(LogTag, string.Format("Failed to Register state changed event callback for storage Id: {0}. err = {1}", Id, err));
71             }
72         }
73
74         /// <summary>
75         /// StorageStateChanged event. This event is occurred when a storage state changes.
76         /// </summary>
77         /// <remarks>
78         /// The storage state will be updated before calling the event handler.
79         /// </remarks>
80         /// <since_tizen> 3 </since_tizen>
81         /// <example>
82         /// <code>
83         /// myStorage.StorageStateChanged += (s, e) =>
84         /// {
85         ///     var storage = s as Storage;
86         ///     Console.WriteLine(string.Format("State Changed to {0}", storage.State));
87         /// }
88         /// </code>
89         /// </example>
90         public event EventHandler StorageStateChanged
91         {
92             add
93             {
94                 if (s_stateChangedEventHandler == null)
95                 {
96                     _state = (Interop.Storage.StorageState)State;
97                     RegisterStateChangedEvent();
98                 }
99                 s_stateChangedEventHandler += value;
100             }
101             remove
102             {
103                 if (s_stateChangedEventHandler != null)
104                 {
105                     s_stateChangedEventHandler -= value;
106                     if (s_stateChangedEventHandler == null)
107                     {
108                         UnregisterStateChangedEvent();
109                     }
110                 }
111             }
112         }
113
114         /// <summary>
115         /// The storage ID.
116         /// </summary>
117         /// <since_tizen> 3 </since_tizen>
118         public int Id { get; }
119         /// <summary>
120         /// The type of storage.
121         /// </summary>
122         /// <since_tizen> 3 </since_tizen>
123         public StorageArea StorageType { get; }
124         /// <summary>
125         /// The root directory for the storage.
126         /// </summary>
127         /// <since_tizen> 3 </since_tizen>
128         public string RootDirectory { get; }
129         /// <summary>
130         /// The total storage size in bytes.
131         /// </summary>
132         /// <since_tizen> 3 </since_tizen>
133         public ulong TotalSpace { get { return _totalSpace; } }
134
135         /// <summary>
136         /// The StorageState.
137         /// </summary>
138         /// <since_tizen> 3 </since_tizen>
139         public StorageState State
140         {
141             get
142             {
143                 if (s_stateChangedEventHandler == null)
144                 {
145                     Interop.Storage.ErrorCode err = Interop.Storage.StorageGetState(Id, out _state);
146                     if (err != Interop.Storage.ErrorCode.None)
147                     {
148                         Log.Warn(LogTag, string.Format("Failed to get storage state for storage Id: {0}. err = {1}", Id, err));
149                     }
150                 }
151                 return (StorageState)_state;
152             }
153         }
154
155         /// <summary>
156         /// The available storage size in bytes.
157         /// </summary>
158         /// <since_tizen> 3 </since_tizen>
159         public ulong AvaliableSpace
160         {
161             get
162             {
163                 ulong available;
164                 Interop.Storage.ErrorCode err = Interop.Storage.StorageGetAvailableSpace(Id, out available);
165                 if (err != Interop.Storage.ErrorCode.None)
166                 {
167                     Log.Warn(LogTag, string.Format("Failed to get available storage stace for storage Id: {0}. err = {1}", Id, err));
168                 }
169
170                 return available;
171             }
172         }
173
174         /// <summary>
175         /// Absolute path for a given directory type in the storage.
176         /// </summary>
177         /// <remarks>
178         /// The returned directory path may not exist, so you must make sure that it exists before using it.
179         /// For accessing internal storage except the ringtones directory, the application should have http://tizen.org/privilege/mediastorage privilege.
180         /// For accessing ringtones directory, the application should have http://tizen.org/privilege/systemsettings privilege.
181         /// For accessing external storage, the application should have http://tizen.org/privilege/externalstorage privilege.
182         /// </remarks>
183         /// <since_tizen> 3 </since_tizen>
184         /// <param name="dirType">Directory type.</param>
185         /// <returns>Absolute path for a given directory type in the storage.</returns>
186         /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
187         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory exception.</exception>
188         /// <exception cref="NotSupportedException">Thrown when failed if the storage is not supported or the application does not have the permission to access the directory path.</exception>
189         /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
190         /// <privilege>http://tizen.org/privilege/systemsettings</privilege>
191         /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
192         /// <example>
193         /// <code>
194         /// // To get the video directories for all the supported storage,
195         /// var storageList = StorageManager.Storages as List&lt;Storage&gt;;
196         /// foreach (var storage in storageList)
197         /// {
198         ///     string pathForVideoDir = storage.GetAbsolutePath(DirectoryType.Videos);
199         /// }
200         /// </code>
201         /// </example>
202         public string GetAbsolutePath(DirectoryType dirType)
203         {
204             string path;
205             Interop.Storage.ErrorCode err = Interop.Storage.StorageGetAbsoluteDirectory(Id, (Interop.Storage.DirectoryType)dirType, out path);
206             if (err != Interop.Storage.ErrorCode.None)
207             {
208                 Log.Warn(LogTag, string.Format("Failed to get package Id. err = {0}", err));
209                 switch (err)
210                 {
211                     case Interop.Storage.ErrorCode.InvalidParameter:
212                         throw new ArgumentException("Invalid Arguments");
213                     case Interop.Storage.ErrorCode.OutOfMemory:
214                         throw new OutOfMemoryException("Out of Memory");
215                     case Interop.Storage.ErrorCode.NotSupported:
216                         throw new NotSupportedException("Operation Not Supported");
217                     default:
218                         throw new InvalidOperationException("Error = " + err);
219                 }
220             }
221             return path;
222         }
223     }
224 }