[Libreoffice-commits] online.git: android/app

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Apr 8 16:45:50 UTC 2019


 android/app/build.gradle                                                                    |    7 
 android/app/src/main/java/org/libreoffice/androidapp/storage/DocumentProviderFactory.java   |    5 
 android/app/src/main/java/org/libreoffice/androidapp/storage/owncloud/OwnCloudFile.java     |  178 +++++++++
 android/app/src/main/java/org/libreoffice/androidapp/storage/owncloud/OwnCloudProvider.java |  192 ++++++++++
 android/app/src/main/java/org/libreoffice/androidapp/ui/LibreOfficeUIActivity.java          |    3 
 android/app/src/main/res/values/strings.xml                                                 |    4 
 6 files changed, 384 insertions(+), 5 deletions(-)

New commits:
commit 8ff2ac2142498a600506927154fb6b513e55e3a7
Author:     kaishu-sahu <kaishusahu101 at gmail.com>
AuthorDate: Tue Apr 2 00:51:06 2019 +0530
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Mon Apr 8 18:45:30 2019 +0200

    android: add ownCloud support from old app.
    
    Change-Id: I11f38bc7b35d2c7d9cc8a718232eac2efe13388f
    Reviewed-on: https://gerrit.libreoffice.org/70084
    Reviewed-by: Jan Holesovsky <kendy at collabora.com>
    Tested-by: Jan Holesovsky <kendy at collabora.com>

diff --git a/android/app/build.gradle b/android/app/build.gradle
index fca7f39fe..522ff61b9 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -50,12 +50,19 @@ android {
     }
 }
 
+repositories {
+    flatDir {
+        dirs "${liboWorkdir}/UnpackedTarball/owncloud_android_lib/build/outputs/aar"
+    }
+}
+
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
     implementation 'androidx.appcompat:appcompat:1.0.2'
     implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
     implementation 'androidx.recyclerview:recyclerview:1.0.0'
     implementation 'com.google.android.material:material:1.1.0-alpha04'
