mirror of
https://github.com/nextcloud/android.git
synced 2024-11-26 07:05:49 +03:00
New user model
New non-nullable user model abstracts away all complexities of Nextcloud user account and provides. - backported java.util.Optional - extended UserAccountManager with User getters - deprecated CurrentAccountProvider.getCurrentAccount() method - migrated connectivity service to new user model - migrated UploadsStorageManager to new user model - migrated OCFileListAdapter Signed-off-by: Chris Narkiewicz <hello@ezaquarii.com>
This commit is contained in:
parent
b9ff6cecfc
commit
609b99666f
16 changed files with 994 additions and 158 deletions
57
src/main/java/com/nextcloud/client/account/AnonymousUser.kt
Normal file
57
src/main/java/com/nextcloud/client/account/AnonymousUser.kt
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Nextcloud Android client application
|
||||||
|
*
|
||||||
|
* @author Chris Narkiewicz <hello@ezaquarii.com>
|
||||||
|
* Copyright (C) 2019 Chris Narkiewicz
|
||||||
|
* Copyright (C) 2019 Nextcloud GmbH
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.nextcloud.client.account
|
||||||
|
|
||||||
|
import android.accounts.Account
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
|
import com.owncloud.android.MainApp
|
||||||
|
import com.owncloud.android.R
|
||||||
|
import com.owncloud.android.lib.common.OwnCloudAccount
|
||||||
|
import com.owncloud.android.lib.common.OwnCloudBasicCredentials
|
||||||
|
import java.net.URI
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This object represents anonymous user, ie. user that did not log in the Nextcloud server.
|
||||||
|
* It serves as a semantically correct "empty value", allowing simplification of logic
|
||||||
|
* in various components requiring user data, such as DB queries.
|
||||||
|
*/
|
||||||
|
internal class AnonymousUser(private val accountType: String) : User {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun fromContext(context: Context): AnonymousUser {
|
||||||
|
val type = context.getString(R.string.account_type)
|
||||||
|
return AnonymousUser(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val accountName: String = "anonymous"
|
||||||
|
override val server = Server(URI.create(""), MainApp.MINIMUM_SUPPORTED_SERVER_VERSION)
|
||||||
|
|
||||||
|
override fun toPlatformAccount(): Account {
|
||||||
|
return Account(accountName, accountType)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toOwnCloudAccount(): OwnCloudAccount {
|
||||||
|
return OwnCloudAccount(Uri.EMPTY, OwnCloudBasicCredentials("", ""))
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,19 +2,31 @@ package com.nextcloud.client.account;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface provides access to currently selected user Account.
|
* This interface provides access to currently selected user.
|
||||||
|
*
|
||||||
* @see UserAccountManager
|
* @see UserAccountManager
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
|
||||||
public interface CurrentAccountProvider {
|
public interface CurrentAccountProvider {
|
||||||
/**
|
/**
|
||||||
* Get currently active account.
|
* Get currently active account.
|
||||||
*
|
*
|
||||||
* @return Currently selected {@link Account} or first valid {@link Account} registered in OS or null, if not available at all.
|
* @return Currently selected {@link Account} or first valid {@link Account} registered in OS or null, if not available at all.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@Nullable
|
@Nullable
|
||||||
Account getCurrentAccount();
|
Account getCurrentAccount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get currently active user profile. If there is no actice user, anonymous user is returned.
|
||||||
|
*
|
||||||
|
* @return User profile. Profile is never null.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
default User getUser() {
|
||||||
|
return new AnonymousUser("dummy");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
46
src/main/java/com/nextcloud/client/account/RegisteredUser.kt
Normal file
46
src/main/java/com/nextcloud/client/account/RegisteredUser.kt
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Nextcloud Android client application
|
||||||
|
*
|
||||||
|
* @author Chris Narkiewicz <hello@ezaquarii.com>
|
||||||
|
* Copyright (C) 2019 Chris Narkiewicz
|
||||||
|
* Copyright (C) 2019 Nextcloud GmbH
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.nextcloud.client.account
|
||||||
|
|
||||||
|
import android.accounts.Account
|
||||||
|
import com.owncloud.android.lib.common.OwnCloudAccount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents normal user logged into the Nextcloud server.
|
||||||
|
*/
|
||||||
|
internal class RegisteredUser(
|
||||||
|
private val account: Account,
|
||||||
|
private val ownCloudAccount: OwnCloudAccount,
|
||||||
|
override val server: Server
|
||||||
|
) : User {
|
||||||
|
|
||||||
|
override val accountName: String get() {
|
||||||
|
return account.name
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toPlatformAccount(): Account {
|
||||||
|
return account
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toOwnCloudAccount(): OwnCloudAccount {
|
||||||
|
return ownCloudAccount
|
||||||
|
}
|
||||||
|
}
|
30
src/main/java/com/nextcloud/client/account/Server.kt
Normal file
30
src/main/java/com/nextcloud/client/account/Server.kt
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Nextcloud Android client application
|
||||||
|
*
|
||||||
|
* @author Chris Narkiewicz <hello@ezaquarii.com>
|
||||||
|
* Copyright (C) 2019 Chris Narkiewicz
|
||||||
|
* Copyright (C) 2019 Nextcloud GmbH
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.nextcloud.client.account
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion
|
||||||
|
import java.net.URI
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This object provides all information necessary to interact
|
||||||
|
* with backend server.
|
||||||
|
*/
|
||||||
|
data class Server(val uri: URI, val version: OwnCloudVersion)
|
53
src/main/java/com/nextcloud/client/account/User.kt
Normal file
53
src/main/java/com/nextcloud/client/account/User.kt
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Nextcloud Android client application
|
||||||
|
*
|
||||||
|
* @author Chris Narkiewicz <hello@ezaquarii.com>
|
||||||
|
* Copyright (C) 2019 Chris Narkiewicz
|
||||||
|
* Copyright (C) 2019 Nextcloud GmbH
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.nextcloud.client.account
|
||||||
|
|
||||||
|
import android.accounts.Account
|
||||||
|
import com.owncloud.android.lib.common.OwnCloudAccount
|
||||||
|
|
||||||
|
interface User {
|
||||||
|
val accountName: String
|
||||||
|
val server: Server
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is temporary helper method created to facilitate incremental refactoring.
|
||||||
|
* Code using legacy platform Account can be partially converted to instantiate User
|
||||||
|
* object and use account instance when required.
|
||||||
|
*
|
||||||
|
* This method calls will allow tracing code awaiting further refactoring.
|
||||||
|
*
|
||||||
|
* @return Account instance that is associated with this User object.
|
||||||
|
*/
|
||||||
|
@Deprecated("Temporary workaround")
|
||||||
|
fun toPlatformAccount(): Account
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is temporary helper method created to facilitate incremental refactoring.
|
||||||
|
* Code using legacy ownCloud account can be partially converted to instantiate User
|
||||||
|
* object and use account instance when required.
|
||||||
|
*
|
||||||
|
* This method calls will allow tracing code awaiting further refactoring.
|
||||||
|
*
|
||||||
|
* @return OwnCloudAccount instance that is associated with this User object.
|
||||||
|
*/
|
||||||
|
@Deprecated("Temporary workaround")
|
||||||
|
fun toOwnCloudAccount(): OwnCloudAccount
|
||||||
|
}
|
|
@ -21,10 +21,13 @@ package com.nextcloud.client.account;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
|
|
||||||
|
import com.nextcloud.java.util.Optional;
|
||||||
import com.owncloud.android.datamodel.OCFile;
|
import com.owncloud.android.datamodel.OCFile;
|
||||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
@ -51,6 +54,22 @@ public interface UserAccountManager extends CurrentAccountProvider {
|
||||||
@NonNull
|
@NonNull
|
||||||
Account[] getAccounts();
|
Account[] getAccounts();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get configured nextcloud user accounts
|
||||||
|
* @return List of users or empty list, if users are not registered.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
List<User> getAllUsers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user with a specific account name.
|
||||||
|
*
|
||||||
|
* @param accountName Account name of the requested user
|
||||||
|
* @return User or empty optional if user does not exist.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
Optional<User> getUser(CharSequence accountName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if Nextcloud account is registered in {@link android.accounts.AccountManager}
|
* Check if Nextcloud account is registered in {@link android.accounts.AccountManager}
|
||||||
*
|
*
|
||||||
|
|
|
@ -27,6 +27,7 @@ import android.content.SharedPreferences;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.nextcloud.java.util.Optional;
|
||||||
import com.owncloud.android.MainApp;
|
import com.owncloud.android.MainApp;
|
||||||
import com.owncloud.android.R;
|
import com.owncloud.android.R;
|
||||||
import com.owncloud.android.datamodel.ArbitraryDataProvider;
|
import com.owncloud.android.datamodel.ArbitraryDataProvider;
|
||||||
|
@ -35,11 +36,18 @@ import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
||||||
import com.owncloud.android.lib.common.UserInfo;
|
import com.owncloud.android.lib.common.UserInfo;
|
||||||
|
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
import com.owncloud.android.lib.resources.users.GetUserInfoRemoteOperation;
|
import com.owncloud.android.lib.resources.users.GetUserInfoRemoteOperation;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
@ -80,6 +88,20 @@ public class UserAccountManagerImpl implements UserAccountManager {
|
||||||
return accountManager.getAccountsByType(getAccountType());
|
return accountManager.getAccountsByType(getAccountType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NonNull
|
||||||
|
public List<User> getAllUsers() {
|
||||||
|
Account[] accounts = getAccounts();
|
||||||
|
List<User> users = new ArrayList<>(accounts.length);
|
||||||
|
for (Account account : accounts) {
|
||||||
|
User user = createUserFromAccount(account);
|
||||||
|
if (user != null) {
|
||||||
|
users.add(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean exists(Account account) {
|
public boolean exists(Account account) {
|
||||||
Account[] nextcloudAccounts = getAccounts();
|
Account[] nextcloudAccounts = getAccounts();
|
||||||
|
@ -103,6 +125,7 @@ public class UserAccountManagerImpl implements UserAccountManager {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public Account getCurrentAccount() {
|
public Account getCurrentAccount() {
|
||||||
Account[] ocAccounts = getAccounts();
|
Account[] ocAccounts = getAccounts();
|
||||||
|
@ -139,6 +162,76 @@ public class UserAccountManagerImpl implements UserAccountManager {
|
||||||
return defaultAccount;
|
return defaultAccount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporary solution to convert platform account to user instance.
|
||||||
|
* It takes null and returns null on error to ease error handling
|
||||||
|
* in legacy code.
|
||||||
|
*
|
||||||
|
* @param account Account instance
|
||||||
|
* @return User instance or null, if conversion failed
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private User createUserFromAccount(@Nullable Account account) {
|
||||||
|
if (account == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
OwnCloudAccount ownCloudAccount = null;
|
||||||
|
try {
|
||||||
|
ownCloudAccount = new OwnCloudAccount(account, context);
|
||||||
|
} catch (AccountUtils.AccountNotFoundException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Server version
|
||||||
|
*/
|
||||||
|
String serverVersionStr = accountManager.getUserData(account, AccountUtils.Constants.KEY_OC_VERSION);
|
||||||
|
OwnCloudVersion serverVersion;
|
||||||
|
if (serverVersionStr != null) {
|
||||||
|
serverVersion = new OwnCloudVersion(serverVersionStr);
|
||||||
|
} else {
|
||||||
|
serverVersion = MainApp.MINIMUM_SUPPORTED_SERVER_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Server address
|
||||||
|
*/
|
||||||
|
String serverAddressStr = accountManager.getUserData(account, AccountUtils.Constants.KEY_OC_BASE_URL);
|
||||||
|
if (serverAddressStr == null || serverAddressStr.isEmpty()) {
|
||||||
|
return AnonymousUser.fromContext(context);
|
||||||
|
}
|
||||||
|
URI serverUri = URI.create(serverAddressStr); // TODO: validate
|
||||||
|
|
||||||
|
return new RegisteredUser(
|
||||||
|
account,
|
||||||
|
ownCloudAccount,
|
||||||
|
new Server(serverUri, serverVersion)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user. If user cannot be retrieved due to data error, anonymous user is returned instead.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return User instance
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public User getUser() {
|
||||||
|
Account account = getCurrentAccount();
|
||||||
|
User user = createUserFromAccount(account);
|
||||||
|
return user != null ? user : AnonymousUser.fromContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NonNull
|
||||||
|
public Optional<User> getUser(CharSequence accountName) {
|
||||||
|
Account account = getAccountByName(accountName.toString());
|
||||||
|
User user = createUserFromAccount(account);
|
||||||
|
return Optional.of(user);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public OwnCloudAccount getCurrentOwnCloudAccount() {
|
public OwnCloudAccount getCurrentOwnCloudAccount() {
|
||||||
|
@ -197,6 +290,7 @@ public class UserAccountManagerImpl implements UserAccountManager {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
@NonNull
|
@NonNull
|
||||||
public OwnCloudVersion getServerVersion(Account account) {
|
public OwnCloudVersion getServerVersion(Account account) {
|
||||||
|
|
|
@ -20,14 +20,13 @@
|
||||||
|
|
||||||
package com.nextcloud.client.network;
|
package com.nextcloud.client.network;
|
||||||
|
|
||||||
import android.accounts.Account;
|
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
|
|
||||||
import com.evernote.android.job.JobRequest;
|
import com.evernote.android.job.JobRequest;
|
||||||
|
import com.nextcloud.client.account.Server;
|
||||||
import com.nextcloud.client.account.UserAccountManager;
|
import com.nextcloud.client.account.UserAccountManager;
|
||||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
import com.nextcloud.client.logger.Logger;
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
|
||||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
|
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
import org.apache.commons.httpclient.HttpClient;
|
||||||
|
@ -44,10 +43,11 @@ class ConnectivityServiceImpl implements ConnectivityService {
|
||||||
|
|
||||||
private final static String TAG = ConnectivityServiceImpl.class.getName();
|
private final static String TAG = ConnectivityServiceImpl.class.getName();
|
||||||
|
|
||||||
private ConnectivityManager connectivityManager;
|
private final ConnectivityManager connectivityManager;
|
||||||
private UserAccountManager accountManager;
|
private final UserAccountManager accountManager;
|
||||||
private ClientFactory clientFactory;
|
private final ClientFactory clientFactory;
|
||||||
private GetRequestBuilder requestBuilder;
|
private final GetRequestBuilder requestBuilder;
|
||||||
|
private final Logger logger;
|
||||||
|
|
||||||
static class GetRequestBuilder implements Function1<String, GetMethod> {
|
static class GetRequestBuilder implements Function1<String, GetMethod> {
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,55 +59,55 @@ class ConnectivityServiceImpl implements ConnectivityService {
|
||||||
ConnectivityServiceImpl(ConnectivityManager connectivityManager,
|
ConnectivityServiceImpl(ConnectivityManager connectivityManager,
|
||||||
UserAccountManager accountManager,
|
UserAccountManager accountManager,
|
||||||
ClientFactory clientFactory,
|
ClientFactory clientFactory,
|
||||||
GetRequestBuilder requestBuilder) {
|
GetRequestBuilder requestBuilder,
|
||||||
|
Logger logger) {
|
||||||
this.connectivityManager = connectivityManager;
|
this.connectivityManager = connectivityManager;
|
||||||
this.accountManager = accountManager;
|
this.accountManager = accountManager;
|
||||||
this.clientFactory = clientFactory;
|
this.clientFactory = clientFactory;
|
||||||
this.requestBuilder = requestBuilder;
|
this.requestBuilder = requestBuilder;
|
||||||
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInternetWalled() {
|
public boolean isInternetWalled() {
|
||||||
if (isOnlineWithWifi()) {
|
if (isOnlineWithWifi()) {
|
||||||
try {
|
try {
|
||||||
Account account = accountManager.getCurrentAccount();
|
Server server = accountManager.getUser().getServer();
|
||||||
OwnCloudAccount ocAccount = accountManager.getCurrentOwnCloudAccount();
|
String baseServerAddress = server.getUri().toString();
|
||||||
if (account != null && ocAccount != null) {
|
if (baseServerAddress.isEmpty()) {
|
||||||
OwnCloudVersion serverVersion = accountManager.getServerVersion(account);
|
return true;
|
||||||
|
}
|
||||||
|
String url;
|
||||||
|
if (server.getVersion().compareTo(OwnCloudVersion.nextcloud_13) > 0) {
|
||||||
|
url = baseServerAddress + "/index.php/204";
|
||||||
|
} else {
|
||||||
|
url = baseServerAddress + "/status.php";
|
||||||
|
}
|
||||||
|
|
||||||
String url;
|
GetMethod get = requestBuilder.invoke(url);
|
||||||
if (serverVersion.compareTo(OwnCloudVersion.nextcloud_13) > 0) {
|
HttpClient client = clientFactory.createPlainClient();
|
||||||
url = ocAccount.getBaseUri() + "/index.php/204";
|
|
||||||
} else {
|
|
||||||
url = ocAccount.getBaseUri() + "/status.php";
|
|
||||||
}
|
|
||||||
|
|
||||||
GetMethod get = requestBuilder.invoke(url);
|
int status = client.executeMethod(get);
|
||||||
HttpClient client = clientFactory.createPlainClient();
|
|
||||||
|
|
||||||
int status = client.executeMethod(get);
|
if (server.getVersion().compareTo(OwnCloudVersion.nextcloud_13) > 0) {
|
||||||
|
return !(status == HttpStatus.SC_NO_CONTENT &&
|
||||||
if (serverVersion.compareTo(OwnCloudVersion.nextcloud_13) > 0) {
|
(get.getResponseContentLength() == -1 || get.getResponseContentLength() == 0));
|
||||||
return !(status == HttpStatus.SC_NO_CONTENT &&
|
} else {
|
||||||
(get.getResponseContentLength() == -1 || get.getResponseContentLength() == 0));
|
if (status == HttpStatus.SC_OK) {
|
||||||
} else {
|
try {
|
||||||
if (status == HttpStatus.SC_OK) {
|
// try parsing json to verify response
|
||||||
try {
|
// check if json contains maintenance and it should be false
|
||||||
// try parsing json to verify response
|
String json = get.getResponseBodyAsString();
|
||||||
// check if json contains maintenance and it should be false
|
return new JSONObject(json).getBoolean("maintenance");
|
||||||
|
} catch (Exception e) {
|
||||||
String json = get.getResponseBodyAsString();
|
|
||||||
return new JSONObject(json).getBoolean("maintenance");
|
|
||||||
} catch (Exception e) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log_OC.e(TAG, "Error checking internet connection", e);
|
logger.e(TAG, "Error checking internet connection", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return getActiveNetworkType() == JobRequest.NetworkType.ANY;
|
return getActiveNetworkType() == JobRequest.NetworkType.ANY;
|
||||||
|
|
|
@ -24,6 +24,7 @@ import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
|
|
||||||
import com.nextcloud.client.account.UserAccountManager;
|
import com.nextcloud.client.account.UserAccountManager;
|
||||||
|
import com.nextcloud.client.logger.Logger;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
@ -36,11 +37,13 @@ public class NetworkModule {
|
||||||
@Provides
|
@Provides
|
||||||
ConnectivityService connectivityService(ConnectivityManager connectivityManager,
|
ConnectivityService connectivityService(ConnectivityManager connectivityManager,
|
||||||
UserAccountManager accountManager,
|
UserAccountManager accountManager,
|
||||||
ClientFactory clientFactory) {
|
ClientFactory clientFactory,
|
||||||
|
Logger logger) {
|
||||||
return new ConnectivityServiceImpl(connectivityManager,
|
return new ConnectivityServiceImpl(connectivityManager,
|
||||||
accountManager,
|
accountManager,
|
||||||
clientFactory,
|
clientFactory,
|
||||||
new ConnectivityServiceImpl.GetRequestBuilder());
|
new ConnectivityServiceImpl.GetRequestBuilder(),
|
||||||
|
logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
366
src/main/java/com/nextcloud/java/util/Optional.java
Normal file
366
src/main/java/com/nextcloud/java/util/Optional.java
Normal file
|
@ -0,0 +1,366 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code 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
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
package com.nextcloud.java.util;
|
||||||
|
|
||||||
|
import com.nextcloud.java.util.function.Predicate;
|
||||||
|
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import androidx.core.util.Consumer;
|
||||||
|
import androidx.core.util.ObjectsCompat;
|
||||||
|
import androidx.core.util.Supplier;
|
||||||
|
import kotlin.jvm.functions.Function1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is backported from Java 8 to be used on older Android API levels.
|
||||||
|
* It uses available interfaces from Kotlin and androidx. It is semantically
|
||||||
|
* identical with Java 8 API, allowing smooth migration when those APIs become
|
||||||
|
* available.
|
||||||
|
*
|
||||||
|
* A container object which may or may not contain a non-null value.
|
||||||
|
* If a value is present, {@code isPresent()} will return {@code true} and
|
||||||
|
* {@code get()} will return the value.
|
||||||
|
*
|
||||||
|
* <p>Additional methods that depend on the presence or absence of a contained
|
||||||
|
* value are provided, such as {@link #orElse(java.lang.Object) orElse()}
|
||||||
|
* (return a default value if value not present) and
|
||||||
|
* {@link #ifPresent(Consumer) ifPresent()} (execute a block
|
||||||
|
* of code if the value is present).
|
||||||
|
*/
|
||||||
|
public final class Optional<T> {
|
||||||
|
/**
|
||||||
|
* Common instance for {@code empty()}.
|
||||||
|
*/
|
||||||
|
private static final Optional<?> EMPTY = new Optional<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If non-null, the value; if null, indicates no value is present
|
||||||
|
*/
|
||||||
|
private final T value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an empty instance.
|
||||||
|
*
|
||||||
|
* @implNote Generally only one empty instance, {@link Optional#EMPTY},
|
||||||
|
* should exist per VM.
|
||||||
|
*/
|
||||||
|
private Optional() {
|
||||||
|
this.value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an empty {@code Optional} instance. No value is present for this
|
||||||
|
* Optional.
|
||||||
|
*
|
||||||
|
* @apiNote Though it may be tempting to do so, avoid testing if an object
|
||||||
|
* is empty by comparing with {@code ==} against instances returned by
|
||||||
|
* {@code Option.empty()}. There is no guarantee that it is a singleton.
|
||||||
|
* Instead, use {@link #isPresent()}.
|
||||||
|
*
|
||||||
|
* @param <T> Type of the non-existent value
|
||||||
|
* @return an empty {@code Optional}
|
||||||
|
*/
|
||||||
|
public static<T> Optional<T> empty() {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Optional<T> t = (Optional<T>) EMPTY;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance with the value present.
|
||||||
|
*
|
||||||
|
* @param value the non-null value to be present
|
||||||
|
* @throws NullPointerException if value is null
|
||||||
|
*/
|
||||||
|
private Optional(T value) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an {@code Optional} with the specified present non-null value.
|
||||||
|
*
|
||||||
|
* @param <T> the class of the value
|
||||||
|
* @param value the value to be present, which must be non-null
|
||||||
|
* @return an {@code Optional} with the value present
|
||||||
|
* @throws NullPointerException if value is null
|
||||||
|
*/
|
||||||
|
public static <T> Optional<T> of(T value) {
|
||||||
|
return new Optional<>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an {@code Optional} describing the specified value, if non-null,
|
||||||
|
* otherwise returns an empty {@code Optional}.
|
||||||
|
*
|
||||||
|
* @param <T> the class of the value
|
||||||
|
* @param value the possibly-null value to describe
|
||||||
|
* @return an {@code Optional} with a present value if the specified value
|
||||||
|
* is non-null, otherwise an empty {@code Optional}
|
||||||
|
*/
|
||||||
|
public static <T> Optional<T> ofNullable(T value) {
|
||||||
|
return value == null ? empty() : of(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a value is present in this {@code Optional}, returns the value,
|
||||||
|
* otherwise throws {@code NoSuchElementException}.
|
||||||
|
*
|
||||||
|
* @return the non-null value held by this {@code Optional}
|
||||||
|
* @throws NoSuchElementException if there is no value present
|
||||||
|
*
|
||||||
|
* @see Optional#isPresent()
|
||||||
|
*/
|
||||||
|
public T get() {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NoSuchElementException("No value present");
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return {@code true} if there is a value present, otherwise {@code false}.
|
||||||
|
*
|
||||||
|
* @return {@code true} if there is a value present, otherwise {@code false}
|
||||||
|
*/
|
||||||
|
public boolean isPresent() {
|
||||||
|
return value != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a value is present, invoke the specified consumer with the value,
|
||||||
|
* otherwise do nothing.
|
||||||
|
*
|
||||||
|
* @param consumer block to be executed if a value is present
|
||||||
|
* @throws NullPointerException if value is present and {@code consumer} is
|
||||||
|
* null
|
||||||
|
*/
|
||||||
|
public void ifPresent(Consumer<? super T> consumer) {
|
||||||
|
if (value != null) {
|
||||||
|
consumer.accept(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a value is present, and the value matches the given predicate,
|
||||||
|
* return an {@code Optional} describing the value, otherwise return an
|
||||||
|
* empty {@code Optional}.
|
||||||
|
*
|
||||||
|
* @param predicate a predicate to apply to the value, if present
|
||||||
|
* @return an {@code Optional} describing the value of this {@code Optional}
|
||||||
|
* if a value is present and the value matches the given predicate,
|
||||||
|
* otherwise an empty {@code Optional}
|
||||||
|
* @throws NullPointerException if the predicate is null
|
||||||
|
*/
|
||||||
|
public Optional<T> filter(Predicate<? super T> predicate) {
|
||||||
|
if (predicate == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
if (!isPresent()) {
|
||||||
|
return this;
|
||||||
|
} else {
|
||||||
|
return predicate.test(value) ? this : empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a value is present, apply the provided mapping function to it,
|
||||||
|
* and if the result is non-null, return an {@code Optional} describing the
|
||||||
|
* result. Otherwise return an empty {@code Optional}.
|
||||||
|
*
|
||||||
|
* @apiNote This method supports post-processing on optional values, without
|
||||||
|
* the need to explicitly check for a return status. For example, the
|
||||||
|
* following code traverses a stream of file names, selects one that has
|
||||||
|
* not yet been processed, and then opens that file, returning an
|
||||||
|
* {@code Optional<FileInputStream>}:
|
||||||
|
*
|
||||||
|
* <pre>{@code
|
||||||
|
* Optional<FileInputStream> fis =
|
||||||
|
* names.stream().filter(name -> !isProcessedYet(name))
|
||||||
|
* .findFirst()
|
||||||
|
* .map(name -> new FileInputStream(name));
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* Here, {@code findFirst} returns an {@code Optional<String>}, and then
|
||||||
|
* {@code map} returns an {@code Optional<FileInputStream>} for the desired
|
||||||
|
* file if one exists.
|
||||||
|
*
|
||||||
|
* @param <U> The type of the result of the mapping function
|
||||||
|
* @param mapper a mapping function to apply to the value, if present
|
||||||
|
* @return an {@code Optional} describing the result of applying a mapping
|
||||||
|
* function to the value of this {@code Optional}, if a value is present,
|
||||||
|
* otherwise an empty {@code Optional}
|
||||||
|
* @throws NullPointerException if the mapping function is null
|
||||||
|
*/
|
||||||
|
public<U> Optional<U> map(Function1<? super T, ? extends U> mapper) {
|
||||||
|
if (mapper == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
if (!isPresent()) {
|
||||||
|
return empty();
|
||||||
|
} else {
|
||||||
|
return Optional.ofNullable(mapper.invoke(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a value is present, apply the provided {@code Optional}-bearing
|
||||||
|
* mapping function to it, return that result, otherwise return an empty
|
||||||
|
* {@code Optional}. This method is similar to {@link #map(Function1)},
|
||||||
|
* but the provided mapper is one whose result is already an {@code Optional},
|
||||||
|
* and if invoked, {@code flatMap} does not wrap it with an additional
|
||||||
|
* {@code Optional}.
|
||||||
|
*
|
||||||
|
* @param <U> The type parameter to the {@code Optional} returned by
|
||||||
|
* @param mapper a mapping function to apply to the value, if present
|
||||||
|
* the mapping function
|
||||||
|
* @return the result of applying an {@code Optional}-bearing mapping
|
||||||
|
* function to the value of this {@code Optional}, if a value is present,
|
||||||
|
* otherwise an empty {@code Optional}
|
||||||
|
* @throws NullPointerException if the mapping function is null or returns
|
||||||
|
* a null result
|
||||||
|
*/
|
||||||
|
public<U> Optional<U> flatMap(Function1<? super T, Optional<U>> mapper) {
|
||||||
|
if(mapper == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
if (!isPresent()) {
|
||||||
|
return empty();
|
||||||
|
} else {
|
||||||
|
Optional<U> u = mapper.invoke(value);
|
||||||
|
if (u == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value if present, otherwise return {@code other}.
|
||||||
|
*
|
||||||
|
* @param other the value to be returned if there is no value present, may
|
||||||
|
* be null
|
||||||
|
* @return the value, if present, otherwise {@code other}
|
||||||
|
*/
|
||||||
|
public T orElse(T other) {
|
||||||
|
return value != null ? value : other;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value if present, otherwise invoke {@code other} and return
|
||||||
|
* the result of that invocation.
|
||||||
|
*
|
||||||
|
* @param other a {@code Supplier} whose result is returned if no value
|
||||||
|
* is present
|
||||||
|
* @return the value if present otherwise the result of {@code other.get()}
|
||||||
|
* @throws NullPointerException if value is not present and {@code other} is
|
||||||
|
* null
|
||||||
|
*/
|
||||||
|
public T orElseGet(Supplier<? extends T> other) {
|
||||||
|
return value != null ? value : other.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the contained value, if present, otherwise throw an exception
|
||||||
|
* to be created by the provided supplier.
|
||||||
|
*
|
||||||
|
* @apiNote A method reference to the exception constructor with an empty
|
||||||
|
* argument list can be used as the supplier. For example,
|
||||||
|
* {@code IllegalStateException::new}
|
||||||
|
*
|
||||||
|
* @param <X> Type of the exception to be thrown
|
||||||
|
* @param exceptionSupplier The supplier which will return the exception to
|
||||||
|
* be thrown
|
||||||
|
* @return the present value
|
||||||
|
* @throws X if there is no value present
|
||||||
|
* @throws NullPointerException if no value is present and
|
||||||
|
* {@code exceptionSupplier} is null
|
||||||
|
*/
|
||||||
|
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
|
||||||
|
if (value != null) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
throw exceptionSupplier.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether some other object is "equal to" this Optional. The
|
||||||
|
* other object is considered equal if:
|
||||||
|
* <ul>
|
||||||
|
* <li>it is also an {@code Optional} and;
|
||||||
|
* <li>both instances have no value present or;
|
||||||
|
* <li>the present values are "equal to" each other via {@code equals()}.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param obj an object to be tested for equality
|
||||||
|
* @return {code true} if the other object is "equal to" this object
|
||||||
|
* otherwise {@code false}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(obj instanceof Optional)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<?> other = (Optional<?>) obj;
|
||||||
|
return ObjectsCompat.equals(value, other.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hash code value of the present value, if any, or 0 (zero) if
|
||||||
|
* no value is present.
|
||||||
|
*
|
||||||
|
* @return hash code value of the present value or 0 if no value is present
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return ObjectsCompat.hashCode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a non-empty string representation of this Optional suitable for
|
||||||
|
* debugging. The exact presentation format is unspecified and may vary
|
||||||
|
* between implementations and versions.
|
||||||
|
*
|
||||||
|
* @implSpec If a value is present the result must include its string
|
||||||
|
* representation in the result. Empty and present Optionals must be
|
||||||
|
* unambiguously differentiable.
|
||||||
|
*
|
||||||
|
* @return the string representation of this instance
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value != null
|
||||||
|
? String.format("Optional[%s]", value)
|
||||||
|
: "Optional.empty";
|
||||||
|
}
|
||||||
|
}
|
121
src/main/java/com/nextcloud/java/util/function/Predicate.java
Normal file
121
src/main/java/com/nextcloud/java/util/function/Predicate.java
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code 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
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
package com.nextcloud.java.util.function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is backported from Java 8 to be used on older Android API levels.
|
||||||
|
*
|
||||||
|
* Represents a predicate (boolean-valued function) of one argument.
|
||||||
|
*
|
||||||
|
* <p>This is a <a href="package-summary.html">functional interface</a>
|
||||||
|
* whose functional method is {@link #test(Object)}.
|
||||||
|
*
|
||||||
|
* @param <T> the type of the input to the predicate
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Predicate<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates this predicate on the given argument.
|
||||||
|
*
|
||||||
|
* @param t the input argument
|
||||||
|
* @return {@code true} if the input argument matches the predicate,
|
||||||
|
* otherwise {@code false}
|
||||||
|
*/
|
||||||
|
boolean test(T t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a composed predicate that represents a short-circuiting logical
|
||||||
|
* AND of this predicate and another. When evaluating the composed
|
||||||
|
* predicate, if this predicate is {@code false}, then the {@code other}
|
||||||
|
* predicate is not evaluated.
|
||||||
|
*
|
||||||
|
* <p>Any exceptions thrown during evaluation of either predicate are relayed
|
||||||
|
* to the caller; if evaluation of this predicate throws an exception, the
|
||||||
|
* {@code other} predicate will not be evaluated.
|
||||||
|
*
|
||||||
|
* @param other a predicate that will be logically-ANDed with this
|
||||||
|
* predicate
|
||||||
|
* @return a composed predicate that represents the short-circuiting logical
|
||||||
|
* AND of this predicate and the {@code other} predicate
|
||||||
|
* @throws NullPointerException if other is null
|
||||||
|
*/
|
||||||
|
default Predicate<T> and(Predicate<? super T> other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
return (t) -> test(t) && other.test(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a predicate that represents the logical negation of this
|
||||||
|
* predicate.
|
||||||
|
*
|
||||||
|
* @return a predicate that represents the logical negation of this
|
||||||
|
* predicate
|
||||||
|
*/
|
||||||
|
default Predicate<T> negate() {
|
||||||
|
return (t) -> !test(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a composed predicate that represents a short-circuiting logical
|
||||||
|
* OR of this predicate and another. When evaluating the composed
|
||||||
|
* predicate, if this predicate is {@code true}, then the {@code other}
|
||||||
|
* predicate is not evaluated.
|
||||||
|
*
|
||||||
|
* <p>Any exceptions thrown during evaluation of either predicate are relayed
|
||||||
|
* to the caller; if evaluation of this predicate throws an exception, the
|
||||||
|
* {@code other} predicate will not be evaluated.
|
||||||
|
*
|
||||||
|
* @param other a predicate that will be logically-ORed with this
|
||||||
|
* predicate
|
||||||
|
* @return a composed predicate that represents the short-circuiting logical
|
||||||
|
* OR of this predicate and the {@code other} predicate
|
||||||
|
* @throws NullPointerException if other is null
|
||||||
|
*/
|
||||||
|
default Predicate<T> or(Predicate<? super T> other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
return (t) -> test(t) || other.test(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a predicate that tests if two arguments are equal according
|
||||||
|
* to {@link androidx.core.util.ObjectsCompat#equals(Object, Object)}.
|
||||||
|
*
|
||||||
|
* @param <T> the type of arguments to the predicate
|
||||||
|
* @param targetRef the object reference with which to compare for equality,
|
||||||
|
* which may be {@code null}
|
||||||
|
* @return a predicate that tests if two arguments are equal according
|
||||||
|
* to {@link androidx.core.util.ObjectsCompat#equals(Object, Object)}
|
||||||
|
*/
|
||||||
|
static <T> Predicate<T> isEqual(Object targetRef) {
|
||||||
|
return (null == targetRef)
|
||||||
|
? object -> object == null
|
||||||
|
: object -> targetRef.equals(object);
|
||||||
|
}
|
||||||
|
}
|
26
src/main/java/com/nextcloud/java/util/package-info.java
Normal file
26
src/main/java/com/nextcloud/java/util/package-info.java
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Nextcloud Android client application
|
||||||
|
*
|
||||||
|
* @author Chris Narkiewicz <hello@ezaquarii.com>
|
||||||
|
* Copyright (C) 2019 Chris Narkiewicz
|
||||||
|
* Copyright (C) 2019 Nextcloud GmbH
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a compatibility package providing some backported Java 8 classes
|
||||||
|
* not available in some older Android runtimes.
|
||||||
|
*/
|
||||||
|
package com.nextcloud.java.util;
|
|
@ -30,6 +30,7 @@ import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import com.nextcloud.client.account.CurrentAccountProvider;
|
import com.nextcloud.client.account.CurrentAccountProvider;
|
||||||
|
import com.nextcloud.client.account.User;
|
||||||
import com.owncloud.android.db.OCUpload;
|
import com.owncloud.android.db.OCUpload;
|
||||||
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
|
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
|
||||||
import com.owncloud.android.db.UploadResult;
|
import com.owncloud.android.db.UploadResult;
|
||||||
|
@ -345,24 +346,19 @@ public class UploadsStorageManager extends Observable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public OCUpload[] getCurrentAndPendingUploadsForCurrentAccount() {
|
public OCUpload[] getCurrentAndPendingUploadsForCurrentAccount() {
|
||||||
Account account = currentAccountProvider.getCurrentAccount();
|
User user = currentAccountProvider.getUser();
|
||||||
|
|
||||||
if (account != null) {
|
return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_IN_PROGRESS.value +
|
||||||
return getUploads(
|
" OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
||||||
ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_IN_PROGRESS.value +
|
"==" + UploadResult.DELAYED_FOR_WIFI.getValue() +
|
||||||
" OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
" OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
||||||
"==" + UploadResult.DELAYED_FOR_WIFI.getValue() +
|
"==" + UploadResult.LOCK_FAILED.getValue() +
|
||||||
" OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
" OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
||||||
"==" + UploadResult.LOCK_FAILED.getValue() +
|
"==" + UploadResult.DELAYED_FOR_CHARGING.getValue() +
|
||||||
" OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
" OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
||||||
"==" + UploadResult.DELAYED_FOR_CHARGING.getValue() +
|
"==" + UploadResult.DELAYED_IN_POWER_SAVE_MODE.getValue() +
|
||||||
" OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
" AND " + ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?",
|
||||||
"==" + UploadResult.DELAYED_IN_POWER_SAVE_MODE.getValue() +
|
user.getAccountName());
|
||||||
" AND " + ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?",
|
|
||||||
account.name);
|
|
||||||
} else {
|
|
||||||
return new OCUpload[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -384,14 +380,10 @@ public class UploadsStorageManager extends Observable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public OCUpload[] getFinishedUploadsForCurrentAccount() {
|
public OCUpload[] getFinishedUploadsForCurrentAccount() {
|
||||||
Account account = currentAccountProvider.getCurrentAccount();
|
User user = currentAccountProvider.getUser();
|
||||||
|
|
||||||
if (account != null) {
|
return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_SUCCEEDED.value + AND +
|
||||||
return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_SUCCEEDED.value + AND +
|
ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?", user.getAccountName());
|
||||||
ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?", account.name);
|
|
||||||
} else {
|
|
||||||
return new OCUpload[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -403,23 +395,19 @@ public class UploadsStorageManager extends Observable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public OCUpload[] getFailedButNotDelayedUploadsForCurrentAccount() {
|
public OCUpload[] getFailedButNotDelayedUploadsForCurrentAccount() {
|
||||||
Account account = currentAccountProvider.getCurrentAccount();
|
User user = currentAccountProvider.getUser();
|
||||||
|
|
||||||
if (account != null) {
|
return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value +
|
||||||
return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value +
|
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
||||||
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
"<>" + UploadResult.DELAYED_FOR_WIFI.getValue() +
|
||||||
"<>" + UploadResult.DELAYED_FOR_WIFI.getValue() +
|
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
||||||
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
"<>" + UploadResult.LOCK_FAILED.getValue() +
|
||||||
"<>" + UploadResult.LOCK_FAILED.getValue() +
|
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
||||||
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
"<>" + UploadResult.DELAYED_FOR_CHARGING.getValue() +
|
||||||
"<>" + UploadResult.DELAYED_FOR_CHARGING.getValue() +
|
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
||||||
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
"<>" + UploadResult.DELAYED_IN_POWER_SAVE_MODE.getValue() +
|
||||||
"<>" + UploadResult.DELAYED_IN_POWER_SAVE_MODE.getValue() +
|
AND + ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?",
|
||||||
AND + ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?",
|
user.getAccountName());
|
||||||
account.name);
|
|
||||||
} else {
|
|
||||||
return new OCUpload[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -446,50 +434,41 @@ public class UploadsStorageManager extends Observable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public long clearFailedButNotDelayedUploads() {
|
public long clearFailedButNotDelayedUploads() {
|
||||||
Account account = currentAccountProvider.getCurrentAccount();
|
User user = currentAccountProvider.getUser();
|
||||||
|
final long deleted = getDB().delete(
|
||||||
long result = 0;
|
ProviderTableMeta.CONTENT_URI_UPLOADS,
|
||||||
if (account != null) {
|
ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value +
|
||||||
result = getDB().delete(
|
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
||||||
ProviderTableMeta.CONTENT_URI_UPLOADS,
|
"<>" + UploadResult.LOCK_FAILED.getValue() +
|
||||||
ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value +
|
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
||||||
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
"<>" + UploadResult.DELAYED_FOR_WIFI.getValue() +
|
||||||
"<>" + UploadResult.LOCK_FAILED.getValue() +
|
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
||||||
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
"<>" + UploadResult.DELAYED_FOR_CHARGING.getValue() +
|
||||||
"<>" + UploadResult.DELAYED_FOR_WIFI.getValue() +
|
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
||||||
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
"<>" + UploadResult.DELAYED_IN_POWER_SAVE_MODE.getValue() +
|
||||||
"<>" + UploadResult.DELAYED_FOR_CHARGING.getValue() +
|
AND + ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?",
|
||||||
AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
|
new String[]{user.getAccountName()}
|
||||||
"<>" + UploadResult.DELAYED_IN_POWER_SAVE_MODE.getValue() +
|
);
|
||||||
AND + ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?",
|
|
||||||
new String[]{account.name}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log_OC.d(TAG, "delete all failed uploads but those delayed for Wifi");
|
Log_OC.d(TAG, "delete all failed uploads but those delayed for Wifi");
|
||||||
if (result > 0) {
|
if (deleted > 0) {
|
||||||
notifyObserversNow();
|
notifyObserversNow();
|
||||||
}
|
}
|
||||||
return result;
|
return deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long clearSuccessfulUploads() {
|
public long clearSuccessfulUploads() {
|
||||||
Account account = currentAccountProvider.getCurrentAccount();
|
User user = currentAccountProvider.getUser();
|
||||||
|
final long deleted = getDB().delete(
|
||||||
long result = 0;
|
ProviderTableMeta.CONTENT_URI_UPLOADS,
|
||||||
if (account != null) {
|
ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_SUCCEEDED.value + AND +
|
||||||
result = getDB().delete(
|
ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?", new String[]{user.getAccountName()}
|
||||||
ProviderTableMeta.CONTENT_URI_UPLOADS,
|
);
|
||||||
ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_SUCCEEDED.value + AND +
|
|
||||||
ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?", new String[]{account.name}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log_OC.d(TAG, "delete all successful uploads");
|
Log_OC.d(TAG, "delete all successful uploads");
|
||||||
if (result > 0) {
|
if (deleted > 0) {
|
||||||
notifyObserversNow();
|
notifyObserversNow();
|
||||||
}
|
}
|
||||||
return result;
|
return deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -47,6 +47,7 @@ import android.widget.TextView;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.bumptech.glide.request.target.BitmapImageViewTarget;
|
import com.bumptech.glide.request.target.BitmapImageViewTarget;
|
||||||
|
import com.nextcloud.client.account.User;
|
||||||
import com.nextcloud.client.account.UserAccountManager;
|
import com.nextcloud.client.account.UserAccountManager;
|
||||||
import com.nextcloud.client.preferences.AppPreferences;
|
import com.nextcloud.client.preferences.AppPreferences;
|
||||||
import com.owncloud.android.R;
|
import com.owncloud.android.R;
|
||||||
|
@ -117,7 +118,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
private Set<OCFile> checkedFiles;
|
private Set<OCFile> checkedFiles;
|
||||||
|
|
||||||
private FileDataStorageManager mStorageManager;
|
private FileDataStorageManager mStorageManager;
|
||||||
private Account account;
|
private User user;
|
||||||
private OCFileListFragmentInterface ocFileListFragmentInterface;
|
private OCFileListFragmentInterface ocFileListFragmentInterface;
|
||||||
|
|
||||||
private FilesFilter mFilesFilter;
|
private FilesFilter mFilesFilter;
|
||||||
|
@ -135,7 +136,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
|
|
||||||
public OCFileListAdapter(
|
public OCFileListAdapter(
|
||||||
Context context,
|
Context context,
|
||||||
Account account,
|
User user,
|
||||||
AppPreferences preferences,
|
AppPreferences preferences,
|
||||||
UserAccountManager accountManager,
|
UserAccountManager accountManager,
|
||||||
ComponentsGetter transferServiceGetter,
|
ComponentsGetter transferServiceGetter,
|
||||||
|
@ -147,16 +148,16 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
mContext = context;
|
mContext = context;
|
||||||
this.preferences = preferences;
|
this.preferences = preferences;
|
||||||
this.accountManager = accountManager;
|
this.accountManager = accountManager;
|
||||||
this.account = account;
|
this.user = user;
|
||||||
mHideItemOptions = argHideItemOptions;
|
mHideItemOptions = argHideItemOptions;
|
||||||
this.gridView = gridView;
|
this.gridView = gridView;
|
||||||
checkedFiles = new HashSet<>();
|
checkedFiles = new HashSet<>();
|
||||||
|
|
||||||
this.transferServiceGetter = transferServiceGetter;
|
this.transferServiceGetter = transferServiceGetter;
|
||||||
|
|
||||||
if (account != null) {
|
if (this.user != null) {
|
||||||
AccountManager platformAccountManager = AccountManager.get(mContext);
|
AccountManager platformAccountManager = AccountManager.get(mContext);
|
||||||
userId = platformAccountManager.getUserData(account,
|
userId = platformAccountManager.getUserData(this.user.toPlatformAccount(),
|
||||||
com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
|
com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
|
||||||
} else {
|
} else {
|
||||||
userId = "";
|
userId = "";
|
||||||
|
@ -399,7 +400,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
showFederatedShareAvatar(sharee.getUserId(), avatarRadius, resources, avatar);
|
showFederatedShareAvatar(sharee.getUserId(), avatarRadius, resources, avatar);
|
||||||
} else {
|
} else {
|
||||||
avatar.setTag(sharee);
|
avatar.setTag(sharee);
|
||||||
DisplayUtils.setAvatar(account,
|
DisplayUtils.setAvatar(user.toPlatformAccount(),
|
||||||
sharee.getUserId(),
|
sharee.getUserId(),
|
||||||
sharee.getDisplayName(),
|
sharee.getDisplayName(),
|
||||||
this,
|
this,
|
||||||
|
@ -460,17 +461,17 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
OperationsService.OperationsServiceBinder operationsServiceBinder = transferServiceGetter.getOperationsServiceBinder();
|
OperationsService.OperationsServiceBinder operationsServiceBinder = transferServiceGetter.getOperationsServiceBinder();
|
||||||
FileDownloader.FileDownloaderBinder fileDownloaderBinder = transferServiceGetter.getFileDownloaderBinder();
|
FileDownloader.FileDownloaderBinder fileDownloaderBinder = transferServiceGetter.getFileDownloaderBinder();
|
||||||
FileUploader.FileUploaderBinder fileUploaderBinder = transferServiceGetter.getFileUploaderBinder();
|
FileUploader.FileUploaderBinder fileUploaderBinder = transferServiceGetter.getFileUploaderBinder();
|
||||||
if (operationsServiceBinder != null && operationsServiceBinder.isSynchronizing(account, file)) {
|
if (operationsServiceBinder != null && operationsServiceBinder.isSynchronizing(user.toPlatformAccount(), file)) {
|
||||||
//synchronizing
|
//synchronizing
|
||||||
gridViewHolder.localFileIndicator.setImageResource(R.drawable.ic_synchronizing);
|
gridViewHolder.localFileIndicator.setImageResource(R.drawable.ic_synchronizing);
|
||||||
gridViewHolder.localFileIndicator.setVisibility(View.VISIBLE);
|
gridViewHolder.localFileIndicator.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
} else if (fileDownloaderBinder != null && fileDownloaderBinder.isDownloading(account, file)) {
|
} else if (fileDownloaderBinder != null && fileDownloaderBinder.isDownloading(user.toPlatformAccount(), file)) {
|
||||||
// downloading
|
// downloading
|
||||||
gridViewHolder.localFileIndicator.setImageResource(R.drawable.ic_synchronizing);
|
gridViewHolder.localFileIndicator.setImageResource(R.drawable.ic_synchronizing);
|
||||||
gridViewHolder.localFileIndicator.setVisibility(View.VISIBLE);
|
gridViewHolder.localFileIndicator.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
} else if (fileUploaderBinder != null && fileUploaderBinder.isUploading(account, file)) {
|
} else if (fileUploaderBinder != null && fileUploaderBinder.isUploading(user.toPlatformAccount(), file)) {
|
||||||
//uploading
|
//uploading
|
||||||
gridViewHolder.localFileIndicator.setImageResource(R.drawable.ic_synchronizing);
|
gridViewHolder.localFileIndicator.setImageResource(R.drawable.ic_synchronizing);
|
||||||
gridViewHolder.localFileIndicator.setVisibility(View.VISIBLE);
|
gridViewHolder.localFileIndicator.setVisibility(View.VISIBLE);
|
||||||
|
@ -575,13 +576,17 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, thumbnailView)) {
|
if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, thumbnailView)) {
|
||||||
try {
|
try {
|
||||||
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
|
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
|
||||||
new ThumbnailsCacheManager.ThumbnailGenerationTask(thumbnailView, mStorageManager,
|
new ThumbnailsCacheManager.ThumbnailGenerationTask(thumbnailView,
|
||||||
account, asyncTasks);
|
mStorageManager,
|
||||||
|
user.toPlatformAccount(),
|
||||||
|
asyncTasks);
|
||||||
|
|
||||||
if (thumbnail == null) {
|
if (thumbnail == null) {
|
||||||
thumbnail = BitmapUtils.drawableToBitmap(
|
thumbnail = BitmapUtils.drawableToBitmap(
|
||||||
MimeTypeUtil.getFileTypeIcon(file.getMimeType(), file.getFileName(),
|
MimeTypeUtil.getFileTypeIcon(file.getMimeType(),
|
||||||
account, mContext));
|
file.getFileName(),
|
||||||
|
user.toPlatformAccount(),
|
||||||
|
mContext));
|
||||||
}
|
}
|
||||||
final ThumbnailsCacheManager.AsyncThumbnailDrawable asyncDrawable =
|
final ThumbnailsCacheManager.AsyncThumbnailDrawable asyncDrawable =
|
||||||
new ThumbnailsCacheManager.AsyncThumbnailDrawable(mContext.getResources(),
|
new ThumbnailsCacheManager.AsyncThumbnailDrawable(mContext.getResources(),
|
||||||
|
@ -602,7 +607,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
} else {
|
} else {
|
||||||
thumbnailView.setImageDrawable(MimeTypeUtil.getFileTypeIcon(file.getMimeType(),
|
thumbnailView.setImageDrawable(MimeTypeUtil.getFileTypeIcon(file.getMimeType(),
|
||||||
file.getFileName(),
|
file.getFileName(),
|
||||||
account,
|
user.toPlatformAccount(),
|
||||||
mContext));
|
mContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -685,7 +690,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
sharedIconView.setImageResource(R.drawable.ic_unshared);
|
sharedIconView.setImageResource(R.drawable.ic_unshared);
|
||||||
sharedIconView.setContentDescription(mContext.getString(R.string.shared_icon_share));
|
sharedIconView.setContentDescription(mContext.getString(R.string.shared_icon_share));
|
||||||
}
|
}
|
||||||
if (accountManager.accountOwnsFile(file, account)) {
|
if (accountManager.accountOwnsFile(file, user.toPlatformAccount())) {
|
||||||
sharedIconView.setOnClickListener(view -> ocFileListFragmentInterface.onShareIconClick(file));
|
sharedIconView.setOnClickListener(view -> ocFileListFragmentInterface.onShareIconClick(file));
|
||||||
} else {
|
} else {
|
||||||
sharedIconView.setOnClickListener(view -> ocFileListFragmentInterface.showShareDetailView(file));
|
sharedIconView.setOnClickListener(view -> ocFileListFragmentInterface.showShareDetailView(file));
|
||||||
|
@ -703,7 +708,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
* @param limitToMimeType show only files of this mimeType
|
* @param limitToMimeType show only files of this mimeType
|
||||||
*/
|
*/
|
||||||
public void swapDirectory(
|
public void swapDirectory(
|
||||||
Account account,
|
User account,
|
||||||
OCFile directory,
|
OCFile directory,
|
||||||
FileDataStorageManager updatedStorageManager,
|
FileDataStorageManager updatedStorageManager,
|
||||||
boolean onlyOnDevice, String limitToMimeType
|
boolean onlyOnDevice, String limitToMimeType
|
||||||
|
@ -712,8 +717,8 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
|
|
||||||
if (updatedStorageManager != null && !updatedStorageManager.equals(mStorageManager)) {
|
if (updatedStorageManager != null && !updatedStorageManager.equals(mStorageManager)) {
|
||||||
mStorageManager = updatedStorageManager;
|
mStorageManager = updatedStorageManager;
|
||||||
showShareAvatar = mStorageManager.getCapability(account.name).getVersion().isShareesOnDavSupported();
|
showShareAvatar = mStorageManager.getCapability(account.getAccountName()).getVersion().isShareesOnDavSupported();
|
||||||
this.account = account;
|
this.user = account;
|
||||||
}
|
}
|
||||||
if (mStorageManager != null) {
|
if (mStorageManager != null) {
|
||||||
mFiles = mStorageManager.getFolderContent(directory, onlyOnDevice);
|
mFiles = mStorageManager.getFolderContent(directory, onlyOnDevice);
|
||||||
|
@ -744,11 +749,11 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
FileDataStorageManager storageManager, OCFile folder, boolean clear) {
|
FileDataStorageManager storageManager, OCFile folder, boolean clear) {
|
||||||
if (storageManager != null && mStorageManager == null) {
|
if (storageManager != null && mStorageManager == null) {
|
||||||
mStorageManager = storageManager;
|
mStorageManager = storageManager;
|
||||||
showShareAvatar = mStorageManager.getCapability(account.name).getVersion().isShareesOnDavSupported();
|
showShareAvatar = mStorageManager.getCapability(user.getAccountName()).getVersion().isShareesOnDavSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mStorageManager == null) {
|
if (mStorageManager == null) {
|
||||||
mStorageManager = new FileDataStorageManager(account, mContext.getContentResolver());
|
mStorageManager = new FileDataStorageManager(user.toPlatformAccount(), mContext.getContentResolver());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clear) {
|
if (clear) {
|
||||||
|
@ -808,12 +813,12 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
shares.add(ocShare);
|
shares.add(ocShare);
|
||||||
|
|
||||||
// get ocFile from Server to have an up-to-date copy
|
// get ocFile from Server to have an up-to-date copy
|
||||||
RemoteOperationResult result = new ReadFileRemoteOperation(ocShare.getPath()).execute(account,
|
RemoteOperationResult result = new ReadFileRemoteOperation(ocShare.getPath()).execute(user.toPlatformAccount(),
|
||||||
mContext);
|
mContext);
|
||||||
|
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
OCFile file = FileStorageUtils.fillOCFile((RemoteFile) result.getData().get(0));
|
OCFile file = FileStorageUtils.fillOCFile((RemoteFile) result.getData().get(0));
|
||||||
FileStorageUtils.searchForLocalFileInDefaultPath(file, account);
|
FileStorageUtils.searchForLocalFileInDefaultPath(file, user.toPlatformAccount());
|
||||||
file = mStorageManager.saveFileWithParent(file, mContext);
|
file = mStorageManager.saveFileWithParent(file, mContext);
|
||||||
|
|
||||||
ShareType newShareType = ocShare.getShareType();
|
ShareType newShareType = ocShare.getShareType();
|
||||||
|
@ -868,7 +873,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
|
|
||||||
for (Object remoteFile : objects) {
|
for (Object remoteFile : objects) {
|
||||||
OCFile ocFile = FileStorageUtils.fillOCFile((RemoteFile) remoteFile);
|
OCFile ocFile = FileStorageUtils.fillOCFile((RemoteFile) remoteFile);
|
||||||
FileStorageUtils.searchForLocalFileInDefaultPath(ocFile, account);
|
FileStorageUtils.searchForLocalFileInDefaultPath(ocFile, user.toPlatformAccount());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (ExtendedListFragment.SearchType.PHOTO_SEARCH == searchType) {
|
if (ExtendedListFragment.SearchType.PHOTO_SEARCH == searchType) {
|
||||||
|
@ -885,9 +890,9 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
mStorageManager,
|
mStorageManager,
|
||||||
account,
|
user.toPlatformAccount(),
|
||||||
mContext);
|
mContext);
|
||||||
refreshFolderOperation.execute(account, mContext);
|
refreshFolderOperation.execute(user.toPlatformAccount(), mContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -332,7 +332,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
||||||
|
|
||||||
mAdapter = new OCFileListAdapter(
|
mAdapter = new OCFileListAdapter(
|
||||||
getActivity(),
|
getActivity(),
|
||||||
accountManager.getCurrentAccount(),
|
accountManager.getUser(),
|
||||||
preferences,
|
preferences,
|
||||||
accountManager,
|
accountManager,
|
||||||
mContainerActivity,
|
mContainerActivity,
|
||||||
|
@ -1180,7 +1180,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
||||||
}
|
}
|
||||||
|
|
||||||
mAdapter.swapDirectory(
|
mAdapter.swapDirectory(
|
||||||
accountManager.getCurrentAccount(),
|
accountManager.getUser(),
|
||||||
directory,
|
directory,
|
||||||
storageManager,
|
storageManager,
|
||||||
onlyOnDevice,
|
onlyOnDevice,
|
||||||
|
|
|
@ -19,16 +19,17 @@
|
||||||
*/
|
*/
|
||||||
package com.nextcloud.client.network
|
package com.nextcloud.client.network
|
||||||
|
|
||||||
import android.accounts.Account
|
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.NetworkInfo
|
import android.net.NetworkInfo
|
||||||
import android.net.Uri
|
import com.nextcloud.client.account.Server
|
||||||
|
import com.nextcloud.client.account.User
|
||||||
import com.nextcloud.client.account.UserAccountManager
|
import com.nextcloud.client.account.UserAccountManager
|
||||||
|
import com.nextcloud.client.logger.Logger
|
||||||
import com.nhaarman.mockitokotlin2.any
|
import com.nhaarman.mockitokotlin2.any
|
||||||
import com.nhaarman.mockitokotlin2.mock
|
import com.nhaarman.mockitokotlin2.mock
|
||||||
|
import com.nhaarman.mockitokotlin2.never
|
||||||
import com.nhaarman.mockitokotlin2.verify
|
import com.nhaarman.mockitokotlin2.verify
|
||||||
import com.nhaarman.mockitokotlin2.whenever
|
import com.nhaarman.mockitokotlin2.whenever
|
||||||
import com.owncloud.android.lib.common.OwnCloudAccount
|
|
||||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion
|
||||||
import org.apache.commons.httpclient.HttpClient
|
import org.apache.commons.httpclient.HttpClient
|
||||||
import org.apache.commons.httpclient.HttpStatus
|
import org.apache.commons.httpclient.HttpStatus
|
||||||
|
@ -42,6 +43,7 @@ import org.junit.runners.Suite
|
||||||
import org.mockito.ArgumentCaptor
|
import org.mockito.ArgumentCaptor
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
|
import java.net.URI
|
||||||
|
|
||||||
@RunWith(Suite::class)
|
@RunWith(Suite::class)
|
||||||
@Suite.SuiteClasses(
|
@Suite.SuiteClasses(
|
||||||
|
@ -86,13 +88,14 @@ class ConnectivityServiceTest {
|
||||||
lateinit var requestBuilder: ConnectivityServiceImpl.GetRequestBuilder
|
lateinit var requestBuilder: ConnectivityServiceImpl.GetRequestBuilder
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var platformAccount: Account
|
lateinit var logger: Logger
|
||||||
|
|
||||||
|
val baseServerUri = URI.create(SERVER_BASE_URL)
|
||||||
|
val newServer = Server(baseServerUri, OwnCloudVersion.nextcloud_14)
|
||||||
|
val legacyServer = Server(baseServerUri, OwnCloudVersion.nextcloud_13)
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var ownCloudAccount: OwnCloudAccount
|
lateinit var user: User
|
||||||
|
|
||||||
@Mock
|
|
||||||
lateinit var baseServerUri: Uri
|
|
||||||
|
|
||||||
lateinit var connectivityService: ConnectivityServiceImpl
|
lateinit var connectivityService: ConnectivityServiceImpl
|
||||||
|
|
||||||
|
@ -103,15 +106,15 @@ class ConnectivityServiceTest {
|
||||||
platformConnectivityManager,
|
platformConnectivityManager,
|
||||||
accountManager,
|
accountManager,
|
||||||
clientFactory,
|
clientFactory,
|
||||||
requestBuilder
|
requestBuilder,
|
||||||
|
logger
|
||||||
)
|
)
|
||||||
|
|
||||||
whenever(platformConnectivityManager.activeNetworkInfo).thenReturn(networkInfo)
|
whenever(platformConnectivityManager.activeNetworkInfo).thenReturn(networkInfo)
|
||||||
whenever(requestBuilder.invoke(any())).thenReturn(getRequest)
|
whenever(requestBuilder.invoke(any())).thenReturn(getRequest)
|
||||||
whenever(clientFactory.createPlainClient()).thenReturn(client)
|
whenever(clientFactory.createPlainClient()).thenReturn(client)
|
||||||
whenever(accountManager.currentOwnCloudAccount).thenReturn(ownCloudAccount)
|
whenever(user.server).thenReturn(newServer)
|
||||||
whenever(accountManager.currentAccount).thenReturn(platformAccount)
|
whenever(accountManager.user).thenReturn(user)
|
||||||
whenever(baseServerUri.toString()).thenReturn(SERVER_BASE_URL)
|
|
||||||
whenever(ownCloudAccount.baseUri).thenReturn(baseServerUri)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +161,7 @@ class ConnectivityServiceTest {
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
whenever(networkInfo.isConnectedOrConnecting).thenReturn(true)
|
whenever(networkInfo.isConnectedOrConnecting).thenReturn(true)
|
||||||
whenever(networkInfo.type).thenReturn(ConnectivityManager.TYPE_WIFI)
|
whenever(networkInfo.type).thenReturn(ConnectivityManager.TYPE_WIFI)
|
||||||
whenever(accountManager.getServerVersion(any())).thenReturn(OwnCloudVersion.nextcloud_13)
|
whenever(user.server).thenReturn(legacyServer)
|
||||||
assertTrue("Precondition failed", connectivityService.isOnlineWithWifi)
|
assertTrue("Precondition failed", connectivityService.isOnlineWithWifi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,6 +210,28 @@ class ConnectivityServiceTest {
|
||||||
assertTrue("Precondition failed", connectivityService.isOnlineWithWifi)
|
assertTrue("Precondition failed", connectivityService.isOnlineWithWifi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `check request is not sent when server uri is not set`() {
|
||||||
|
// GIVEN
|
||||||
|
// network connectivity is present
|
||||||
|
// user has no server URI (empty)
|
||||||
|
val serverWithoutUri = Server(URI(""), OwnCloudVersion.nextcloud_14)
|
||||||
|
whenever(user.server).thenReturn(serverWithoutUri)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
// connectivity is checked
|
||||||
|
val result = connectivityService.isInternetWalled
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
// connection is walled
|
||||||
|
// request is not sent
|
||||||
|
assertTrue("Server should not be accessible", result)
|
||||||
|
verify(requestBuilder, never()).invoke(any())
|
||||||
|
verify(client, never()).executeMethod(any())
|
||||||
|
verify(client, never()).executeMethod(any(), any())
|
||||||
|
verify(client, never()).executeMethod(any(), any(), any())
|
||||||
|
}
|
||||||
|
|
||||||
fun mockResponse(contentLength: Long = 0, status: Int = HttpStatus.SC_OK) {
|
fun mockResponse(contentLength: Long = 0, status: Int = HttpStatus.SC_OK) {
|
||||||
whenever(client.executeMethod(any())).thenReturn(status)
|
whenever(client.executeMethod(any())).thenReturn(status)
|
||||||
whenever(getRequest.statusCode).thenReturn(status)
|
whenever(getRequest.statusCode).thenReturn(status)
|
||||||
|
|
Loading…
Reference in a new issue