New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Addition of File Manager #816
Addition of File Manager #816
Conversation
- Uncommented FileManager sections in SdlManager - Implement SdlFile and SdlArtwork classes - Implement methods in FileManager - Multiple file upload and deletion repeatedly calls completionListener, may be changed in future (ISdl)
…om/smartdevicelink/sdl_android into feature/issue_782_file_manager
- Replaced ArrayList type in member variable with List interface - Added missing calls to send RPC requests in setup and delete file
Codecov Report
@@ Coverage Diff @@
## feature/issue_782_Android_Managers #816 +/- ##
========================================================================
+ Coverage 42.64% 42.93% +0.29%
- Complexity 2980 3028 +48
========================================================================
Files 376 379 +3
Lines 17729 17939 +210
Branches 1800 1832 +32
========================================================================
+ Hits 7561 7703 +142
- Misses 9816 9863 +47
- Partials 352 373 +21
Continue to review full report at Codecov.
|
- Multiple file and artwork upload/deletion now uses MultipleFileCompletionListener (which returns map of unsuccesful filenames and error messages) - ISdl now includes sendRequests (multiple RPCs asynch) - Refactored contentsOfResource and contentsOfUri methods to minimize code duplication - Updated FileManagerTests for new multiple upload and deletion methods
…om/smartdevicelink/sdl_android into feature/issue_782_file_manager # Conflicts: # sdl_android/src/main/java/com/smartdevicelink/api/SdlManager.java
- Added null check for ListFilesResponse - now transitions to ERROR state if initialization fails - new sendMultipleFileOperations avoids code duplication between uploadFiles and deleteRemoteFiles
- Added javadocs to all public methods in FileManager - Refactored tests to use Mockito apis, shrinking overhead and imports
@@ -0,0 +1,58 @@ | |||
package com.smartdevicelink.api; | |||
|
|||
import android.content.res.Resources; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This import can be removed
|| fileType.equals(FileType.GRAPHIC_BMP)){ | ||
super.setType(fileType); | ||
}else{ | ||
throw new IllegalArgumentException("Only JPEG and PNG image types are supported."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also BMP is supported
* @param listener callback that is called on response from core | ||
*/ | ||
public void deleteRemoteFileWithName(final String fileName, final CompletionListener listener){ | ||
if(fileName == null){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably we should call listener.onComplete(false) here to let the developer know what happened? and also in deleteRemoteFilesWithNames(), uploadFiles()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if they don't provide a file or the list is empty, it's pretty much on them. They shouldn't be expecting a callback at that point
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, right I agree.
@@ -315,6 +315,15 @@ public void sendRPCRequest(RPCRequest message){ | |||
} | |||
} | |||
|
|||
@Override |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why we have to add this public method since there is already one that does that in the same class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to implement this new method in ISdl to create the _internalInterface
that is used by SdlManager and submanagers. See how sendRPCRequest()
does it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh you are right. I did not realize that the new method is inside Isdl.
* @param file SdlArtwork with file name and one of A) fileData, B) Uri, or C) resourceID set | ||
* @param listener called when core responds to the attempt to upload the file | ||
*/ | ||
public void uploadArtwork(final SdlArtwork file, final CompletionListener listener){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that uploadArtwork() & uploadArtworks() are unnecessary and can be removed. Because we can use uploadFile() & uploadFiles() to handle both SDLFile & SDLArtWork
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The iOS library has these APIs so if we can stay consistent that is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh okay, it makes sense.
-Remove unused import -Fix error message in SdlArtwork -Add null checks in FileManager apis
@askirk |
Also added description for each class
- Add method and supporting list structure in FileManager - Add corresponding unit test - Fix logic where remoteFiles list was not being updated on multiple delete file operation. Add unit test to cover such a case
*/ | ||
public class FileManager extends BaseSubManager { | ||
|
||
private static String TAG = "FileManager"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add final
modifier.
|
||
private static String TAG = "FileManager"; | ||
private List<String> remoteFiles, uploadedEphemeralFileNames; | ||
private WeakReference<Context> context; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add final
modifier.
} | ||
// on callback set manager to ready state | ||
transitionToState(BaseSubManager.READY); | ||
}else{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This case will actually never happen. onResponse
is only called when the response was successful. There is another method to override onError
that is called when issues occur.
* @param fileName name of file to be deleted | ||
* @param listener callback that is called on response from core | ||
*/ | ||
public void deleteRemoteFileWithName(final String fileName, final CompletionListener listener){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the @nonnull tag to the fileName
param
* @param listener callback that is called on response from core | ||
*/ | ||
public void deleteRemoteFileWithName(final String fileName, final CompletionListener listener){ | ||
if(fileName == null || listener == null){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it actually matter if the listener is null? Can't the developer just request the file be deleted without caring if it was successful?
* @param fileNames list of file names to be deleted | ||
* @param listener callback that is called once core responds to all deletion requests | ||
*/ | ||
public void deleteRemoteFilesWithNames(List<String> fileNames, final MultipleFileCompletionListener listener){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the @nonnull tag to the fileNames
param
* @param listener callback that is called once core responds to all deletion requests | ||
*/ | ||
public void deleteRemoteFilesWithNames(List<String> fileNames, final MultipleFileCompletionListener listener){ | ||
if(fileNames == null || fileNames.isEmpty() || listener == null){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question above about the listener being null
* @param file SdlFile with fileName and one of A) fileData, B) Uri, or C) resourceID set | ||
* @return a valid PutFile request if SdlFile contained a fileName and sufficient data | ||
*/ | ||
private PutFile createPutFile(final SdlFile file){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the @nonnull tag to the file
param
private void sendMultipleFileOperations(final List<? extends RPCRequest> requests, final MultipleFileCompletionListener listener){ | ||
final Map<String, String> errors = new HashMap<>(); | ||
final SparseArray<String> fileNameMap = new SparseArray<>(); | ||
final Boolean deletionOperation; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be a primitive boolean
* @param file SdlFile with file name and one of A) fileData, B) Uri, or C) resourceID set | ||
* @param listener called when core responds to the attempt to upload the file | ||
*/ | ||
public void uploadFile(final SdlFile file, final CompletionListener listener){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the @nonnull tag to the file
param
* @param listener called when core responds to the attempt to upload the file | ||
*/ | ||
public void uploadFile(final SdlFile file, final CompletionListener listener){ | ||
if(file == null || listener == null){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question about the listener being null as above
* @param file SdlFile | ||
* @return boolean that tells whether file has been uploaded to core (true) or not (false) | ||
*/ | ||
public boolean hasUploadedFile(SdlFile file){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the @nonnull tag to the file
param
Please pull in the |
- Add NonNull tags where appropriate - Add some final keywords to applicable variables - No longer return early if completionListener is null, just don’t attempt to call it - Fix test case that used null parameter
…om/smartdevicelink/sdl_android into feature/issue_782_file_manager # Conflicts: # sdl_android/src/main/java/com/smartdevicelink/api/SdlManager.java
- Also moved PermissionManagerTests to api folder
@@ -21,10 +21,22 @@ | |||
public OnMultipleRequestListener(){ | |||
setListenerType(UPDATE_LISTENER_TYPE_MULTIPLE_REQUESTS); | |||
correlationIds = new Vector<>(); | |||
final OnMultipleRequestListener reference = this; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unnecessary. Just call OnMultipleRequestListener.this.method
update(correlationId); | ||
} | ||
|
||
private void update(int correlationId){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be synchronized to make it thread safe
update(correlationId); | ||
} | ||
|
||
private void update(int correlationId){ | ||
correlationIds.remove(Integer.valueOf(correlationId)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just change the vector to int
instead of Integer
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Vector can't use primitive type
Fixes (Part of) #782
This PR is ready for review.
Risk
This PR makes minor API changes.
Testing Plan
Unit tests in this PR should cover all new code.
Summary
CLA