+    implementation(name:'owncloud_android_lib', ext:'aar')
 }
 
 task copyUnpackAssets(type: Copy) {
diff --git a/android/app/src/main/java/org/libreoffice/androidapp/storage/DocumentProviderFactory.java b/android/app/src/main/java/org/libreoffice/androidapp/storage/DocumentProviderFactory.java
index 2fc3e031a..eb4a0ac91 100644
--- a/android/app/src/main/java/org/libreoffice/androidapp/storage/DocumentProviderFactory.java
+++ b/android/app/src/main/java/org/libreoffice/androidapp/storage/DocumentProviderFactory.java
@@ -16,12 +16,11 @@ import org.libreoffice.androidapp.storage.external.ExtsdDocumentsProvider;
 import org.libreoffice.androidapp.storage.external.OTGDocumentsProvider;
 import org.libreoffice.androidapp.storage.local.LocalDocumentsDirectoryProvider;
 import org.libreoffice.androidapp.storage.local.LocalDocumentsProvider;
+import org.libreoffice.androidapp.storage.owncloud.OwnCloudProvider;
 
 import java.util.HashSet;
 import java.util.Set;
 
-//import org.libreoffice.androidapp.storage.owncloud.OwnCloudProvider;
-
 /**
  * Keeps the instances of the available IDocumentProviders in the system.
  * Instances are maintained in a sorted list and providers have to be
@@ -64,7 +63,7 @@ public final class DocumentProviderFactory {
             instance.providers[0] = new LocalDocumentsDirectoryProvider(0);
             instance.providers[1] = new LocalDocumentsProvider(1);
             instance.providers[OTG_PROVIDER_INDEX] = new OTGDocumentsProvider(OTG_PROVIDER_INDEX, context);
-//            instance.providers[4] = new OwnCloudProvider(4, context);
+            instance.providers[4] = new OwnCloudProvider(4, context);
 
             instance.providers[EXTSD_PROVIDER_INDEX] = new ExtsdDocumentsProvider(EXTSD_PROVIDER_INDEX, context);
 
diff --git a/android/app/src/main/java/org/libreoffice/androidapp/storage/owncloud/OwnCloudFile.java b/android/app/src/main/java/org/libreoffice/androidapp/storage/owncloud/OwnCloudFile.java
new file mode 100644
index 000000000..21d800234
--- /dev/null
+++ b/android/app/src/main/java/org/libreoffice/androidapp/storage/owncloud/OwnCloudFile.java
@@ -0,0 +1,178 @@
+package org.libreoffice.androidapp.storage.owncloud;
+
+import android.content.Context;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.libreoffice.androidapp.storage.IFile;
+
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.resources.files.ChunkedUploadRemoteFileOperation;
+import com.owncloud.android.lib.resources.files.DownloadRemoteFileOperation;
+import com.owncloud.android.lib.resources.files.ReadRemoteFolderOperation;
+import com.owncloud.android.lib.resources.files.RemoteFile;
+import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation;
+
+/**
+ * Implementation of IFile for ownCloud servers.
+ */
+public class OwnCloudFile implements IFile {
+
+    private OwnCloudProvider provider;
+    private RemoteFile file;
+
+    private String name;
+    private String parentPath;
+
+    protected OwnCloudFile(OwnCloudProvider provider, RemoteFile file) {
+        this.provider = provider;
+        this.file = file;
+
+        // get name and parent from path
+        File localFile = new File(file.getRemotePath());
+        this.name = localFile.getName();
+        this.parentPath = localFile.getParent();
+    }
+
+    @Override
+    public URI getUri(){
+
+        try{
+            return URI.create(URLEncoder.encode(file.getRemotePath(),"UTF-8"));
+        }catch(UnsupportedEncodingException e){
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public boolean isDirectory() {
+        return file.getMimeType().equals("DIR");
+    }
+
+    @Override
+    public long getSize() {
+        return file.getLength();
+    }
+
+    @Override
+    public Date getLastModified() {
+        return new Date(file.getModifiedTimestamp());
+    }
+
+    @Override
+    public List<IFile> listFiles() {
+        List<IFile> children = new ArrayList<IFile>();
+        if (isDirectory()) {
+            ReadRemoteFolderOperation refreshOperation = new ReadRemoteFolderOperation(
+                    file.getRemotePath());
+            RemoteOperationResult result = refreshOperation.execute(provider
+                    .getClient());
+            if (!result.isSuccess()) {
+                throw provider.buildRuntimeExceptionForResultCode(result.getCode());
+            }
+            for (Object obj : result.getData()) {
+                RemoteFile child = (RemoteFile) obj;
+                if (!child.getRemotePath().equals(file.getRemotePath()))
+                    children.add(new OwnCloudFile(provider, child));
+            }
+        }
+        return children;
+    }
+
+    @Override
+    public List<IFile> listFiles(FileFilter filter) {
+        List<IFile> children = new ArrayList<IFile>();
+        if (isDirectory()) {
+            ReadRemoteFolderOperation refreshOperation = new ReadRemoteFolderOperation(
+                    file.getRemotePath());
+            RemoteOperationResult result = refreshOperation.execute(provider
+                    .getClient());
+            if (!result.isSuccess()) {
+                throw provider.buildRuntimeExceptionForResultCode(result.getCode());
+            }
+
+            for (Object obj : result.getData()) {
+                RemoteFile child = (RemoteFile) obj;
+                if (!child.getRemotePath().equals(file.getRemotePath())){
+                    OwnCloudFile ownCloudFile = new OwnCloudFile(provider, child);
+                    if(!ownCloudFile.isDirectory()){
+                        File f = new File(provider.getCacheDir().getAbsolutePath(),
+                                ownCloudFile.getName());
+                        if(filter.accept(f))
+                            children.add(ownCloudFile);
+                        f.delete();
+                    }else{
+                        children.add(ownCloudFile);
+                    }
+                }
+            }
+        }
+        return children;
+    }
+
+    @Override
+    public IFile getParent(Context context) {
+        if (parentPath == null)
+            // this is the root node
+            return null;
+
+        return provider.createFromUri(context, URI.create(parentPath));
+    }
+
+    @Override
+    public File getDocument() {
+        if (isDirectory()) {
+            return null;
+        }
+        File downFolder = provider.getCacheDir();
+        DownloadRemoteFileOperation operation = new DownloadRemoteFileOperation(
+                file.getRemotePath(), downFolder.getAbsolutePath());
+        RemoteOperationResult result = operation.execute(provider.getClient());
+        if (!result.isSuccess()) {
+            throw provider.buildRuntimeExceptionForResultCode(result.getCode());
+        }
+        return new File(downFolder.getAbsolutePath() + file.getRemotePath());
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object)
+            return true;
+        if (!(object instanceof OwnCloudFile))
+            return false;
+        OwnCloudFile file = (OwnCloudFile) object;
+        return file.getUri().equals(getUri());
+    }
+
+    @Override
+    public void saveDocument(File newFile) {
+        UploadRemoteFileOperation uploadOperation;
+        if (newFile.length() > ChunkedUploadRemoteFileOperation.CHUNK_SIZE) {
+            uploadOperation = new ChunkedUploadRemoteFileOperation(
+                    newFile.getPath(), file.getRemotePath(), file.getMimeType());
+        } else {
+            uploadOperation = new UploadRemoteFileOperation(newFile.getPath(),
+                    file.getRemotePath(), file.getMimeType());
+        }
+
+        RemoteOperationResult result = uploadOperation.execute(provider
+                .getClient());
+        if (!result.isSuccess()) {
+            throw provider.buildRuntimeExceptionForResultCode(result.getCode());
+        }
+    }
+}
diff --git a/android/app/src/main/java/org/libreoffice/androidapp/storage/owncloud/OwnCloudProvider.java b/android/app/src/main/java/org/libreoffice/androidapp/storage/owncloud/OwnCloudProvider.java
new file mode 100644
index 000000000..e270c728c
--- /dev/null
+++ b/android/app/src/main/java/org/libreoffice/androidapp/storage/owncloud/OwnCloudProvider.java
@@ -0,0 +1,192 @@
+package org.libreoffice.androidapp.storage.owncloud;
+
+import java.io.File;
+import java.net.URI;
+
+import org.libreoffice.androidapp.R;
+import org.libreoffice.androidapp.storage.DocumentProviderSettingsActivity;
+import org.libreoffice.androidapp.storage.IDocumentProvider;
+import org.libreoffice.androidapp.storage.IFile;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.net.Uri;
+import android.preference.PreferenceManager;
+
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.OwnCloudClientFactory;
+import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
+import com.owncloud.android.lib.resources.files.FileUtils;
+import com.owncloud.android.lib.resources.files.ReadRemoteFileOperation;
+import com.owncloud.android.lib.resources.files.RemoteFile;
+
+
+/**
+ * Implementation of IDocumentProvider for ownCloud servers.
+ */
+public class OwnCloudProvider implements IDocumentProvider,
+        OnSharedPreferenceChangeListener {
+
+    private int id;
+
+    private Context context;
+    private OwnCloudClient client;
+    private File cacheDir;
+
+    private String serverUrl;
+    private String userName;
+    private String password;
+    private RemoteOperationResult result;
+
+    public OwnCloudProvider(int id, Context context) {
+        this.id = id;
+        this.context = context;
+
+        // read preferences
+        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
+        serverUrl = preferences.getString(
+                DocumentProviderSettingsActivity.KEY_PREF_OWNCLOUD_SERVER, "");
+        userName = preferences.getString(
+                DocumentProviderSettingsActivity.KEY_PREF_OWNCLOUD_USER_NAME, "");
+        password = preferences.getString(
+                DocumentProviderSettingsActivity.KEY_PREF_OWNCLOUD_PASSWORD, "");
+
+        setupClient();
+
+        // make sure cache directory exists, and clear it
+        // TODO: probably we should do smarter cache management
+        cacheDir = new File(context.getCacheDir(), "ownCloud");
+        if (cacheDir.exists()) {
+            deleteRecursive(cacheDir);
+        }
+        cacheDir.mkdirs();
+    }
+
+    private void setupClient() {
+        Uri serverUri = Uri.parse(serverUrl);
+        client = OwnCloudClientFactory.createOwnCloudClient(serverUri, context,
+                true);
+        client.setCredentials(OwnCloudCredentialsFactory.newBasicCredentials(
+                userName, password));
+    }
+
+    @Override
+    public IFile getRootDirectory(Context context) {
+        return createFromUri(context, URI.create(FileUtils.PATH_SEPARATOR));
+    }
+
+    @Override
+    public IFile createFromUri(Context context, URI uri) {
+        if(serverUrl != "" || userName != "" || password != ""){
+            ReadRemoteFileOperation refreshOperation = new ReadRemoteFileOperation(
+                    uri.getPath());
+            this.result = refreshOperation.execute(client);
+            if (!result.isSuccess()) {
+                throw buildRuntimeExceptionForResultCode(result.getCode());
+            }
+            if (result.getData().size() > 0) {
+                return new OwnCloudFile(this, (RemoteFile) result.getData().get(0));
+            }
+        } else {
+            throw buildRuntimeExceptionForResultCode(ResultCode.WRONG_CONNECTION);
+        }
+
+        return null;
+    }
+
+    @Override
+    public int getNameResource() {
+        return R.string.owncloud;
+    }
+
+    /**
+     * Used by OwnCloudFiles to get a configured client to run their own
+     * operations.
+     *
+     * @return configured OwnCloudClient.
+     */
+    protected OwnCloudClient getClient() {
+        return client;
+    }
+
+    /**
+     * Used by OwnCloudFiles to get the cache directory they should download
+     * files to.
+     *
+     * @return cache directory.
+     */
+    protected File getCacheDir() {
+        return cacheDir;
+    }
+
+    /**
+     * Build the proper RuntimeException for some error result.
+     *
+     * @param code Result code got from some RemoteOperationResult.
+     * @return exception with the proper internationalized error message.
+     */
+    protected RuntimeException buildRuntimeExceptionForResultCode(ResultCode code) {
+        int errorMessage;
+        switch (code) {
+            case WRONG_CONNECTION:  // SocketException
+            case FILE_NOT_FOUND:    // HTTP 404
+                errorMessage = R.string.owncloud_wrong_connection;
+                break;
+            case UNAUTHORIZED:      // wrong user/pass
+                errorMessage = R.string.owncloud_unauthorized;
+                break;
+            default:
+                errorMessage = R.string.owncloud_unspecified_error;
+                break;
+        }
+        return new RuntimeException(context.getString(errorMessage));
+    }
+
+    /**
+     * Deletes files and recursively deletes directories.
+     *
+     * @param file
+     *            File or directory to be deleted.
+     */
+    private static void deleteRecursive(File file) {
+        if (file.isDirectory()) {
+            for (File child : file.listFiles())
+                deleteRecursive(child);
+        }
+        file.delete();
+    }
+
+    @Override
+    public void onSharedPreferenceChanged(SharedPreferences preferences,
+            String key) {
+        boolean changed = false;
+        if (key.equals(DocumentProviderSettingsActivity.KEY_PREF_OWNCLOUD_SERVER)) {
+            serverUrl = preferences.getString(key, "");
+            changed = true;
+        }
+        else if (key.equals(DocumentProviderSettingsActivity.KEY_PREF_OWNCLOUD_USER_NAME)) {
+            userName = preferences.getString(key, "");
+            changed = true;
+        }
+        else if (key.equals(DocumentProviderSettingsActivity.KEY_PREF_OWNCLOUD_PASSWORD)) {
+            password = preferences.getString(key, "");
+            changed = true;
+        }
+
+        if (changed)
+            setupClient();
+    }
+
+    @Override
+    public int getId() {
+        return id;
+    }
+
+    @Override
+    public boolean checkProviderAvailability(Context context) {
+        return client != null;
+    }
+}
diff --git a/android/app/src/main/java/org/libreoffice/androidapp/ui/LibreOfficeUIActivity.java b/android/app/src/main/java/org/libreoffice/androidapp/ui/LibreOfficeUIActivity.java
index 7035fd473..8f003b6c0 100644
--- a/android/app/src/main/java/org/libreoffice/androidapp/ui/LibreOfficeUIActivity.java
+++ b/android/app/src/main/java/org/libreoffice/androidapp/ui/LibreOfficeUIActivity.java
@@ -261,8 +261,7 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements /*Settin
         );
 
         // Loop through the document providers menu items and check if they are available or not
-        //TODO remove -1. Used right now to ignore opencloud
-        for (int index = 0; index < providerNames.size() - 1; index++) {
+        for (int index = 0; index < providerNames.size(); index++) {
             MenuItem item = navigationDrawer.getMenu().getItem(index);
             item.setEnabled(documentProviderFactory.getProvider(index).checkProviderAvailability(this));
         }
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
index bfde02318..69f49d340 100644
--- a/android/app/src/main/res/values/strings.xml
+++ b/android/app/src/main/res/values/strings.xml
@@ -55,6 +55,10 @@
     <string name="owncloud">Remote server</string>
     <string name="usb_connected_configure">USB connected, configure your device.</string>
 
+    <string name="owncloud_wrong_connection">Cannot connect to ownCloud server. Check your configuration.</string>
+    <string name="owncloud_unauthorized">Cannot log into ownCloud server. Check your configuration.</string>
+    <string name="owncloud_unspecified_error">Unspecified error connecting to ownCloud server. Check your configuration and/or try later.</string>
+
     <string name="ext_document_provider_error">Invalid root file. Check your sd card configuration.</string>
     <string name="otg_missing_error">Invalid root file. Check your OTG device and/or configuration.</string>
 


More information about the Libreoffice-commits mailing list