Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
* @author Christian Schabesberger
* @author Shashvat Kedia
* Copyright (C) 2019 ownCloud GmbH.
*
* <p>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* <p>
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* <p>
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
Expand Down Expand Up @@ -69,7 +69,6 @@
import com.owncloud.android.operations.common.SyncOperation;

import java.io.IOException;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
Expand Down Expand Up @@ -109,14 +108,11 @@ public class OperationsService extends Service {
public static final String ACTION_COPY_FILE = "COPY_FILE";
public static final String ACTION_CHECK_CURRENT_CREDENTIALS = "CHECK_CURRENT_CREDENTIALS";

public static final String ACTION_OPERATION_ADDED = OperationsService.class.getName() +
".OPERATION_ADDED";
public static final String ACTION_OPERATION_FINISHED = OperationsService.class.getName() +
".OPERATION_FINISHED";
public static final String ACTION_OPERATION_ADDED = OperationsService.class.getName() + ".OPERATION_ADDED";
public static final String ACTION_OPERATION_FINISHED = OperationsService.class.getName() + ".OPERATION_FINISHED";

private ConcurrentMap<Integer, Pair<RemoteOperation, RemoteOperationResult>>
mUndispatchedFinishedOperations =
new ConcurrentHashMap<>();
mUndispatchedFinishedOperations = new ConcurrentHashMap<>();

private static class Target {
public Uri mServerUrl;
Expand Down Expand Up @@ -146,8 +142,7 @@ public void onCreate() {
Log_OC.d(TAG, "Creating service");

/// First worker thread for most of operations
HandlerThread thread = new HandlerThread("Operations thread",
Process.THREAD_PRIORITY_BACKGROUND);
HandlerThread thread = new HandlerThread("Operations thread", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
mOperationsHandler = new ServiceHandler(thread.getLooper(), this);
mOperationsBinder = new OperationsServiceBinder(mOperationsHandler);
Expand All @@ -163,7 +158,7 @@ public void onCreate() {

/**
* Entry point to add a new operation to the queue of operations.
*
* <p>
* New operations are added calling to startService(), resulting in a call to this method.
* This ensures the service will keep on working although the caller activity goes away.
*/
Expand All @@ -186,8 +181,7 @@ public int onStartCommand(Intent intent, int flags, int startId) {

Pair<Target, RemoteOperation> itemToQueue = newOperation(intent);
if (itemToQueue != null) {
mSyncFolderHandler.add(account, remotePath,
(SynchronizeFolderOperation) itemToQueue.second);
mSyncFolderHandler.add(account, remotePath, (SynchronizeFolderOperation) itemToQueue.second);
Message msg = mSyncFolderHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = itemSyncKey;
Expand Down Expand Up @@ -254,16 +248,15 @@ public boolean onUnbind(Intent intent) {
* <p/>
* It provides by itself the available operations.
*/
public class OperationsServiceBinder extends Binder /* implements OnRemoteOperationListener */ {
public class OperationsServiceBinder extends Binder {

/**
* Map of listeners that will be reported about the end of operations from a
* {@link OperationsServiceBinder} instance
*/
private final ConcurrentMap<OnRemoteOperationListener, Handler> mBoundListeners =
new ConcurrentHashMap<>();
private final ConcurrentMap<OnRemoteOperationListener, Handler> mBoundListeners = new ConcurrentHashMap<>();

private ServiceHandler mServiceHandler = null;
private ServiceHandler mServiceHandler;

public OperationsServiceBinder(ServiceHandler serviceHandler) {
mServiceHandler = serviceHandler;
Expand All @@ -280,7 +273,6 @@ public void cancel(Account account, OCFile file) {
}

public void clearListeners() {

mBoundListeners.clear();
}

Expand All @@ -291,8 +283,7 @@ public void clearListeners() {
* @param callbackHandler {@link Handler} to access the listener without
* breaking Android threading protection.
*/
public void addOperationListener(OnRemoteOperationListener listener,
Handler callbackHandler) {
public void addOperationListener(OnRemoteOperationListener listener, Handler callbackHandler) {
synchronized (mBoundListeners) {
mBoundListeners.put(listener, callbackHandler);
}
Expand Down Expand Up @@ -322,7 +313,7 @@ public boolean isPerformingBlockingOperation() {

/**
* Creates and adds to the queue a new operation, as described by operationIntent.
*
* <p>
* Calls startService to make the operation is processed by the ServiceHandler.
*
* @param operationIntent Intent describing a new operation to queue and execute.
Expand All @@ -342,23 +333,21 @@ public long queueNewOperation(Intent operationIntent) {
}
}

public boolean dispatchResultIfFinished(int operationId,
OnRemoteOperationListener listener) {
public boolean dispatchResultIfFinished(int operationId, OnRemoteOperationListener listener) {
Pair<RemoteOperation, RemoteOperationResult> undispatched =
mUndispatchedFinishedOperations.remove(operationId);
if (undispatched != null) {
listener.onRemoteOperationFinish(undispatched.first, undispatched.second);
return true;
//Log_OC.e(TAG, "Sending callback later");
} else {
return (!mServiceHandler.mPendingOperations.isEmpty());
return !mServiceHandler.mPendingOperations.isEmpty();
}
}

/**
* Returns True when the file described by 'file' in the ownCloud account 'account' is
* downloading or waiting to download.
*
* <p>
* If 'file' is a directory, returns 'true' if some of its descendant files is downloading
* or waiting to download.
*
Expand All @@ -374,7 +363,7 @@ public boolean isSynchronizing(Account account, OCFile file) {

/**
* Operations worker. Performs the pending operations in the order they were requested.
*
* <p>
* Created with the Looper of a new thread, started in {@link OperationsService#onCreate()}.
*/
private static class ServiceHandler extends Handler {
Expand All @@ -383,9 +372,8 @@ private static class ServiceHandler extends Handler {

OperationsService mService;

private ConcurrentLinkedQueue<Pair<Target, RemoteOperation>> mPendingOperations =
private final ConcurrentLinkedQueue<Pair<Target, RemoteOperation>> mPendingOperations =
new ConcurrentLinkedQueue<>();
private RemoteOperation mCurrentOperation = null;
private Target mLastTarget = null;
private OwnCloudClient mOwnCloudClient = null;
private FileDataStorageManager mStorageManager;
Expand Down Expand Up @@ -419,7 +407,7 @@ private void nextOperation() {

if (next != null) {

mCurrentOperation = next.second;
RemoteOperation currentOperation = next.second;
RemoteOperationResult result;
try {
/// prepare client object to send the request to the ownCloud server
Expand Down Expand Up @@ -451,11 +439,10 @@ private void nextOperation() {
}

/// perform the operation
if (mCurrentOperation instanceof SyncOperation) {
result = ((SyncOperation) mCurrentOperation).execute(mOwnCloudClient,
mStorageManager);
if (currentOperation instanceof SyncOperation) {
result = ((SyncOperation) currentOperation).execute(mOwnCloudClient, mStorageManager);
} else {
result = mCurrentOperation.execute(mOwnCloudClient);
result = currentOperation.execute(mOwnCloudClient);
}

} catch (AccountsException | IOException e) {
Expand All @@ -482,14 +469,14 @@ private void nextOperation() {
}
}

mService.dispatchResultToOperationListeners(mCurrentOperation, result);
mService.dispatchResultToOperationListeners(currentOperation, result);
}
}
}

/**
* Creates a new operation, as described by operationIntent.
*
* <p>
* TODO - move to ServiceHandler (probably)
*
* @param operationIntent Intent describing a new operation to queue and execute.
Expand Down Expand Up @@ -544,24 +531,20 @@ private Pair<Target, RemoteOperation> newOperation(Intent operationIntent) {
} else if (action.equals(ACTION_REMOVE)) {
// Remove file or folder
String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
boolean onlyLocalCopy = operationIntent.getBooleanExtra(EXTRA_REMOVE_ONLY_LOCAL,
false);
boolean onlyLocalCopy = operationIntent.getBooleanExtra(EXTRA_REMOVE_ONLY_LOCAL, false);
operation = new RemoveFileOperation(remotePath, onlyLocalCopy,
operationIntent.getBooleanExtra(EXTRA_IS_LAST_FILE_TO_REMOVE, false));

} else if (action.equals(ACTION_CREATE_FOLDER)) {
// Create Folder
String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
boolean createFullPath = operationIntent.getBooleanExtra(EXTRA_CREATE_FULL_PATH,
true);
boolean createFullPath = operationIntent.getBooleanExtra(EXTRA_CREATE_FULL_PATH, true);
operation = new CreateFolderOperation(remotePath, createFullPath);

} else if (action.equals(ACTION_SYNC_FILE)) {
// Sync file
String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
operation = new SynchronizeFileOperation(
remotePath, account, getApplicationContext()
);
operation = new SynchronizeFileOperation(remotePath, account, getApplicationContext());

} else if (action.equals(ACTION_SYNC_FOLDER)) {
// Sync folder (all its descendant files are sync'ed)
Expand Down Expand Up @@ -612,14 +595,13 @@ remotePath, account, getApplicationContext()

/**
* Sends a broadcast when a new operation is added to the queue.
*
* <p>
* Local broadcasts are only delivered to activities in the same process, but can't be
* done sticky :\
*
* @param target Account or URL pointing to an OC server.
* @param operation Added operation.
* @param target Account or URL pointing to an OC server.
*/
private void sendBroadcastNewOperation(Target target, RemoteOperation operation) {
private void sendBroadcastNewOperation(Target target) {
Intent intent = new Intent(ACTION_OPERATION_ADDED);
if (target.mAccount != null) {
intent.putExtra(EXTRA_ACCOUNT, target.mAccount);
Expand All @@ -634,15 +616,13 @@ private void sendBroadcastNewOperation(Target target, RemoteOperation operation)
/**
* Sends a LOCAL broadcast when an operations finishes in order to the interested activities c
* an update their view
*
* <p>
* Local broadcasts are only delivered to activities in the same process.
*
* @param target Account or URL pointing to an OC server.
* @param operation Finished operation.
* @param result Result of the operation.
* @param target Account or URL pointing to an OC server.
* @param result Result of the operation.
*/
private void sendBroadcastOperationFinished(Target target, RemoteOperation operation,
RemoteOperationResult result) {
private void sendBroadcastOperationFinished(Target target, RemoteOperationResult result) {
Intent intent = new Intent(ACTION_OPERATION_FINISHED);
intent.putExtra(EXTRA_RESULT, result);
if (target.mAccount != null) {
Expand All @@ -663,24 +643,15 @@ protected void dispatchResultToOperationListeners(
final RemoteOperation operation, final RemoteOperationResult result
) {
int count = 0;
Iterator<OnRemoteOperationListener> listeners =
mOperationsBinder.mBoundListeners.keySet().iterator();
while (listeners.hasNext()) {
final OnRemoteOperationListener listener = listeners.next();
for (OnRemoteOperationListener listener : mOperationsBinder.mBoundListeners.keySet()) {
final Handler handler = mOperationsBinder.mBoundListeners.get(listener);
if (handler != null) {
handler.post(new Runnable() {
@Override
public void run() {
listener.onRemoteOperationFinish(operation, result);
}
});
handler.post(() -> listener.onRemoteOperationFinish(operation, result));
count += 1;
}
}
if (count == 0) {
Pair<RemoteOperation, RemoteOperationResult> undispatched =
new Pair<>(operation, result);
Pair<RemoteOperation, RemoteOperationResult> undispatched = new Pair<>(operation, result);
mUndispatchedFinishedOperations.put(operation.hashCode(), undispatched);
}
Log_OC.d(TAG, "Called " + count + " listeners");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ private void doOperation(Account account, String remotePath) {
}
}

public void add(Account account, String remotePath,
SynchronizeFolderOperation syncFolderOperation) {
public void add(Account account, String remotePath, SynchronizeFolderOperation syncFolderOperation) {
Pair<String, String> putResult =
mPendingOperations.putIfAbsent(account.name, remotePath, syncFolderOperation);
if (putResult != null) {
Expand Down Expand Up @@ -171,8 +170,6 @@ public void cancel(Account account, OCFile file) {
mCurrentSyncOperation.cancel();
}
}

//sendBroadcastFinishedSyncFolder(account, file.getRemotePath());
}

/**
Expand All @@ -183,22 +180,19 @@ private void sendBroadcastNewSyncFolder(Account account, String remotePath) {
Intent added = new Intent(FileDownloader.getDownloadAddedMessage());
added.putExtra(Extras.EXTRA_ACCOUNT_NAME, account.name);
added.putExtra(Extras.EXTRA_REMOTE_PATH, remotePath);
added.putExtra(Extras.EXTRA_FILE_PATH, FileStorageUtils.getSavePath(account.name)
+ remotePath);
added.putExtra(Extras.EXTRA_FILE_PATH, FileStorageUtils.getSavePath(account.name) + remotePath);
mLocalBroadcastManager.sendBroadcast(added);
}

/**
* TODO review this method when "folder synchronization" replaces "folder download";
* this is a fast and ugly patch.
*/
private void sendBroadcastFinishedSyncFolder(Account account, String remotePath,
boolean success) {
private void sendBroadcastFinishedSyncFolder(Account account, String remotePath, boolean success) {
Intent finished = new Intent(FileDownloader.getDownloadFinishMessage());
finished.putExtra(Extras.EXTRA_ACCOUNT_NAME, account.name);
finished.putExtra(Extras.EXTRA_REMOTE_PATH, remotePath);
finished.putExtra(Extras.EXTRA_FILE_PATH,
FileStorageUtils.getSavePath(account.name) + remotePath);
finished.putExtra(Extras.EXTRA_FILE_PATH, FileStorageUtils.getSavePath(account.name) + remotePath);
finished.putExtra(Extras.EXTRA_DOWNLOAD_RESULT, success);
mLocalBroadcastManager.sendBroadcast(finished);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.getbase.floatingactionbutton.FloatingActionButton;
Expand Down Expand Up @@ -140,10 +141,7 @@ public boolean isGridEnabled() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log_OC.d("onCreateView");

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.list_fragment, null);

mProgressBar = v.findViewById(R.id.syncProgressBar);
Expand Down Expand Up @@ -216,15 +214,15 @@ public void onActivityCreated(Bundle savedInstanceState) {
setMessageForEmptyList(savedInstanceState.getString(KEY_EMPTY_LIST_MESSAGE));

} else {
mIndexes = new ArrayList<Integer>();
mFirstPositions = new ArrayList<Integer>();
mTops = new ArrayList<Integer>();
mIndexes = new ArrayList<>();
mFirstPositions = new ArrayList<>();
mTops = new ArrayList<>();
mHeightCell = 0;
}
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
public void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Log_OC.d("onSaveInstanceState()");
savedInstanceState.putBoolean(KEY_IS_GRID_VISIBLE, isGridEnabled());
Expand Down
Loading