Skip to content

Commit

Permalink
Android: AndroidDropboxService is now waiting for newer files to down…
Browse files Browse the repository at this point in the history
…load before calling OnCloudFileDownloaded. Fixed several bugfs in AndroidDropboxService.
  • Loading branch information
ycastonguay committed Nov 25, 2013
1 parent a3cda90 commit bb47072
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 67 deletions.
79 changes: 62 additions & 17 deletions MPfm/MPfm.Android/Classes/Services/AndroidDropboxService.cs
Expand Up @@ -184,24 +184,39 @@ public void StopWatchFile(string path)
}
}

public void CloseAllFiles()
{
foreach (var file in _watchedFiles)
{
file.RemoveListener(this);
file.Close();
}
_watchedFiles.Clear();
}

public void DownloadFile(string path)
{
DbxFile file = null;
byte[] bytes = null;

try
file = _fileSystem.Open(new DbxPath(path));
Tracing.Log("AndroidDropboxService - DownloadFile - path: {0} isCached: {1} isLatest: {2}", path, file.SyncStatus.IsCached, file.SyncStatus.IsLatest);
if (file.NewerStatus == null)
{
file = _fileSystem.Open(new DbxPath(path));
bytes = ReadFully(file.ReadStream);
file.Close();

if (OnCloudFileDownloaded != null)
OnCloudFileDownloaded(path, bytes);
}
finally
else
{
if (file != null)
file.Close();
}

if (OnCloudFileDownloaded != null)
OnCloudFileDownloaded(path, bytes);
Tracing.Log("AndroidDropboxService - DownloadFile - NewerStatus; adding listener - path: {0}", path);
file.AddListener(this);
_watchedFiles.Add(file);
Tracing.Log("AndroidDropboxService - DownloadFile - NewerStatus; *AFTER* adding listener - path: {0} isLatest: {1}", path, file.SyncStatus.IsLatest);
}
}

public void UploadFile(string path, byte[] data)
Expand Down Expand Up @@ -327,7 +342,7 @@ public static byte[] ReadFully(Stream input)

