/*
* Copyright (c) 2016 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;
namespace Tizen.System
{
///
/// The class to access the storage device information.
///
/// 3
public class Storage
{
private const string LogTag = "Tizen.System";
private Interop.Storage.StorageState _state;
private Interop.Storage.StorageDevice _devicetype;
private Interop.Storage.StorageArea _storagetype;
private string _fstype;
private string _fsuuid;
private ulong _totalSpace;
private bool _primary;
private int _flags;
private bool information_set = false;
internal Storage(int storageID, Interop.Storage.StorageArea storageType, Interop.Storage.StorageState storagestate, string rootDirectory)
{
Id = storageID;
_storagetype = 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);
}
};
}
internal Storage(int storageID, Interop.Storage.StorageArea storageType, Interop.Storage.StorageState storagestate, string rootDirectory, Interop.Storage.StorageDevice devicetype, string fstype, string fsuuid, bool primary, int flags)
{
Id = storageID;
_storagetype = storageType;
RootDirectory = rootDirectory;
_state = storagestate;
_devicetype = devicetype;
_fstype = fstype;
_fsuuid = fsuuid;
_primary = primary;
_flags = flags;
information_set = true;
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.
///
///
/// The storage state will be updated before calling the event handler.
///
/// 3
/// http://tizen.org/feature/storage.external
///
///
/// 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();
}
}
}
}
///
/// The storage ID.
///
/// 3
/// http://tizen.org/feature/storage.external
public int Id { get; }
///
/// The type of storage.
///
/// 3
/// http://tizen.org/feature/storage.external
public StorageArea StorageType { get { return (StorageArea)_storagetype; } }
///
/// The root directory for the storage.
///
/// 3
/// http://tizen.org/feature/storage.external
public string RootDirectory { get; }
///
/// The total storage size in bytes.
///
/// 3
/// http://tizen.org/feature/storage.external
public ulong TotalSpace { get { return _totalSpace; } }
///
/// The StorageState.
///
/// 3
/// http://tizen.org/feature/storage.external
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;
}
}
///
/// The StorageDevice.
///
/// 5
/// http://tizen.org/feature/storage.external
/// Thrown when DeviceType is not initialized.
public StorageDevice DeviceType
{
get
{
Interop.Storage.ErrorCode err = Interop.Storage.StorageGetTypeDev(Id, out _storagetype, out _devicetype);
if (err != Interop.Storage.ErrorCode.None)
{
Log.Warn(LogTag, string.Format("Failed to get storage device type for storage Id: {0}. err = {1}", Id, err));
}
return (StorageDevice)_devicetype;
}
}
///
/// The type of file system.
///
/// 5
/// http://tizen.org/feature/storage.external
/// Thrown when Fstype is not initialized.
public string Fstype
{
get
{
if (!information_set)
{
Log.Error(LogTag, string.Format("Doesn't know fstype."));
throw new InvalidOperationException("Doesn't know type of file system");
}
return _fstype;
}
}
///
/// The UUID of the file system.
///
/// 5
/// http://tizen.org/feature/storage.external
/// Thrown when Fsuuid is not initialized.
public string Fsuuid
{
get
{
if (!information_set)
{
Log.Error(LogTag, string.Format("Doesn't know fsuuid."));
throw new InvalidOperationException("Doesn't know uuid of file system");
}
return _fsuuid;
}
}
///
/// Information whether this is a primary partition.
///
/// 5
/// http://tizen.org/feature/storage.external
/// Thrown when primary is not initialized.
public bool Primary
{
get
{
if (!information_set)
{
Log.Error(LogTag, string.Format("Doesn't know primary information."));
throw new InvalidOperationException("Doesn't know primary information");
}
return _primary;
}
}
///
/// The flags for the storage status.
///
/// 5
/// http://tizen.org/feature/storage.external
/// Thrown when flags are not initialized.
public int Flags
{
get
{
if (!information_set)
{
Log.Error(LogTag, string.Format("Doesn't know flags."));
throw new InvalidOperationException("Doesn't know flags");
}
return _flags;
}
}
///
/// [Obsolete("Please do not use! this will be deprecated")]
///
/// 3
/// Please do not use! this will be deprecated!
/// Instead please use AvailableSpace.
[Obsolete("Please do not use! This will be deprecated! Please use AvailableSpace instead!")]
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;
}
}
///
/// The available storage size in bytes.
///
/// 5
/// http://tizen.org/feature/storage.external
public ulong AvailableSpace
{
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 a given directory type in the storage.
///
///
/// The returned directory path may not exist, so you must make sure that it exists before using it.
/// For accessing internal storage except the ringtones directory, the application should have http://tizen.org/privilege/mediastorage privilege.
/// For accessing ringtones directory, the application should have http://tizen.org/privilege/systemsettings privilege.
/// For accessing external storage, the application should have http://tizen.org/privilege/externalstorage privilege.
///
/// 3
/// Directory type.
/// Absolute path for a given directory type in the storage.
/// http://tizen.org/feature/storage.external
/// Thrown when failed because of an invalid argument.
/// Thrown when failed due to out of memory exception.
/// Thrown when the storage is not supported or the application does not have the permission to access the directory path.
/// http://tizen.org/privilege/mediastorage
/// http://tizen.org/privilege/systemsettings
/// http://tizen.org/privilege/externalstorage
///
///
/// // To get the video directories for all the 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;
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("Storage Not Supported");
default:
throw new InvalidOperationException("Error = " + err);
}
}
return path;
}
}
}