public void OnDatastoreStatusChange(DbxDatastore store)
{
// Console.WriteLine("SyncCloudActivity - OnDatastoreStatusChange - hasIncoming: {0}", store.SyncStatus.HasIncoming);
// Tracing.Log("SyncCloudActivity - OnDatastoreStatusChange - hasIncoming: {0}", store.SyncStatus.HasIncoming);
// //if (OnDropboxDataChanged != null) OnDropboxDataChanged(string.Format("Data changed: {0} incoming: {1}", DateTime.Now.ToLongTimeString(), store.SyncStatus.HasIncoming));
// if (store.SyncStatus.HasIncoming)
// {
Expand All @@ -349,7 +364,7 @@ public void OnDatastoreStatusChange(DbxDatastore store)
// }
// catch (Exception ex)
// {
// Console.WriteLine("SyncCloudActivity - OnDatastoreStatusChange exception: {0}", ex);
// Tracing.Log("SyncCloudActivity - OnDatastoreStatusChange exception: {0}", ex);
// if (OnCloudDataChanged != null) OnCloudDataChanged(string.Format("Error: {0}", ex));
// //throw;
// }
Expand All @@ -358,36 +373,66 @@ public void OnDatastoreStatusChange(DbxDatastore store)

public void OnLinkedAccountChange(DbxAccountManager accountManager, DbxAccount account)
{
Console.WriteLine("AndroidDropboxService - OnLinkedAccountChange");
Tracing.Log("AndroidDropboxService - OnLinkedAccountChange");
_account = account.IsLinked ? account : null;
}

public void OnSyncStatusChange(DbxFileSystem fileSystem)
{
Console.WriteLine("AndroidDropboxService - OnSyncStatusChange - anyInProgress: {0}", fileSystem.SyncStatus.AnyInProgress());
Tracing.Log("AndroidDropboxService - OnSyncStatusChange - anyInProgress: {0}", fileSystem.SyncStatus.AnyInProgress());
}

public void OnPathChange(DbxFileSystem fileSystem, DbxPath registeredPath, DbxFileSystem.PathListenerMode registeredMode)
{
Console.WriteLine("AndroidDropboxService - OnPathChange - path: {0}", registeredPath.Name);
Tracing.Log("AndroidDropboxService - OnPathChange - path: {0}", registeredPath.Name);

Task.Factory.StartNew(() =>
{
var fileInfos = fileSystem.ListFolder(registeredPath);
foreach(var fileInfo in fileInfos)
{
Console.WriteLine("AndroidDropboxService - OnPathChange - path: {0} size: {1} modifiedTime: {2} isFolder: {3}", fileInfo.Path.Name, fileInfo.Size, fileInfo.ModifiedTime, fileInfo.IsFolder);
Tracing.Log("AndroidDropboxService - OnPathChange - path: {0} size: {1} modifiedTime: {2} isFolder: {3}", fileInfo.Path.Name, fileInfo.Size, fileInfo.ModifiedTime, fileInfo.IsFolder);
}
});
}

public void OnFileChange(DbxFile file)
{
Tracing.Log("AndroidDropboxService - OnFileChange");
if (file == null)
return;

Console.WriteLine("AndroidDropboxService - OnFileChange - path: {0} syncStatus: {1}", file.Path, file.SyncStatus);
Task.Factory.StartNew(() =>
{
try
{
Tracing.Log("AndroidDropboxService - OnFileChange - path: {0} syncStatus: {1} bytesTransfered: {2} bytesTotal: {3} isCached: {4} isLatest: {5}", file.Path.Name, file.SyncStatus.Pending, file.SyncStatus.BytesTransferred, file.SyncStatus.BytesTotal, file.SyncStatus.IsCached, file.SyncStatus.IsLatest);
if (file.NewerStatus != null)
{
Tracing.Log("AndroidDropboxService - OnFileChange - path: {0} newerStatus: {1} bytesTransfered: {2} bytesTotal: {3} isCached: {4} isLatest: {5}", file.Path.Name, file.NewerStatus.Pending, file.NewerStatus.BytesTransferred, file.NewerStatus.BytesTotal, file.NewerStatus.IsCached, file.NewerStatus.IsLatest);
if (file.NewerStatus.IsLatest)
{
Tracing.Log("AndroidDropboxService - OnFileChange - Finished downloading! Updating file...");
file.Update();
byte[] bytes = ReadFully(file.ReadStream);
Tracing.Log("AndroidDropboxService - OnFileChange - Finished downloading! (2)");
if (OnCloudFileDownloaded != null)
{
Tracing.Log("AndroidDropboxService - OnFileChange - Finished downloading! (3)");
OnCloudFileDownloaded(string.Format("/Devices/{0}", file.Path.Name), bytes);
Tracing.Log("AndroidDropboxService - OnFileChange - Finished downloading! (4)");
}
Tracing.Log("AndroidDropboxService - OnFileChange - Finished downloading! (5)");
}
}
}
catch (Exception ex)
{
// Ignore file close exceptions
Tracing.Log("AndroidDropboxService - OnFileChanged - Exception: {0}", ex);
}
});
}

}
}
111 changes: 64 additions & 47 deletions MPfm/MPfm.Library/Services/CloudLibraryService.cs
Expand Up @@ -31,6 +31,7 @@ namespace MPfm.Library.Services
{
public class CloudLibraryService : ICloudLibraryService
{
private readonly object _locker = new object();
private readonly ICloudService _cloudService;
private readonly ILibraryService _libraryService;
private readonly IAudioFileCacheService _audioFileCacheService;
Expand Down Expand Up @@ -66,68 +67,84 @@ private void Initialize()

private void CloudServiceOnCloudFileDownloaded(string path, byte[] data)
{
try
lock (_locker)
{
string json = Encoding.UTF8.GetString(data);
var device = JsonConvert.DeserializeObject<CloudDeviceInfo>(json);

// Try to update the list instead of adding/removing item
int itemIndex = _deviceInfos.FindIndex(x => x.DeviceId == device.DeviceId);
if (itemIndex == -1)
_deviceInfos.Add(device);
else
_deviceInfos[itemIndex] = device;
}
catch (Exception ex)
{
Tracing.Log("AndroidDropboxService - Failed to deserialize JSON for path {0} - ex: {1}", path, ex);
}
try
{
Tracing.Log("CloudLibraryService - CloudServiceOnCloudFileDownloaded - path: {0}", path);
string json = Encoding.UTF8.GetString(data);
var device = JsonConvert.DeserializeObject<CloudDeviceInfo>(json);

Tracing.Log("CloudLibraryService - CloudServiceOnCloudFileDownloaded - path: {0} device: {1} artist: {2}", path, device.DeviceName, device.ArtistName);

// Try to update the list instead of adding/removing item
int itemIndex = _deviceInfos.FindIndex(x => x.DeviceId == device.DeviceId);
if (itemIndex == -1)
_deviceInfos.Add(device);
else
_deviceInfos[itemIndex] = device;
}
catch (Exception ex)
{
Tracing.Log("AndroidDropboxService - Failed to deserialize JSON for path {0} - ex: {1}", path, ex);
}

if (OnDeviceInfosDownloadProgress != null)
OnDeviceInfosDownloadProgress(_deviceInfos.Count / (_deviceInfos.Count + _deviceInfosLeftToDownload.Count));
if (OnDeviceInfosDownloadProgress != null)
OnDeviceInfosDownloadProgress(_deviceInfos.Count/(_deviceInfos.Count + _deviceInfosLeftToDownload.Count));

// On iOS and Android, the filePath is relative; on desktop devices it is absolute.
_deviceInfosLeftToDownload.Remove(path);
Tracing.Log("CloudLibraryService - CloudServiceOnCloudFileDownloaded - path: {0} deviceInfosLeftToDownload.Count: {1} deviceInfos.Count: {2}", path, _deviceInfosLeftToDownload.Count, _deviceInfos.Count);
if (_deviceInfosLeftToDownload.Count == 0)
{
Tracing.Log("CloudLibraryService - CloudServiceOnCloudFileDownloaded - Finished download files!");
if (OnDeviceInfosAvailable != null)
OnDeviceInfosAvailable(_deviceInfos);
// Check if list is already empty; do not raise OnDeviceInfosAvailable multiple times
if (_deviceInfosLeftToDownload.Count == 0)
return;

_deviceInfosLeftToDownload.Remove(path);
Tracing.Log("CloudLibraryService - CloudServiceOnCloudFileDownloaded - path: {0} deviceInfosLeftToDownload.Count: {1} deviceInfos.Count: {2}", path, _deviceInfosLeftToDownload.Count, _deviceInfos.Count);
if (_deviceInfosLeftToDownload.Count == 0)
{
Tracing.Log("CloudLibraryService - CloudServiceOnCloudFileDownloaded - Finished downloading files!");
_cloudService.CloseAllFiles();
if (OnDeviceInfosAvailable != null)
OnDeviceInfosAvailable(_deviceInfos);
}
}
}

public void InitializeAppFolder()
{
if(!_cloudService.FileExists("/Devices"))
_cloudService.CreateFolder("/Devices");
if (!_cloudService.FileExists("/Playlists"))
_cloudService.CreateFolder("/Playlists");
Task.Factory.StartNew(() =>
{
if (!_cloudService.FileExists("/Devices"))
_cloudService.CreateFolder("/Devices");
if (!_cloudService.FileExists("/Playlists"))
_cloudService.CreateFolder("/Playlists");
});
}

public void PushDeviceInfo(AudioFile audioFile, long positionBytes, string position)
{
{
if (!HasLinkedAccount)
throw new CloudAppNotLinkedException();

var device = new CloudDeviceInfo()
Task.Factory.StartNew(() =>
{
AudioFileId = audioFile.Id,
ArtistName = audioFile.ArtistName,
AlbumTitle = audioFile.AlbumTitle,
SongTitle = audioFile.Title,
Position = position,
PositionBytes = positionBytes,
DeviceType = _deviceSpecifications.GetDeviceType().ToString(),
DeviceName = _deviceSpecifications.GetDeviceName(),
DeviceId = _deviceSpecifications.GetDeviceUniqueId(),
IPAddress = _deviceSpecifications.GetIPAddress(),
Timestamp = DateTime.Now
};

string json = JsonConvert.SerializeObject(device);
byte[] bytes = Encoding.UTF8.GetBytes(json);
_cloudService.UploadFile(string.Format("/Devices/{0}.json", device.DeviceId), bytes);
var device = new CloudDeviceInfo()
{
AudioFileId = audioFile.Id,
ArtistName = audioFile.ArtistName,
AlbumTitle = audioFile.AlbumTitle,
SongTitle = audioFile.Title,
Position = position,
PositionBytes = positionBytes,
DeviceType = _deviceSpecifications.GetDeviceType().ToString(),
DeviceName = _deviceSpecifications.GetDeviceName(),
DeviceId = _deviceSpecifications.GetDeviceUniqueId(),
IPAddress = _deviceSpecifications.GetIPAddress(),
Timestamp = DateTime.Now
};
string json = JsonConvert.SerializeObject(device);
byte[] bytes = Encoding.UTF8.GetBytes(json);
_cloudService.UploadFile(string.Format("/Devices/{0}.json", device.DeviceId), bytes);
});
}

public void PullDeviceInfos()
Expand Down
5 changes: 3 additions & 2 deletions MPfm/MPfm.Library/Services/Interfaces/ICloudService.cs
Expand Up @@ -46,10 +46,11 @@ public interface ICloudService
void CreateFolder(string path);
bool FileExists(string path);
List<string> ListFiles(string path, string extension);
void WatchFile(string path);
void StopWatchFile(string path);
void DownloadFile(string path);
void UploadFile(string path, byte[] data);
void WatchFile(string path);
void StopWatchFile(string path);
void CloseAllFiles();
}

public enum CloudAuthenticationStatusType
Expand Down
2 changes: 1 addition & 1 deletion MPfm/MPfm.MVP/Presenters/SplashPresenter.cs
Expand Up @@ -131,7 +131,7 @@ private void Close()
{
if (_hasFinishedInitialization)
return;
View.InitDone(true);
_onInitDone();
View.RefreshStatus("Opening app...");
Expand Down

0 comments on commit bb47072

Please sign in to comment.