From: Bartek Przybylski
Date: Tue, 31 Jul 2012 15:43:37 +0000 (+0200)
Subject: moving from eu.alefzero.eu to com.owncloud.android
X-Git-Tag: oc-android-1.4.3~219
X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/a4ba6170ea7696e085b07adfef73eeb8b77cb8e2
moving from eu.alefzero.eu to com.owncloud.android
---
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 53a199dd..a75fbfbf 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
-->
-
@@ -123,11 +123,6 @@
-
-
-
-
-
diff --git a/res/layout-land/account_setup.xml b/res/layout-land/account_setup.xml
index 1420234d..1a452ddf 100644
--- a/res/layout-land/account_setup.xml
+++ b/res/layout-land/account_setup.xml
@@ -17,7 +17,7 @@
along with this program. If not, see .
-->
-
\ No newline at end of file
+
diff --git a/res/layout-large-land/files.xml b/res/layout-large-land/files.xml
index 32d86b0a..13d16f99 100644
--- a/res/layout-large-land/files.xml
+++ b/res/layout-large-land/files.xml
@@ -32,7 +32,7 @@
android:id="@+id/fileList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
- class="eu.alefzero.owncloud.ui.fragment.FileListFragment" >
+ class="com.owncloud.android.ui.fragment.FileListFragment" >
@@ -46,4 +46,4 @@
-
\ No newline at end of file
+
diff --git a/res/layout/account_setup.xml b/res/layout/account_setup.xml
index 65e1cd9f..5f128722 100644
--- a/res/layout/account_setup.xml
+++ b/res/layout/account_setup.xml
@@ -17,7 +17,7 @@
along with this program. If not, see .
-->
-
\ No newline at end of file
+
diff --git a/res/layout/files.xml b/res/layout/files.xml
index 9f868cab..78f8daf0 100644
--- a/res/layout/files.xml
+++ b/res/layout/files.xml
@@ -27,9 +27,9 @@
android:id="@+id/fileList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
- class="eu.alefzero.owncloud.ui.fragment.FileListFragment" >
+ class="com.owncloud.android.ui.fragment.FileListFragment" >
-
\ No newline at end of file
+
diff --git a/res/layout/pincodelock.xml b/res/layout/pincodelock.xml
index 61645fed..a02ca267 100644
--- a/res/layout/pincodelock.xml
+++ b/res/layout/pincodelock.xml
@@ -16,7 +16,7 @@
along with this program. If not, see .
-->
-
\ No newline at end of file
+
diff --git a/src/com/owncloud/android/AccountUtils.java b/src/com/owncloud/android/AccountUtils.java
new file mode 100644
index 00000000..9c487939
--- /dev/null
+++ b/src/com/owncloud/android/AccountUtils.java
@@ -0,0 +1,109 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android;
+
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.utils.OwnCloudVersion;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+public class AccountUtils {
+ public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php";
+ public static final String WEBDAV_PATH_2_0 = "/files/webdav.php";
+ public static final String WEBDAV_PATH_4_0 = "/remote.php/webdav";
+ public static final String CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php";
+ public static final String CARDDAV_PATH_4_0 = "/remote/carddav.php";
+ public static final String STATUS_PATH = "/status.php";
+
+ /**
+ * Can be used to get the currently selected ownCloud account in the
+ * preferences
+ *
+ * @param context The current appContext
+ * @return The current account or first available, if none is available,
+ * then null.
+ */
+ public static Account getCurrentOwnCloudAccount(Context context) {
+ Account[] ocAccounts = AccountManager.get(context).getAccountsByType(
+ AccountAuthenticator.ACCOUNT_TYPE);
+ Account defaultAccount = null;
+
+ SharedPreferences appPreferences = PreferenceManager
+ .getDefaultSharedPreferences(context);
+ String accountName = appPreferences
+ .getString("select_oc_account", null);
+
+ if (accountName != null) {
+ for (Account account : ocAccounts) {
+ if (account.name.equals(accountName)) {
+ defaultAccount = account;
+ break;
+ }
+ }
+ } else if (ocAccounts.length != 0) {
+ // we at least need to take first account as fallback
+ defaultAccount = ocAccounts[0];
+ }
+
+ return defaultAccount;
+ }
+
+
+
+ /**
+ * Checks, whether or not there are any ownCloud accounts setup.
+ *
+ * @return true, if there is at least one account.
+ */
+ public static boolean accountsAreSetup(Context context) {
+ AccountManager accMan = AccountManager.get(context);
+ Account[] accounts = accMan
+ .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
+ return accounts.length > 0;
+ }
+
+
+ public static void setCurrentOwnCloudAccount(Context context, String name) {
+ SharedPreferences.Editor appPrefs = PreferenceManager
+ .getDefaultSharedPreferences(context).edit();
+ appPrefs.putString("select_oc_account", name);
+ appPrefs.commit();
+ }
+
+ /**
+ *
+ * @param version version of owncloud
+ * @return webdav path for given OC version, null if OC version unknown
+ */
+ public static String getWebdavPath(OwnCloudVersion version) {
+ if (version.compareTo(OwnCloudVersion.owncloud_v4) >= 0)
+ return WEBDAV_PATH_4_0;
+ if (version.compareTo(OwnCloudVersion.owncloud_v3) >= 0
+ || version.compareTo(OwnCloudVersion.owncloud_v2) >= 0)
+ return WEBDAV_PATH_2_0;
+ if (version.compareTo(OwnCloudVersion.owncloud_v1) >= 0)
+ return WEBDAV_PATH_1_2;
+ return null;
+ }
+
+}
diff --git a/src/com/owncloud/android/CrashHandler.java b/src/com/owncloud/android/CrashHandler.java
new file mode 100644
index 00000000..e2ceb10b
--- /dev/null
+++ b/src/com/owncloud/android/CrashHandler.java
@@ -0,0 +1,154 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.owncloud.android.authenticator.AccountAuthenticator;
+
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.net.ConnectivityManager;
+import android.os.Environment;
+import android.util.Log;
+
+public class CrashHandler implements UncaughtExceptionHandler {
+
+ public static final String KEY_CRASH_FILENAME = "KEY_CRASH_FILENAME";
+
+ private Context mContext;
+ private static final String TAG = "CrashHandler";
+ private static final String crash_filename_template = "crash";
+ private static List TAGS;
+ private UncaughtExceptionHandler defaultUEH;
+
+ // TODO: create base activity which will register for crashlog tag automaticly
+ static {
+ TAGS = new LinkedList();
+ TAGS.add("AccountAuthenticator");
+ TAGS.add("AccountAuthenticator");
+ TAGS.add("ConnectionCheckerRunnable");
+ TAGS.add("EasySSLSocketFactory");
+ TAGS.add("FileDataStorageManager");
+ TAGS.add("PhotoTakenBroadcastReceiver");
+ TAGS.add("InstantUploadService");
+ TAGS.add("FileDownloader");
+ TAGS.add("FileUploader");
+ TAGS.add("LocationUpdateService");
+ TAGS.add("FileSyncAdapter");
+ TAGS.add("AuthActivity");
+ TAGS.add("OwnCloudPreferences");
+ TAGS.add("FileDetailFragment");
+ TAGS.add("FileListFragment");
+ TAGS.add("ownCloudUploader");
+ TAGS.add("WebdavClient");
+ }
+
+ public CrashHandler(Context context) {
+ mContext = context;
+ defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
+ }
+
+ @Override
+ public void uncaughtException(Thread thread, Throwable ex) {
+ final Writer writer = new StringWriter();
+ final PrintWriter printwriter = new PrintWriter(writer);
+ ex.printStackTrace(printwriter);
+ final String startrace = writer.toString();
+ printwriter.close();
+ File ocdir = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), "owncloud");
+ ocdir.mkdirs();
+
+ String crash_filename = crash_filename_template + System.currentTimeMillis() + ".txt";
+ File crashfile = new File(ocdir, crash_filename);
+ try {
+ PackageInfo pi = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
+ ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ String header = String.format("Model: %s, SDK: %d, Current net: %s AppVersion: %s\n\n",
+ android.os.Build.MODEL,
+ android.os.Build.VERSION.SDK_INT,
+ cm.getActiveNetworkInfo() != null ? cm.getActiveNetworkInfo().getTypeName() : "NONE",
+ pi.versionName);
+ Account account = AccountUtils.getCurrentOwnCloudAccount(mContext);
+ AccountManager am = AccountManager.get(mContext);
+ String header2 = String.format("Account: %s, OCUrl: %s, OCVersion: %s\n\n",
+ account.name,
+ am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL),
+ am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION));
+
+ crashfile.createNewFile();
+ FileWriter fw = new FileWriter(crashfile);
+ fw.write(header);
+ fw.write(header2);
+ fw.write(startrace);
+ fw.write("\n\n");
+
+ String logcat = "logcat -d *:S ";
+
+ for (String s : TAGS)
+ logcat += s + ":V ";
+
+ Process process = Runtime.getRuntime().exec(logcat);
+ BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ String logline;
+ while ((logline = br.readLine()) != null)
+ fw.write(logline+"\n");
+
+ br.close();
+ fw.close();
+
+ Intent dataintent = new Intent(mContext, CrashlogSendActivity.class);
+ dataintent.putExtra(KEY_CRASH_FILENAME, crashfile.getAbsolutePath());
+ PendingIntent intent;
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+ intent = PendingIntent.getActivity(mContext.getApplicationContext(), 0, dataintent, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ } else {
+ intent = PendingIntent.getActivity(mContext.getApplicationContext(), 0, dataintent, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ }
+ AlarmManager mngr = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
+ if (mngr == null) {
+ Log.e(TAG, "Couldn't retrieve alarm manager!");
+ defaultUEH.uncaughtException(thread, ex);
+ return;
+ }
+ mngr.set(AlarmManager.RTC, System.currentTimeMillis(), intent);
+ System.exit(2);
+ } catch (Exception e1) {
+ Log.e(TAG, "Crash handler failed!");
+ Log.e(TAG, e1.toString());
+ defaultUEH.uncaughtException(thread, ex);
+ return;
+ }
+ }
+}
diff --git a/src/com/owncloud/android/CrashlogSendActivity.java b/src/com/owncloud/android/CrashlogSendActivity.java
new file mode 100644
index 00000000..7f4074fc
--- /dev/null
+++ b/src/com/owncloud/android/CrashlogSendActivity.java
@@ -0,0 +1,112 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android;
+
+import java.io.File;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.FilePart;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.actionbarsherlock.app.SherlockActivity;
+
+import com.owncloud.android.R;
+
+public class CrashlogSendActivity extends SherlockActivity implements OnClickListener, OnCancelListener {
+
+ private static final String TAG = "CrashlogSendActivity";
+ private static final String CRASHLOG_SUBMIT_URL = "http://alefzero.eu/a/crashlog/";
+ private static final int DIALOG_SUBMIT = 5;
+
+ private String mLogFilename;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mLogFilename = getIntent().getStringExtra(CrashHandler.KEY_CRASH_FILENAME);
+ if (mLogFilename == null) {
+ Log.wtf(TAG, "No file crashlog path given!");
+ finish();
+ return;
+ }
+ Log.i(TAG, "crashlog file path " + mLogFilename);
+
+ showDialog(DIALOG_SUBMIT);
+ }
+
+
+ @Override
+ protected Dialog onCreateDialog(int id) {
+ if (id == DIALOG_SUBMIT) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setMessage(R.string.crashlog_message);
+ builder.setNegativeButton(R.string.crashlog_dont_send_report, this);
+ builder.setPositiveButton(R.string.crashlog_send_report, this);
+ builder.setCancelable(true);
+ builder.setOnCancelListener(this);
+ return builder.create();
+ }
+ return super.onCreateDialog(id);
+ }
+
+
+ @Override
+ public void onClick(DialogInterface dialog, final int which) {
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ // TODO Auto-generated method stub
+ File file = new File(mLogFilename);
+ if (which == Dialog.BUTTON_POSITIVE) {
+ try {
+ HttpClient client = new HttpClient();
+ PostMethod post = new PostMethod(CRASHLOG_SUBMIT_URL);
+ Part[] parts = {new FilePart("crashfile", file)};
+ post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
+ client.executeMethod(post);
+ post.releaseConnection();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ file.delete();
+ finish();
+ }
+ }).start();
+ }
+
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ new File(mLogFilename).delete();
+ finish();
+ }
+
+}
diff --git a/src/com/owncloud/android/DisplayUtils.java b/src/com/owncloud/android/DisplayUtils.java
new file mode 100644
index 00000000..a9cfe1dc
--- /dev/null
+++ b/src/com/owncloud/android/DisplayUtils.java
@@ -0,0 +1,117 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android;
+
+import java.util.Date;
+import java.util.HashMap;
+
+/**
+ * A helper class for some string operations.
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class DisplayUtils {
+
+ private static final String[] suffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
+
+ private static HashMap mimeType2HUmanReadable;
+ static {
+ mimeType2HUmanReadable = new HashMap();
+ // images
+ mimeType2HUmanReadable.put("image/jpeg", "JPEG image");
+ mimeType2HUmanReadable.put("image/jpg", "JPEG image");
+ mimeType2HUmanReadable.put("image/png", "PNG image");
+ mimeType2HUmanReadable.put("image/bmp", "Bitmap image");
+ mimeType2HUmanReadable.put("image/gif", "GIF image");
+ mimeType2HUmanReadable.put("image/svg+xml", "JPEG image");
+ mimeType2HUmanReadable.put("image/tiff", "TIFF image");
+ // music
+ mimeType2HUmanReadable.put("audio/mpeg", "MP3 music file");
+ mimeType2HUmanReadable.put("application/ogg", "OGG music file");
+
+ }
+
+ /**
+ * Converts the file size in bytes to human readable output.
+ *
+ * @param bytes Input file size
+ * @return Like something readable like "12 MB"
+ */
+ public static String bytesToHumanReadable(long bytes) {
+ double result = bytes;
+ int attachedsuff = 0;
+ while (result > 1024 && attachedsuff < suffixes.length) {
+ result /= 1024.;
+ attachedsuff++;
+ }
+ result = ((int) (result * 100)) / 100.;
+ return result + " " + suffixes[attachedsuff];
+ }
+
+ /**
+ * Removes special HTML entities from a string
+ *
+ * @param s Input string
+ * @return A cleaned version of the string
+ */
+ public static String HtmlDecode(String s) {
+ /*
+ * TODO: Perhaps we should use something more proven like:
+ * http://commons.apache.org/lang/api-2.6/org/apache/commons/lang/StringEscapeUtils.html#unescapeHtml%28java.lang.String%29
+ */
+
+ String ret = "";
+ for (int i = 0; i < s.length(); ++i) {
+ if (s.charAt(i) == '%') {
+ ret += (char) Integer.parseInt(s.substring(i + 1, i + 3), 16);
+ i += 2;
+ } else {
+ ret += s.charAt(i);
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Converts MIME types like "image/jpg" to more end user friendly output
+ * like "JPG image".
+ *
+ * @param mimetype MIME type to convert
+ * @return A human friendly version of the MIME type
+ */
+ public static String convertMIMEtoPrettyPrint(String mimetype) {
+ if (mimeType2HUmanReadable.containsKey(mimetype)) {
+ return mimeType2HUmanReadable.get(mimetype);
+ }
+ if (mimetype.split("/").length >= 2)
+ return mimetype.split("/")[1].toUpperCase() + " file";
+ return "Unknown type";
+ }
+
+ /**
+ * Converts Unix time to human readable format
+ * @param miliseconds that have passed since 01/01/1970
+ * @return The human readable time for the users locale
+ */
+ public static String unixTimeToHumanReadable(long milliseconds) {
+ Date date = new Date(milliseconds);
+ return date.toLocaleString();
+ }
+}
diff --git a/src/com/owncloud/android/OwnCloudSession.java b/src/com/owncloud/android/OwnCloudSession.java
new file mode 100644
index 00000000..67f9b8e1
--- /dev/null
+++ b/src/com/owncloud/android/OwnCloudSession.java
@@ -0,0 +1,56 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android;
+
+/**
+ * Represents a session to an ownCloud instance
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class OwnCloudSession {
+ private String mSessionName;
+ private String mSessionUrl;
+ private int mEntryId;
+
+ public OwnCloudSession(String name, String url, int entryId) {
+ mSessionName = name;
+ mSessionUrl = url;
+ mEntryId = entryId;
+ }
+
+ public void setName(String name) {
+ mSessionName = name;
+ }
+
+ public String getName() {
+ return mSessionName;
+ }
+
+ public void setUrl(String url) {
+ mSessionUrl = url;
+ }
+
+ public String getUrl() {
+ return mSessionUrl;
+ }
+
+ public int getEntryId() {
+ return mEntryId;
+ }
+}
diff --git a/src/com/owncloud/android/Uploader.java b/src/com/owncloud/android/Uploader.java
new file mode 100644
index 00000000..718911d3
--- /dev/null
+++ b/src/com/owncloud/android/Uploader.java
@@ -0,0 +1,415 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Stack;
+import java.util.Vector;
+
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.datamodel.DataStorageManager;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.services.FileUploader;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.app.Dialog;
+import android.app.ListActivity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.provider.MediaStore.Images.Media;
+import android.util.Log;
+import android.view.View;
+import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.SimpleAdapter;
+import com.owncloud.android.R;
+import eu.alefzero.webdav.WebdavClient;
+
+/**
+ * This can be used to upload things to an ownCloud instance.
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class Uploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {
+ private static final String TAG = "ownCloudUploader";
+
+ private Account mAccount;
+ private AccountManager mAccountManager;
+ private Stack mParents;
+ private ArrayList mStreamsToUpload;
+ private boolean mCreateDir;
+ private String mUploadPath;
+ private static final String[] CONTENT_PROJECTION = { Media.DATA, Media.DISPLAY_NAME, Media.MIME_TYPE, Media.SIZE };
+ private DataStorageManager mStorageManager;
+ private OCFile mFile;
+
+ private final static int DIALOG_NO_ACCOUNT = 0;
+ private final static int DIALOG_WAITING = 1;
+ private final static int DIALOG_NO_STREAM = 2;
+ private final static int DIALOG_MULTIPLE_ACCOUNT = 3;
+ private final static int DIALOG_GET_DIRNAME = 4;
+
+ private final static int REQUEST_CODE_SETUP_ACCOUNT = 0;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().requestFeature(Window.FEATURE_NO_TITLE);
+ mParents = new Stack();
+ mParents.add("");
+ if (getIntent().hasExtra(Intent.EXTRA_STREAM)) {
+ prepareStreamsToUpload();
+ mAccountManager = (AccountManager) getSystemService(Context.ACCOUNT_SERVICE);
+ Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
+ if (accounts.length == 0) {
+ Log.i(TAG, "No ownCloud account is available");
+ showDialog(DIALOG_NO_ACCOUNT);
+ } else if (accounts.length > 1) {
+ Log.i(TAG, "More then one ownCloud is available");
+ showDialog(DIALOG_MULTIPLE_ACCOUNT);
+ } else {
+ mAccount = accounts[0];
+ setContentView(R.layout.uploader_layout);
+ mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
+ populateDirectoryList();
+ }
+ } else {
+ showDialog(DIALOG_NO_STREAM);
+ }
+ }
+
+ @Override
+ protected Dialog onCreateDialog(final int id) {
+ final AlertDialog.Builder builder = new Builder(this);
+ switch (id) {
+ case DIALOG_WAITING:
+ ProgressDialog pDialog = new ProgressDialog(this);
+ pDialog.setIndeterminate(false);
+ pDialog.setCancelable(false);
+ pDialog.setMessage(getResources().getString(R.string.uploader_info_uploading));
+ return pDialog;
+ case DIALOG_NO_ACCOUNT:
+ builder.setIcon(android.R.drawable.ic_dialog_alert);
+ builder.setTitle(R.string.uploader_wrn_no_account_title);
+ builder.setMessage(R.string.uploader_wrn_no_account_text);
+ builder.setCancelable(false);
+ builder.setPositiveButton(R.string.uploader_wrn_no_account_setup_btn_text, new OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ECLAIR_MR1) {
+ // using string value since in API7 this
+ // constatn is not defined
+ // in API7 < this constatant is defined in
+ // Settings.ADD_ACCOUNT_SETTINGS
+ // and Settings.EXTRA_AUTHORITIES
+ Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
+ intent.putExtra("authorities", new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
+ startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
+ } else {
+ // since in API7 there is no direct call for
+ // account setup, so we need to
+ // show our own AccountSetupAcricity, get
+ // desired results and setup
+ // everything for ourself
+ Intent intent = new Intent(getBaseContext(), AccountAuthenticator.class);
+ startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
+ }
+ }
+ });
+ builder.setNegativeButton(R.string.uploader_wrn_no_account_quit_btn_text, new OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ finish();
+ }
+ });
+ return builder.create();
+ /*case DIALOG_GET_DIRNAME:
+ final EditText dirName = new EditText(getBaseContext());
+ builder.setView(dirName);
+ builder.setTitle(R.string.uploader_info_dirname);
+ String pathToUpload;
+ if (mParents.empty()) {
+ pathToUpload = "/";
+ } else {
+ mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()), null,
+ null, null, null);
+ mCursor.moveToFirst();
+ pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH))
+ + mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20"); // TODO don't make this ; use WebdavUtils.encode in the right moment
+ }
+ a a = new a(pathToUpload, dirName);
+ builder.setPositiveButton(R.string.common_ok, a);
+ builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+ return builder.create();*/
+ case DIALOG_MULTIPLE_ACCOUNT:
+ CharSequence ac[] = new CharSequence[mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];
+ for (int i = 0; i < ac.length; ++i) {
+ ac[i] = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[i].name;
+ }
+ builder.setTitle(R.string.common_choose_account);
+ builder.setItems(ac, new OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ mAccount = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[which];
+ mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
+ populateDirectoryList();
+ }
+ });
+ builder.setCancelable(true);
+ builder.setOnCancelListener(new OnCancelListener() {
+ public void onCancel(DialogInterface dialog) {
+ dialog.cancel();
+ finish();
+ }
+ });
+ return builder.create();
+ default:
+ throw new IllegalArgumentException("Unknown dialog id: " + id);
+ }
+ }
+
+ class a implements OnClickListener {
+ String mPath;
+ EditText mDirname;
+
+ public a(String path, EditText dirname) {
+ mPath = path;
+ mDirname = dirname;
+ }
+
+ public void onClick(DialogInterface dialog, int which) {
+ Uploader.this.mUploadPath = mPath + mDirname.getText().toString();
+ Uploader.this.mCreateDir = true;
+ uploadFiles();
+ }
+ }
+
+ @Override
+ public void onBackPressed() {
+
+ if (mParents.size() <= 1) {
+ super.onBackPressed();
+ return;
+ } else {
+ mParents.pop();
+ populateDirectoryList();
+ }
+ }
+
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ // click on folder in the list
+ Log.d(TAG, "on item click");
+ Vector tmpfiles = mStorageManager.getDirectoryContent(mFile);
+ if (tmpfiles == null) return;
+ // filter on dirtype
+ Vector files = new Vector();
+ for (OCFile f : tmpfiles)
+ if (f.isDirectory())
+ files.add(f);
+ if (files.size() < position) {
+ throw new IndexOutOfBoundsException("Incorrect item selected");
+ }
+ mParents.push(files.get(position).getFileName());
+ populateDirectoryList();
+ }
+
+ public void onClick(View v) {
+ // click on button
+ switch (v.getId()) {
+ case R.id.uploader_choose_folder:
+ mUploadPath = ""; // first element in mParents is root dir, represented by ""; init mUploadPath with "/" results in a "//" prefix
+ for (String p : mParents)
+ mUploadPath += p + OCFile.PATH_SEPARATOR;
+ Log.d(TAG, "Uploading file to dir " + mUploadPath);
+
+ uploadFiles();
+
+ break;
+ case android.R.id.button1: // dynamic action for create aditional dir
+ showDialog(DIALOG_GET_DIRNAME);
+ break;
+ default:
+ throw new IllegalArgumentException("Wrong element clicked");
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ Log.i(TAG, "result received. req: " + requestCode + " res: " + resultCode);
+ if (requestCode == REQUEST_CODE_SETUP_ACCOUNT) {
+ dismissDialog(DIALOG_NO_ACCOUNT);
+ if (resultCode == RESULT_CANCELED) {
+ finish();
+ }
+ Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.AUTH_TOKEN_TYPE);
+ if (accounts.length == 0) {
+ showDialog(DIALOG_NO_ACCOUNT);
+ } else {
+ // there is no need for checking for is there more then one
+ // account at this point
+ // since account setup can set only one account at time
+ mAccount = accounts[0];
+ populateDirectoryList();
+ }
+ }
+ }
+
+ private void populateDirectoryList() {
+ setContentView(R.layout.uploader_layout);
+
+ String full_path = "";
+ for (String a : mParents)
+ full_path += a + "/";
+
+ Log.d(TAG, "Populating view with content of : " + full_path);
+
+ mFile = mStorageManager.getFileByPath(full_path);
+ if (mFile != null) {
+ Vector files = mStorageManager.getDirectoryContent(mFile);
+ if (files != null) {
+ List> data = new LinkedList>();
+ for (OCFile f : files) {
+ HashMap h = new HashMap();
+ if (f.isDirectory()) {
+ h.put("dirname", f.getFileName());
+ data.add(h);
+ }
+ }
+ SimpleAdapter sa = new SimpleAdapter(this,
+ data,
+ R.layout.uploader_list_item_layout,
+ new String[] {"dirname"},
+ new int[] {R.id.textView1});
+ setListAdapter(sa);
+ Button btn = (Button) findViewById(R.id.uploader_choose_folder);
+ btn.setOnClickListener(this);
+ getListView().setOnItemClickListener(this);
+ }
+ }
+ /*
+ mCursor = managedQuery(ProviderMeta.ProviderTableMeta.CONTENT_URI, null, ProviderTableMeta.FILE_NAME
+ + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", new String[] { "/", mAccount.name }, null);
+
+ if (mCursor.moveToFirst()) {
+ mCursor = managedQuery(
+ ProviderMeta.ProviderTableMeta.CONTENT_URI,
+ null,
+ ProviderTableMeta.FILE_CONTENT_TYPE + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND "
+ + ProviderTableMeta.FILE_PARENT + "=?",
+ new String[] { "DIR", mAccount.name,
+ mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID)) }, null);
+
+ ListView lv = getListView();
+ lv.setOnItemClickListener(this);
+ SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout, mCursor,
+ new String[] { ProviderTableMeta.FILE_NAME }, new int[] { R.id.textView1 });
+ setListAdapter(sca);
+ Button btn = (Button) findViewById(R.id.uploader_choose_folder);
+ btn.setOnClickListener(this);
+ /*
+ * disable this until new server interaction service wont be created
+ * // insert create new directory for multiple items uploading if
+ * (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
+ * Button createDirBtn = new Button(this);
+ * createDirBtn.setId(android.R.id.button1);
+ * createDirBtn.setText(R.string.uploader_btn_create_dir_text);
+ * createDirBtn.setOnClickListener(this); ((LinearLayout)
+ * findViewById(R.id.linearLayout1)).addView( createDirBtn,
+ * LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); }
+ *
+ }*/
+ }
+
+ private void prepareStreamsToUpload() {
+ if (getIntent().getAction().equals(Intent.ACTION_SEND)) {
+ mStreamsToUpload = new ArrayList();
+ mStreamsToUpload.add(getIntent().getParcelableExtra(Intent.EXTRA_STREAM));
+ } else if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
+ mStreamsToUpload = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM);
+ } else {
+ // unknow action inserted
+ throw new IllegalArgumentException("Unknown action given: " + getIntent().getAction());
+ }
+ }
+
+ public void uploadFiles() {
+ WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());
+ wdc.allowSelfsignedCertificates();
+
+ // create last directory in path if nessesary
+ if (mCreateDir) {
+ wdc.createDirectory(mUploadPath);
+ }
+
+ String[] local = new String[mStreamsToUpload.size()], remote = new String[mStreamsToUpload.size()];
+
+ for (int i = 0; i < mStreamsToUpload.size(); ++i) {
+ Uri uri = (Uri) mStreamsToUpload.get(i);
+ if (uri.getScheme().equals("content")) {
+ Cursor c = getContentResolver().query((Uri) mStreamsToUpload.get(i),
+ CONTENT_PROJECTION,
+ null,
+ null,
+ null);
+
+ if (!c.moveToFirst())
+ continue;
+
+ final String display_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
+ data = c.getString(c.getColumnIndex(Media.DATA));
+ local[i] = data;
+ remote[i] = mUploadPath + display_name;
+ } else if (uri.getScheme().equals("file")) {
+ final File file = new File(Uri.decode(uri.toString()).replace(uri.getScheme() + "://", ""));
+ local[i] = file.getAbsolutePath();
+ remote[i] = mUploadPath + file.getName();
+ }
+
+ }
+ Intent intent = new Intent(getApplicationContext(), FileUploader.class);
+ intent.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_MULTIPLE_FILES);
+ intent.putExtra(FileUploader.KEY_LOCAL_FILE, local);
+ intent.putExtra(FileUploader.KEY_REMOTE_FILE, remote);
+ intent.putExtra(FileUploader.KEY_ACCOUNT, mAccount);
+ startService(intent);
+ finish();
+ }
+
+}
diff --git a/src/com/owncloud/android/authenticator/AccountAuthenticator.java b/src/com/owncloud/android/authenticator/AccountAuthenticator.java
new file mode 100644
index 00000000..543b0df5
--- /dev/null
+++ b/src/com/owncloud/android/authenticator/AccountAuthenticator.java
@@ -0,0 +1,281 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.authenticator;
+
+import com.owncloud.android.ui.activity.AuthenticatorActivity;
+
+import android.accounts.*;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+public class AccountAuthenticator extends AbstractAccountAuthenticator {
+ /**
+ * Is used by android system to assign accounts to authenticators. Should be
+ * used by application and all extensions.
+ */
+ public static final String ACCOUNT_TYPE = "owncloud";
+ public static final String AUTH_TOKEN_TYPE = "org.owncloud";
+
+ public static final String KEY_AUTH_TOKEN_TYPE = "authTokenType";
+ public static final String KEY_REQUIRED_FEATURES = "requiredFeatures";
+ public static final String KEY_LOGIN_OPTIONS = "loginOptions";
+ public static final String KEY_ACCOUNT = "account";
+ /**
+ * Value under this key should handle path to webdav php script. Will be
+ * removed and usage should be replaced by combining
+ * {@link eu.alefzero.owncloud.authenticator.KEY_OC_BASE_URL} and
+ * {@link com.owncloud.android.utils.OwnCloudVersion}
+ *
+ * @deprecated
+ */
+ public static final String KEY_OC_URL = "oc_url";
+ /**
+ * Version should be 3 numbers separated by dot so it can be parsed by
+ * {@link com.owncloud.android.utils.OwnCloudVersion}
+ */
+ public static final String KEY_OC_VERSION = "oc_version";
+ /**
+ * Base url should point to owncloud installation without trailing / ie:
+ * http://server/path or https://owncloud.server
+ */
+ public static final String KEY_OC_BASE_URL = "oc_base_url";
+
+ private static final String TAG = "AccountAuthenticator";
+ private Context mContext;
+
+ public AccountAuthenticator(Context context) {
+ super(context);
+ mContext = context;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Bundle addAccount(AccountAuthenticatorResponse response,
+ String accountType, String authTokenType,
+ String[] requiredFeatures, Bundle options)
+ throws NetworkErrorException {
+ Log.i(TAG, "Adding account with type " + accountType
+ + " and auth token " + authTokenType);
+ try {
+ validateAccountType(accountType);
+ } catch (AuthenticatorException e) {
+ Log.e(TAG, "Failed to validate account type " + accountType + ": "
+ + e.getMessage());
+ e.printStackTrace();
+ return e.getFailureBundle();
+ }
+ final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
+ intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
+ response);
+ intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
+ intent.putExtra(KEY_REQUIRED_FEATURES, requiredFeatures);
+ intent.putExtra(KEY_LOGIN_OPTIONS, options);
+
+ setIntentFlags(intent);
+ final Bundle bundle = new Bundle();
+ bundle.putParcelable(AccountManager.KEY_INTENT, intent);
+ return bundle;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Bundle confirmCredentials(AccountAuthenticatorResponse response,
+ Account account, Bundle options) throws NetworkErrorException {
+ try {
+ validateAccountType(account.type);
+ } catch (AuthenticatorException e) {
+ Log.e(TAG, "Failed to validate account type " + account.type + ": "
+ + e.getMessage());
+ e.printStackTrace();
+ return e.getFailureBundle();
+ }
+ Intent intent = new Intent(mContext, AuthenticatorActivity.class);
+ intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
+ response);
+ intent.putExtra(KEY_ACCOUNT, account);
+ intent.putExtra(KEY_LOGIN_OPTIONS, options);
+
+ setIntentFlags(intent);
+
+ Bundle resultBundle = new Bundle();
+ resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);
+ return resultBundle;
+ }
+
+ @Override
+ public Bundle editProperties(AccountAuthenticatorResponse response,
+ String accountType) {
+ return null;
+ }
+
+ @Override
+ public Bundle getAuthToken(AccountAuthenticatorResponse response,
+ Account account, String authTokenType, Bundle options)
+ throws NetworkErrorException {
+ try {
+ validateAccountType(account.type);
+ validateAuthTokenType(authTokenType);
+ } catch (AuthenticatorException e) {
+ Log.e(TAG, "Failed to validate account type " + account.type + ": "
+ + e.getMessage());
+ e.printStackTrace();
+ return e.getFailureBundle();
+ }
+ final AccountManager am = AccountManager.get(mContext);
+ final String password = am.getPassword(account);
+ if (password != null) {
+ final Bundle result = new Bundle();
+ result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
+ result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
+ result.putString(AccountManager.KEY_AUTHTOKEN, password);
+ return result;
+ }
+
+ final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
+ intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
+ response);
+ intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
+ intent.putExtra(KEY_LOGIN_OPTIONS, options);
+ intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
+
+ final Bundle bundle = new Bundle();
+ bundle.putParcelable(AccountManager.KEY_INTENT, intent);
+ return bundle;
+ }
+
+ @Override
+ public String getAuthTokenLabel(String authTokenType) {
+ return null;
+ }
+
+ @Override
+ public Bundle hasFeatures(AccountAuthenticatorResponse response,
+ Account account, String[] features) throws NetworkErrorException {
+ final Bundle result = new Bundle();
+ result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
+ return result;
+ }
+
+ @Override
+ public Bundle updateCredentials(AccountAuthenticatorResponse response,
+ Account account, String authTokenType, Bundle options)
+ throws NetworkErrorException {
+ final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
+ intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
+ response);
+ intent.putExtra(KEY_ACCOUNT, account);
+ intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
+ intent.putExtra(KEY_LOGIN_OPTIONS, options);
+ setIntentFlags(intent);
+
+ final Bundle bundle = new Bundle();
+ bundle.putParcelable(AccountManager.KEY_INTENT, intent);
+ return bundle;
+ }
+
+ @Override
+ public Bundle getAccountRemovalAllowed(
+ AccountAuthenticatorResponse response, Account account)
+ throws NetworkErrorException {
+ return super.getAccountRemovalAllowed(response, account);
+ }
+
+ private void setIntentFlags(Intent intent) {
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
+ intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
+ }
+
+ private void validateAccountType(String type)
+ throws UnsupportedAccountTypeException {
+ if (!type.equals(ACCOUNT_TYPE)) {
+ throw new UnsupportedAccountTypeException();
+ }
+ }
+
+ private void validateAuthTokenType(String authTokenType)
+ throws UnsupportedAuthTokenTypeException {
+ if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {
+ throw new UnsupportedAuthTokenTypeException();
+ }
+ }
+
+ public static class AuthenticatorException extends Exception {
+ private static final long serialVersionUID = 1L;
+ private Bundle mFailureBundle;
+
+ public AuthenticatorException(int code, String errorMsg) {
+ mFailureBundle = new Bundle();
+ mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);
+ mFailureBundle
+ .putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
+ }
+
+ public Bundle getFailureBundle() {
+ return mFailureBundle;
+ }
+ }
+
+ public static class UnsupportedAccountTypeException extends
+ AuthenticatorException {
+ private static final long serialVersionUID = 1L;
+
+ public UnsupportedAccountTypeException() {
+ super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
+ "Unsupported account type");
+ }
+ }
+
+ public static class UnsupportedAuthTokenTypeException extends
+ AuthenticatorException {
+ private static final long serialVersionUID = 1L;
+
+ public UnsupportedAuthTokenTypeException() {
+ super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
+ "Unsupported auth token type");
+ }
+ }
+
+ public static class UnsupportedFeaturesException extends
+ AuthenticatorException {
+ public static final long serialVersionUID = 1L;
+
+ public UnsupportedFeaturesException() {
+ super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
+ "Unsupported features");
+ }
+ }
+
+ public static class AccessDeniedException extends AuthenticatorException {
+ public AccessDeniedException(int code, String errorMsg) {
+ super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ }
+}
diff --git a/src/com/owncloud/android/authenticator/AccountAuthenticatorService.java b/src/com/owncloud/android/authenticator/AccountAuthenticatorService.java
new file mode 100644
index 00000000..e11b03a4
--- /dev/null
+++ b/src/com/owncloud/android/authenticator/AccountAuthenticatorService.java
@@ -0,0 +1,41 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.authenticator;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class AccountAuthenticatorService extends Service {
+
+ private AccountAuthenticator mAuthenticator;
+ static final public String ACCOUNT_TYPE = "owncloud";
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mAuthenticator = new AccountAuthenticator(this);
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mAuthenticator.getIBinder();
+ }
+
+}
diff --git a/src/com/owncloud/android/authenticator/AuthenticationRunnable.java b/src/com/owncloud/android/authenticator/AuthenticationRunnable.java
new file mode 100644
index 00000000..dba32819
--- /dev/null
+++ b/src/com/owncloud/android/authenticator/AuthenticationRunnable.java
@@ -0,0 +1,81 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.authenticator;
+
+import java.net.URL;
+
+import org.apache.commons.httpclient.HttpStatus;
+
+import eu.alefzero.webdav.WebdavClient;
+
+import android.net.Uri;
+import android.os.Handler;
+
+public class AuthenticationRunnable implements Runnable {
+
+ private OnAuthenticationResultListener mListener;
+ private Handler mHandler;
+ private URL mUrl;
+ private String mUsername;
+ private String mPassword;
+
+ public AuthenticationRunnable(URL url, String username, String password) {
+ mListener = null;
+ mUrl = url;
+ mUsername = username;
+ mPassword = password;
+ }
+
+ public void setOnAuthenticationResultListener(
+ OnAuthenticationResultListener listener, Handler handler) {
+ mListener = listener;
+ mHandler = handler;
+ }
+
+ @Override
+ public void run() {
+ Uri uri;
+ uri = Uri.parse(mUrl.toString());
+ int login_result = WebdavClient.tryToLogin(uri, mUsername, mPassword);
+ switch (login_result) {
+ case HttpStatus.SC_OK:
+ postResult(true, uri.toString());
+ break;
+ case HttpStatus.SC_UNAUTHORIZED:
+ postResult(false, "Invalid login or/and password");
+ break;
+ case HttpStatus.SC_NOT_FOUND:
+ postResult(false, "Wrong path given");
+ break;
+ default:
+ postResult(false, "Internal server error, code: " + login_result);
+ }
+ }
+
+ private void postResult(final boolean success, final String message) {
+ if (mHandler != null && mListener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onAuthenticationResult(success, message);
+ }
+ });
+ }
+ }
+}
diff --git a/src/com/owncloud/android/authenticator/ConnectionCheckerRunnable.java b/src/com/owncloud/android/authenticator/ConnectionCheckerRunnable.java
new file mode 100644
index 00000000..d1d10706
--- /dev/null
+++ b/src/com/owncloud/android/authenticator/ConnectionCheckerRunnable.java
@@ -0,0 +1,170 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.authenticator;
+
+import java.net.ConnectException;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+
+import javax.net.ssl.SSLHandshakeException;
+
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authenticator.OnConnectCheckListener.ResultType;
+import com.owncloud.android.utils.OwnCloudVersion;
+
+import eu.alefzero.webdav.WebdavClient;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.util.Log;
+
+public class ConnectionCheckerRunnable implements Runnable {
+
+ /** Maximum time to wait for a response from the server when the connection is being tested, in MILLISECONDs. */
+ public static final int TRY_CONNECTION_TIMEOUT = 5000;
+
+ private static final String TAG = "ConnectionCheckerRunnable";
+ private OnConnectCheckListener mListener;
+ private String mUrl;
+ private Handler mHandler;
+ private ResultType mLatestResult;
+ private Context mContext;
+ private OwnCloudVersion mOCVersion;
+
+ public void setListener(OnConnectCheckListener listener, Handler handler) {
+ mListener = listener;
+ mHandler = handler;
+ }
+
+ public ConnectionCheckerRunnable(String url, Context context) {
+ mListener = null;
+ mHandler = null;
+ mUrl = url;
+ mContext = context;
+ mOCVersion = null;
+ }
+
+ @Override
+ public void run() {
+
+ if (!isOnline()) {
+ postResult(ResultType.NO_NETWORK_CONNECTION);
+ return;
+ }
+ if (mUrl.startsWith("http://") || mUrl.startsWith("https://")) {
+ mLatestResult = (mUrl.startsWith("https://"))? ResultType.OK_SSL : ResultType.OK_NO_SSL;
+ tryConnection(Uri.parse(mUrl + AccountUtils.STATUS_PATH));
+ postResult(mLatestResult);
+ } else {
+ Uri uri = Uri.parse("https://" + mUrl + AccountUtils.STATUS_PATH);
+ if (tryConnection(uri)) {
+ postResult(ResultType.OK_SSL);
+ return;
+ }
+ Log.d(TAG,
+ "establishing secure connection failed, trying non secure connection");
+ uri = Uri.parse("http://" + mUrl + AccountUtils.STATUS_PATH);
+
+ if (tryConnection(uri)) {
+ postResult(ResultType.OK_NO_SSL);
+ return;
+ }
+ postResult(mLatestResult);
+ }
+ }
+
+ public OwnCloudVersion getDiscoveredVersion() {
+ return mOCVersion;
+ }
+
+ private boolean tryConnection(Uri uri) {
+ WebdavClient wc = new WebdavClient();
+ wc.allowSelfsignedCertificates();
+ GetMethod get = new GetMethod(uri.toString());
+ boolean retval = false;
+ try {
+ int status = wc.executeMethod(get, TRY_CONNECTION_TIMEOUT);
+ switch (status) {
+ case HttpStatus.SC_OK: {
+ String response = get.getResponseBodyAsString();
+ JSONObject json = new JSONObject(response);
+ if (!json.getBoolean("installed")) {
+ mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
+ break;
+ }
+ mOCVersion = new OwnCloudVersion(json.getString("version"));
+ if (!mOCVersion.isVersionValid())
+ break;
+ retval = true;
+ break;
+ }
+ case HttpStatus.SC_NOT_FOUND:
+ mLatestResult = ResultType.FILE_NOT_FOUND;
+ break;
+ case HttpStatus.SC_INTERNAL_SERVER_ERROR:
+ mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
+ break;
+ default:
+ mLatestResult = ResultType.UNKNOWN_ERROR;
+ Log.e(TAG, "Not handled status received from server: " + status);
+ }
+
+ } catch (Exception e) {
+ if (e instanceof UnknownHostException
+ || e instanceof ConnectException
+ || e instanceof SocketTimeoutException) {
+ mLatestResult = ResultType.HOST_NOT_AVAILABLE;
+ } else if (e instanceof JSONException) {
+ mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
+ } else if (e instanceof SSLHandshakeException) {
+ mLatestResult = ResultType.SSL_INIT_ERROR;
+ } else {
+ mLatestResult = ResultType.UNKNOWN_ERROR;
+ }
+ e.printStackTrace();
+ }
+
+ return retval;
+ }
+
+ private boolean isOnline() {
+ ConnectivityManager cm = (ConnectivityManager) mContext
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ return cm != null && cm.getActiveNetworkInfo() != null
+ && cm.getActiveNetworkInfo().isConnectedOrConnecting();
+ }
+
+ private void postResult(final ResultType result) {
+ if (mHandler != null && mListener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onConnectionCheckResult(result);
+ }
+ });
+ }
+ }
+
+}
diff --git a/src/com/owncloud/android/authenticator/EasySSLSocketFactory.java b/src/com/owncloud/android/authenticator/EasySSLSocketFactory.java
new file mode 100644
index 00000000..0a3f8bee
--- /dev/null
+++ b/src/com/owncloud/android/authenticator/EasySSLSocketFactory.java
@@ -0,0 +1,221 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package com.owncloud.android.authenticator;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+
+import org.apache.commons.httpclient.ConnectTimeoutException;
+import org.apache.commons.httpclient.HttpClientError;
+import org.apache.commons.httpclient.params.HttpConnectionParams;
+import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
+import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
+
+import android.util.Log;
+
+/**
+ *
+ * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s that
+ * accept self-signed certificates.
+ *
+ *
+ * This socket factory SHOULD NOT be used for productive systems due to security
+ * reasons, unless it is a concious decision and you are perfectly aware of
+ * security implications of accepting self-signed certificates
+ *
+ *
+ *
+ * Example of using custom protocol socket factory for a specific host:
+ *
+ *
+ * Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(),
+ * 443);
+ *
+ * URI uri = new URI("https://localhost/", true);
+ * // use relative url only
+ * GetMethod httpget = new GetMethod(uri.getPathQuery());
+ * HostConfiguration hc = new HostConfiguration();
+ * hc.setHost(uri.getHost(), uri.getPort(), easyhttps);
+ * HttpClient client = new HttpClient();
+ * client.executeMethod(hc, httpget);
+ *
+ *
+ *
+ *
+ * Example of using custom protocol socket factory per default instead of the
+ * standard one:
+ *
+ *
+ * Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(),
+ * 443);
+ * Protocol.registerProtocol("https", easyhttps);
+ *
+ * HttpClient client = new HttpClient();
+ * GetMethod httpget = new GetMethod("https://localhost/");
+ * client.executeMethod(httpget);
+ *
+ *
+ *
+ *
+ * @author Oleg Kalnichevski
+ *
+ *
+ * DISCLAIMER: HttpClient developers DO NOT actively support this
+ * component. The component is provided as a reference material, which
+ * may be inappropriate for use without additional customization.
+ *
+ */
+
+public class EasySSLSocketFactory implements ProtocolSocketFactory {
+
+ private static final String TAG = "EasySSLSocketFactory";
+ private SSLContext sslcontext = null;
+
+ /**
+ * Constructor for EasySSLProtocolSocketFactory.
+ */
+ public EasySSLSocketFactory() {
+ super();
+ }
+
+ private static SSLContext createEasySSLContext() {
+ try {
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(null, new TrustManager[] { new EasyX509TrustManager(
+ null) }, null);
+ return context;
+ } catch (Exception er) {
+ Log.e(TAG, er.getMessage() + "");
+ throw new HttpClientError(er.toString());
+ }
+ }
+
+ private SSLContext getSSLContext() {
+ if (this.sslcontext == null) {
+ this.sslcontext = createEasySSLContext();
+ }
+ return this.sslcontext;
+ }
+
+ /**
+ * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
+ */
+ public Socket createSocket(String host, int port, InetAddress clientHost,
+ int clientPort) throws IOException, UnknownHostException {
+
+ return getSSLContext().getSocketFactory().createSocket(host, port,
+ clientHost, clientPort);
+ }
+
+ /**
+ * Attempts to get a new socket connection to the given host within the
+ * given time limit.
+ *
+ * To circumvent the limitations of older JREs that do not support connect
+ * timeout a controller thread is executed. The controller thread attempts
+ * to create a new socket within the given limit of time. If socket
+ * constructor does not return until the timeout expires, the controller
+ * terminates and throws an {@link ConnectTimeoutException}
+ *
+ *
+ * @param host the host name/IP
+ * @param port the port on the host
+ * @param clientHost the local host name/IP to bind the socket to
+ * @param clientPort the port on the local machine
+ * @param params {@link HttpConnectionParams Http connection parameters}
+ *
+ * @return Socket a new socket
+ *
+ * @throws IOException if an I/O error occurs while creating the socket
+ * @throws UnknownHostException if the IP address of the host cannot be
+ * determined
+ */
+ public Socket createSocket(final String host, final int port,
+ final InetAddress localAddress, final int localPort,
+ final HttpConnectionParams params) throws IOException,
+ UnknownHostException, ConnectTimeoutException {
+ if (params == null) {
+ throw new IllegalArgumentException("Parameters may not be null");
+ }
+ int timeout = params.getConnectionTimeout();
+ SocketFactory socketfactory = getSSLContext().getSocketFactory();
+ if (timeout == 0) {
+ Socket socket = socketfactory.createSocket(host, port, localAddress,
+ localPort);
+ socket.setSoTimeout(params.getSoTimeout());
+ return socket;
+ } else {
+ Socket socket = socketfactory.createSocket();
+ SocketAddress localaddr = new InetSocketAddress(localAddress,
+ localPort);
+ SocketAddress remoteaddr = new InetSocketAddress(host, port);
+ socket.setSoTimeout(params.getSoTimeout());
+ socket.bind(localaddr);
+ socket.connect(remoteaddr, timeout);
+ return socket;
+ }
+ }
+
+ /**
+ * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
+ */
+ public Socket createSocket(String host, int port) throws IOException,
+ UnknownHostException {
+ return getSSLContext().getSocketFactory().createSocket(host, port);
+ }
+
+ /**
+ * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
+ */
+ public Socket createSocket(Socket socket, String host, int port,
+ boolean autoClose) throws IOException, UnknownHostException {
+ return getSSLContext().getSocketFactory().createSocket(socket, host,
+ port, autoClose);
+ }
+
+ public boolean equals(Object obj) {
+ return ((obj != null) && obj.getClass().equals(
+ EasySSLSocketFactory.class));
+ }
+
+ public int hashCode() {
+ return EasySSLSocketFactory.class.hashCode();
+ }
+
+}
\ No newline at end of file
diff --git a/src/com/owncloud/android/authenticator/EasyX509TrustManager.java b/src/com/owncloud/android/authenticator/EasyX509TrustManager.java
new file mode 100644
index 00000000..0c7b0834
--- /dev/null
+++ b/src/com/owncloud/android/authenticator/EasyX509TrustManager.java
@@ -0,0 +1,88 @@
+package com.owncloud.android.authenticator;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * @author olamy
+ * @version $Id: EasyX509TrustManager.java 765355 2009-04-15 20:59:07Z evenisse
+ * $
+ * @since 1.2.3
+ */
+public class EasyX509TrustManager implements X509TrustManager {
+
+ private X509TrustManager standardTrustManager = null;
+
+ /**
+ * Constructor for EasyX509TrustManager.
+ */
+ public EasyX509TrustManager(KeyStore keystore)
+ throws NoSuchAlgorithmException, KeyStoreException {
+ super();
+ TrustManagerFactory factory = TrustManagerFactory
+ .getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ factory.init(keystore);
+ TrustManager[] trustmanagers = factory.getTrustManagers();
+ if (trustmanagers.length == 0) {
+ throw new NoSuchAlgorithmException("no trust manager found");
+ }
+ this.standardTrustManager = (X509TrustManager) trustmanagers[0];
+ }
+
+ /**
+ * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],
+ * String authType)
+ */
+ public void checkClientTrusted(X509Certificate[] certificates,
+ String authType) throws CertificateException {
+ standardTrustManager.checkClientTrusted(certificates, authType);
+ }
+
+ /**
+ * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],
+ * String authType)
+ */
+ public void checkServerTrusted(X509Certificate[] certificates,
+ String authType) throws CertificateException {
+ if ((certificates != null) && (certificates.length == 1)) {
+ certificates[0].checkValidity();
+ } else {
+ // standardTrustManager.checkServerTrusted( certificates, authType
+ // );
+ }
+ }
+
+ /**
+ * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
+ */
+ public X509Certificate[] getAcceptedIssuers() {
+ return this.standardTrustManager.getAcceptedIssuers();
+ }
+
+}
\ No newline at end of file
diff --git a/src/com/owncloud/android/authenticator/OnAuthenticationResultListener.java b/src/com/owncloud/android/authenticator/OnAuthenticationResultListener.java
new file mode 100644
index 00000000..11cbdceb
--- /dev/null
+++ b/src/com/owncloud/android/authenticator/OnAuthenticationResultListener.java
@@ -0,0 +1,7 @@
+package com.owncloud.android.authenticator;
+
+public interface OnAuthenticationResultListener {
+
+ public void onAuthenticationResult(boolean success, String message);
+
+}
diff --git a/src/com/owncloud/android/authenticator/OnConnectCheckListener.java b/src/com/owncloud/android/authenticator/OnConnectCheckListener.java
new file mode 100644
index 00000000..bca71ae7
--- /dev/null
+++ b/src/com/owncloud/android/authenticator/OnConnectCheckListener.java
@@ -0,0 +1,11 @@
+package com.owncloud.android.authenticator;
+
+public interface OnConnectCheckListener {
+
+ enum ResultType {
+ OK_SSL, OK_NO_SSL, SSL_INIT_ERROR, HOST_NOT_AVAILABLE, TIMEOUT, NO_NETWORK_CONNECTION, INORRECT_ADDRESS, INSTANCE_NOT_CONFIGURED, FILE_NOT_FOUND, UNKNOWN_ERROR
+ }
+
+ public void onConnectionCheckResult(ResultType type);
+
+}
diff --git a/src/com/owncloud/android/datamodel/DataStorageManager.java b/src/com/owncloud/android/datamodel/DataStorageManager.java
new file mode 100644
index 00000000..a73ab66c
--- /dev/null
+++ b/src/com/owncloud/android/datamodel/DataStorageManager.java
@@ -0,0 +1,41 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.datamodel;
+
+import java.util.List;
+import java.util.Vector;
+
+public interface DataStorageManager {
+
+ public OCFile getFileByPath(String path);
+
+ public OCFile getFileById(long id);
+
+ public boolean fileExists(String path);
+
+ public boolean fileExists(long id);
+
+ public boolean saveFile(OCFile file);
+
+ public void saveFiles(List files);
+
+ public Vector getDirectoryContent(OCFile f);
+
+ public void removeFile(OCFile file);
+}
diff --git a/src/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/com/owncloud/android/datamodel/FileDataStorageManager.java
new file mode 100644
index 00000000..49a88c36
--- /dev/null
+++ b/src/com/owncloud/android/datamodel/FileDataStorageManager.java
@@ -0,0 +1,422 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.datamodel;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import com.owncloud.android.db.ProviderMeta;
+import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
+import com.owncloud.android.files.services.FileDownloader;
+
+import android.accounts.Account;
+import android.content.ContentProviderClient;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.OperationApplicationException;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.RemoteException;
+import android.util.Log;
+
+public class FileDataStorageManager implements DataStorageManager {
+
+ private ContentResolver mContentResolver;
+ private ContentProviderClient mContentProvider;
+ private Account mAccount;
+
+ private static String TAG = "FileDataStorageManager";
+
+ public FileDataStorageManager(Account account, ContentResolver cr) {
+ mContentProvider = null;
+ mContentResolver = cr;
+ mAccount = account;
+ }
+
+ public FileDataStorageManager(Account account, ContentProviderClient cp) {
+ mContentProvider = cp;
+ mContentResolver = null;
+ mAccount = account;
+ }
+
+ @Override
+ public OCFile getFileByPath(String path) {
+ Cursor c = getCursorForValue(ProviderTableMeta.FILE_PATH, path);
+ OCFile file = null;
+ if (c.moveToFirst()) {
+ file = createFileInstance(c);
+ }
+ c.close();
+ return file;
+ }
+
+ @Override
+ public OCFile getFileById(long id) {
+ Cursor c = getCursorForValue(ProviderTableMeta._ID, String.valueOf(id));
+ OCFile file = null;
+ if (c.moveToFirst()) {
+ file = createFileInstance(c);
+ }
+ c.close();
+ return file;
+ }
+
+ @Override
+ public boolean fileExists(long id) {
+ return fileExists(ProviderTableMeta._ID, String.valueOf(id));
+ }
+
+ @Override
+ public boolean fileExists(String path) {
+ return fileExists(ProviderTableMeta.FILE_PATH, path);
+ }
+
+ @Override
+ public boolean saveFile(OCFile file) {
+ boolean overriden = false;
+ ContentValues cv = new ContentValues();
+ cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
+ cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
+ cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
+ cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
+ cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
+ if (file.getParentId() != 0)
+ cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
+ cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
+ if (!file.isDirectory())
+ cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
+ cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
+ cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDate());
+ cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
+
+ if (fileExists(file.getRemotePath())) {
+ OCFile oldFile = getFileByPath(file.getRemotePath());
+ if (file.getStoragePath() == null && oldFile.getStoragePath() != null)
+ file.setStoragePath(oldFile.getStoragePath());
+ if (!file.isDirectory());
+ cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
+ file.setFileId(oldFile.getFileId());
+
+ overriden = true;
+ if (getContentResolver() != null) {
+ getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv,
+ ProviderTableMeta._ID + "=?",
+ new String[] { String.valueOf(file.getFileId()) });
+ } else {
+ try {
+ getContentProvider().update(ProviderTableMeta.CONTENT_URI,
+ cv, ProviderTableMeta._ID + "=?",
+ new String[] { String.valueOf(file.getFileId()) });
+ } catch (RemoteException e) {
+ Log.e(TAG,
+ "Fail to insert insert file to database "
+ + e.getMessage());
+ }
+ }
+ } else {
+ Uri result_uri = null;
+ if (getContentResolver() != null) {
+ result_uri = getContentResolver().insert(
+ ProviderTableMeta.CONTENT_URI_FILE, cv);
+ } else {
+ try {
+ result_uri = getContentProvider().insert(
+ ProviderTableMeta.CONTENT_URI_FILE, cv);
+ } catch (RemoteException e) {
+ Log.e(TAG,
+ "Fail to insert insert file to database "
+ + e.getMessage());
+ }
+ }
+ if (result_uri != null) {
+ long new_id = Long.parseLong(result_uri.getPathSegments()
+ .get(1));
+ file.setFileId(new_id);
+ }
+ }
+
+ if (file.isDirectory() && file.needsUpdatingWhileSaving())
+ for (OCFile f : getDirectoryContent(file))
+ saveFile(f);
+
+ return overriden;
+ }
+
+
+ @Override
+ public void saveFiles(List files) {
+
+ Iterator filesIt = files.iterator();
+ ArrayList operations = new ArrayList(files.size());
+ OCFile file = null;
+
+ // prepare operations to perform
+ while (filesIt.hasNext()) {
+ file = filesIt.next();
+ ContentValues cv = new ContentValues();
+ cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
+ cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
+ cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
+ cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
+ cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
+ if (file.getParentId() != 0)
+ cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
+ cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
+ if (!file.isDirectory())
+ cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
+ cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
+ cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDate());
+ cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
+
+ if (fileExists(file.getRemotePath())) {
+ OCFile tmpfile = getFileByPath(file.getRemotePath());
+ file.setStoragePath(tmpfile.getStoragePath());
+ if (!file.isDirectory());
+ cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
+ file.setFileId(tmpfile.getFileId());
+
+ operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
+ withValues(cv).
+ withSelection( ProviderTableMeta._ID + "=?",
+ new String[] { String.valueOf(file.getFileId()) })
+ .build());
+
+ } else {
+ operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
+ }
+ }
+
+ // apply operations in batch
+ ContentProviderResult[] results = null;
+ try {
+ if (getContentResolver() != null) {
+ results = getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations);
+
+ } else {
+ results = getContentProvider().applyBatch(operations);
+ }
+
+ } catch (OperationApplicationException e) {
+ Log.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
+
+ } catch (RemoteException e) {
+ Log.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
+ }
+
+ // update new id in file objects for insertions
+ if (results != null) {
+ long newId;
+ for (int i=0; i getDirectoryContent(OCFile f) {
+ if (f != null && f.isDirectory() && f.getFileId() != -1) {
+ Vector ret = new Vector();
+
+ Uri req_uri = Uri.withAppendedPath(
+ ProviderTableMeta.CONTENT_URI_DIR,
+ String.valueOf(f.getFileId()));
+ Cursor c = null;
+
+ if (getContentProvider() != null) {
+ try {
+ c = getContentProvider().query(req_uri, null,
+ ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+ new String[] { mAccount.name }, null);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage());
+ return ret;
+ }
+ } else {
+ c = getContentResolver().query(req_uri, null,
+ ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+ new String[] { mAccount.name }, null);
+ }
+
+ if (c.moveToFirst()) {
+ do {
+ OCFile child = createFileInstance(c);
+ ret.add(child);
+ } while (c.moveToNext());
+ }
+
+ c.close();
+
+ Collections.sort(ret);
+
+ return ret;
+ }
+ return null;
+ }
+
+ private boolean fileExists(String cmp_key, String value) {
+ Cursor c;
+ if (getContentResolver() != null) {
+ c = getContentResolver()
+ .query(ProviderTableMeta.CONTENT_URI,
+ null,
+ cmp_key + "=? AND "
+ + ProviderTableMeta.FILE_ACCOUNT_OWNER
+ + "=?",
+ new String[] { value, mAccount.name }, null);
+ } else {
+ try {
+ c = getContentProvider().query(
+ ProviderTableMeta.CONTENT_URI,
+ null,
+ cmp_key + "=? AND "
+ + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+ new String[] { value, mAccount.name }, null);
+ } catch (RemoteException e) {
+ Log.e(TAG,
+ "Couldn't determine file existance, assuming non existance: "
+ + e.getMessage());
+ return false;
+ }
+ }
+ boolean retval = c.moveToFirst();
+ c.close();
+ return retval;
+ }
+
+ private Cursor getCursorForValue(String key, String value) {
+ Cursor c = null;
+ if (getContentResolver() != null) {
+ c = getContentResolver()
+ .query(ProviderTableMeta.CONTENT_URI,
+ null,
+ key + "=? AND "
+ + ProviderTableMeta.FILE_ACCOUNT_OWNER
+ + "=?",
+ new String[] { value, mAccount.name }, null);
+ } else {
+ try {
+ c = getContentProvider().query(
+ ProviderTableMeta.CONTENT_URI,
+ null,
+ key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER
+ + "=?", new String[] { value, mAccount.name },
+ null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not get file details: " + e.getMessage());
+ c = null;
+ }
+ }
+ return c;
+ }
+
+ private OCFile createFileInstance(Cursor c) {
+ OCFile file = null;
+ if (c != null) {
+ file = new OCFile(c.getString(c
+ .getColumnIndex(ProviderTableMeta.FILE_PATH)));
+ file.setFileId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
+ file.setParentId(c.getLong(c
+ .getColumnIndex(ProviderTableMeta.FILE_PARENT)));
+ file.setMimetype(c.getString(c
+ .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)));
+ if (!file.isDirectory()) {
+ file.setStoragePath(c.getString(c
+ .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));
+ if (file.getStoragePath() == null) {
+ // try to find existing file and bind it with current account
+ File f = new File(FileDownloader.getSavePath(mAccount.name) + file.getRemotePath());
+ if (f.exists())
+ file.setStoragePath(f.getAbsolutePath());
+ }
+ }
+ file.setFileLength(c.getLong(c
+ .getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH)));
+ file.setCreationTimestamp(c.getLong(c
+ .getColumnIndex(ProviderTableMeta.FILE_CREATION)));
+ file.setModificationTimestamp(c.getLong(c
+ .getColumnIndex(ProviderTableMeta.FILE_MODIFIED)));
+ file.setLastSyncDate(c.getLong(c
+ .getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE)));
+ file.setKeepInSync(c.getInt(
+ c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false);
+ }
+ return file;
+ }
+
+ public void removeFile(OCFile file) {
+ Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, ""+file.getFileId());
+ if (getContentProvider() != null) {
+ try {
+ getContentProvider().delete(file_uri,
+ ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
+ new String[]{mAccount.name});
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ } else {
+ getContentResolver().delete(file_uri,
+ ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
+ new String[]{mAccount.name});
+ }
+ if (file.isDown()) {
+ new File(file.getStoragePath()).delete();
+ }
+ }
+
+}
diff --git a/src/com/owncloud/android/datamodel/OCFile.java b/src/com/owncloud/android/datamodel/OCFile.java
new file mode 100644
index 00000000..f50a86fc
--- /dev/null
+++ b/src/com/owncloud/android/datamodel/OCFile.java
@@ -0,0 +1,382 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.datamodel;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import com.owncloud.android.files.services.FileDownloader;
+
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class OCFile implements Parcelable, Comparable {
+
+ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
+ @Override
+ public OCFile createFromParcel(Parcel source) {
+ return new OCFile(source);
+ }
+
+ @Override
+ public OCFile[] newArray(int size) {
+ return new OCFile[size];
+ }
+ };
+
+ public static final String PATH_SEPARATOR = "/";
+
+ private long mId;
+ private long mParentId;
+ private long mLength;
+ private long mCreationTimestamp;
+ private long mModifiedTimestamp;
+ private String mRemotePath;
+ private String mLocalPath;
+ private String mMimeType;
+ private boolean mNeedsUpdating;
+ private long mLastSyncDate;
+ private boolean mKeepInSync;
+
+ /**
+ * Create new {@link OCFile} with given path.
+ *
+ * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'.
+ *
+ * @param path The remote path of the file.
+ */
+ public OCFile(String path) {
+ resetData();
+ mNeedsUpdating = false;
+ if (path == null || path.length() <= 0 || !path.startsWith(PATH_SEPARATOR)) {
+ throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path);
+ }
+ mRemotePath = path;
+ }
+
+ /**
+ * Reconstruct from parcel
+ *
+ * @param source The source parcel
+ */
+ private OCFile(Parcel source) {
+ mId = source.readLong();
+ mParentId = source.readLong();
+ mLength = source.readLong();
+ mCreationTimestamp = source.readLong();
+ mModifiedTimestamp = source.readLong();
+ mRemotePath = source.readString();
+ mLocalPath = source.readString();
+ mMimeType = source.readString();
+ mNeedsUpdating = source.readInt() == 0;
+ mKeepInSync = source.readInt() == 1;
+ mLastSyncDate = source.readLong();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(mId);
+ dest.writeLong(mParentId);
+ dest.writeLong(mLength);
+ dest.writeLong(mCreationTimestamp);
+ dest.writeLong(mModifiedTimestamp);
+ dest.writeString(mRemotePath);
+ dest.writeString(mLocalPath);
+ dest.writeString(mMimeType);
+ dest.writeInt(mNeedsUpdating ? 1 : 0);
+ dest.writeInt(mKeepInSync ? 1 : 0);
+ dest.writeLong(mLastSyncDate);
+ }
+
+ /**
+ * Gets the ID of the file
+ *
+ * @return the file ID
+ */
+ public long getFileId() {
+ return mId;
+ }
+
+ /**
+ * Returns the remote path of the file on ownCloud
+ *
+ * @return The remote path to the file
+ */
+ public String getRemotePath() {
+ return mRemotePath;
+ }
+
+ /**
+ * Can be used to check, whether or not this file exists in the database
+ * already
+ *
+ * @return true, if the file exists in the database
+ */
+ public boolean fileExists() {
+ return mId != -1;
+ }
+
+ /**
+ * Use this to find out if this file is a Directory
+ *
+ * @return true if it is a directory
+ */
+ public boolean isDirectory() {
+ return mMimeType != null && mMimeType.equals("DIR");
+ }
+
+ /**
+ * Use this to check if this file is available locally
+ *
+ * @return true if it is
+ */
+ public boolean isDown() {
+ if (mLocalPath != null && mLocalPath.length() > 0) {
+ File file = new File(mLocalPath);
+ return (file.exists());
+ }
+ return false;
+ }
+
+ /**
+ * The path, where the file is stored locally
+ *
+ * @return The local path to the file
+ */
+ public String getStoragePath() {
+ return mLocalPath;
+ }
+
+ /**
+ * Can be used to set the path where the file is stored
+ *
+ * @param storage_path to set
+ */
+ public void setStoragePath(String storage_path) {
+ mLocalPath = storage_path;
+ }
+
+ /**
+ * Get a UNIX timestamp of the file creation time
+ *
+ * @return A UNIX timestamp of the time that file was created
+ */
+ public long getCreationTimestamp() {
+ return mCreationTimestamp;
+ }
+
+ /**
+ * Set a UNIX timestamp of the time the file was created
+ *
+ * @param creation_timestamp to set
+ */
+ public void setCreationTimestamp(long creation_timestamp) {
+ mCreationTimestamp = creation_timestamp;
+ }
+
+ /**
+ * Get a UNIX timestamp of the file modification time
+ *
+ * @return A UNIX timestamp of the modification time
+ */
+ public long getModificationTimestamp() {
+ return mModifiedTimestamp;
+ }
+
+ /**
+ * Set a UNIX timestamp of the time the time the file was modified.
+ *
+ * @param modification_timestamp to set
+ */
+ public void setModificationTimestamp(long modification_timestamp) {
+ mModifiedTimestamp = modification_timestamp;
+ }
+
+ /**
+ * Returns the filename and "/" for the root directory
+ *
+ * @return The name of the file
+ */
+ public String getFileName() {
+ File f = new File(getRemotePath());
+ return f.getName().length() == 0 ? "/" : f.getName();
+ }
+
+ /**
+ * Can be used to get the Mimetype
+ *
+ * @return the Mimetype as a String
+ */
+ public String getMimetype() {
+ return mMimeType;
+ }
+
+ /**
+ * Adds a file to this directory. If this file is not a directory, an
+ * exception gets thrown.
+ *
+ * @param file to add
+ * @throws IllegalStateException if you try to add a something and this is
+ * not a directory
+ */
+ public void addFile(OCFile file) throws IllegalStateException {
+ if (isDirectory()) {
+ file.mParentId = mId;
+ mNeedsUpdating = true;
+ return;
+ }
+ throw new IllegalStateException(
+ "This is not a directory where you can add stuff to!");
+ }
+
+ /**
+ * Used internally. Reset all file properties
+ */
+ private void resetData() {
+ mId = -1;
+ mRemotePath = null;
+ mParentId = 0;
+ mLocalPath = null;
+ mMimeType = null;
+ mLength = 0;
+ mCreationTimestamp = 0;
+ mModifiedTimestamp = 0;
+ mLastSyncDate = 0;
+ mKeepInSync = false;
+ mNeedsUpdating = false;
+ }
+
+ /**
+ * Sets the ID of the file
+ *
+ * @param file_id to set
+ */
+ public void setFileId(long file_id) {
+ mId = file_id;
+ }
+
+ /**
+ * Sets the Mime-Type of the
+ *
+ * @param mimetype to set
+ */
+ public void setMimetype(String mimetype) {
+ mMimeType = mimetype;
+ }
+
+ /**
+ * Sets the ID of the parent folder
+ *
+ * @param parent_id to set
+ */
+ public void setParentId(long parent_id) {
+ mParentId = parent_id;
+ }
+
+ /**
+ * Sets the file size in bytes
+ *
+ * @param file_len to set
+ */
+ public void setFileLength(long file_len) {
+ mLength = file_len;
+ }
+
+ /**
+ * Returns the size of the file in bytes
+ *
+ * @return The filesize in bytes
+ */
+ public long getFileLength() {
+ return mLength;
+ }
+
+ /**
+ * Returns the ID of the parent Folder
+ *
+ * @return The ID
+ */
+ public long getParentId() {
+ return mParentId;
+ }
+
+ /**
+ * Check, if this file needs updating
+ *
+ * @return
+ */
+ public boolean needsUpdatingWhileSaving() {
+ return mNeedsUpdating;
+ }
+
+ public long getLastSyncDate() {
+ return mLastSyncDate;
+ }
+
+ public void setLastSyncDate(long lastSyncDate) {
+ mLastSyncDate = lastSyncDate;
+ }
+
+ public void setKeepInSync(boolean keepInSync) {
+ mKeepInSync = keepInSync;
+ }
+
+ public boolean keepInSync() {
+ return mKeepInSync;
+ }
+
+ @Override
+ public int describeContents() {
+ return this.hashCode();
+ }
+
+ @Override
+ public int compareTo(OCFile another) {
+ if (isDirectory() && another.isDirectory()) {
+ return getRemotePath().toLowerCase().compareTo(another.getRemotePath().toLowerCase());
+ } else if (isDirectory()) {
+ return -1;
+ } else if (another.isDirectory()) {
+ return 1;
+ }
+ return getRemotePath().toLowerCase().compareTo(another.getRemotePath().toLowerCase());
+ }
+
+ public boolean equals(Object o) {
+ if(o instanceof OCFile){
+ OCFile that = (OCFile) o;
+ if(that != null){
+ return this.mId == that.mId;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ String asString = "[id=%s, name=%s, mime=%s, downloaded=%s, local=%s, remote=%s, parentId=%s, keepInSinc=%s]";
+ asString = String.format(asString, new Long(mId), getFileName(), mMimeType, isDown(), mLocalPath, mRemotePath, new Long(mParentId), new Boolean(mKeepInSync));
+ return asString;
+ }
+
+}
diff --git a/src/com/owncloud/android/db/DbHandler.java b/src/com/owncloud/android/db/DbHandler.java
new file mode 100644
index 00000000..61d56557
--- /dev/null
+++ b/src/com/owncloud/android/db/DbHandler.java
@@ -0,0 +1,87 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.db;
+
+import java.util.Vector;
+
+import com.owncloud.android.OwnCloudSession;
+
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+/**
+ * Custom database helper for ownCloud
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class DbHandler {
+ private SQLiteDatabase mDB;
+ private OpenerHepler mHelper;
+ private final String mDatabaseName = "ownCloud";
+ private final String TABLE_SESSIONS = "sessions";
+ private final int mDatabaseVersion = 1;
+
+ private final String TABLE_INSTANT_UPLOAD = "instant_upload";
+
+ public DbHandler(Context context) {
+ mHelper = new OpenerHepler(context);
+ mDB = mHelper.getWritableDatabase();
+ }
+
+ public void close() {
+ mDB.close();
+ }
+
+ public boolean putFileForLater(String filepath, String account) {
+ ContentValues cv = new ContentValues();
+ cv.put("path", filepath);
+ cv.put("account", account);
+ return mDB.insert(TABLE_INSTANT_UPLOAD, null, cv) != -1;
+ }
+
+ public Cursor getAwaitingFiles() {
+ return mDB.query(TABLE_INSTANT_UPLOAD, null, null, null, null, null, null);
+ }
+
+ public void clearFiles() {
+ mDB.delete(TABLE_INSTANT_UPLOAD, null, null);
+ }
+
+ private class OpenerHepler extends SQLiteOpenHelper {
+ public OpenerHepler(Context context) {
+ super(context, mDatabaseName, null, mDatabaseVersion);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE " + TABLE_INSTANT_UPLOAD + " ("
+ + " _id INTEGET PRIMARY KEY, "
+ + " path TEXT,"
+ + " account TEXT);");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ }
+ }
+}
diff --git a/src/com/owncloud/android/db/ProviderMeta.java b/src/com/owncloud/android/db/ProviderMeta.java
new file mode 100644
index 00000000..c7f86b63
--- /dev/null
+++ b/src/com/owncloud/android/db/ProviderMeta.java
@@ -0,0 +1,67 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.db;
+
+import android.net.Uri;
+import android.provider.BaseColumns;
+
+/**
+ * Meta-Class that holds various static field information
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class ProviderMeta {
+
+ public static final String AUTHORITY_FILES = "org.owncloud";
+ public static final String DB_FILE = "owncloud.db";
+ public static final String DB_NAME = "filelist";
+ public static final int DB_VERSION = 2;
+
+ private ProviderMeta() {
+ }
+
+ static public class ProviderTableMeta implements BaseColumns {
+ public static final String DB_NAME = "filelist";
+ public static final Uri CONTENT_URI = Uri.parse("content://"
+ + AUTHORITY_FILES + "/");
+ public static final Uri CONTENT_URI_FILE = Uri.parse("content://"
+ + AUTHORITY_FILES + "/file");
+ public static final Uri CONTENT_URI_DIR = Uri.parse("content://"
+ + AUTHORITY_FILES + "/dir");
+
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.owncloud.file";
+ public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.owncloud.file";
+
+ public static final String FILE_PARENT = "parent";
+ public static final String FILE_NAME = "filename";
+ public static final String FILE_CREATION = "created";
+ public static final String FILE_MODIFIED = "modified";
+ public static final String FILE_CONTENT_LENGTH = "content_length";
+ public static final String FILE_CONTENT_TYPE = "content_type";
+ public static final String FILE_STORAGE_PATH = "media_path";
+ public static final String FILE_PATH = "path";
+ public static final String FILE_ACCOUNT_OWNER = "file_owner";
+ public static final String FILE_LAST_SYNC_DATE = "last_sync_date";
+ public static final String FILE_KEEP_IN_SYNC = "keep_in_sync";
+
+ public static final String DEFAULT_SORT_ORDER = FILE_NAME
+ + " collate nocase asc";
+
+ }
+}
diff --git a/src/com/owncloud/android/extensions/ExtensionsAvailableActivity.java b/src/com/owncloud/android/extensions/ExtensionsAvailableActivity.java
new file mode 100644
index 00000000..e389fd33
--- /dev/null
+++ b/src/com/owncloud/android/extensions/ExtensionsAvailableActivity.java
@@ -0,0 +1,17 @@
+package com.owncloud.android.extensions;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentManager;
+
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+
+public class ExtensionsAvailableActivity extends SherlockFragmentActivity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ FragmentManager fm = getSupportFragmentManager();
+ ExtensionsAvailableDialog ead = new ExtensionsAvailableDialog();
+ ead.show(fm, "extensions_available_dialog");
+ }
+}
diff --git a/src/com/owncloud/android/extensions/ExtensionsAvailableDialog.java b/src/com/owncloud/android/extensions/ExtensionsAvailableDialog.java
new file mode 100644
index 00000000..55483fa2
--- /dev/null
+++ b/src/com/owncloud/android/extensions/ExtensionsAvailableDialog.java
@@ -0,0 +1,50 @@
+package com.owncloud.android.extensions;
+
+import com.owncloud.android.R;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+public class ExtensionsAvailableDialog extends DialogFragment implements
+ OnClickListener {
+
+ public ExtensionsAvailableDialog() {
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.extensions_available_dialog,
+ container);
+ Button btnYes = (Button) view.findViewById(R.id.buttonYes);
+ Button btnNo = (Button) view.findViewById(R.id.buttonNo);
+ btnYes.setOnClickListener(this);
+ btnNo.setOnClickListener(this);
+ getDialog().setTitle(R.string.extensions_avail_title);
+ return view;
+ }
+
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.buttonYes: {
+ Intent i = new Intent(getActivity(), ExtensionsListActivity.class);
+ startActivity(i);
+ getActivity().finish();
+ }
+ break;
+ case R.id.buttonNo:
+ getActivity().finish();
+ break;
+ default:
+ Log.e("EAD", "Button with unknown id clicked " + v.getId());
+ }
+ }
+
+}
diff --git a/src/com/owncloud/android/extensions/ExtensionsListActivity.java b/src/com/owncloud/android/extensions/ExtensionsListActivity.java
new file mode 100644
index 00000000..44aa819c
--- /dev/null
+++ b/src/com/owncloud/android/extensions/ExtensionsListActivity.java
@@ -0,0 +1,134 @@
+package com.owncloud.android.extensions;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Vector;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.owncloud.android.utils.OwnCloudVersion;
+
+
+import android.R;
+import android.app.Activity;
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.widget.SimpleAdapter;
+
+public class ExtensionsListActivity extends ListActivity {
+
+ private static final String packages_url = "http://alefzero.eu/a/packages.php";
+
+ private Thread mGetterThread;
+ private final Handler mHandler = new Handler();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mGetterThread = new Thread(new JsonGetter());
+ mGetterThread.start();
+ }
+
+ public void done(JSONArray a) {
+ LinkedList> ll = new LinkedList>();
+ for (int i = 0; i < a.length(); ++i) {
+ try {
+ ExtensionApplicationEntry ela = new ExtensionApplicationEntry(
+ ((JSONObject) a.get(i)));
+ HashMap ss = new HashMap();
+ ss.put("NAME", ela.getName());
+ ss.put("DESC", ela.getDescription());
+ ll.add(ss);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ setListAdapter(new SimpleAdapter(this, ll, R.layout.simple_list_item_2,
+ new String[] { "NAME", "DESC" }, new int[] {
+ android.R.id.text1, android.R.id.text2 }));
+
+ }
+
+ private class JsonGetter implements Runnable {
+
+ @Override
+ public void run() {
+ HttpClient hc = new HttpClient();
+ GetMethod gm = new GetMethod(packages_url);
+ final JSONArray ar;
+ try {
+ hc.executeMethod(gm);
+ Log.e("ASD", gm.getResponseBodyAsString() + "");
+ ar = new JSONObject(gm.getResponseBodyAsString())
+ .getJSONArray("apps");
+ } catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ done(ar);
+ }
+ });
+
+ }
+
+ }
+
+ private class ExtensionApplicationEntry {
+ private static final String APP_NAME = "name";
+ private static final String APP_VERSION = "version";
+ private static final String APP_DESC = "description";
+ private static final String APP_ICON = "icon";
+ private static final String APP_URL = "download";
+ private static final String APP_PLAYID = "play_id";
+
+ private String mName, mDescription, mIcon, mDownload, mPlayId;
+ private OwnCloudVersion mVersion;
+
+ public ExtensionApplicationEntry(JSONObject appentry) {
+ try {
+ mName = appentry.getString(APP_NAME);
+ mDescription = appentry.getString(APP_DESC);
+ mIcon = appentry.getString(APP_ICON);
+ mDownload = appentry.getString(APP_URL);
+ mPlayId = appentry.getString(APP_PLAYID);
+ mVersion = new OwnCloudVersion(appentry.getString(APP_VERSION));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public String getDescription() {
+ return mDescription;
+ }
+
+ public String getIcon() {
+ return mIcon;
+ }
+
+ public String getDownload() {
+ return mDownload;
+ }
+
+ public String getPlayId() {
+ return mPlayId;
+ }
+
+ public OwnCloudVersion getVersion() {
+ return mVersion;
+ }
+ }
+}
diff --git a/src/com/owncloud/android/files/PhotoTakenBroadcastReceiver.java b/src/com/owncloud/android/files/PhotoTakenBroadcastReceiver.java
new file mode 100644
index 00000000..ec313b6a
--- /dev/null
+++ b/src/com/owncloud/android/files/PhotoTakenBroadcastReceiver.java
@@ -0,0 +1,151 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.files;
+
+import java.io.File;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.db.DbHandler;
+import com.owncloud.android.files.services.InstantUploadService;
+
+import com.owncloud.android.R;
+import android.accounts.Account;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.ConnectivityManager;
+import android.preference.Preference;
+import android.preference.PreferenceManager;
+import android.provider.MediaStore.Images.Media;
+import android.util.Log;
+import android.webkit.MimeTypeMap;
+
+public class PhotoTakenBroadcastReceiver extends BroadcastReceiver {
+
+ private static String TAG = "PhotoTakenBroadcastReceiver";
+ private static final String[] CONTENT_PROJECTION = { Media.DATA, Media.DISPLAY_NAME, Media.MIME_TYPE, Media.SIZE };
+
+ private static String NEW_PHOTO_ACTION = "com.android.camera.NEW_PICTURE";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_uploading", false)) {
+ Log.d(TAG, "Instant upload disabled, abording uploading");
+ return;
+ }
+ if (intent.getAction().equals(android.net.ConnectivityManager.CONNECTIVITY_ACTION)) {
+ handleConnectivityAction(context, intent);
+ } else if (intent.getAction().equals(NEW_PHOTO_ACTION)) {
+ handleNewPhontoAction(context, intent);
+ } else {
+ Log.e(TAG, "Incorrect intent sent: " + intent.getAction());
+ }
+ }
+
+ private void handleNewPhontoAction(Context context, Intent intent) {
+ Account account = AccountUtils.getCurrentOwnCloudAccount(context);
+ if (account == null) {
+ Log.w(TAG, "No owncloud account found for instant upload, abording");
+ return;
+ }
+
+ Cursor c = context.getContentResolver().query(intent.getData(), CONTENT_PROJECTION, null, null, null);
+
+ if (!c.moveToFirst()) {
+ Log.e(TAG, "Couldn't resolve given uri!");
+ return;
+ }
+
+ String file_path = c.getString(c.getColumnIndex(Media.DATA));
+ String file_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME));
+ String mime_type = c.getString(c.getColumnIndex(Media.MIME_TYPE));
+ long file_size = c.getLong(c.getColumnIndex(Media.SIZE));
+
+ c.close();
+
+ if (!isOnline(context)) {
+ DbHandler db = new DbHandler(context);
+ db.putFileForLater(file_path, account.name);
+ db.close();
+ return;
+ }
+
+ Intent upload_intent = new Intent(context, InstantUploadService.class);
+ upload_intent.putExtra(InstantUploadService.KEY_ACCOUNT, account);
+ upload_intent.putExtra(InstantUploadService.KEY_FILE_PATH, file_path);
+ upload_intent.putExtra(InstantUploadService.KEY_DISPLAY_NAME, file_name);
+ upload_intent.putExtra(InstantUploadService.KEY_FILE_SIZE, file_size);
+ upload_intent.putExtra(InstantUploadService.KEY_MIME_TYPE, mime_type);
+
+ context.startService(upload_intent);
+ }
+
+ private void handleConnectivityAction(Context context, Intent intent) {
+ if (!intent.hasExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY) ||
+ isOnline(context)) {
+ DbHandler db = new DbHandler(context);
+ Cursor c = db.getAwaitingFiles();
+ if (c.moveToFirst()) {
+ do {
+ String account_name = c.getString(c.getColumnIndex("account"));
+ String file_path = c.getString(c.getColumnIndex("path"));
+ File f = new File(file_path);
+ if (f.exists()) {
+ Intent upload_intent = new Intent(context, InstantUploadService.class);
+ Account account = new Account(account_name, AccountAuthenticator.ACCOUNT_TYPE);
+
+ String mimeType = null;
+ try {
+ mimeType = MimeTypeMap.getSingleton()
+ .getMimeTypeFromExtension(
+ f.getName().substring(f.getName().lastIndexOf('.') + 1));
+
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, "Trying to find out MIME type of a file without extension: " + f.getName());
+ }
+ if (mimeType == null)
+ mimeType = "application/octet-stream";
+
+ upload_intent.putExtra(InstantUploadService.KEY_ACCOUNT, account);
+ upload_intent.putExtra(InstantUploadService.KEY_FILE_PATH, file_path);
+ upload_intent.putExtra(InstantUploadService.KEY_DISPLAY_NAME, f.getName());
+ upload_intent.putExtra(InstantUploadService.KEY_FILE_SIZE, f.length());
+ upload_intent.putExtra(InstantUploadService.KEY_MIME_TYPE, mimeType);
+
+ context.startService(upload_intent);
+ } else {
+ Log.w(TAG, "Instant upload file " + f.getName() + " dont exist anymore");
+ }
+ } while(c.moveToNext());
+ c.close();
+ }
+ db.clearFiles();
+ db.close();
+ }
+
+ }
+
+ private boolean isOnline(Context context) {
+ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
+ }
+
+}
diff --git a/src/com/owncloud/android/files/interfaces/OnDatatransferProgressListener.java b/src/com/owncloud/android/files/interfaces/OnDatatransferProgressListener.java
new file mode 100644
index 00000000..f3ae82bb
--- /dev/null
+++ b/src/com/owncloud/android/files/interfaces/OnDatatransferProgressListener.java
@@ -0,0 +1,6 @@
+package com.owncloud.android.files.interfaces;
+
+public interface OnDatatransferProgressListener {
+ void transferProgress(long progressRate);
+
+}
diff --git a/src/com/owncloud/android/files/managers/OCNotificationManager.java b/src/com/owncloud/android/files/managers/OCNotificationManager.java
new file mode 100644
index 00000000..851a8f88
--- /dev/null
+++ b/src/com/owncloud/android/files/managers/OCNotificationManager.java
@@ -0,0 +1,154 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.files.managers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.widget.RemoteViews;
+
+import com.owncloud.android.R;
+
+public class OCNotificationManager {
+
+ enum NotificationType {
+ NOTIFICATION_SIMPLE,
+ NOTIFICATION_PROGRESS
+ }
+
+ static public class NotificationData {
+ private String mText, mSubtitle;
+ private int mPercent;
+ private boolean mOngoing;
+
+ public NotificationData(String text, String subtitle, boolean ongoing) {
+ this(text, subtitle, -1, ongoing);
+ }
+
+ public NotificationData(int percent, boolean ongoing) {
+ this(null, null, percent, ongoing);
+ }
+
+ public NotificationData(String text, int percent, boolean ongoing) {
+ this(text, null, percent, ongoing);
+ }
+
+ public NotificationData(String text, String subtitle, int percent, boolean ongoing) {
+ mText = text;
+ mPercent = percent;
+ mSubtitle = subtitle;
+ mOngoing = ongoing;
+ }
+
+ public String getText() { return mText; }
+ public int getPercent() { return mPercent; }
+ public String getSubtitle() { return mSubtitle; }
+ public boolean getOngoing() { return mOngoing; }
+ }
+
+ static private OCNotificationManager mInstance = null;
+
+ private class NotificationTypePair {
+ public Notification mNotificaiton;
+ public NotificationType mType;
+ public NotificationTypePair(Notification n, NotificationType type) {
+ mNotificaiton = n;
+ mType = type;
+ }
+ }
+
+ private Context mContext;
+ private Map mNotificationMap;
+ private int mNotificationCounter;
+ NotificationManager mNM;
+
+ static OCNotificationManager getInstance(Context context) {
+ if (mInstance == null)
+ mInstance = new OCNotificationManager(context);
+ return mInstance;
+ }
+
+ OCNotificationManager(Context context) {
+ mContext = context;
+ mNotificationMap = new HashMap();
+ mNM = (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ mNotificationCounter = 0;
+ }
+
+ public int postNotification(NotificationType type, NotificationData data) {
+ mNotificationCounter++;
+ Notification notification = null;
+
+ switch (type) {
+ case NOTIFICATION_SIMPLE:
+ notification = new Notification(R.drawable.icon, data.getText(), System.currentTimeMillis());
+ break;
+ case NOTIFICATION_PROGRESS:
+ notification = new Notification();
+ notification.contentView = new RemoteViews(mContext.getPackageName(), R.layout.progressbar_layout);
+ notification.contentView.setTextViewText(R.id.status_text,
+ data.getText());
+ notification.contentView.setImageViewResource(R.id.status_icon,
+ R.id.icon);
+ notification.contentView.setProgressBar(R.id.status_progress,
+ 100,
+ data.getPercent(),
+ false);
+ break;
+ default:
+ return -1;
+ }
+ if (data.getOngoing()) {
+ notification.flags |= notification.flags | Notification.FLAG_ONGOING_EVENT;
+ }
+
+ mNotificationMap.put(mNotificationCounter, new NotificationTypePair(notification, type));
+ return mNotificationCounter;
+ }
+
+ public boolean updateNotification(int notification_id, NotificationData data) {
+ if (!mNotificationMap.containsKey(notification_id)) {
+ return false;
+ }
+ NotificationTypePair pair = mNotificationMap.get(notification_id);
+ switch (pair.mType) {
+ case NOTIFICATION_PROGRESS:
+ pair.mNotificaiton.contentView.setProgressBar(R.id.status_text,
+ 100,
+ data.getPercent(),
+ false);
+ return true;
+ case NOTIFICATION_SIMPLE:
+ pair.mNotificaiton = new Notification(R.drawable.icon,
+ data.getText(), System.currentTimeMillis());
+ mNM.notify(notification_id, pair.mNotificaiton);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public void discardNotification(int notification_id) {
+ mNM.cancel(notification_id);
+ mNotificationMap.remove(notification_id);
+ }
+}
diff --git a/src/com/owncloud/android/files/services/FileDownloader.java b/src/com/owncloud/android/files/services/FileDownloader.java
new file mode 100644
index 00000000..4aafcceb
--- /dev/null
+++ b/src/com/owncloud/android/files/services/FileDownloader.java
@@ -0,0 +1,253 @@
+package com.owncloud.android.files.services;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
+import com.owncloud.android.files.interfaces.OnDatatransferProgressListener;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.util.Log;
+import android.widget.RemoteViews;
+import com.owncloud.android.R;
+import eu.alefzero.webdav.WebdavClient;
+
+public class FileDownloader extends Service implements OnDatatransferProgressListener {
+ public static final String DOWNLOAD_FINISH_MESSAGE = "DOWNLOAD_FINISH";
+ public static final String EXTRA_DOWNLOAD_RESULT = "RESULT";
+ public static final String EXTRA_ACCOUNT = "ACCOUNT";
+ public static final String EXTRA_FILE_PATH = "FILE_PATH";
+ public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
+ public static final String EXTRA_FILE_SIZE = "FILE_SIZE";
+ public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
+
+ private static final String TAG = "FileDownloader";
+
+ private NotificationManager mNotificationMngr;
+ private Looper mServiceLooper;
+ private ServiceHandler mServiceHandler;
+ private Account mAccount;
+ private String mFilePath;
+ private String mRemotePath;
+ private int mLastPercent;
+ private long mTotalDownloadSize;
+ private long mCurrentDownloadSize;
+ private Notification mNotification;
+
+ /**
+ * Static map with the files being download and the path to the temporal file were are download
+ */
+ private static Map mDownloadsInProgress = Collections.synchronizedMap(new HashMap());
+
+ /**
+ * Returns True when the file referred by 'remotePath' in the ownCloud account 'account' is downloading
+ */
+ public static boolean isDownloading(Account account, String remotePath) {
+ return (mDownloadsInProgress.get(buildRemoteName(account.name, remotePath)) != null);
+ }
+
+ /**
+ * Builds a key for mDownloadsInProgress from the accountName and remotePath
+ */
+ private static String buildRemoteName(String accountName, String remotePath) {
+ return accountName + remotePath;
+ }
+
+
+ private final class ServiceHandler extends Handler {
+ public ServiceHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ downloadFile();
+ stopSelf(msg.arg1);
+ }
+ }
+
+ public static final String getSavePath(String accountName) {
+ File sdCard = Environment.getExternalStorageDirectory();
+ return sdCard.getAbsolutePath() + "/owncloud/" + Uri.encode(accountName, "@");
+ // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B
+ }
+
+ public static final String getTemporalPath(String accountName) {
+ File sdCard = Environment.getExternalStorageDirectory();
+ return sdCard.getAbsolutePath() + "/owncloud/tmp/" + Uri.encode(accountName, "@");
+ // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mNotificationMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+ HandlerThread thread = new HandlerThread("FileDownladerThread",
+ Process.THREAD_PRIORITY_BACKGROUND);
+ thread.start();
+ mServiceLooper = thread.getLooper();
+ mServiceHandler = new ServiceHandler(mServiceLooper);
+ }
+
+ @Override
+ public IBinder onBind(Intent arg0) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if ( !intent.hasExtra(EXTRA_ACCOUNT) ||
+ !intent.hasExtra(EXTRA_FILE_PATH) ||
+ !intent.hasExtra(EXTRA_REMOTE_PATH)
+ ) {
+ Log.e(TAG, "Not enough information provided in intent");
+ return START_NOT_STICKY;
+ }
+ mAccount = intent.getParcelableExtra(EXTRA_ACCOUNT);
+ mFilePath = intent.getStringExtra(EXTRA_FILE_PATH);
+ mRemotePath = intent.getStringExtra(EXTRA_REMOTE_PATH);
+ mTotalDownloadSize = intent.getLongExtra(EXTRA_FILE_SIZE, -1);
+ mCurrentDownloadSize = mLastPercent = 0;
+
+ Message msg = mServiceHandler.obtainMessage();
+ msg.arg1 = startId;
+ mServiceHandler.sendMessage(msg);
+
+ return START_NOT_STICKY;
+ }
+
+ /**
+ * Core download method: requests the file to download and stores it.
+ */
+ private void downloadFile() {
+ boolean downloadResult = false;
+
+ /// prepare client object to send the request to the ownCloud server
+ AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
+ WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());
+ String username = mAccount.name.split("@")[0];
+ String password = null;
+ try {
+ password = am.blockingGetAuthToken(mAccount,
+ AccountAuthenticator.AUTH_TOKEN_TYPE, true);
+ } catch (Exception e) {
+ Log.e(TAG, "Access to account credentials failed", e);
+ sendFinalBroadcast(downloadResult, null);
+ return;
+ }
+ wdc.setCredentials(username, password);
+ wdc.allowSelfsignedCertificates();
+ wdc.setDataTransferProgressListener(this);
+
+
+ /// download will be in a temporal file
+ File tmpFile = new File(getTemporalPath(mAccount.name) + mFilePath);
+
+ /// create status notification to show the download progress
+ mNotification = new Notification(R.drawable.icon, getString(R.string.downloader_download_in_progress_ticker), System.currentTimeMillis());
+ mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
+ mNotification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.progressbar_layout);
+ mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, mTotalDownloadSize == -1);
+ mNotification.contentView.setTextViewText(R.id.status_text, String.format(getString(R.string.downloader_download_in_progress_content), 0, tmpFile.getName()));
+ mNotification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon);
+ // TODO put something smart in the contentIntent below
+ mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
+ mNotificationMngr.notify(R.string.downloader_download_in_progress_ticker, mNotification);
+
+
+ /// perform the download
+ tmpFile.getParentFile().mkdirs();
+ mDownloadsInProgress.put(buildRemoteName(mAccount.name, mRemotePath), tmpFile.getAbsolutePath());
+ File newFile = null;
+ try {
+ if (wdc.downloadFile(mRemotePath, tmpFile)) {
+ newFile = new File(getSavePath(mAccount.name) + mFilePath);
+ newFile.getParentFile().mkdirs();
+ boolean moved = tmpFile.renameTo(newFile);
+
+ if (moved) {
+ ContentValues cv = new ContentValues();
+ cv.put(ProviderTableMeta.FILE_STORAGE_PATH, newFile.getAbsolutePath());
+ getContentResolver().update(
+ ProviderTableMeta.CONTENT_URI,
+ cv,
+ ProviderTableMeta.FILE_NAME + "=? AND "
+ + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+ new String[] {
+ mFilePath.substring(mFilePath.lastIndexOf('/') + 1),
+ mAccount.name });
+ downloadResult = true;
+ }
+ }
+ } finally {
+ mDownloadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePath));
+ }
+
+
+ /// notify result
+ mNotificationMngr.cancel(R.string.downloader_download_in_progress_ticker);
+ int tickerId = (downloadResult) ? R.string.downloader_download_succeeded_ticker : R.string.downloader_download_failed_ticker;
+ int contentId = (downloadResult) ? R.string.downloader_download_succeeded_content : R.string.downloader_download_failed_content;
+ Notification finalNotification = new Notification(R.drawable.icon, getString(tickerId), System.currentTimeMillis());
+ finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;
+ // TODO put something smart in the contentIntent below
+ finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
+ finalNotification.setLatestEventInfo(getApplicationContext(), getString(tickerId), String.format(getString(contentId), tmpFile.getName()), finalNotification.contentIntent);
+ mNotificationMngr.notify(tickerId, finalNotification);
+
+ sendFinalBroadcast(downloadResult, (downloadResult)?newFile.getAbsolutePath():null);
+ }
+
+ /**
+ * Callback method to update the progress bar in the status notification.
+ */
+ @Override
+ public void transferProgress(long progressRate) {
+ mCurrentDownloadSize += progressRate;
+ int percent = (int)(100.0*((double)mCurrentDownloadSize)/((double)mTotalDownloadSize));
+ if (percent != mLastPercent) {
+ mNotification.contentView.setProgressBar(R.id.status_progress, 100, (int)(100*mCurrentDownloadSize/mTotalDownloadSize), mTotalDownloadSize == -1);
+ mNotification.contentView.setTextViewText(R.id.status_text, String.format(getString(R.string.downloader_download_in_progress_content), percent, new File(mFilePath).getName()));
+ mNotificationMngr.notify(R.string.downloader_download_in_progress_ticker, mNotification);
+ }
+
+ mLastPercent = percent;
+ }
+
+
+ /**
+ * Sends a broadcast in order to the interested activities can update their view
+ *
+ * @param downloadResult 'True' if the download was successful
+ * @param newFilePath Absolute path to the download file
+ */
+ private void sendFinalBroadcast(boolean downloadResult, String newFilePath) {
+ Intent end = new Intent(DOWNLOAD_FINISH_MESSAGE);
+ end.putExtra(EXTRA_DOWNLOAD_RESULT, downloadResult);
+ end.putExtra(ACCOUNT_NAME, mAccount.name);
+ end.putExtra(EXTRA_REMOTE_PATH, mRemotePath);
+ if (downloadResult) {
+ end.putExtra(EXTRA_FILE_PATH, newFilePath);
+ }
+ sendBroadcast(end);
+ }
+
+}
diff --git a/src/com/owncloud/android/files/services/FileOperation.java b/src/com/owncloud/android/files/services/FileOperation.java
new file mode 100644
index 00000000..bdb76cd3
--- /dev/null
+++ b/src/com/owncloud/android/files/services/FileOperation.java
@@ -0,0 +1,54 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.files.services;
+
+import java.io.File;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.datamodel.OCFile;
+
+import android.accounts.Account;
+import android.content.Context;
+import eu.alefzero.webdav.WebdavClient;
+
+public class FileOperation {
+
+ Context mContext;
+
+ public FileOperation(Context contex){
+ this.mContext = contex;
+ }
+
+ /**
+ * Deletes a file from ownCloud - locally and remote.
+ * @param file The file to delete
+ * @return True on success, otherwise false
+ */
+ public boolean delete(OCFile file){
+
+ Account account = AccountUtils.getCurrentOwnCloudAccount(mContext);
+ WebdavClient client = new WebdavClient(account, mContext);
+ if(client.deleteFile(file.getRemotePath())){
+ File localFile = new File(file.getStoragePath());
+ return localFile.delete();
+ }
+
+ return false;
+ }
+
+}
diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java
new file mode 100644
index 00000000..34d795b1
--- /dev/null
+++ b/src/com/owncloud/android/files/services/FileUploader.java
@@ -0,0 +1,327 @@
+package com.owncloud.android.files.services;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.interfaces.OnDatatransferProgressListener;
+
+import android.accounts.Account;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.util.Log;
+import android.webkit.MimeTypeMap;
+import android.widget.RemoteViews;
+import com.owncloud.android.R;
+import eu.alefzero.webdav.WebdavClient;
+
+public class FileUploader extends Service implements OnDatatransferProgressListener {
+
+ public static final String UPLOAD_FINISH_MESSAGE = "UPLOAD_FINISH";
+ public static final String EXTRA_PARENT_DIR_ID = "PARENT_DIR_ID";
+ public static final String EXTRA_UPLOAD_RESULT = "RESULT";
+ public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
+ public static final String EXTRA_FILE_PATH = "FILE_PATH";
+
+ public static final String KEY_LOCAL_FILE = "LOCAL_FILE";
+ public static final String KEY_REMOTE_FILE = "REMOTE_FILE";
+ public static final String KEY_ACCOUNT = "ACCOUNT";
+ public static final String KEY_UPLOAD_TYPE = "UPLOAD_TYPE";
+ public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
+
+ public static final int UPLOAD_SINGLE_FILE = 0;
+ public static final int UPLOAD_MULTIPLE_FILES = 1;
+
+ private static final String TAG = "FileUploader";
+
+ private NotificationManager mNotificationManager;
+ private Looper mServiceLooper;
+ private ServiceHandler mServiceHandler;
+ private Account mAccount;
+ private String[] mLocalPaths, mRemotePaths;
+ private int mUploadType;
+ private Notification mNotification;
+ private long mTotalDataToSend, mSendData;
+ private int mCurrentIndexUpload, mPreviousPercent;
+ private int mSuccessCounter;
+
+ /**
+ * Static map with the files being download and the path to the temporal file were are download
+ */
+ private static Map mUploadsInProgress = Collections.synchronizedMap(new HashMap());
+
+ /**
+ * Returns True when the file referred by 'remotePath' in the ownCloud account 'account' is downloading
+ */
+ public static boolean isUploading(Account account, String remotePath) {
+ return (mUploadsInProgress.get(buildRemoteName(account.name, remotePath)) != null);
+ }
+
+ /**
+ * Builds a key for mUplaodsInProgress from the accountName and remotePath
+ */
+ private static String buildRemoteName(String accountName, String remotePath) {
+ return accountName + remotePath;
+ }
+
+
+
+
+ @Override
+ public IBinder onBind(Intent arg0) {
+ return null;
+ }
+
+ private final class ServiceHandler extends Handler {
+ public ServiceHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ uploadFile();
+ stopSelf(msg.arg1);
+ }
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+ HandlerThread thread = new HandlerThread("FileUploaderThread",
+ Process.THREAD_PRIORITY_BACKGROUND);
+ thread.start();
+ mServiceLooper = thread.getLooper();
+ mServiceHandler = new ServiceHandler(mServiceLooper);
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (!intent.hasExtra(KEY_ACCOUNT) && !intent.hasExtra(KEY_UPLOAD_TYPE)) {
+ Log.e(TAG, "Not enough information provided in intent");
+ return Service.START_NOT_STICKY;
+ }
+ mAccount = intent.getParcelableExtra(KEY_ACCOUNT);
+ mUploadType = intent.getIntExtra(KEY_UPLOAD_TYPE, -1);
+ if (mUploadType == -1) {
+ Log.e(TAG, "Incorrect upload type provided");
+ return Service.START_NOT_STICKY;
+ }
+ if (mUploadType == UPLOAD_SINGLE_FILE) {
+ mLocalPaths = new String[] { intent.getStringExtra(KEY_LOCAL_FILE) };
+ mRemotePaths = new String[] { intent
+ .getStringExtra(KEY_REMOTE_FILE) };
+ } else { // mUploadType == UPLOAD_MULTIPLE_FILES
+ mLocalPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
+ mRemotePaths = intent.getStringArrayExtra(KEY_REMOTE_FILE);
+ }
+
+ if (mLocalPaths.length != mRemotePaths.length) {
+ Log.e(TAG, "Different number of remote paths and local paths!");
+ return Service.START_NOT_STICKY;
+ }
+
+ Message msg = mServiceHandler.obtainMessage();
+ msg.arg1 = startId;
+ mServiceHandler.sendMessage(msg);
+
+ return Service.START_NOT_STICKY;
+ }
+
+
+ /**
+ * Core upload method: sends the file(s) to upload
+ */
+ public void uploadFile() {
+ FileDataStorageManager storageManager = new FileDataStorageManager(mAccount, getContentResolver());
+
+ mTotalDataToSend = mSendData = mPreviousPercent = 0;
+
+ /// prepare client object to send the request to the ownCloud server
+ WebdavClient wc = new WebdavClient(mAccount, getApplicationContext());
+ wc.allowSelfsignedCertificates();
+ wc.setDataTransferProgressListener(this);
+
+ /// create status notification to show the upload progress
+ mNotification = new Notification(R.drawable.icon, getString(R.string.uploader_upload_in_progress_ticker), System.currentTimeMillis());
+ mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
+ RemoteViews oldContentView = mNotification.contentView;
+ mNotification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.progressbar_layout);
+ mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, false);
+ mNotification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon);
+ // dvelasco ; contentIntent MUST be assigned to avoid app crashes in versions previous to Android 4.x ;
+ // BUT an empty Intent is not a very elegant solution; something smart should happen when a user 'clicks' on an upload in the notification bar
+ mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
+ mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification);
+
+
+ /// perform the upload
+ File [] localFiles = new File[mLocalPaths.length];
+ for (int i = 0; i < mLocalPaths.length; ++i) {
+ localFiles[i] = new File(mLocalPaths[i]);
+ mTotalDataToSend += localFiles[i].length();
+ }
+ Log.d(TAG, "Will upload " + mTotalDataToSend + " bytes, with " + mLocalPaths.length + " files");
+ mSuccessCounter = 0;
+ for (int i = 0; i < mLocalPaths.length; ++i) {
+ String mimeType = null;
+ try {
+ mimeType = MimeTypeMap.getSingleton()
+ .getMimeTypeFromExtension(
+ mLocalPaths[i].substring(mLocalPaths[i]
+ .lastIndexOf('.') + 1));
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, "Trying to find out MIME type of a file without extension: " + mLocalPaths[i]);
+ }
+ if (mimeType == null)
+ mimeType = "application/octet-stream";
+ mCurrentIndexUpload = i;
+ long parentDirId = -1;
+ boolean uploadResult = false;
+ String availablePath = getAvailableRemotePath(wc, mRemotePaths[i]);
+ try {
+ File f = new File(mRemotePaths[i]);
+ parentDirId = storageManager.getFileByPath(f.getParent().endsWith("/")?f.getParent():f.getParent()+"/").getFileId();
+ if(availablePath != null) {
+ mRemotePaths[i] = availablePath;
+ mUploadsInProgress.put(buildRemoteName(mAccount.name, mRemotePaths[i]), mLocalPaths[i]);
+ if (wc.putFile(mLocalPaths[i], mRemotePaths[i], mimeType)) {
+ OCFile new_file = new OCFile(mRemotePaths[i]);
+ new_file.setMimetype(mimeType);
+ new_file.setFileLength(localFiles[i].length());
+ new_file.setModificationTimestamp(System.currentTimeMillis());
+ new_file.setLastSyncDate(0);
+ new_file.setStoragePath(mLocalPaths[i]);
+ new_file.setParentId(parentDirId);
+ storageManager.saveFile(new_file);
+ mSuccessCounter++;
+ uploadResult = true;
+ }
+ }
+ } finally {
+ mUploadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePaths[i]));
+
+ /// notify upload (or fail) of EACH file to activities interested
+ Intent end = new Intent(UPLOAD_FINISH_MESSAGE);
+ end.putExtra(EXTRA_PARENT_DIR_ID, parentDirId);
+ end.putExtra(EXTRA_UPLOAD_RESULT, uploadResult);
+ end.putExtra(EXTRA_REMOTE_PATH, mRemotePaths[i]);
+ end.putExtra(EXTRA_FILE_PATH, mLocalPaths[i]);
+ end.putExtra(ACCOUNT_NAME, mAccount.name);
+ sendBroadcast(end);
+ }
+
+ }
+
+ /// notify final result
+ if (mSuccessCounter == mLocalPaths.length) { // success
+ //Notification finalNotification = new Notification(R.drawable.icon, getString(R.string.uploader_upload_succeeded_ticker), System.currentTimeMillis());
+ mNotification.flags ^= Notification.FLAG_ONGOING_EVENT; // remove the ongoing flag
+ mNotification.flags |= Notification.FLAG_AUTO_CANCEL;
+ mNotification.contentView = oldContentView;
+ // TODO put something smart in the contentIntent below
+ mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
+ if (mLocalPaths.length == 1) {
+ mNotification.setLatestEventInfo( getApplicationContext(),
+ getString(R.string.uploader_upload_succeeded_ticker),
+ String.format(getString(R.string.uploader_upload_succeeded_content_single), localFiles[0].getName()),
+ mNotification.contentIntent);
+ } else {
+ mNotification.setLatestEventInfo( getApplicationContext(),
+ getString(R.string.uploader_upload_succeeded_ticker),
+ String.format(getString(R.string.uploader_upload_succeeded_content_multiple), mSuccessCounter),
+ mNotification.contentIntent);
+ }
+ mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification); // NOT AN ERROR; uploader_upload_in_progress_ticker is the target, not a new notification
+
+ } else {
+ mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);
+ Notification finalNotification = new Notification(R.drawable.icon, getString(R.string.uploader_upload_failed_ticker), System.currentTimeMillis());
+ finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;
+ // TODO put something smart in the contentIntent below
+ finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
+ if (mLocalPaths.length == 1) {
+ finalNotification.setLatestEventInfo( getApplicationContext(),
+ getString(R.string.uploader_upload_failed_ticker),
+ String.format(getString(R.string.uploader_upload_failed_content_single), localFiles[0].getName()),
+ finalNotification.contentIntent);
+ } else {
+ finalNotification.setLatestEventInfo( getApplicationContext(),
+ getString(R.string.uploader_upload_failed_ticker),
+ String.format(getString(R.string.uploader_upload_failed_content_multiple), mSuccessCounter, mLocalPaths.length),
+ finalNotification.contentIntent);
+ }
+ mNotificationManager.notify(R.string.uploader_upload_failed_ticker, finalNotification);
+ }
+
+ }
+
+ /**
+ * Checks if remotePath does not exist in the server and returns it, or adds a suffix to it in order to avoid the server
+ * file is overwritten.
+ *
+ * @param string
+ * @return
+ */
+ private String getAvailableRemotePath(WebdavClient wc, String remotePath) {
+ Boolean check = wc.existsFile(remotePath);
+ if (check == null) { // null means fail
+ return null;
+ } else if (!check) {
+ return remotePath;
+ }
+
+ int pos = remotePath.lastIndexOf(".");
+ String suffix = "";
+ String extension = "";
+ if (pos >= 0) {
+ extension = remotePath.substring(pos+1);
+ remotePath = remotePath.substring(0, pos);
+ }
+ int count = 2;
+ while (check != null && check) {
+ suffix = " (" + count + ")";
+ if (pos >= 0)
+ check = wc.existsFile(remotePath + suffix + "." + extension);
+ else
+ check = wc.existsFile(remotePath + suffix);
+ count++;
+ }
+ if (check == null) {
+ return null;
+ } else if (pos >=0) {
+ return remotePath + suffix + "." + extension;
+ } else {
+ return remotePath + suffix;
+ }
+ }
+
+
+ /**
+ * Callback method to update the progress bar in the status notification.
+ */
+ @Override
+ public void transferProgress(long progressRate) {
+ mSendData += progressRate;
+ int percent = (int)(100*((double)mSendData)/((double)mTotalDataToSend));
+ if (percent != mPreviousPercent) {
+ String text = String.format(getString(R.string.uploader_upload_in_progress_content), percent, new File(mLocalPaths[mCurrentIndexUpload]).getName());
+ mNotification.contentView.setProgressBar(R.id.status_progress, 100, percent, false);
+ mNotification.contentView.setTextViewText(R.id.status_text, text);
+ mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification);
+ }
+ mPreviousPercent = percent;
+ }
+}
diff --git a/src/com/owncloud/android/files/services/InstantUploadService.java b/src/com/owncloud/android/files/services/InstantUploadService.java
new file mode 100644
index 00000000..0324f592
--- /dev/null
+++ b/src/com/owncloud/android/files/services/InstantUploadService.java
@@ -0,0 +1,162 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.files.services;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.httpclient.HttpException;
+import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.utils.OwnCloudVersion;
+
+import eu.alefzero.webdav.WebdavClient;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.Service;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.IBinder;
+import android.util.Log;
+
+public class InstantUploadService extends Service {
+
+ public static String KEY_FILE_PATH = "KEY_FILEPATH";
+ public static String KEY_FILE_SIZE = "KEY_FILESIZE";
+ public static String KEY_MIME_TYPE = "KEY_MIMETYPE";
+ public static String KEY_DISPLAY_NAME = "KEY_FILENAME";
+ public static String KEY_ACCOUNT = "KEY_ACCOUNT";
+
+ private static String TAG = "InstantUploadService";
+ private static String INSTANT_UPLOAD_DIR = "/InstantUpload";
+ private UploaderRunnable mUploaderRunnable;
+
+ @Override
+ public IBinder onBind(Intent arg0) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (intent == null ||
+ !intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_DISPLAY_NAME) ||
+ !intent.hasExtra(KEY_FILE_PATH) || !intent.hasExtra(KEY_FILE_SIZE) ||
+ !intent.hasExtra(KEY_MIME_TYPE)) {
+ Log.w(TAG, "Not all required information was provided, abording");
+ return Service.START_NOT_STICKY;
+ }
+
+ if (mUploaderRunnable == null) {
+ mUploaderRunnable = new UploaderRunnable();
+ }
+
+ String filename = intent.getStringExtra(KEY_DISPLAY_NAME);
+ String filepath = intent.getStringExtra(KEY_FILE_PATH);
+ String mimetype = intent.getStringExtra(KEY_MIME_TYPE);
+ Account account = intent.getParcelableExtra(KEY_ACCOUNT);
+ long filesize = intent.getLongExtra(KEY_FILE_SIZE, -1);
+
+ mUploaderRunnable.addElementToQueue(filename, filepath, mimetype, filesize, account);
+
+ // starting new thread for new download doesnt seems like a good idea
+ // maybe some thread pool or single background thread would be better
+ Log.d(TAG, "Starting instant upload thread");
+ new Thread(mUploaderRunnable).start();
+
+ return Service.START_STICKY;
+ }
+
+ private class UploaderRunnable implements Runnable {
+
+ Object mLock;
+ List> mHashMapList;
+
+ public UploaderRunnable() {
+ mHashMapList = new LinkedList>();
+ mLock = new Object();
+ }
+
+ public void addElementToQueue(String filename,
+ String filepath,
+ String mimetype,
+ long length,
+ Account account) {
+ HashMap new_map = new HashMap();
+ new_map.put(KEY_ACCOUNT, account);
+ new_map.put(KEY_DISPLAY_NAME, filename);
+ new_map.put(KEY_FILE_PATH, filepath);
+ new_map.put(KEY_MIME_TYPE, mimetype);
+ new_map.put(KEY_FILE_SIZE, length);
+
+ synchronized (mLock) {
+ mHashMapList.add(new_map);
+ }
+ }
+
+ private HashMap getFirstObject() {
+ synchronized (mLock) {
+ if (mHashMapList.size() == 0)
+ return null;
+ HashMap ret = mHashMapList.get(0);
+ mHashMapList.remove(0);
+ return ret;
+ }
+ }
+
+ public void run() {
+ HashMap working_map;
+ AccountManager am = AccountManager.get(getApplicationContext());
+
+ while ((working_map = getFirstObject()) != null) {
+ Account account = (Account) working_map.get(KEY_ACCOUNT);
+ String username = account.name.substring(0, account.name.lastIndexOf('@'));
+ String password = am.getPassword(account);
+ String filename = (String) working_map.get(KEY_DISPLAY_NAME);
+ String filepath = (String) working_map.get(KEY_FILE_PATH);
+ String mimetype = (String) working_map.get(KEY_MIME_TYPE);
+
+ String oc_base_url = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL);
+ String oc_version = am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION);
+ OwnCloudVersion ocv = new OwnCloudVersion(oc_version);
+ String webdav_path = AccountUtils.getWebdavPath(ocv);
+ WebdavClient wdc = new WebdavClient(account, getApplicationContext());
+ wdc.allowSelfsignedCertificates();
+ wdc.setCredentials(username, password);
+
+ MkColMethod mkcol = new MkColMethod(oc_base_url+webdav_path+INSTANT_UPLOAD_DIR);
+ int status = 0;
+ try {
+ status = wdc.executeMethod(mkcol);
+ Log.e(TAG, "mkcol returned " + status);
+ wdc.putFile(filepath, INSTANT_UPLOAD_DIR + "/" + filename, mimetype);
+ } catch (HttpException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/com/owncloud/android/files/services/OnUploadCompletedListener.java b/src/com/owncloud/android/files/services/OnUploadCompletedListener.java
new file mode 100644
index 00000000..80917ddf
--- /dev/null
+++ b/src/com/owncloud/android/files/services/OnUploadCompletedListener.java
@@ -0,0 +1,8 @@
+package com.owncloud.android.files.services;
+
+public interface OnUploadCompletedListener extends Runnable {
+
+ public boolean getUploadResult();
+
+ public void setUploadResult(boolean result);
+}
diff --git a/src/com/owncloud/android/location/LocationServiceLauncherReciever.java b/src/com/owncloud/android/location/LocationServiceLauncherReciever.java
new file mode 100644
index 00000000..19efd7ea
--- /dev/null
+++ b/src/com/owncloud/android/location/LocationServiceLauncherReciever.java
@@ -0,0 +1,87 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.location;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningServiceInfo;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+public class LocationServiceLauncherReciever extends BroadcastReceiver {
+
+ private final String TAG = getClass().getSimpleName();
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Intent deviceTrackingIntent = new Intent();
+ deviceTrackingIntent
+ .setAction("eu.alefzero.owncloud.location.LocationUpdateService");
+ SharedPreferences preferences = PreferenceManager
+ .getDefaultSharedPreferences(context);
+ boolean trackDevice = preferences.getBoolean("enable_devicetracking",
+ true);
+
+ // Used in Preferences activity so that tracking is disabled or
+ // reenabled
+ if (intent.hasExtra("TRACKING_SETTING")) {
+ trackDevice = intent.getBooleanExtra("TRACKING_SETTING", true);
+ }
+
+ startOrStopDeviceTracking(context, trackDevice);
+ }
+
+ /**
+ * Used internally. Starts or stops the device tracking service
+ *
+ * @param trackDevice true to start the service, false to stop it
+ */
+ private void startOrStopDeviceTracking(Context context, boolean trackDevice) {
+ Intent deviceTrackingIntent = new Intent();
+ deviceTrackingIntent
+ .setAction("eu.alefzero.owncloud.location.LocationUpdateService");
+ if (!isDeviceTrackingServiceRunning(context) && trackDevice) {
+ Log.d(TAG, "Starting device tracker service");
+ context.startService(deviceTrackingIntent);
+ } else if (isDeviceTrackingServiceRunning(context) && !trackDevice) {
+ Log.d(TAG, "Stopping device tracker service");
+ context.stopService(deviceTrackingIntent);
+ }
+ }
+
+ /**
+ * Checks to see whether or not the LocationUpdateService is running
+ *
+ * @return true, if it is. Otherwise false
+ */
+ private boolean isDeviceTrackingServiceRunning(Context context) {
+ ActivityManager manager = (ActivityManager) context
+ .getSystemService(Context.ACTIVITY_SERVICE);
+ for (RunningServiceInfo service : manager
+ .getRunningServices(Integer.MAX_VALUE)) {
+ if (getClass().getName().equals(service.service.getClassName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/src/com/owncloud/android/location/LocationUpdateService.java b/src/com/owncloud/android/location/LocationUpdateService.java
new file mode 100644
index 00000000..6e3dfb83
--- /dev/null
+++ b/src/com/owncloud/android/location/LocationUpdateService.java
@@ -0,0 +1,110 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.location;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.location.Criteria;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.owncloud.android.R;
+
+public class LocationUpdateService extends IntentService implements
+ LocationListener {
+
+ public static final String TAG = "LocationUpdateService";
+
+ private LocationManager mLocationManager;
+ private LocationProvider mLocationProvider;
+ private SharedPreferences mPreferences;
+
+ public LocationUpdateService() {
+ super(TAG);
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
+ // Determine, how we can track the device
+ Criteria criteria = new Criteria();
+ criteria.setAccuracy(Criteria.ACCURACY_FINE);
+ criteria.setPowerRequirement(Criteria.POWER_LOW);
+ mLocationProvider = mLocationManager.getProvider(mLocationManager
+ .getBestProvider(criteria, true));
+
+ // Notify user if there is no way to track the device
+ if (mLocationProvider == null) {
+ Toast.makeText(this,
+ R.string.location_no_provider,
+ Toast.LENGTH_LONG);
+ stopSelf();
+ return;
+ }
+
+ // Get preferences for device tracking
+ mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+ boolean trackDevice = mPreferences.getBoolean("enable_devicetracking",
+ true);
+ int updateIntervall = Integer.parseInt(mPreferences.getString(
+ "devicetracking_update_intervall", "30")) * 60 * 1000;
+ int distanceBetweenLocationChecks = 50;
+
+ // If we do shall track the device -> Stop
+ if (!trackDevice) {
+ Log.d(TAG, "Devicetracking is disabled");
+ stopSelf();
+ return;
+ }
+
+ mLocationManager.requestLocationUpdates(mLocationProvider.getName(),
+ updateIntervall, distanceBetweenLocationChecks, this);
+ }
+
+ @Override
+ public void onLocationChanged(Location location) {
+ Log.d(TAG, "Location changed: " + location);
+
+ }
+
+ @Override
+ public void onProviderDisabled(String arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onProviderEnabled(String arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/src/com/owncloud/android/providers/FileContentProvider.java b/src/com/owncloud/android/providers/FileContentProvider.java
new file mode 100644
index 00000000..6605d89b
--- /dev/null
+++ b/src/com/owncloud/android/providers/FileContentProvider.java
@@ -0,0 +1,238 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.providers;
+
+import java.util.HashMap;
+
+import com.owncloud.android.db.ProviderMeta;
+import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
+
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * The ContentProvider for the ownCloud App.
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class FileContentProvider extends ContentProvider {
+
+ private DataBaseHelper mDbHelper;
+
+ private static HashMap mProjectionMap;
+ static {
+ mProjectionMap = new HashMap();
+ mProjectionMap.put(ProviderTableMeta._ID, ProviderTableMeta._ID);
+ mProjectionMap.put(ProviderTableMeta.FILE_PARENT,
+ ProviderTableMeta.FILE_PARENT);
+ mProjectionMap.put(ProviderTableMeta.FILE_PATH,
+ ProviderTableMeta.FILE_PATH);
+ mProjectionMap.put(ProviderTableMeta.FILE_NAME,
+ ProviderTableMeta.FILE_NAME);
+ mProjectionMap.put(ProviderTableMeta.FILE_CREATION,
+ ProviderTableMeta.FILE_CREATION);
+ mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED,
+ ProviderTableMeta.FILE_MODIFIED);
+ mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_LENGTH,
+ ProviderTableMeta.FILE_CONTENT_LENGTH);
+ mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_TYPE,
+ ProviderTableMeta.FILE_CONTENT_TYPE);
+ mProjectionMap.put(ProviderTableMeta.FILE_STORAGE_PATH,
+ ProviderTableMeta.FILE_STORAGE_PATH);
+ mProjectionMap.put(ProviderTableMeta.FILE_LAST_SYNC_DATE,
+ ProviderTableMeta.FILE_LAST_SYNC_DATE);
+ mProjectionMap.put(ProviderTableMeta.FILE_KEEP_IN_SYNC,
+ ProviderTableMeta.FILE_KEEP_IN_SYNC);
+ }
+
+ private static final int SINGLE_FILE = 1;
+ private static final int DIRECTORY = 2;
+ private static final int ROOT_DIRECTORY = 3;
+ private static final UriMatcher mUriMatcher;
+ static {
+ mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "/", ROOT_DIRECTORY);
+ mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/", SINGLE_FILE);
+ mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/#", SINGLE_FILE);
+ mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/#", DIRECTORY);
+ }
+
+ @Override
+ public int delete(Uri uri, String where, String[] whereArgs) {
+ SQLiteDatabase db = mDbHelper.getWritableDatabase();
+ int count = 0;
+ switch (mUriMatcher.match(uri)) {
+ case SINGLE_FILE:
+ count = db.delete(ProviderTableMeta.DB_NAME,
+ ProviderTableMeta._ID
+ + "="
+ + uri.getPathSegments().get(1)
+ + (!TextUtils.isEmpty(where) ? " AND (" + where
+ + ")" : ""), whereArgs);
+ break;
+ case ROOT_DIRECTORY:
+ count = db.delete(ProviderTableMeta.DB_NAME, where, whereArgs);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown uri: " + uri.toString());
+ }
+ getContext().getContentResolver().notifyChange(uri, null);
+ return count;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ switch (mUriMatcher.match(uri)) {
+ case ROOT_DIRECTORY:
+ return ProviderTableMeta.CONTENT_TYPE;
+ case SINGLE_FILE:
+ return ProviderTableMeta.CONTENT_TYPE_ITEM;
+ default:
+ throw new IllegalArgumentException("Unknown Uri id."
+ + uri.toString());
+ }
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ if (mUriMatcher.match(uri) != SINGLE_FILE &&
+ mUriMatcher.match(uri) != ROOT_DIRECTORY) {
+
+ throw new IllegalArgumentException("Unknown uri id: " + uri);
+ }
+
+ SQLiteDatabase db = mDbHelper.getWritableDatabase();
+ long rowId = db.insert(ProviderTableMeta.DB_NAME, null, values);
+ if (rowId > 0) {
+ Uri insertedFileUri = ContentUris.withAppendedId(
+ ProviderTableMeta.CONTENT_URI_FILE, rowId);
+ getContext().getContentResolver().notifyChange(insertedFileUri,
+ null);
+ return insertedFileUri;
+ }
+ throw new SQLException("ERROR " + uri);
+ }
+
+ @Override
+ public boolean onCreate() {
+ mDbHelper = new DataBaseHelper(getContext());
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();
+
+ sqlQuery.setTables(ProviderTableMeta.DB_NAME);
+ sqlQuery.setProjectionMap(mProjectionMap);
+
+ switch (mUriMatcher.match(uri)) {
+ case ROOT_DIRECTORY:
+ break;
+ case DIRECTORY:
+ sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="
+ + uri.getPathSegments().get(1));
+ break;
+ case SINGLE_FILE:
+ if (uri.getPathSegments().size() > 1) {
+ sqlQuery.appendWhere(ProviderTableMeta._ID + "="
+ + uri.getPathSegments().get(1));
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown uri id: " + uri);
+ }
+
+ String order;
+ if (TextUtils.isEmpty(sortOrder)) {
+ order = ProviderTableMeta.DEFAULT_SORT_ORDER;
+ } else {
+ order = sortOrder;
+ }
+
+ SQLiteDatabase db = mDbHelper.getReadableDatabase();
+ Cursor c = sqlQuery.query(db, projection, selection, selectionArgs,
+ null, null, order);
+
+ c.setNotificationUri(getContext().getContentResolver(), uri);
+
+ return c;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection,
+ String[] selectionArgs) {
+ return mDbHelper.getWritableDatabase().update(
+ ProviderTableMeta.DB_NAME, values, selection, selectionArgs);
+ }
+
+ class DataBaseHelper extends SQLiteOpenHelper {
+
+ public DataBaseHelper(Context context) {
+ super(context, ProviderMeta.DB_NAME, null, ProviderMeta.DB_VERSION);
+
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // files table
+ Log.i("SQL", "Entering in onCreate");
+ db.execSQL("CREATE TABLE " + ProviderTableMeta.DB_NAME + "("
+ + ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "
+ + ProviderTableMeta.FILE_NAME + " TEXT, "
+ + ProviderTableMeta.FILE_PATH + " TEXT, "
+ + ProviderTableMeta.FILE_PARENT + " INTEGER, "
+ + ProviderTableMeta.FILE_CREATION + " INTEGER, "
+ + ProviderTableMeta.FILE_MODIFIED + " INTEGER, "
+ + ProviderTableMeta.FILE_CONTENT_TYPE + " TEXT, "
+ + ProviderTableMeta.FILE_CONTENT_LENGTH + " INTEGER, "
+ + ProviderTableMeta.FILE_STORAGE_PATH + " TEXT, "
+ + ProviderTableMeta.FILE_ACCOUNT_OWNER + " TEXT, "
+ + ProviderTableMeta.FILE_LAST_SYNC_DATE + " INTEGER, "
+ + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER );");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ Log.i("SQL", "Entering in onUpgrade");
+ if (oldVersion == 1 && newVersion >= 2) {
+ Log.i("SQL", "Entering in the ADD in onUpgrade");
+ db.execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +
+ " ADD COLUMN " + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER " +
+ " DEFAULT 0");
+ } else Log.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion + ", newVersion == " + newVersion);
+ }
+
+ }
+
+}
diff --git a/src/com/owncloud/android/syncadapter/AbstractOwnCloudSyncAdapter.java b/src/com/owncloud/android/syncadapter/AbstractOwnCloudSyncAdapter.java
new file mode 100644
index 00000000..e8b1fcb2
--- /dev/null
+++ b/src/com/owncloud/android/syncadapter/AbstractOwnCloudSyncAdapter.java
@@ -0,0 +1,164 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.syncadapter;
+
+import java.io.IOException;
+import java.net.UnknownHostException;
+import java.util.Date;
+
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.conn.ConnectionKeepAliveStrategy;
+import org.apache.http.protocol.HttpContext;
+
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.datamodel.DataStorageManager;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.AbstractThreadedSyncAdapter;
+import android.content.ContentProviderClient;
+import android.content.Context;
+import android.net.Uri;
+import eu.alefzero.webdav.WebdavClient;
+
+/**
+ * Base SyncAdapter for OwnCloud Designed to be subclassed for the concrete
+ * SyncAdapter, like ConcatsSync, CalendarSync, FileSync etc..
+ *
+ * @author sassman
+ *
+ */
+public abstract class AbstractOwnCloudSyncAdapter extends
+ AbstractThreadedSyncAdapter {
+
+ private AccountManager accountManager;
+ private Account account;
+ private ContentProviderClient contentProvider;
+ private Date lastUpdated;
+ private DataStorageManager mStoreManager;
+
+ private WebdavClient mClient = null;
+
+ public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize) {
+ super(context, autoInitialize);
+ this.setAccountManager(AccountManager.get(context));
+ }
+
+ public AccountManager getAccountManager() {
+ return accountManager;
+ }
+
+ public void setAccountManager(AccountManager accountManager) {
+ this.accountManager = accountManager;
+ }
+
+ public Account getAccount() {
+ return account;
+ }
+
+ public void setAccount(Account account) {
+ this.account = account;
+ }
+
+ public ContentProviderClient getContentProvider() {
+ return contentProvider;
+ }
+
+ public void setContentProvider(ContentProviderClient contentProvider) {
+ this.contentProvider = contentProvider;
+ }
+
+ public Date getLastUpdated() {
+ return lastUpdated;
+ }
+
+ public void setLastUpdated(Date lastUpdated) {
+ this.lastUpdated = lastUpdated;
+ }
+
+ public void setStorageManager(DataStorageManager storage_manager) {
+ mStoreManager = storage_manager;
+ }
+
+ public DataStorageManager getStorageManager() {
+ return mStoreManager;
+ }
+
+ protected ConnectionKeepAliveStrategy getKeepAliveStrategy() {
+ return new ConnectionKeepAliveStrategy() {
+ public long getKeepAliveDuration(HttpResponse response,
+ HttpContext context) {
+ // Change keep alive straategy basing on response: ie
+ // forbidden/not found/etc
+ // should have keep alive 0
+ // default return: 5s
+ int statusCode = response.getStatusLine().getStatusCode();
+
+ // HTTP 400, 500 Errors as well as HTTP 118 - Connection timed
+ // out
+ if ((statusCode >= 400 && statusCode <= 418)
+ || (statusCode >= 421 && statusCode <= 426)
+ || (statusCode >= 500 && statusCode <= 510)
+ || statusCode == 118) {
+ return 0;
+ }
+
+ return 5 * 1000;
+ }
+ };
+ }
+
+ protected HttpResponse fireRawRequest(HttpRequest query)
+ throws ClientProtocolException, OperationCanceledException,
+ AuthenticatorException, IOException {
+ /*
+ * BasicHttpContext httpContext = new BasicHttpContext(); BasicScheme
+ * basicAuth = new BasicScheme();
+ * httpContext.setAttribute("preemptive-auth", basicAuth);
+ *
+ * HttpResponse response = getClient().execute(mHost, query,
+ * httpContext);
+ */
+ return null;
+ }
+
+ protected Uri getUri() {
+ return Uri.parse(this.getAccountManager().getUserData(getAccount(),
+ AccountAuthenticator.KEY_OC_URL));
+ }
+
+ protected WebdavClient getClient() throws OperationCanceledException,
+ AuthenticatorException, IOException {
+ if (mClient == null) {
+ if (this.getAccountManager().getUserData(getAccount(),
+ AccountAuthenticator.KEY_OC_URL) == null) {
+ throw new UnknownHostException();
+ }
+ mClient = new WebdavClient(account, getContext());
+ mClient.allowSelfsignedCertificates();
+ // mHost = mClient.getTargetHost();
+ }
+
+ return mClient;
+ }
+}
\ No newline at end of file
diff --git a/src/com/owncloud/android/syncadapter/ContactSyncAdapter.java b/src/com/owncloud/android/syncadapter/ContactSyncAdapter.java
new file mode 100644
index 00000000..2508dcd6
--- /dev/null
+++ b/src/com/owncloud/android/syncadapter/ContactSyncAdapter.java
@@ -0,0 +1,107 @@
+package com.owncloud.android.syncadapter;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.ByteArrayEntity;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.db.ProviderMeta;
+import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.ContentProviderClient;
+import android.content.Context;
+import android.content.SyncResult;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.util.Log;
+
+public class ContactSyncAdapter extends AbstractOwnCloudSyncAdapter {
+ private String mAddrBookUri;
+
+ public ContactSyncAdapter(Context context, boolean autoInitialize) {
+ super(context, autoInitialize);
+ mAddrBookUri = null;
+ }
+
+ @Override
+ public void onPerformSync(Account account, Bundle extras, String authority,
+ ContentProviderClient provider, SyncResult syncResult) {
+ setAccount(account);
+ setContentProvider(provider);
+ Cursor c = getLocalContacts(false);
+ if (c.moveToFirst()) {
+ do {
+ String lookup = c.getString(c
+ .getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
+ String a = getAddressBookUri();
+ String uri = a + lookup + ".vcf";
+ FileInputStream f;
+ try {
+ f = getContactVcard(lookup);
+ HttpPut query = new HttpPut(uri);
+ byte[] b = new byte[f.available()];
+ f.read(b);
+ query.setEntity(new ByteArrayEntity(b));
+ HttpResponse response = fireRawRequest(query);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return;
+ } catch (OperationCanceledException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (AuthenticatorException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ } while (c.moveToNext());
+ // } while (c.moveToNext());
+ }
+
+ }
+
+ private String getAddressBookUri() {
+ if (mAddrBookUri != null)
+ return mAddrBookUri;
+
+ AccountManager am = getAccountManager();
+ String uri = am.getUserData(getAccount(),
+ AccountAuthenticator.KEY_OC_URL).replace(
+ AccountUtils.WEBDAV_PATH_2_0, AccountUtils.CARDDAV_PATH_2_0);
+ uri += "/addressbooks/"
+ + getAccount().name.substring(0,
+ getAccount().name.lastIndexOf('@')) + "/default/";
+ mAddrBookUri = uri;
+ return uri;
+ }
+
+ private FileInputStream getContactVcard(String lookupKey)
+ throws IOException {
+ Uri uri = Uri.withAppendedPath(
+ ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
+ AssetFileDescriptor fd = getContext().getContentResolver()
+ .openAssetFileDescriptor(uri, "r");
+ return fd.createInputStream();
+ }
+
+ private Cursor getLocalContacts(boolean include_hidden_contacts) {
+ return getContext().getContentResolver().query(
+ ContactsContract.Contacts.CONTENT_URI,
+ new String[] { ContactsContract.Contacts._ID,
+ ContactsContract.Contacts.LOOKUP_KEY },
+ ContactsContract.Contacts.IN_VISIBLE_GROUP + " = ?",
+ new String[] { (include_hidden_contacts ? "0" : "1") },
+ ContactsContract.Contacts._ID + " DESC");
+ }
+
+}
diff --git a/src/com/owncloud/android/syncadapter/ContactSyncService.java b/src/com/owncloud/android/syncadapter/ContactSyncService.java
new file mode 100644
index 00000000..3016c851
--- /dev/null
+++ b/src/com/owncloud/android/syncadapter/ContactSyncService.java
@@ -0,0 +1,26 @@
+package com.owncloud.android.syncadapter;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class ContactSyncService extends Service {
+ private static final Object syncAdapterLock = new Object();
+ private static AbstractOwnCloudSyncAdapter mSyncAdapter = null;
+
+ @Override
+ public void onCreate() {
+ synchronized (syncAdapterLock) {
+ if (mSyncAdapter == null) {
+ mSyncAdapter = new ContactSyncAdapter(getApplicationContext(),
+ true);
+ }
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent arg0) {
+ return mSyncAdapter.getSyncAdapterBinder();
+ }
+
+}
diff --git a/src/com/owncloud/android/syncadapter/FileSyncAdapter.java b/src/com/owncloud/android/syncadapter/FileSyncAdapter.java
new file mode 100644
index 00000000..f7bfa432
--- /dev/null
+++ b/src/com/owncloud/android/syncadapter/FileSyncAdapter.java
@@ -0,0 +1,294 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.syncadapter;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Vector;
+
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.MultiStatus;
+import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
+
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.services.FileDownloader;
+
+import android.accounts.Account;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.ContentProviderClient;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SyncResult;
+import android.os.Bundle;
+import android.util.Log;
+import eu.alefzero.webdav.WebdavEntry;
+import eu.alefzero.webdav.WebdavUtils;
+
+/**
+ * SyncAdapter implementation for syncing sample SyncAdapter contacts to the
+ * platform ContactOperations provider.
+ *
+ * @author Bartek Przybylski
+ */
+public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
+
+ private final static String TAG = "FileSyncAdapter";
+
+ /* Commented code for ugly performance tests
+ private final static int MAX_DELAYS = 100;
+ private static long[] mResponseDelays = new long[MAX_DELAYS];
+ private static long[] mSaveDelays = new long[MAX_DELAYS];
+ private int mDelaysIndex = 0;
+ private int mDelaysCount = 0;
+ */
+
+ private long mCurrentSyncTime;
+ private boolean mCancellation;
+ private Account mAccount;
+
+ public FileSyncAdapter(Context context, boolean autoInitialize) {
+ super(context, autoInitialize);
+ }
+
+ @Override
+ public synchronized void onPerformSync(Account account, Bundle extras,
+ String authority, ContentProviderClient provider,
+ SyncResult syncResult) {
+
+ mCancellation = false;
+ mAccount = account;
+
+ this.setAccount(mAccount);
+ this.setContentProvider(provider);
+ this.setStorageManager(new FileDataStorageManager(mAccount,
+ getContentProvider()));
+
+ /* Commented code for ugly performance tests
+ mDelaysIndex = 0;
+ mDelaysCount = 0;
+ */
+
+
+ Log.d(TAG, "syncing owncloud account " + mAccount.name);
+
+ sendStickyBroadcast(true, null); // message to signal the start to the UI
+
+ PropFindMethod query;
+ try {
+ mCurrentSyncTime = System.currentTimeMillis();
+ query = new PropFindMethod(getUri().toString() + "/");
+ getClient().executeMethod(query);
+ MultiStatus resp = null;
+ resp = query.getResponseBodyAsMultiStatus();
+
+ if (resp.getResponses().length > 0) {
+ WebdavEntry we = new WebdavEntry(resp.getResponses()[0], getUri().getPath());
+ OCFile file = fillOCFile(we);
+ file.setParentId(0);
+ getStorageManager().saveFile(file);
+ if (!mCancellation) {
+ fetchData(getUri().toString(), syncResult, file.getFileId());
+ }
+ }
+ } catch (OperationCanceledException e) {
+ e.printStackTrace();
+ } catch (AuthenticatorException e) {
+ syncResult.stats.numAuthExceptions++;
+ e.printStackTrace();
+ } catch (IOException e) {
+ syncResult.stats.numIoExceptions++;
+ e.printStackTrace();
+ } catch (DavException e) {
+ syncResult.stats.numIoExceptions++;
+ e.printStackTrace();
+ } catch (Throwable t) {
+ // TODO update syncResult
+ Log.e(TAG, "problem while synchronizing owncloud account " + account.name, t);
+ t.printStackTrace();
+ }
+
+ /* Commented code for ugly performance tests
+ long sum = 0, mean = 0, max = 0, min = Long.MAX_VALUE;
+ for (int i=0; i updatedFiles = new Vector(resp.getResponses().length - 1);
+ for (int i = 1; i < resp.getResponses().length; ++i) {
+ WebdavEntry we = new WebdavEntry(resp.getResponses()[i], getUri().getPath());
+ OCFile file = fillOCFile(we);
+ file.setParentId(parentId);
+ if (getStorageManager().getFileByPath(file.getRemotePath()) != null &&
+ getStorageManager().getFileByPath(file.getRemotePath()).keepInSync() &&
+ file.getModificationTimestamp() > getStorageManager().getFileByPath(file.getRemotePath())
+ .getModificationTimestamp()) {
+ Intent intent = new Intent(this.getContext(), FileDownloader.class);
+ intent.putExtra(FileDownloader.EXTRA_ACCOUNT, getAccount());
+ intent.putExtra(FileDownloader.EXTRA_FILE_PATH, file.getRemotePath());
+ intent.putExtra(FileDownloader.EXTRA_REMOTE_PATH, file.getRemotePath());
+ intent.putExtra(FileDownloader.EXTRA_FILE_SIZE, file.getFileLength());
+ file.setKeepInSync(true);
+ getContext().startService(intent);
+ }
+ if (getStorageManager().getFileByPath(file.getRemotePath()) != null)
+ file.setKeepInSync(getStorageManager().getFileByPath(file.getRemotePath()).keepInSync());
+
+ //Log.v(TAG, "adding file: " + file);
+ updatedFiles.add(file);
+ if (parentId == 0)
+ parentId = file.getFileId();
+ }
+ /* Commented code for ugly performance tests
+ long saveDelay = System.currentTimeMillis();
+ */
+ getStorageManager().saveFiles(updatedFiles); // all "at once" ; trying to get a best performance in database update
+ /* Commented code for ugly performance tests
+ saveDelay = System.currentTimeMillis() - saveDelay;
+ Log.e(TAG, "syncing: SAVE TIME for " + uri + " contents, " + mSaveDelays[mDelaysIndex] + "ms");
+ */
+
+ // removal of obsolete files
+ Vector files = getStorageManager().getDirectoryContent(
+ getStorageManager().getFileById(parentId));
+ OCFile file;
+ for (int i=0; i < files.size(); ) {
+ file = files.get(i);
+ if (file.getLastSyncDate() != mCurrentSyncTime) {
+ Log.v(TAG, "removing file: " + file);
+ getStorageManager().removeFile(file);
+ files.remove(i);
+ } else {
+ i++;
+ }
+ }
+
+ // synchronized folder -> notice to UI
+ sendStickyBroadcast(true, getStorageManager().getFileById(parentId).getRemotePath());
+
+ // recursive fetch
+ for (int i=0; i < files.size() && !mCancellation; i++) {
+ OCFile newFile = files.get(i);
+ if (newFile.getMimetype().equals("DIR")) {
+ fetchData(getUri().toString() + WebdavUtils.encodePath(newFile.getRemotePath()), syncResult, newFile.getFileId());
+ }
+ }
+ if (mCancellation) Log.d(TAG, "Leaving " + uri + " because cancelation request");
+
+ /* Commented code for ugly performance tests
+ mResponseDelays[mDelaysIndex] = responseDelay;
+ mSaveDelays[mDelaysIndex] = saveDelay;
+ mDelaysCount++;
+ mDelaysIndex++;
+ if (mDelaysIndex >= MAX_DELAYS)
+ mDelaysIndex = 0;
+ */
+
+
+
+ } catch (OperationCanceledException e) {
+ e.printStackTrace();
+ } catch (AuthenticatorException e) {
+ syncResult.stats.numAuthExceptions++;
+ e.printStackTrace();
+ } catch (IOException e) {
+ syncResult.stats.numIoExceptions++;
+ e.printStackTrace();
+ } catch (DavException e) {
+ syncResult.stats.numIoExceptions++;
+ e.printStackTrace();
+ } catch (Throwable t) {
+ // TODO update syncResult
+ Log.e(TAG, "problem while synchronizing owncloud account " + mAccount.name, t);
+ t.printStackTrace();
+ }
+ }
+
+ private OCFile fillOCFile(WebdavEntry we) {
+ OCFile file = new OCFile(we.decodedPath());
+ file.setCreationTimestamp(we.createTimestamp());
+ file.setFileLength(we.contentLength());
+ file.setMimetype(we.contentType());
+ file.setModificationTimestamp(we.modifiedTimesamp());
+ file.setLastSyncDate(mCurrentSyncTime);
+ return file;
+ }
+
+
+ private void sendStickyBroadcast(boolean inProgress, String dirRemotePath) {
+ Intent i = new Intent(FileSyncService.SYNC_MESSAGE);
+ i.putExtra(FileSyncService.IN_PROGRESS, inProgress);
+ i.putExtra(FileSyncService.ACCOUNT_NAME, getAccount().name);
+ if (dirRemotePath != null) {
+ i.putExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH, dirRemotePath);
+ }
+ getContext().sendStickyBroadcast(i);
+ }
+
+ /**
+ * Called by system SyncManager when a synchronization is required to be cancelled.
+ *
+ * Sets the mCancellation flag to 'true'. THe synchronization will be stopped when before a new folder is fetched. Data of the last folder
+ * fetched will be still saved in the database. See onPerformSync implementation.
+ */
+ @Override
+ public void onSyncCanceled() {
+ Log.d(TAG, "Synchronization of " + mAccount.name + " has been requested to cancell");
+ mCancellation = true;
+ super.onSyncCanceled();
+ }
+
+}
diff --git a/src/com/owncloud/android/syncadapter/FileSyncService.java b/src/com/owncloud/android/syncadapter/FileSyncService.java
new file mode 100644
index 00000000..74c7fa67
--- /dev/null
+++ b/src/com/owncloud/android/syncadapter/FileSyncService.java
@@ -0,0 +1,50 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.syncadapter;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+/**
+ * Background service for syncing files to our local Database
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class FileSyncService extends Service {
+ public static final String SYNC_MESSAGE = "ACCOUNT_SYNC";
+ public static final String SYNC_FOLDER_REMOTE_PATH = "SYNC_FOLDER_REMOTE_PATH";
+ public static final String IN_PROGRESS = "SYNC_IN_PROGRESS";
+ public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
+
+ /*
+ * {@inheritDoc}
+ */
+ @Override
+ public void onCreate() {
+ }
+
+ /*
+ * {@inheritDoc}
+ */
+ @Override
+ public IBinder onBind(Intent intent) {
+ return new FileSyncAdapter(getApplicationContext(), true).getSyncAdapterBinder();
+ }
+}
diff --git a/src/com/owncloud/android/ui/ActionItem.java b/src/com/owncloud/android/ui/ActionItem.java
new file mode 100644
index 00000000..b2be7029
--- /dev/null
+++ b/src/com/owncloud/android/ui/ActionItem.java
@@ -0,0 +1,61 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.ui;
+
+import android.graphics.drawable.Drawable;
+import android.view.View.OnClickListener;
+
+/**
+ * Represents an Item on the ActionBar.
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class ActionItem {
+ private Drawable mIcon;
+ private String mTitle;
+ private OnClickListener mClickListener;
+
+ public ActionItem() {
+ }
+
+ public void setTitle(String title) {
+ mTitle = title;
+ }
+
+ public String getTitle() {
+ return mTitle;
+ }
+
+ public void setIcon(Drawable icon) {
+ mIcon = icon;
+ }
+
+ public Drawable getIcon() {
+ return mIcon;
+ }
+
+ public void setOnClickListener(OnClickListener listener) {
+ mClickListener = listener;
+ }
+
+ public OnClickListener getOnClickListerner() {
+ return mClickListener;
+ }
+
+}
diff --git a/src/com/owncloud/android/ui/CustomPopup.java b/src/com/owncloud/android/ui/CustomPopup.java
new file mode 100644
index 00000000..b7ce4265
--- /dev/null
+++ b/src/com/owncloud/android/ui/CustomPopup.java
@@ -0,0 +1,154 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.ui;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.View.OnTouchListener;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.PopupWindow;
+
+/**
+ * Represents a custom PopupWindows
+ *
+ * @author Lorensius. W. T
+ *
+ */
+public class CustomPopup {
+ protected final View mAnchor;
+ protected final PopupWindow mWindow;
+ private View root;
+ private Drawable background = null;
+ protected final WindowManager mWManager;
+
+ public CustomPopup(View anchor) {
+ mAnchor = anchor;
+ mWindow = new PopupWindow(anchor.getContext());
+
+ mWindow.setTouchInterceptor(new OnTouchListener() {
+
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
+ CustomPopup.this.dismiss();
+ return true;
+ }
+ return false;
+ }
+ });
+
+ mWManager = (WindowManager) anchor.getContext().getSystemService(
+ Context.WINDOW_SERVICE);
+ onCreate();
+ }
+
+ public void onCreate() {
+ }
+
+ public void onShow() {
+ }
+
+ public void preShow() {
+ if (root == null) {
+ throw new IllegalStateException(
+ "setContentView called with a view to display");
+ }
+
+ onShow();
+
+ if (background == null) {
+ mWindow.setBackgroundDrawable(new BitmapDrawable());
+ } else {
+ mWindow.setBackgroundDrawable(background);
+ }
+
+ mWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
+ mWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
+ mWindow.setTouchable(true);
+ mWindow.setFocusable(true);
+ mWindow.setOutsideTouchable(true);
+
+ mWindow.setContentView(root);
+ }
+
+ public void setBackgroundDrawable(Drawable background) {
+ this.background = background;
+ }
+
+ public void setContentView(View root) {
+ this.root = root;
+ mWindow.setContentView(root);
+ }
+
+ public void setContentView(int layoutResId) {
+ LayoutInflater inflater = (LayoutInflater) mAnchor.getContext()
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ setContentView(inflater.inflate(layoutResId, null));
+ }
+
+ public void showDropDown() {
+ showDropDown(0, 0);
+ }
+
+ public void showDropDown(int x, int y) {
+ preShow();
+ mWindow.setAnimationStyle(android.R.style.Animation_Dialog);
+ mWindow.showAsDropDown(mAnchor, x, y);
+ }
+
+ public void showLikeQuickAction() {
+ showLikeQuickAction(0, 0);
+ }
+
+ public void showLikeQuickAction(int x, int y) {
+ preShow();
+
+ mWindow.setAnimationStyle(android.R.style.Animation_Dialog);
+ int[] location = new int[2];
+ mAnchor.getLocationOnScreen(location);
+
+ Rect anchorRect = new Rect(location[0], location[1], location[0]
+ + mAnchor.getWidth(), location[1] + mAnchor.getHeight());
+
+ root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT));
+ root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+
+ int rootW = root.getWidth(), rootH = root.getHeight();
+ int screenW = mWManager.getDefaultDisplay().getWidth();
+
+ int xpos = ((screenW - rootW) / 2) + x;
+ int ypos = anchorRect.top - rootH + y;
+
+ if (rootH > anchorRect.top) {
+ ypos = anchorRect.bottom + y;
+ }
+ mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xpos, ypos);
+ }
+
+ public void dismiss() {
+ mWindow.dismiss();
+ }
+
+}
diff --git a/src/com/owncloud/android/ui/FragmentListView.java b/src/com/owncloud/android/ui/FragmentListView.java
new file mode 100644
index 00000000..98ac0008
--- /dev/null
+++ b/src/com/owncloud/android/ui/FragmentListView.java
@@ -0,0 +1,52 @@
+package com.owncloud.android.ui;
+
+import com.actionbarsherlock.app.SherlockFragment;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.AdapterView.OnItemClickListener;
+
+public class FragmentListView extends SherlockFragment implements
+ OnItemClickListener, OnItemLongClickListener {
+ ListView mList;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ public void setListAdapter(ListAdapter listAdapter) {
+ mList.setAdapter(listAdapter);
+ mList.invalidate();
+ }
+
+ public ListView getListView() {
+ return mList;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mList = new ListView(getActivity());
+ mList.setOnItemClickListener(this);
+ mList.setOnItemLongClickListener(this);
+ return mList;
+ // return super.onCreateView(inflater, container, savedInstanceState);
+ }
+
+ public void onItemClick(AdapterView> arg0, View arg1, int arg2, long arg3) {
+ }
+
+ @Override
+ public boolean onItemLongClick(AdapterView> arg0, View arg1, int arg2,
+ long arg3) {
+ return false;
+ }
+
+}
diff --git a/src/com/owncloud/android/ui/QuickAction.java b/src/com/owncloud/android/ui/QuickAction.java
new file mode 100644
index 00000000..122792d5
--- /dev/null
+++ b/src/com/owncloud/android/ui/QuickAction.java
@@ -0,0 +1,305 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.ui;
+
+import android.content.Context;
+
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup.LayoutParams;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+
+import com.owncloud.android.R;
+
+/**
+ * Popup window, shows action list as icon and text like the one in Gallery3D
+ * app.
+ *
+ * @author Lorensius. W. T
+ */
+public class QuickAction extends CustomPopup {
+ private final View root;
+ private final ImageView mArrowUp;
+ private final ImageView mArrowDown;
+ private final LayoutInflater inflater;
+ private final Context context;
+
+ protected static final int ANIM_GROW_FROM_LEFT = 1;
+ protected static final int ANIM_GROW_FROM_RIGHT = 2;
+ protected static final int ANIM_GROW_FROM_CENTER = 3;
+ protected static final int ANIM_REFLECT = 4;
+ protected static final int ANIM_AUTO = 5;
+
+ private int animStyle;
+ private ViewGroup mTrack;
+ private ScrollView scroller;
+ private ArrayList actionList;
+
+ /**
+ * Constructor
+ *
+ * @param anchor {@link View} on where the popup window should be displayed
+ */
+ public QuickAction(View anchor) {
+ super(anchor);
+
+ actionList = new ArrayList();
+ context = anchor.getContext();
+ inflater = (LayoutInflater) context
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ root = (ViewGroup) inflater.inflate(R.layout.popup, null);
+
+ mArrowDown = (ImageView) root.findViewById(R.id.arrow_down);
+ mArrowUp = (ImageView) root.findViewById(R.id.arrow_up);
+
+ setContentView(root);
+
+ mTrack = (ViewGroup) root.findViewById(R.id.tracks);
+ scroller = (ScrollView) root.findViewById(R.id.scroller);
+ animStyle = ANIM_AUTO;
+ }
+
+ /**
+ * Set animation style
+ *
+ * @param animStyle animation style, default is set to ANIM_AUTO
+ */
+ public void setAnimStyle(int animStyle) {
+ this.animStyle = animStyle;
+ }
+
+ /**
+ * Add action item
+ *
+ * @param action {@link ActionItem} object
+ */
+ public void addActionItem(ActionItem action) {
+ actionList.add(action);
+ }
+
+ /**
+ * Show popup window. Popup is automatically positioned, on top or bottom of
+ * anchor view.
+ *
+ */
+ public void show() {
+ preShow();
+
+ int xPos, yPos;
+
+ int[] location = new int[2];
+
+ mAnchor.getLocationOnScreen(location);
+
+ Rect anchorRect = new Rect(location[0], location[1], location[0]
+ + mAnchor.getWidth(), location[1] + mAnchor.getHeight());
+
+ createActionList();
+
+ root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT));
+ root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+
+ int rootHeight = root.getMeasuredHeight();
+ int rootWidth = root.getMeasuredWidth();
+
+ int screenWidth = mWManager.getDefaultDisplay().getWidth();
+ int screenHeight = mWManager.getDefaultDisplay().getHeight();
+
+ // automatically get X coord of popup (top left)
+ if ((anchorRect.left + rootWidth) > screenWidth) {
+ xPos = anchorRect.left - (rootWidth - mAnchor.getWidth());
+ } else {
+ if (mAnchor.getWidth() > rootWidth) {
+ xPos = anchorRect.centerX() - (rootWidth / 2);
+ } else {
+ xPos = anchorRect.left;
+ }
+ }
+
+ int dyTop = anchorRect.top;
+ int dyBottom = screenHeight - anchorRect.bottom;
+
+ boolean onTop = (dyTop > dyBottom) ? true : false;
+
+ if (onTop) {
+ if (rootHeight > dyTop) {
+ yPos = 15;
+ LayoutParams l = scroller.getLayoutParams();
+ l.height = dyTop - mAnchor.getHeight();
+ } else {
+ yPos = anchorRect.top - rootHeight;
+ }
+ } else {
+ yPos = anchorRect.bottom;
+
+ if (rootHeight > dyBottom) {
+ LayoutParams l = scroller.getLayoutParams();
+ l.height = dyBottom;
+ }
+ }
+
+ showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up),
+ anchorRect.centerX() - xPos);
+
+ setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
+
+ mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xPos, yPos);
+ }
+
+ /**
+ * Set animation style
+ *
+ * @param screenWidth screen width
+ * @param requestedX distance from left edge
+ * @param onTop flag to indicate where the popup should be displayed. Set
+ * TRUE if displayed on top of anchor view and vice versa
+ */
+ private void setAnimationStyle(int screenWidth, int requestedX,
+ boolean onTop) {
+ int arrowPos = requestedX - mArrowUp.getMeasuredWidth() / 2;
+
+ switch (animStyle) {
+ case ANIM_GROW_FROM_LEFT:
+ mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
+ : R.style.Animations_PopDownMenu_Left);
+ break;
+
+ case ANIM_GROW_FROM_RIGHT:
+ mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
+ : R.style.Animations_PopDownMenu_Right);
+ break;
+
+ case ANIM_GROW_FROM_CENTER:
+ mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
+ : R.style.Animations_PopDownMenu_Center);
+ break;
+
+ case ANIM_REFLECT:
+ mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect
+ : R.style.Animations_PopDownMenu_Reflect);
+ break;
+
+ case ANIM_AUTO:
+ if (arrowPos <= screenWidth / 4) {
+ mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
+ : R.style.Animations_PopDownMenu_Left);
+ } else if (arrowPos > screenWidth / 4
+ && arrowPos < 3 * (screenWidth / 4)) {
+ mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
+ : R.style.Animations_PopDownMenu_Center);
+ } else {
+ mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
+ : R.style.Animations_PopDownMenu_Right);
+ }
+
+ break;
+ }
+ }
+
+ /**
+ * Create action list
+ */
+ private void createActionList() {
+ View view;
+ String title;
+ Drawable icon;
+ OnClickListener listener;
+
+ for (int i = 0; i < actionList.size(); i++) {
+ title = actionList.get(i).getTitle();
+ icon = actionList.get(i).getIcon();
+ listener = actionList.get(i).getOnClickListerner();
+
+ view = getActionItem(title, icon, listener);
+
+ view.setFocusable(true);
+ view.setClickable(true);
+
+ mTrack.addView(view);
+ }
+ }
+
+ /**
+ * Get action item {@link View}
+ *
+ * @param title action item title
+ * @param icon {@link Drawable} action item icon
+ * @param listener {@link View.OnClickListener} action item listener
+ * @return action item {@link View}
+ */
+ private View getActionItem(String title, Drawable icon,
+ OnClickListener listener) {
+ LinearLayout container = (LinearLayout) inflater.inflate(
+ R.layout.action_item, null);
+
+ ImageView img = (ImageView) container.findViewById(R.id.icon);
+ TextView text = (TextView) container.findViewById(R.id.title);
+
+ if (icon != null) {
+ img.setImageDrawable(icon);
+ }
+
+ if (title != null) {
+ text.setText(title);
+ }
+
+ if (listener != null) {
+ container.setOnClickListener(listener);
+ }
+
+ return container;
+ }
+
+ /**
+ * Show arrow
+ *
+ * @param whichArrow arrow type resource id
+ * @param requestedX distance from left screen
+ */
+ private void showArrow(int whichArrow, int requestedX) {
+ final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp
+ : mArrowDown;
+ final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown
+ : mArrowUp;
+
+ final int arrowWidth = mArrowUp.getMeasuredWidth();
+
+ showArrow.setVisibility(View.VISIBLE);
+
+ ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams) showArrow
+ .getLayoutParams();
+
+ param.leftMargin = requestedX - arrowWidth / 2;
+
+ hideArrow.setVisibility(View.INVISIBLE);
+ }
+}
\ No newline at end of file
diff --git a/src/com/owncloud/android/ui/activity/AccountSelectActivity.java b/src/com/owncloud/android/ui/activity/AccountSelectActivity.java
new file mode 100644
index 00000000..78ec8c0f
--- /dev/null
+++ b/src/com/owncloud/android/ui/activity/AccountSelectActivity.java
@@ -0,0 +1,189 @@
+package com.owncloud.android.ui.activity;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.CheckedTextView;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+import android.widget.TextView;
+
+import com.actionbarsherlock.app.ActionBar;
+import com.actionbarsherlock.app.SherlockListActivity;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuInflater;
+import com.actionbarsherlock.view.MenuItem;
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+
+import com.owncloud.android.R;
+
+public class AccountSelectActivity extends SherlockListActivity implements
+ AccountManagerCallback {
+
+ private final Handler mHandler = new Handler();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ ActionBar action_bar = getSupportActionBar();
+ action_bar.setDisplayShowTitleEnabled(true);
+ action_bar.setDisplayHomeAsUpEnabled(false);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ populateAccountList();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getSherlock().getMenuInflater();
+ inflater.inflate(R.menu.account_picker, menu);
+ return true;
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenuInfo menuInfo) {
+ getMenuInflater().inflate(R.menu.account_picker_long_click, menu);
+ super.onCreateContextMenu(menu, v, menuInfo);
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ String accountName = ((TextView) v.findViewById(android.R.id.text1))
+ .getText().toString();
+ AccountUtils.setCurrentOwnCloudAccount(this, accountName);
+
+ // trigger synchronization when current account is changed
+ ContentResolver.cancelSync(null, "org.owncloud");
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+ ContentResolver.requestSync(AccountUtils.getCurrentOwnCloudAccount(this), "org.owncloud", bundle);
+
+ Intent i = new Intent(this, FileDisplayActivity.class);
+ i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(i);
+ finish();
+ }
+
+ @Override
+ public boolean onMenuItemSelected(int featureId, MenuItem item) {
+ if (item.getItemId() == R.id.createAccount) {
+ Intent intent = new Intent(
+ android.provider.Settings.ACTION_ADD_ACCOUNT);
+ intent.putExtra("authorities",
+ new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
+ startActivity(intent);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onContextItemSelected(android.view.MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
+ .getMenuInfo();
+ int index = info.position;
+ HashMap map = (HashMap) getListAdapter()
+ .getItem(index);
+ String accountName = map.get("NAME");
+ AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
+ Account accounts[] = am
+ .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
+ for (Account a : accounts) {
+ if (a.name.equals(accountName)) {
+ am.removeAccount(a, this, mHandler);
+ }
+ }
+
+ return false;
+ }
+
+ private void populateAccountList() {
+ AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
+ Account accounts[] = am
+ .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
+ LinkedList> ll = new LinkedList>();
+ for (Account a : accounts) {
+ HashMap h = new HashMap();
+ h.put("NAME", a.name);
+ h.put("VER",
+ "ownCloud version: "
+ + am.getUserData(a,
+ AccountAuthenticator.KEY_OC_VERSION));
+ ll.add(h);
+ }
+
+ setListAdapter(new AccountCheckedSimpleAdepter(this, ll,
+ android.R.layout.simple_list_item_single_choice,
+ new String[] { "NAME" }, new int[] { android.R.id.text1 }));
+ registerForContextMenu(getListView());
+ }
+
+ @Override
+ public void run(AccountManagerFuture future) {
+ if (future.isDone()) {
+ Account a = AccountUtils.getCurrentOwnCloudAccount(this);
+ String accountName = "";
+ if (a == null) {
+ Account[] accounts = AccountManager.get(this)
+ .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
+ if (accounts.length != 0)
+ accountName = accounts[0].name;
+ AccountUtils.setCurrentOwnCloudAccount(this, accountName);
+ }
+ populateAccountList();
+ }
+ }
+
+ private class AccountCheckedSimpleAdepter extends SimpleAdapter {
+ private Account mCurrentAccount;
+ private List extends Map> mPrivateData;
+
+ public AccountCheckedSimpleAdepter(Context context,
+ List extends Map> data, int resource,
+ String[] from, int[] to) {
+ super(context, data, resource, from, to);
+ mCurrentAccount = AccountUtils
+ .getCurrentOwnCloudAccount(AccountSelectActivity.this);
+ mPrivateData = data;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v = super.getView(position, convertView, parent);
+ CheckedTextView ctv = (CheckedTextView) v
+ .findViewById(android.R.id.text1);
+ if (mPrivateData.get(position).get("NAME")
+ .equals(mCurrentAccount.name)) {
+ ctv.setChecked(true);
+ }
+ return v;
+ }
+
+ }
+
+}
diff --git a/src/com/owncloud/android/ui/activity/AuthenticatorActivity.java b/src/com/owncloud/android/ui/activity/AuthenticatorActivity.java
new file mode 100644
index 00000000..4aa7cddd
--- /dev/null
+++ b/src/com/owncloud/android/ui/activity/AuthenticatorActivity.java
@@ -0,0 +1,399 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.ui.activity;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLEncoder;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.authenticator.AuthenticationRunnable;
+import com.owncloud.android.authenticator.ConnectionCheckerRunnable;
+import com.owncloud.android.authenticator.OnAuthenticationResultListener;
+import com.owncloud.android.authenticator.OnConnectCheckListener;
+import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
+import com.owncloud.android.extensions.ExtensionsAvailableActivity;
+import com.owncloud.android.utils.OwnCloudVersion;
+
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorActivity;
+import android.accounts.AccountManager;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.ContentResolver;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.PreferenceManager;
+import android.text.InputType;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnFocusChangeListener;
+import android.view.Window;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.owncloud.android.R;
+
+/**
+ * This Activity is used to add an ownCloud account to the App
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class AuthenticatorActivity extends AccountAuthenticatorActivity
+ implements OnAuthenticationResultListener, OnConnectCheckListener,
+ OnFocusChangeListener, OnClickListener {
+ private static final int DIALOG_LOGIN_PROGRESS = 0;
+
+ private static final String TAG = "AuthActivity";
+
+ private Thread mAuthThread;
+ private AuthenticationRunnable mAuthRunnable;
+ private ConnectionCheckerRunnable mConnChkRunnable;
+ private final Handler mHandler = new Handler();
+ private String mBaseUrl;
+
+ private static final String STATUS_TEXT = "STATUS_TEXT";
+ private static final String STATUS_ICON = "STATUS_ICON";
+ private static final String STATUS_CORRECT = "STATUS_CORRECT";
+ private static final String IS_SSL_CONN = "IS_SSL_CONN";
+ private int mStatusText, mStatusIcon;
+ private boolean mStatusCorrect, mIsSslConn;
+
+ public static final String PARAM_USERNAME = "param_Username";
+ public static final String PARAM_HOSTNAME = "param_Hostname";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().requestFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.account_setup);
+ ImageView iv = (ImageView) findViewById(R.id.refreshButton);
+ ImageView iv2 = (ImageView) findViewById(R.id.viewPassword);
+ TextView tv = (TextView) findViewById(R.id.host_URL);
+ TextView tv2 = (TextView) findViewById(R.id.account_password);
+
+ if (savedInstanceState != null) {
+ mStatusIcon = savedInstanceState.getInt(STATUS_ICON);
+ mStatusText = savedInstanceState.getInt(STATUS_TEXT);
+ mStatusCorrect = savedInstanceState.getBoolean(STATUS_CORRECT);
+ mIsSslConn = savedInstanceState.getBoolean(IS_SSL_CONN);
+ setResultIconAndText(mStatusIcon, mStatusText);
+ findViewById(R.id.buttonOK).setEnabled(mStatusCorrect);
+ if (!mStatusCorrect)
+ iv.setVisibility(View.VISIBLE);
+ else
+ iv.setVisibility(View.INVISIBLE);
+
+ } else {
+ mStatusText = mStatusIcon = 0;
+ mStatusCorrect = false;
+ mIsSslConn = false;
+ }
+ iv.setOnClickListener(this);
+ iv2.setOnClickListener(this);
+ tv.setOnFocusChangeListener(this);
+ tv2.setOnFocusChangeListener(this);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ outState.putInt(STATUS_ICON, mStatusIcon);
+ outState.putInt(STATUS_TEXT, mStatusText);
+ outState.putBoolean(STATUS_CORRECT, mStatusCorrect);
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int id) {
+ Dialog dialog = null;
+ switch (id) {
+ case DIALOG_LOGIN_PROGRESS: {
+ ProgressDialog working_dialog = new ProgressDialog(this);
+ working_dialog.setMessage(getResources().getString(
+ R.string.auth_trying_to_login));
+ working_dialog.setIndeterminate(true);
+ working_dialog.setCancelable(true);
+ working_dialog
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ Log.i(TAG, "Login canceled");
+ if (mAuthThread != null) {
+ mAuthThread.interrupt();
+ finish();
+ }
+ }
+ });
+ dialog = working_dialog;
+ break;
+ }
+ default:
+ Log.e(TAG, "Incorrect dialog called with id = " + id);
+ }
+ return dialog;
+ }
+
+ public void onAuthenticationResult(boolean success, String message) {
+ if (success) {
+ TextView username_text = (TextView) findViewById(R.id.account_username), password_text = (TextView) findViewById(R.id.account_password);
+
+ URL url;
+ try {
+ url = new URL(message);
+ } catch (MalformedURLException e) {
+ // should never happen
+ Log.e(getClass().getName(), "Malformed URL: " + message);
+ return;
+ }
+
+ String username = username_text.getText().toString().trim();
+ String accountName = username + "@" + url.getHost();
+ if (url.getPort() >= 0) {
+ accountName += ":" + url.getPort();
+ }
+ Account account = new Account(accountName,
+ AccountAuthenticator.ACCOUNT_TYPE);
+ AccountManager accManager = AccountManager.get(this);
+ accManager.addAccountExplicitly(account, password_text.getText()
+ .toString(), null);
+
+ // Add this account as default in the preferences, if there is none
+ // already
+ Account defaultAccount = AccountUtils
+ .getCurrentOwnCloudAccount(this);
+ if (defaultAccount == null) {
+ SharedPreferences.Editor editor = PreferenceManager
+ .getDefaultSharedPreferences(this).edit();
+ editor.putString("select_oc_account", accountName);
+ editor.commit();
+ }
+
+ final Intent intent = new Intent();
+ intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE,
+ AccountAuthenticator.ACCOUNT_TYPE);
+ intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
+ intent.putExtra(AccountManager.KEY_AUTHTOKEN,
+ AccountAuthenticator.ACCOUNT_TYPE);
+ intent.putExtra(AccountManager.KEY_USERDATA, username);
+
+ accManager.setUserData(account, AccountAuthenticator.KEY_OC_URL,
+ url.toString());
+ accManager.setUserData(account,
+ AccountAuthenticator.KEY_OC_VERSION, mConnChkRunnable
+ .getDiscoveredVersion().toString());
+ accManager.setUserData(account,
+ AccountAuthenticator.KEY_OC_BASE_URL, mBaseUrl);
+
+ setAccountAuthenticatorResult(intent.getExtras());
+ setResult(RESULT_OK, intent);
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+ //getContentResolver().startSync(ProviderTableMeta.CONTENT_URI,
+ // bundle);
+ ContentResolver.requestSync(account, "org.owncloud", bundle);
+
+ /*
+ * if
+ * (mConnChkRunnable.getDiscoveredVersion().compareTo(OwnCloudVersion
+ * .owncloud_v2) >= 0) { Intent i = new Intent(this,
+ * ExtensionsAvailableActivity.class); startActivity(i); }
+ */
+
+ finish();
+ } else {
+ dismissDialog(DIALOG_LOGIN_PROGRESS);
+ TextView tv = (TextView) findViewById(R.id.account_username);
+ tv.setError(message);
+ }
+ }
+ public void onCancelClick(View view) {
+ finish();
+ }
+
+ public void onOkClick(View view) {
+ String prefix = "";
+ String url = ((TextView) findViewById(R.id.host_URL)).getText()
+ .toString();
+ if (mIsSslConn) {
+ prefix = "https://";
+ } else {
+ prefix = "http://";
+ }
+ if (url.toLowerCase().startsWith("http://")
+ || url.toLowerCase().startsWith("https://")) {
+ prefix = "";
+ }
+ continueConnection(prefix);
+ }
+
+ private void continueConnection(String prefix) {
+ String url = ((TextView) findViewById(R.id.host_URL)).getText()
+ .toString();
+ String username = ((TextView) findViewById(R.id.account_username))
+ .getText().toString();
+ String password = ((TextView) findViewById(R.id.account_password))
+ .getText().toString();
+ if (url.endsWith("/"))
+ url = url.substring(0, url.length() - 1);
+
+ URL uri = null;
+ String webdav_path = AccountUtils.getWebdavPath(mConnChkRunnable
+ .getDiscoveredVersion());
+
+ try {
+ mBaseUrl = prefix + url;
+ String url_str = prefix + url + webdav_path;
+ uri = new URL(url_str);
+ } catch (MalformedURLException e) {
+ // should not happend
+ e.printStackTrace();
+ }
+
+ showDialog(DIALOG_LOGIN_PROGRESS);
+ mAuthRunnable = new AuthenticationRunnable(uri, username, password);
+ mAuthRunnable.setOnAuthenticationResultListener(this, mHandler);
+ mAuthThread = new Thread(mAuthRunnable);
+ mAuthThread.start();
+ }
+
+ @Override
+ public void onConnectionCheckResult(ResultType type) {
+ mStatusText = mStatusIcon = 0;
+ mStatusCorrect = false;
+ String t_url = ((TextView) findViewById(R.id.host_URL)).getText()
+ .toString().toLowerCase();
+
+ switch (type) {
+ case OK_SSL:
+ mIsSslConn = true;
+ mStatusIcon = android.R.drawable.ic_secure;
+ mStatusText = R.string.auth_secure_connection;
+ mStatusCorrect = true;
+ break;
+ case OK_NO_SSL:
+ mIsSslConn = false;
+ mStatusCorrect = true;
+ if (t_url.startsWith("http://") ) {
+ mStatusText = R.string.auth_connection_established;
+ mStatusIcon = R.drawable.ic_ok;
+ } else {
+ mStatusText = R.string.auth_nossl_plain_ok_title;
+ mStatusIcon = android.R.drawable.ic_partial_secure;
+ }
+ break;
+ case TIMEOUT:
+ case INORRECT_ADDRESS:
+ case SSL_INIT_ERROR:
+ case HOST_NOT_AVAILABLE:
+ mStatusIcon = R.drawable.common_error;
+ mStatusText = R.string.auth_unknow_host_title;
+ break;
+ case NO_NETWORK_CONNECTION:
+ mStatusIcon = R.drawable.no_network;
+ mStatusText = R.string.auth_no_net_conn_title;
+ break;
+ case INSTANCE_NOT_CONFIGURED:
+ mStatusIcon = R.drawable.common_error;
+ mStatusText = R.string.auth_not_configured_title;
+ break;
+ case UNKNOWN_ERROR:
+ mStatusIcon = R.drawable.common_error;
+ mStatusText = R.string.auth_unknow_error;
+ break;
+ case FILE_NOT_FOUND:
+ mStatusIcon = R.drawable.common_error;
+ mStatusText = R.string.auth_incorrect_path_title;
+ break;
+ default:
+ Log.e(TAG, "Incorrect connection checker result type: " + type);
+ }
+ setResultIconAndText(mStatusIcon, mStatusText);
+ if (!mStatusCorrect)
+ findViewById(R.id.refreshButton).setVisibility(View.VISIBLE);
+ else
+ findViewById(R.id.refreshButton).setVisibility(View.INVISIBLE);
+ findViewById(R.id.buttonOK).setEnabled(mStatusCorrect);
+ }
+
+ @Override
+ public void onFocusChange(View view, boolean hasFocus) {
+ if (view.getId() == R.id.host_URL) {
+ if (!hasFocus) {
+ TextView tv = ((TextView) findViewById(R.id.host_URL));
+ String uri = tv.getText().toString();
+ if (uri.length() != 0) {
+ setResultIconAndText(R.drawable.progress_small,
+ R.string.auth_testing_connection);
+ findViewById(R.id.buttonOK).setEnabled(false); // avoid connect can be clicked if the test was previously passed
+ mConnChkRunnable = new ConnectionCheckerRunnable(uri, this);
+ mConnChkRunnable.setListener(this, mHandler);
+ mAuthThread = new Thread(mConnChkRunnable);
+ mAuthThread.start();
+ } else {
+ findViewById(R.id.refreshButton).setVisibility(
+ View.INVISIBLE);
+ setResultIconAndText(0, 0);
+ }
+ }
+ } else if (view.getId() == R.id.account_password) {
+ ImageView iv = (ImageView) findViewById(R.id.viewPassword);
+ if (hasFocus) {
+ iv.setVisibility(View.VISIBLE);
+ } else {
+ TextView v = (TextView) findViewById(R.id.account_password);
+ int input_type = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_PASSWORD;
+ v.setInputType(input_type);
+ iv.setVisibility(View.INVISIBLE);
+ }
+ }
+ }
+
+ private void setResultIconAndText(int drawable_id, int text_id) {
+ ImageView iv = (ImageView) findViewById(R.id.action_indicator);
+ TextView tv = (TextView) findViewById(R.id.status_text);
+
+ if (drawable_id == 0 && text_id == 0) {
+ iv.setVisibility(View.INVISIBLE);
+ tv.setVisibility(View.INVISIBLE);
+ } else {
+ iv.setImageResource(drawable_id);
+ tv.setText(text_id);
+ iv.setVisibility(View.VISIBLE);
+ tv.setVisibility(View.VISIBLE);
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v.getId() == R.id.refreshButton) {
+ onFocusChange(findViewById(R.id.host_URL), false);
+ } else if (v.getId() == R.id.viewPassword) {
+ TextView view = (TextView) findViewById(R.id.account_password);
+ int input_type = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
+ view.setInputType(input_type);
+ }
+ }
+}
diff --git a/src/com/owncloud/android/ui/activity/FileDetailActivity.java b/src/com/owncloud/android/ui/activity/FileDetailActivity.java
new file mode 100644
index 00000000..3c80a48d
--- /dev/null
+++ b/src/com/owncloud/android/ui/activity/FileDetailActivity.java
@@ -0,0 +1,144 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.ui.activity;
+
+import android.accounts.Account;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+
+import com.actionbarsherlock.app.ActionBar;
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+import com.actionbarsherlock.view.MenuItem;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.services.FileDownloader;
+import com.owncloud.android.ui.fragment.FileDetailFragment;
+
+import com.owncloud.android.R;
+
+/**
+ * This activity displays the details of a file like its name, its size and so
+ * on.
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class FileDetailActivity extends SherlockFragmentActivity implements FileDetailFragment.ContainerActivity {
+
+ public static final int DIALOG_SHORT_WAIT = 0;
+
+ private boolean mConfigurationChangedToLandscape = false;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // check if configuration changed to large-land ; for a tablet being changed from portrait to landscape when in FileDetailActivity
+ Configuration conf = getResources().getConfiguration();
+ mConfigurationChangedToLandscape = (conf.orientation == Configuration.ORIENTATION_LANDSCAPE &&
+ (conf.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
+ );
+
+ if (!mConfigurationChangedToLandscape) {
+ setContentView(R.layout.file_activity_details);
+
+ ActionBar actionBar = getSupportActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+
+ OCFile file = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);
+ Account account = getIntent().getParcelableExtra(FileDownloader.EXTRA_ACCOUNT);
+ FileDetailFragment mFileDetail = new FileDetailFragment(file, account);
+
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+ ft.replace(R.id.fragment, mFileDetail, FileDetailFragment.FTAG);
+ ft.commit();
+
+ } else {
+ backToDisplayActivity(); // the 'back' won't be effective until this.onStart() and this.onResume() are completed;
+ }
+
+
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ boolean returnValue = false;
+
+ switch(item.getItemId()){
+ case android.R.id.home:
+ backToDisplayActivity();
+ returnValue = true;
+ }
+
+ return returnValue;
+ }
+
+
+
+ @Override
+ protected void onResume() {
+
+ super.onResume();
+ if (!mConfigurationChangedToLandscape) {
+ FileDetailFragment fragment = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
+ fragment.updateFileDetails();
+ }
+ }
+
+
+ private void backToDisplayActivity() {
+ Intent intent = new Intent(this, FileDisplayActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ intent.putExtra(FileDetailFragment.EXTRA_FILE, getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE));
+ startActivity(intent);
+ finish();
+ }
+
+
+ @Override
+ protected Dialog onCreateDialog(int id) {
+ Dialog dialog = null;
+ switch (id) {
+ case DIALOG_SHORT_WAIT: {
+ ProgressDialog working_dialog = new ProgressDialog(this);
+ working_dialog.setMessage(getResources().getString(
+ R.string.wait_a_moment));
+ working_dialog.setIndeterminate(true);
+ working_dialog.setCancelable(false);
+ dialog = working_dialog;
+ break;
+ }
+ default:
+ dialog = null;
+ }
+ return dialog;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onFileStateChanged() {
+ // nothing to do here!
+ }
+
+}
diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java
new file mode 100644
index 00000000..54c99e6c
--- /dev/null
+++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java
@@ -0,0 +1,886 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.ui.activity;
+
+import java.io.File;
+import java.util.ArrayList;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.app.AlertDialog.Builder;
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources.NotFoundException;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.PreferenceManager;
+import android.provider.MediaStore;
+import android.support.v4.app.FragmentTransaction;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.actionbarsherlock.app.ActionBar;
+import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuInflater;
+import com.actionbarsherlock.view.MenuItem;
+import com.actionbarsherlock.view.Window;
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.CrashHandler;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.datamodel.DataStorageManager;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.services.FileDownloader;
+import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.syncadapter.FileSyncService;
+import com.owncloud.android.ui.fragment.FileDetailFragment;
+import com.owncloud.android.ui.fragment.FileListFragment;
+
+import com.owncloud.android.R;
+import eu.alefzero.webdav.WebdavClient;
+
+/**
+ * Displays, what files the user has available in his ownCloud.
+ *
+ * @author Bartek Przybylski
+ *
+ */
+
+public class FileDisplayActivity extends SherlockFragmentActivity implements
+ FileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNavigationListener, OnClickListener, android.view.View.OnClickListener {
+
+ private ArrayAdapter mDirectories;
+ private OCFile mCurrentDir;
+ private String[] mDirs = null;
+
+ private DataStorageManager mStorageManager;
+ private SyncBroadcastReceiver mSyncBroadcastReceiver;
+ private UploadFinishReceiver mUploadFinishReceiver;
+ private DownloadFinishReceiver mDownloadFinishReceiver;
+
+ private View mLayoutView = null;
+ private FileListFragment mFileList;
+
+ private boolean mDualPane;
+
+ private boolean mForcedLoginToCreateFirstAccount = false;
+
+ private static final String KEY_DIR_ARRAY = "DIR_ARRAY";
+ private static final String KEY_CURRENT_DIR = "DIR";
+
+ private static final int DIALOG_SETUP_ACCOUNT = 0;
+ private static final int DIALOG_CREATE_DIR = 1;
+ private static final int DIALOG_ABOUT_APP = 2;
+ public static final int DIALOG_SHORT_WAIT = 3;
+
+ private static final int ACTION_SELECT_FILE = 1;
+
+ private static final String TAG = "FileDisplayActivity";
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.i(getClass().toString(), "onCreate() start");
+ super.onCreate(savedInstanceState);
+
+ requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+
+ Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(getApplicationContext()));
+
+ if(savedInstanceState != null) {
+ mDirs = savedInstanceState.getStringArray(KEY_DIR_ARRAY);
+ mDirectories = new CustomArrayAdapter(this, R.layout.sherlock_spinner_dropdown_item);
+ mDirectories.add(OCFile.PATH_SEPARATOR);
+ if (mDirs != null)
+ for (String s : mDirs)
+ mDirectories.insert(s, 0);
+ mCurrentDir = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_FILE);
+ }
+
+ mLayoutView = getLayoutInflater().inflate(R.layout.files, null); // always inflate this at onCreate() ; just once!
+
+ if (AccountUtils.accountsAreSetup(this)) {
+
+ initDelayedTilAccountAvailabe();
+
+ // PIN CODE request ; best location is to decide, let's try this first
+ //if (savedInstanceState == null) {
+ if (getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_MAIN) && savedInstanceState == null) {
+ requestPinCode();
+ }
+
+
+ } else {
+
+ setContentView(R.layout.no_account_available);
+ getSupportActionBar().setNavigationMode(ActionBar.DISPLAY_SHOW_TITLE);
+ findViewById(R.id.setup_account).setOnClickListener(this);
+
+ setSupportProgressBarIndeterminateVisibility(false);
+
+ Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
+ intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
+ startActivity(intent); // although the code is here, the activity won't be created until this.onStart() and this.onResume() are finished;
+ mForcedLoginToCreateFirstAccount = true;
+ }
+
+ Log.i(getClass().toString(), "onCreate() end");
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getSherlock().getMenuInflater();
+ inflater.inflate(R.menu.menu, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ boolean retval = true;
+ switch (item.getItemId()) {
+ case R.id.createDirectoryItem: {
+ showDialog(DIALOG_CREATE_DIR);
+ break;
+ }
+ case R.id.startSync: {
+ ContentResolver.cancelSync(null, "org.owncloud"); // cancel the current synchronizations of any ownCloud account
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+ ContentResolver.requestSync(
+ AccountUtils.getCurrentOwnCloudAccount(this),
+ "org.owncloud", bundle);
+ break;
+ }
+ case R.id.action_upload: {
+ Intent action = new Intent(Intent.ACTION_GET_CONTENT);
+ action = action.setType("*/*")
+ .addCategory(Intent.CATEGORY_OPENABLE);
+ startActivityForResult(
+ Intent.createChooser(action, getString(R.string.upload_chooser_title)),
+ ACTION_SELECT_FILE);
+ break;
+ }
+ case R.id.action_settings: {
+ Intent settingsIntent = new Intent(this, Preferences.class);
+ startActivity(settingsIntent);
+ break;
+ }
+ case R.id.about_app : {
+ showDialog(DIALOG_ABOUT_APP);
+ break;
+ }
+ case android.R.id.home: {
+ if(mCurrentDir != null && mCurrentDir.getParentId() != 0){
+ onBackPressed();
+ }
+ break;
+ }
+ default:
+ retval = false;
+ }
+ return retval;
+ }
+
+ @Override
+ public boolean onNavigationItemSelected(int itemPosition, long itemId) {
+ int i = itemPosition;
+ while (i-- != 0) {
+ onBackPressed();
+ }
+ return true;
+ }
+
+ /**
+ * Called, when the user selected something for uploading
+ */
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == ACTION_SELECT_FILE) {
+ if (resultCode == RESULT_OK) {
+ String filepath = null;
+ try {
+ Uri selectedImageUri = data.getData();
+
+ String filemanagerstring = selectedImageUri.getPath();
+ String selectedImagePath = getPath(selectedImageUri);
+
+ if (selectedImagePath != null)
+ filepath = selectedImagePath;
+ else
+ filepath = filemanagerstring;
+
+ } catch (Exception e) {
+ Log.e("FileDisplay", "Unexpected exception when trying to read the result of Intent.ACTION_GET_CONTENT", e);
+ e.printStackTrace();
+
+ } finally {
+ if (filepath == null) {
+ Log.e("FileDisplay", "Couldnt resolve path to file");
+ Toast t = Toast.makeText(this, getString(R.string.filedisplay_unexpected_bad_get_content), Toast.LENGTH_LONG);
+ t.show();
+ return;
+ }
+ }
+
+ Intent i = new Intent(this, FileUploader.class);
+ i.putExtra(FileUploader.KEY_ACCOUNT,
+ AccountUtils.getCurrentOwnCloudAccount(this));
+ String remotepath = new String();
+ for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
+ remotepath += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
+ }
+ if (!remotepath.endsWith(OCFile.PATH_SEPARATOR))
+ remotepath += OCFile.PATH_SEPARATOR;
+ remotepath += new File(filepath).getName();
+
+ i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);
+ i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);
+ i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
+ startService(i);
+ }
+
+ }/* dvelasco: WIP - not working as expected ... yet :)
+ else if (requestCode == ACTION_CREATE_FIRST_ACCOUNT) {
+ if (resultCode != RESULT_OK) {
+ finish(); // the user cancelled the AuthenticatorActivity
+ }
+ }*/
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (mDirectories == null || mDirectories.getCount() <= 1) {
+ finish();
+ return;
+ }
+ popDirname();
+ mFileList.onNavigateUp();
+ mCurrentDir = mFileList.getCurrentFile();
+
+ if(mCurrentDir.getParentId() == 0){
+ ActionBar actionBar = getSupportActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(false);
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ // responsability of restore is prefered in onCreate() before than in onRestoreInstanceState when there are Fragments involved
+ Log.i(getClass().toString(), "onSaveInstanceState() start");
+ super.onSaveInstanceState(outState);
+ if(mDirectories != null && mDirectories.getCount() != 0){
+ mDirs = new String[mDirectories.getCount()-1];
+ for (int j = mDirectories.getCount() - 2, i = 0; j >= 0; --j, ++i) {
+ mDirs[i] = mDirectories.getItem(j);
+ }
+ }
+ outState.putStringArray(KEY_DIR_ARRAY, mDirs);
+ outState.putParcelable(FileDetailFragment.EXTRA_FILE, mCurrentDir);
+ Log.i(getClass().toString(), "onSaveInstanceState() end");
+ }
+
+ @Override
+ protected void onResume() {
+ Log.i(getClass().toString(), "onResume() start");
+ super.onResume();
+
+ if (AccountUtils.accountsAreSetup(this)) {
+ // at least an account exist: normal operation
+
+ // set the layout only if it couldn't be set in onCreate
+ if (mForcedLoginToCreateFirstAccount) {
+ initDelayedTilAccountAvailabe();
+ mForcedLoginToCreateFirstAccount = false;
+ }
+
+ // Listen for sync messages
+ IntentFilter syncIntentFilter = new IntentFilter(FileSyncService.SYNC_MESSAGE);
+ mSyncBroadcastReceiver = new SyncBroadcastReceiver();
+ registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
+
+ // Listen for upload messages
+ IntentFilter uploadIntentFilter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
+ mUploadFinishReceiver = new UploadFinishReceiver();
+ registerReceiver(mUploadFinishReceiver, uploadIntentFilter);
+
+ // Listen for download messages
+ IntentFilter downloadIntentFilter = new IntentFilter(FileDownloader.DOWNLOAD_FINISH_MESSAGE);
+ mDownloadFinishReceiver = new DownloadFinishReceiver();
+ registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);
+
+ // Storage manager initialization
+ mStorageManager = new FileDataStorageManager(
+ AccountUtils.getCurrentOwnCloudAccount(this),
+ getContentResolver());
+
+ // File list fragments
+ mFileList = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
+
+
+ // Figure out what directory to list.
+ // Priority: Intent (here), savedInstanceState (onCreate), root dir (dir is null)
+ if(getIntent().hasExtra(FileDetailFragment.EXTRA_FILE)){
+ mCurrentDir = (OCFile) getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);
+ if(mCurrentDir != null && !mCurrentDir.isDirectory()){
+ mCurrentDir = mStorageManager.getFileById(mCurrentDir.getParentId());
+ }
+
+ // Clear intent extra, so rotating the screen will not return us to this directory
+ getIntent().removeExtra(FileDetailFragment.EXTRA_FILE);
+ }
+
+ if (mCurrentDir == null)
+ mCurrentDir = mStorageManager.getFileByPath("/");
+
+ // Drop-Down navigation and file list restore
+ mDirectories = new CustomArrayAdapter(this, R.layout.sherlock_spinner_dropdown_item);
+
+
+ // Given the case we have a file to display:
+ if(mCurrentDir != null){
+ ArrayList files = new ArrayList();
+ OCFile currFile = mCurrentDir;
+ while(currFile != null){
+ files.add(currFile);
+ currFile = mStorageManager.getFileById(currFile.getParentId());
+ }
+
+ // Insert in mDirs
+ mDirs = new String[files.size()];
+ for(int i = files.size() - 1; i >= 0; i--){
+ mDirs[i] = files.get(i).getFileName();
+ }
+ }
+
+ if (mDirs != null) {
+ for (String s : mDirs)
+ mDirectories.add(s);
+ } else {
+ mDirectories.add(OCFile.PATH_SEPARATOR);
+ }
+
+ // Actionbar setup
+ ActionBar action_bar = getSupportActionBar();
+ action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
+ action_bar.setDisplayShowTitleEnabled(false);
+ action_bar.setListNavigationCallbacks(mDirectories, this);
+ if(mCurrentDir != null && mCurrentDir.getParentId() != 0){
+ action_bar.setDisplayHomeAsUpEnabled(true);
+ } else {
+ action_bar.setDisplayHomeAsUpEnabled(false);
+ }
+
+ // List dir here
+ mFileList.listDirectory(mCurrentDir);
+ }
+ Log.i(getClass().toString(), "onResume() end");
+ }
+
+ @Override
+ protected void onPause() {
+ Log.i(getClass().toString(), "onPause() start");
+ super.onPause();
+ if (mSyncBroadcastReceiver != null) {
+ unregisterReceiver(mSyncBroadcastReceiver);
+ mSyncBroadcastReceiver = null;
+ }
+ if (mUploadFinishReceiver != null) {
+ unregisterReceiver(mUploadFinishReceiver);
+ mUploadFinishReceiver = null;
+ }
+ if (mDownloadFinishReceiver != null) {
+ unregisterReceiver(mDownloadFinishReceiver);
+ mDownloadFinishReceiver = null;
+ }
+
+ getIntent().putExtra(FileDetailFragment.EXTRA_FILE, mCurrentDir);
+ Log.i(getClass().toString(), "onPause() end");
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int id) {
+ Dialog dialog = null;
+ AlertDialog.Builder builder;
+ switch (id) {
+ case DIALOG_SETUP_ACCOUNT:
+ builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.main_tit_accsetup);
+ builder.setMessage(R.string.main_wrn_accsetup);
+ builder.setCancelable(false);
+ builder.setPositiveButton(android.R.string.ok, this);
+ builder.setNegativeButton(android.R.string.cancel, this);
+ dialog = builder.create();
+ break;
+ case DIALOG_ABOUT_APP: {
+ builder = new AlertDialog.Builder(this);
+ builder.setTitle(getString(R.string.about_title));
+ PackageInfo pkg;
+ try {
+ pkg = getPackageManager().getPackageInfo(getPackageName(), 0);
+ builder.setMessage("ownCloud android client\n\nversion: " + pkg.versionName );
+ builder.setIcon(android.R.drawable.ic_menu_info_details);
+ dialog = builder.create();
+ } catch (NameNotFoundException e) {
+ builder = null;
+ dialog = null;
+ Log.e(TAG, "Error while showing about dialog", e);
+ }
+ break;
+ }
+ case DIALOG_CREATE_DIR: {
+ builder = new Builder(this);
+ final EditText dirNameInput = new EditText(getBaseContext());
+ final Account a = AccountUtils.getCurrentOwnCloudAccount(this);
+ builder.setView(dirNameInput);
+ builder.setTitle(R.string.uploader_info_dirname);
+ int typed_color = getResources().getColor(R.color.setup_text_typed);
+ dirNameInput.setTextColor(typed_color);
+ builder.setPositiveButton(android.R.string.ok,
+ new OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ String directoryName = dirNameInput.getText().toString();
+ if (directoryName.trim().length() == 0) {
+ dialog.cancel();
+ return;
+ }
+
+ // Figure out the path where the dir needs to be created
+ String path;
+ if (mCurrentDir == null) {
+ // this is just a patch; we should ensure that mCurrentDir never is null
+ if (!mStorageManager.fileExists(OCFile.PATH_SEPARATOR)) {
+ OCFile file = new OCFile(OCFile.PATH_SEPARATOR);
+ mStorageManager.saveFile(file);
+ }
+ mCurrentDir = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);
+ }
+ path = FileDisplayActivity.this.mCurrentDir.getRemotePath();
+
+ // Create directory
+ path += directoryName + OCFile.PATH_SEPARATOR;
+ Thread thread = new Thread(new DirectoryCreator(path, a, new Handler()));
+ thread.start();
+
+ dialog.dismiss();
+
+ showDialog(DIALOG_SHORT_WAIT);
+ }
+ });
+ builder.setNegativeButton(R.string.common_cancel,
+ new OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+ dialog = builder.create();
+ break;
+ }
+ case DIALOG_SHORT_WAIT: {
+ ProgressDialog working_dialog = new ProgressDialog(this);
+ working_dialog.setMessage(getResources().getString(
+ R.string.wait_a_moment));
+ working_dialog.setIndeterminate(true);
+ working_dialog.setCancelable(false);
+ dialog = working_dialog;
+ break;
+ }
+ default:
+ dialog = null;
+ }
+
+ return dialog;
+ }
+
+
+ /**
+ * Responds to the "There are no ownCloud Accounts setup" dialog
+ * TODO: Dialog is 100% useless -> Remove
+ */
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // In any case - we won't need it anymore
+ dialog.dismiss();
+ switch (which) {
+ case DialogInterface.BUTTON_POSITIVE:
+ Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
+ intent.putExtra("authorities",
+ new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
+ startActivity(intent);
+ break;
+ case DialogInterface.BUTTON_NEGATIVE:
+ finish();
+ }
+
+ }
+
+ /**
+ * Translates a content URI of an image to a physical path
+ * on the disk
+ * @param uri The URI to resolve
+ * @return The path to the image or null if it could not be found
+ */
+ public String getPath(Uri uri) {
+ String[] projection = { MediaStore.Images.Media.DATA };
+ Cursor cursor = managedQuery(uri, projection, null, null, null);
+ if (cursor != null) {
+ int column_index = cursor
+ .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
+ cursor.moveToFirst();
+ return cursor.getString(column_index);
+ }
+ return null;
+ }
+
+ /**
+ * Pushes a directory to the drop down list
+ * @param directory to push
+ * @throws IllegalArgumentException If the {@link OCFile#isDirectory()} returns false.
+ */
+ public void pushDirname(OCFile directory) {
+ if(!directory.isDirectory()){
+ throw new IllegalArgumentException("Only directories may be pushed!");
+ }
+ mDirectories.insert(directory.getFileName(), 0);
+ mCurrentDir = directory;
+ }
+
+ /**
+ * Pops a directory name from the drop down list
+ * @return True, unless the stack is empty
+ */
+ public boolean popDirname() {
+ mDirectories.remove(mDirectories.getItem(0));
+ return !mDirectories.isEmpty();
+ }
+
+ private class DirectoryCreator implements Runnable {
+ private String mTargetPath;
+ private Account mAccount;
+ private AccountManager mAm;
+ private Handler mHandler;
+
+ public DirectoryCreator(String targetPath, Account account, Handler handler) {
+ mTargetPath = targetPath;
+ mAccount = account;
+ mAm = (AccountManager) getSystemService(ACCOUNT_SERVICE);
+ mHandler = handler;
+ }
+
+ @Override
+ public void run() {
+ WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());
+
+ String username = mAccount.name.substring(0,
+ mAccount.name.lastIndexOf('@'));
+ String password = mAm.getPassword(mAccount);
+
+ wdc.setCredentials(username, password);
+ wdc.allowSelfsignedCertificates();
+ boolean created = wdc.createDirectory(mTargetPath);
+ if (created) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ dismissDialog(DIALOG_SHORT_WAIT);
+
+ // Save new directory in local database
+ OCFile newDir = new OCFile(mTargetPath);
+ newDir.setMimetype("DIR");
+ newDir.setParentId(mCurrentDir.getFileId());
+ mStorageManager.saveFile(newDir);
+
+ // Display the new folder right away
+ mFileList.listDirectory(mCurrentDir);
+ }
+ });
+
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ dismissDialog(DIALOG_SHORT_WAIT);
+ try {
+ Toast msg = Toast.makeText(FileDisplayActivity.this, R.string.create_dir_fail_msg, Toast.LENGTH_LONG);
+ msg.show();
+
+ } catch (NotFoundException e) {
+ Log.e(TAG, "Error while trying to show fail message " , e);
+ }
+ }
+ });
+ }
+ }
+
+ }
+
+ // Custom array adapter to override text colors
+ private class CustomArrayAdapter extends ArrayAdapter {
+
+ public CustomArrayAdapter(FileDisplayActivity ctx, int view) {
+ super(ctx, view);
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v = super.getView(position, convertView, parent);
+
+ ((TextView) v).setTextColor(getResources().getColorStateList(
+ android.R.color.white));
+ return v;
+ }
+
+ public View getDropDownView(int position, View convertView,
+ ViewGroup parent) {
+ View v = super.getDropDownView(position, convertView, parent);
+
+ ((TextView) v).setTextColor(getResources().getColorStateList(
+ android.R.color.white));
+
+ return v;
+ }
+
+ }
+
+ private class SyncBroadcastReceiver extends BroadcastReceiver {
+ /**
+ * {@link BroadcastReceiver} to enable syncing feedback in UI
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ boolean inProgress = intent.getBooleanExtra(
+ FileSyncService.IN_PROGRESS, false);
+ String accountName = intent
+ .getStringExtra(FileSyncService.ACCOUNT_NAME);
+
+ Log.d("FileDisplay", "sync of account " + accountName
+ + " is in_progress: " + inProgress);
+
+ if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name)) {
+
+ String synchFolderRemotePath = intent.getStringExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH);
+
+ boolean fillBlankRoot = false;
+ if (mCurrentDir == null) {
+ mCurrentDir = mStorageManager.getFileByPath("/");
+ fillBlankRoot = (mCurrentDir != null);
+ }
+
+ if ((synchFolderRemotePath != null && mCurrentDir != null && (mCurrentDir.getRemotePath().equals(synchFolderRemotePath)))
+ || fillBlankRoot ) {
+ if (!fillBlankRoot)
+ mCurrentDir = getStorageManager().getFileByPath(synchFolderRemotePath);
+ FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.fileList);
+ if (fileListFragment != null) {
+ fileListFragment.listDirectory(mCurrentDir);
+ }
+ }
+
+ setSupportProgressBarIndeterminateVisibility(inProgress);
+
+ }
+ }
+ }
+
+
+ private class UploadFinishReceiver extends BroadcastReceiver {
+ /**
+ * Once the file upload has finished -> update view
+ * @author David A. Velasco
+ * {@link BroadcastReceiver} to enable upload feedback in UI
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ long parentDirId = intent.getLongExtra(FileUploader.EXTRA_PARENT_DIR_ID, -1);
+ OCFile parentDir = mStorageManager.getFileById(parentDirId);
+ String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);
+
+ if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name) &&
+ parentDir != null &&
+ ( (mCurrentDir == null && parentDir.getFileName().equals("/")) ||
+ parentDir.equals(mCurrentDir)
+ )
+ ) {
+ FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
+ if (fileListFragment != null) {
+ fileListFragment.listDirectory();
+ }
+ }
+ }
+
+ }
+
+
+ /**
+ * Once the file download has finished -> update view
+ */
+ private class DownloadFinishReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
+ String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);
+
+ if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name) &&
+ mCurrentDir != null && mCurrentDir.getFileId() == mStorageManager.getFileByPath(downloadedRemotePath).getParentId()) {
+ FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
+ if (fileListFragment != null) {
+ fileListFragment.listDirectory();
+ }
+ }
+ }
+ }
+
+
+ @Override
+ public void onClick(View v) {
+ if (v.getId() == R.id.setup_account) {
+ Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
+ intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
+ startActivity(intent);
+ mForcedLoginToCreateFirstAccount = true;
+ }
+ }
+
+
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public DataStorageManager getStorageManager() {
+ return mStorageManager;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onDirectoryClick(OCFile directory) {
+ pushDirname(directory);
+ ActionBar actionBar = getSupportActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+
+ if (mDualPane) {
+ // Resets the FileDetailsFragment on Tablets so that it always displays
+ FileDetailFragment fileDetails = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
+ if (fileDetails != null) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ transaction.remove(fileDetails);
+ transaction.add(R.id.file_details_container, new FileDetailFragment(null, null));
+ transaction.commit();
+ }
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onFileClick(OCFile file) {
+
+ // If we are on a large device -> update fragment
+ if (mDualPane) {
+ // buttons in the details view are problematic when trying to reuse an existing fragment; create always a new one solves some of them, BUT no all; downloads are 'dangerous'
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ transaction.replace(R.id.file_details_container, new FileDetailFragment(file, AccountUtils.getCurrentOwnCloudAccount(this)), FileDetailFragment.FTAG);
+ transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
+ transaction.commit();
+
+ } else { // small or medium screen device -> new Activity
+ Intent showDetailsIntent = new Intent(this, FileDetailActivity.class);
+ showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, file);
+ showDetailsIntent.putExtra(FileDownloader.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
+ startActivity(showDetailsIntent);
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onFileStateChanged() {
+ FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
+ if (fileListFragment != null) {
+ fileListFragment.listDirectory();
+ }
+ }
+
+
+ /**
+ * Operations in this method should be preferably performed in onCreate to have a lighter onResume method.
+ *
+ * But we need to delay them to onResume for the first start of the application, when no account exists and the login activity must be shown; and
+ * put instead the ugly view that shows the 'Setup' button to restart the login activity.
+ *
+ * In other way, if the users cancels or presses BACK in the login page that first time (users can be cruel sometimes) would show a blank view (the
+ * FragmentList view empty).
+ *
+ * This is temporal, until we found out how to get a result in this activity after launching the ADD_ACCOUNT Intent with startActivityForResult (not trivial)
+ */
+ private void initDelayedTilAccountAvailabe() {
+ setContentView(mLayoutView);
+ mDualPane = (findViewById(R.id.file_details_container) != null);
+ if (mDualPane && getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG) == null) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment
+ transaction.commit();
+ }
+ setSupportProgressBarIndeterminateVisibility(false);
+ }
+
+
+ /**
+ * Launch an intent to request the PIN code to the user before letting him use the app
+ */
+ private void requestPinCode() {
+ boolean pinStart = false;
+ SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+ pinStart = appPrefs.getBoolean("set_pincode", false);
+ if (pinStart) {
+ Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);
+ i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "FileDisplayActivity");
+ startActivity(i);
+ }
+ }
+
+
+}
diff --git a/src/com/owncloud/android/ui/activity/LandingActivity.java b/src/com/owncloud/android/ui/activity/LandingActivity.java
new file mode 100644
index 00000000..ce7ff2f6
--- /dev/null
+++ b/src/com/owncloud/android/ui/activity/LandingActivity.java
@@ -0,0 +1,158 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.ui.activity;
+
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.ui.adapter.LandingScreenAdapter;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.GridView;
+import android.widget.Toast;
+import com.owncloud.android.R;
+
+/**
+ * This activity is used as a landing page when the user first opens this app.
+ *
+ * @author Lennart Rosam
+ *
+ */
+public class LandingActivity extends SherlockFragmentActivity implements
+ OnClickListener, OnItemClickListener {
+
+ public static final int DIALOG_SETUP_ACCOUNT = 1;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ // Fill the grid view of the landing screen with icons
+ GridView landingScreenItems = (GridView) findViewById(R.id.homeScreenGrid);
+ landingScreenItems.setAdapter(new LandingScreenAdapter(this));
+ landingScreenItems.setOnItemClickListener(this);
+
+ // Check, if there are ownCloud accounts
+ if (!accountsAreSetup()) {
+ showDialog(DIALOG_SETUP_ACCOUNT);
+ } else {
+ // Start device tracking service
+ Intent locationServiceIntent = new Intent();
+ locationServiceIntent
+ .setAction("eu.alefzero.owncloud.location.LocationLauncher");
+ sendBroadcast(locationServiceIntent);
+ }
+
+ }
+
+ @Override
+ protected void onRestart() {
+ super.onRestart();
+ // Check, if there are ownCloud accounts
+ if (!accountsAreSetup()) {
+ showDialog(DIALOG_SETUP_ACCOUNT);
+ }
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ // Check, if there are ownCloud accounts
+ if (!accountsAreSetup()) {
+ showDialog(DIALOG_SETUP_ACCOUNT);
+ }
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int id) {
+ Dialog dialog;
+ switch (id) {
+ case DIALOG_SETUP_ACCOUNT:
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.main_tit_accsetup);
+ builder.setMessage(R.string.main_wrn_accsetup);
+ builder.setCancelable(false);
+ builder.setPositiveButton(R.string.common_ok, this);
+ builder.setNegativeButton(R.string.common_cancel, this);
+ dialog = builder.create();
+ break;
+ default:
+ dialog = null;
+ }
+
+ return dialog;
+ }
+
+ public void onClick(DialogInterface dialog, int which) {
+ // In any case - we won't need it anymore
+ dialog.dismiss();
+ switch (which) {
+ case DialogInterface.BUTTON_POSITIVE:
+ Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
+ intent.putExtra("authorities",
+ new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
+ startActivity(intent);
+ break;
+ case DialogInterface.BUTTON_NEGATIVE:
+ finish();
+ }
+
+ }
+
+ @Override
+ /**
+ * Start an activity based on the selection
+ * the user made
+ */
+ public void onItemClick(AdapterView> parent, View view, int position,
+ long id) {
+ Intent intent;
+ intent = (Intent) parent.getAdapter().getItem(position);
+ if (intent != null) {
+ startActivity(intent);
+ } else {
+ // TODO: Implement all of this and make this text go away ;-)
+ Toast toast = Toast.makeText(this, "Not yet implemented!",
+ Toast.LENGTH_SHORT);
+ toast.show();
+ }
+ }
+
+ /**
+ * Checks, whether or not there are any ownCloud accounts setup.
+ *
+ * @return true, if there is at least one account.
+ */
+ private boolean accountsAreSetup() {
+ AccountManager accMan = AccountManager.get(this);
+ Account[] accounts = accMan
+ .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
+ return accounts.length > 0;
+ }
+
+}
diff --git a/src/com/owncloud/android/ui/activity/PinCodeActivity.java b/src/com/owncloud/android/ui/activity/PinCodeActivity.java
new file mode 100644
index 00000000..fc3926d2
--- /dev/null
+++ b/src/com/owncloud/android/ui/activity/PinCodeActivity.java
@@ -0,0 +1,652 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.ui.activity;
+
+import java.util.Arrays;
+
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+
+import com.owncloud.android.R;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.PreferenceManager;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.text.method.PasswordTransformationMethod;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnFocusChangeListener;
+import android.view.View.OnKeyListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+
+public class PinCodeActivity extends SherlockFragmentActivity {
+
+
+ public final static String EXTRA_ACTIVITY = "eu.alefzero.owncloud.ui.activity.PinCodeActivity.ACTIVITY";
+ public final static String EXTRA_NEW_STATE = "eu.alefzero.owncloud.ui.activity.PinCodeActivity.NEW_STATE";
+
+ Button bCancel;
+ TextView mPinHdr;
+ EditText mText1;
+ EditText mText2;
+ EditText mText3;
+ EditText mText4;
+
+ String [] tempText ={"","","",""};
+
+ String activity;
+
+ boolean confirmingPinCode = false;
+ boolean pinCodeChecked = false;
+ boolean newPasswordEntered = false;
+ boolean bChange = true; // to control that only one blocks jump
+ int tCounter ; // Count the number of attempts an user could introduce the PIN code
+
+
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.pincodelock);
+
+ Intent intent = getIntent();
+ activity = intent.getStringExtra(EXTRA_ACTIVITY);
+
+ bCancel = (Button) findViewById(R.id.cancel);
+ mPinHdr = (TextView) findViewById(R.id.pinHdr);
+ mText1 = (EditText) findViewById(R.id.txt1);
+ mText1.requestFocus();
+ getWindow().setSoftInputMode(android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+ mText2 = (EditText) findViewById(R.id.txt2);
+ mText3 = (EditText) findViewById(R.id.txt3);
+ mText4 = (EditText) findViewById(R.id.txt4);
+
+
+
+ SharedPreferences appPrefs = PreferenceManager
+ .getDefaultSharedPreferences(getApplicationContext());
+
+
+ // Not PIN Code defined yet.
+ // In a previous version settings is allow from start
+ if ( (appPrefs.getString("PrefPinCode1", null) == null ) ){
+ setChangePincodeView(true);
+ pinCodeChecked = true;
+ newPasswordEntered = true;
+
+ }else{
+
+ if (appPrefs.getBoolean("set_pincode", false)){
+ // pincode activated
+ if (activity.equals("preferences")){
+ // PIN has been activated yet
+ mPinHdr.setText(R.string.pincode_configure_your_pin);
+ pinCodeChecked = true ; // No need to check it
+ setChangePincodeView(true);
+ }else{
+ // PIN active
+ bCancel.setVisibility(View.INVISIBLE);
+ bCancel.setVisibility(View.GONE);
+ mPinHdr.setText(R.string.pincode_enter_pin_code);
+ setChangePincodeView(false);
+ }
+
+ }else {
+ // pincode removal
+ mPinHdr.setText(R.string.pincode_remove_your_pincode);
+ pinCodeChecked = false;
+ setChangePincodeView(true);
+ }
+
+ }
+ setTextListeners();
+
+
+ }
+
+
+
+ protected void setInitVars(){
+ confirmingPinCode = false;
+ pinCodeChecked = false;
+ newPasswordEntered = false;
+
+ }
+
+ protected void setInitView(){
+ bCancel.setVisibility(View.INVISIBLE);
+ bCancel.setVisibility(View.GONE);
+ mPinHdr.setText(R.string.pincode_enter_pin_code);
+ }
+
+
+ protected void setChangePincodeView(boolean state){
+
+ if(state){
+ bCancel.setVisibility(View.VISIBLE);
+ bCancel.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+
+ SharedPreferences.Editor appPrefsE = PreferenceManager
+ .getDefaultSharedPreferences(getApplicationContext()).edit();
+
+ SharedPreferences appPrefs = PreferenceManager
+ .getDefaultSharedPreferences(getApplicationContext());
+
+ boolean state = appPrefs.getBoolean("set_pincode", false);
+ appPrefsE.putBoolean("set_pincode",!state);
+ appPrefsE.commit();
+ setInitVars();
+ finish();
+ }
+ });
+ }
+
+ }
+
+
+
+ /*
+ *
+ */
+ protected void setTextListeners(){
+
+ /*------------------------------------------------
+ * FIRST BOX
+ -------------------------------------------------*/
+
+ mText1.addTextChangedListener(new TextWatcher() {
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before,
+ int count) {
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count,
+ int after) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (s.length() > 0) {
+ if (!confirmingPinCode){
+ tempText[0] = mText1.getText().toString();
+
+ }
+ mText2.requestFocus();
+ }
+ }
+ });
+
+
+
+ /*------------------------------------------------
+ * SECOND BOX
+ -------------------------------------------------*/
+ mText2.addTextChangedListener(new TextWatcher() {
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before,
+ int count) {
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count,
+ int after) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (s.length() > 0) {
+ if (!confirmingPinCode){
+ tempText[1] = mText2.getText().toString();
+ }
+
+ mText3.requestFocus();
+ }
+ }
+ });
+
+ mText2.setOnKeyListener(new OnKeyListener() {
+
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ // TODO Auto-generated method stub
+
+ if (keyCode == KeyEvent.KEYCODE_DEL && bChange) {
+
+ mText1.setText("");
+ mText1.requestFocus();
+ if (!confirmingPinCode)
+ tempText[0] = "";
+ bChange= false;
+
+ }else if(!bChange){
+ bChange=true;
+
+ }
+ return false;
+ }
+ });
+
+ mText2.setOnFocusChangeListener(new OnFocusChangeListener() {
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ // TODO Auto-generated method stub
+
+ mText2.setCursorVisible(true);
+ if (mText1.getText().toString().equals("")){
+ mText2.setSelected(false);
+ mText2.setCursorVisible(false);
+ mText1.requestFocus();
+ mText1.setSelected(true);
+ mText1.setSelection(0);
+ }
+
+ }
+ });
+
+
+ /*------------------------------------------------
+ * THIRD BOX
+ -------------------------------------------------*/
+ mText3.addTextChangedListener(new TextWatcher() {
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before,
+ int count) {
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count,
+ int after) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (s.length() > 0) {
+ if (!confirmingPinCode){
+ tempText[2] = mText3.getText().toString();
+ }
+ mText4.requestFocus();
+ }
+ }
+ });
+
+ mText3.setOnKeyListener(new OnKeyListener() {
+
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ // TODO Auto-generated method stub
+
+ if (keyCode == KeyEvent.KEYCODE_DEL && bChange) {
+ mText2.requestFocus();
+ if (!confirmingPinCode)
+ tempText[1] = "";
+ mText2.setText("");
+ bChange= false;
+
+ }else if(!bChange){
+ bChange=true;
+
+ }
+ return false;
+ }
+ });
+
+ mText3.setOnFocusChangeListener(new OnFocusChangeListener() {
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ // TODO Auto-generated method stub
+ mText3.setCursorVisible(true);
+ if (mText1.getText().toString().equals("")){
+ mText3.setSelected(false);
+ mText3.setCursorVisible(false);
+ mText1.requestFocus();
+ mText1.setSelected(true);
+ mText1.setSelection(0);
+ }else if (mText2.getText().toString().equals("")){
+ mText3.setSelected(false);
+ mText3.setCursorVisible(false);
+ mText2.requestFocus();
+ mText2.setSelected(true);
+ mText2.setSelection(0);
+ }
+
+ }
+ });
+
+ /*------------------------------------------------
+ * FOURTH BOX
+ -------------------------------------------------*/
+ mText4.addTextChangedListener(new TextWatcher() {
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before,
+ int count) {
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count,
+ int after) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (s.length() > 0) {
+
+ if (!confirmingPinCode){
+ tempText[3] = mText4.getText().toString();
+ }
+ mText1.requestFocus();
+
+ if (!pinCodeChecked){
+ pinCodeChecked = checkPincode();
+ }
+
+ if (pinCodeChecked && activity.equals("FileDisplayActivity")){
+ finish();
+ } else if (pinCodeChecked){
+
+ Intent intent = getIntent();
+ String newState = intent.getStringExtra(EXTRA_NEW_STATE);
+
+ if (newState.equals("false")){
+ SharedPreferences.Editor appPrefs = PreferenceManager
+ .getDefaultSharedPreferences(getApplicationContext()).edit();
+ appPrefs.putBoolean("set_pincode",false);
+ appPrefs.commit();
+
+ setInitVars();
+ pinCodeEnd(false);
+
+ }else{
+
+ if (!confirmingPinCode){
+ pinCodeChangeRequest();
+
+ } else {
+ confirmPincode();
+ }
+ }
+
+
+ }
+ }
+ }
+ });
+
+
+
+ mText4.setOnKeyListener(new OnKeyListener() {
+
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ // TODO Auto-generated method stub
+
+ if (keyCode == KeyEvent.KEYCODE_DEL && bChange) {
+ mText3.requestFocus();
+ if (!confirmingPinCode)
+ tempText[2]="";
+ mText3.setText("");
+ bChange= false;
+
+ }else if(!bChange){
+ bChange=true;
+ }
+ return false;
+ }
+ });
+
+ mText4.setOnFocusChangeListener(new OnFocusChangeListener() {
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ // TODO Auto-generated method stub
+
+ mText4.setCursorVisible(true);
+
+ if (mText1.getText().toString().equals("")){
+ mText4.setSelected(false);
+ mText4.setCursorVisible(false);
+ mText1.requestFocus();
+ mText1.setSelected(true);
+ mText1.setSelection(0);
+ }else if (mText2.getText().toString().equals("")){
+ mText4.setSelected(false);
+ mText4.setCursorVisible(false);
+ mText2.requestFocus();
+ mText2.setSelected(true);
+ mText2.setSelection(0);
+ }else if (mText3.getText().toString().equals("")){
+ mText4.setSelected(false);
+ mText4.setCursorVisible(false);
+ mText3.requestFocus();
+ mText3.setSelected(true);
+ mText3.setSelection(0);
+ }
+
+ }
+ });
+
+
+
+ } // end setTextListener
+
+
+ protected void pinCodeChangeRequest(){
+
+ clearBoxes();
+ mPinHdr.setText(R.string.pincode_reenter_your_pincode);
+ confirmingPinCode =true;
+
+ }
+
+
+ protected boolean checkPincode(){
+
+
+ SharedPreferences appPrefs = PreferenceManager
+ .getDefaultSharedPreferences(getApplicationContext());
+
+ String pText1 = appPrefs.getString("PrefPinCode1", null);
+ String pText2 = appPrefs.getString("PrefPinCode2", null);
+ String pText3 = appPrefs.getString("PrefPinCode3", null);
+ String pText4 = appPrefs.getString("PrefPinCode4", null);
+
+ if ( tempText[0].equals(pText1) &&
+ tempText[1].equals(pText2) &&
+ tempText[2].equals(pText3) &&
+ tempText[3].equals(pText4) ) {
+
+ return true;
+
+
+ }else {
+ Arrays.fill(tempText, null);
+ AlertDialog aDialog = new AlertDialog.Builder(this).create();
+ CharSequence errorSeq = getString(R.string.common_error);
+ aDialog.setTitle(errorSeq);
+ CharSequence cseq = getString(R.string.pincode_wrong);
+ aDialog.setMessage(cseq);
+ CharSequence okSeq = getString(R.string.common_ok);
+ aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub("");
+ return;
+ }
+
+ });
+ aDialog.show();
+ clearBoxes();
+ mPinHdr.setText(R.string.pincode_enter_pin_code);
+ newPasswordEntered = true;
+ confirmingPinCode = false;
+
+ }
+
+
+ return false;
+ }
+
+ protected void confirmPincode(){
+
+ confirmingPinCode = false;
+
+ String rText1 = mText1.getText().toString();
+ String rText2 = mText2.getText().toString();
+ String rText3 = mText3.getText().toString();
+ String rText4 = mText4.getText().toString();
+
+ if ( tempText[0].equals(rText1) &&
+ tempText[1].equals(rText2) &&
+ tempText[2].equals(rText3) &&
+ tempText[3].equals(rText4) ) {
+
+ savePincodeAndExit();
+
+ } else {
+
+ Arrays.fill(tempText, null);
+ AlertDialog aDialog = new AlertDialog.Builder(this).create();
+ CharSequence errorSeq = getString(R.string.common_error);
+ aDialog.setTitle(errorSeq);
+ CharSequence cseq = getString(R.string.pincode_mismatch);
+ aDialog.setMessage(cseq);
+ CharSequence okSeq = getString(R.string.common_ok);
+ aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub("");
+ return;
+ }
+
+ });
+ aDialog.show();
+ mPinHdr.setText(R.string.pincode_configure_your_pin);
+ clearBoxes();
+ }
+
+ }
+
+
+ protected void pinCodeEnd(boolean state){
+ AlertDialog aDialog = new AlertDialog.Builder(this).create();
+
+ if (state){
+ CharSequence saveSeq = getString(R.string.common_save_exit);
+ aDialog.setTitle(saveSeq);
+ CharSequence cseq = getString(R.string.pincode_stored);
+ aDialog.setMessage(cseq);
+
+ }else{
+ CharSequence saveSeq = getString(R.string.common_save_exit);
+ aDialog.setTitle(saveSeq);
+ CharSequence cseq = getString(R.string.pincode_removed);
+ aDialog.setMessage(cseq);
+
+ }
+ CharSequence okSeq = getString(R.string.common_ok);
+ aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub("");
+ finish();
+ return;
+ }
+
+ });
+ aDialog.show();
+ }
+
+ protected void savePincodeAndExit(){
+ SharedPreferences.Editor appPrefs = PreferenceManager
+ .getDefaultSharedPreferences(getApplicationContext()).edit();
+
+ appPrefs.putString("PrefPinCode1", tempText[0]);
+ appPrefs.putString("PrefPinCode2",tempText[1]);
+ appPrefs.putString("PrefPinCode3", tempText[2]);
+ appPrefs.putString("PrefPinCode4", tempText[3]);
+ appPrefs.putBoolean("set_pincode",true);
+ appPrefs.commit();
+
+ pinCodeEnd(true);
+
+
+
+ }
+
+
+ protected void clearBoxes(){
+
+ mText1.setText("");
+ mText2.setText("");
+ mText3.setText("");
+ mText4.setText("");
+ mText1.requestFocus();
+ }
+
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event){
+ if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount()== 0){
+
+ if (activity.equals("preferences")){
+ SharedPreferences.Editor appPrefsE = PreferenceManager
+
+ .getDefaultSharedPreferences(getApplicationContext()).edit();
+
+ SharedPreferences appPrefs = PreferenceManager
+ .getDefaultSharedPreferences(getApplicationContext());
+
+ boolean state = appPrefs.getBoolean("set_pincode", false);
+ appPrefsE.putBoolean("set_pincode",!state);
+ appPrefsE.commit();
+ setInitVars();
+ finish();
+ }
+ return true;
+
+ }
+
+ return super.onKeyDown(keyCode, event);
+ }
+
+
+
+
+
+}
diff --git a/src/com/owncloud/android/ui/activity/Preferences.java b/src/com/owncloud/android/ui/activity/Preferences.java
new file mode 100644
index 00000000..7b23856d
--- /dev/null
+++ b/src/com/owncloud/android/ui/activity/Preferences.java
@@ -0,0 +1,240 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.ui.activity;
+
+import java.util.Vector;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceManager;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.util.Log;
+
+import com.actionbarsherlock.app.ActionBar;
+import com.actionbarsherlock.app.SherlockPreferenceActivity;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuItem;
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.OwnCloudSession;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.db.DbHandler;
+
+import com.owncloud.android.R;
+
+/**
+ * An Activity that allows the user to change the application's settings.
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class Preferences extends SherlockPreferenceActivity implements
+ OnPreferenceChangeListener{
+ private static final String TAG = "OwnCloudPreferences";
+ private final int mNewSession = 47;
+ private final int mEditSession = 48;
+ private DbHandler mDbHandler;
+ private Vector mSessions;
+ //private Account[] mAccounts;
+ //private ListPreference mAccountList;
+ private ListPreference mTrackingUpdateInterval;
+ private CheckBoxPreference mDeviceTracking;
+ private CheckBoxPreference pCode;
+ private int mSelectedMenuItem;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mDbHandler = new DbHandler(getBaseContext());
+ mSessions = new Vector();
+ addPreferencesFromResource(R.xml.preferences);
+ //populateAccountList();
+ ActionBar actionBar = getSherlock().getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ Preference p = findPreference("manage_account");
+ if (p != null)
+ p.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ Intent i = new Intent(getApplicationContext(), AccountSelectActivity.class);
+ startActivity(i);
+ return true;
+ }
+ });
+
+ pCode = (CheckBoxPreference) findPreference("set_pincode");
+
+
+ if (pCode != null){
+
+ pCode.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+
+ Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);
+ i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "preferences");
+ i.putExtra(PinCodeActivity.EXTRA_NEW_STATE, newValue.toString());
+
+ startActivity(i);
+
+ return true;
+ }
+ });
+
+ }
+
+ }
+
+
+ @Override
+ protected void onResume() {
+ // TODO Auto-generated method stub
+ SharedPreferences appPrefs = PreferenceManager
+ .getDefaultSharedPreferences(getApplicationContext());
+
+ boolean state = appPrefs.getBoolean("set_pincode", false);
+ pCode.setChecked(state);
+
+ super.onResume();
+ }
+
+
+
+ /**
+ * Populates the account selector
+ *-/
+ private void populateAccountList() {
+ AccountManager accMan = AccountManager.get(this);
+ mAccounts = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
+ mAccountList = (ListPreference) findPreference("select_oc_account");
+ mAccountList.setOnPreferenceChangeListener(this);
+
+ // Display the name of the current account if there is any
+ Account defaultAccount = AccountUtils.getCurrentOwnCloudAccount(this);
+ if (defaultAccount != null) {
+ mAccountList.setSummary(defaultAccount.name);
+ }
+
+ // Transform accounts into array of string for preferences to use
+ String[] accNames = new String[mAccounts.length];
+ for (int i = 0; i < mAccounts.length; i++) {
+ Account account = mAccounts[i];
+ accNames[i] = account.name;
+ }
+
+ mAccountList.setEntries(accNames);
+ mAccountList.setEntryValues(accNames);
+ }*/
+
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ //MenuInflater inflater = getSherlock().getMenuInflater();
+ //inflater.inflate(R.menu.prefs_menu, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onMenuItemSelected(int featureId, MenuItem item) {
+ super.onMenuItemSelected(featureId, item);
+ Intent intent;
+
+ switch (item.getItemId()) {
+ //case R.id.addSessionItem:
+ case 1:
+ intent = new Intent(this, PreferencesNewSession.class);
+ startActivityForResult(intent, mNewSession);
+ break;
+ case R.id.SessionContextEdit:
+ intent = new Intent(this, PreferencesNewSession.class);
+ intent.putExtra("sessionId", mSessions.get(mSelectedMenuItem)
+ .getEntryId());
+ intent.putExtra("sessionName", mSessions.get(mSelectedMenuItem)
+ .getName());
+ intent.putExtra("sessionURL", mSessions.get(mSelectedMenuItem)
+ .getUrl());
+ startActivityForResult(intent, mEditSession);
+ break;
+ case android.R.id.home:
+ intent = new Intent(getBaseContext(), FileDisplayActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(intent);
+ break;
+ default:
+ Log.w(TAG, "Unknown menu item triggered");
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ protected void onDestroy() {
+ mDbHandler.close();
+ super.onDestroy();
+ }
+
+
+
+ @Override
+ /**
+ * Updates various summaries after updates. Also starts and stops
+ * the
+ */
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ // Update current account summary
+ /*if (preference.equals(mAccountList)) {
+ mAccountList.setSummary(newValue.toString());
+ }
+
+ // Update tracking interval summary
+ else*/ if (preference.equals(mTrackingUpdateInterval)) {
+ String trackingSummary = getResources().getString(
+ R.string.prefs_trackmydevice_interval_summary);
+ trackingSummary = String.format(trackingSummary,
+ newValue.toString());
+ mTrackingUpdateInterval.setSummary(trackingSummary);
+ }
+
+ // Start or stop tracking service
+ else if (preference.equals(mDeviceTracking)) {
+ Intent locationServiceIntent = new Intent();
+ locationServiceIntent
+ .setAction("eu.alefzero.owncloud.location.LocationLauncher");
+ locationServiceIntent.putExtra("TRACKING_SETTING",
+ (Boolean) newValue);
+ sendBroadcast(locationServiceIntent);
+ }
+ return true;
+ }
+
+
+
+}
diff --git a/src/com/owncloud/android/ui/activity/PreferencesNewSession.java b/src/com/owncloud/android/ui/activity/PreferencesNewSession.java
new file mode 100644
index 00000000..3e9eb261
--- /dev/null
+++ b/src/com/owncloud/android/ui/activity/PreferencesNewSession.java
@@ -0,0 +1,98 @@
+package com.owncloud.android.ui.activity;
+
+import android.accounts.AccountAuthenticatorActivity;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+public class PreferencesNewSession extends AccountAuthenticatorActivity
+ implements OnClickListener {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // setContentView(R.layout.add_new_session);
+ /*
+ * EditText et;// = (EditText)
+ * findViewById(R.id.newSession_sessionName);
+ *
+ * et = (EditText) findViewById(R.id.newSession_URL); if
+ * (getIntent().hasExtra("sessionURL")) { try { URI uri = new
+ * URI(getIntent().getStringExtra("sessionURL")); String url =
+ * uri.getHost(); if (uri.getPort() != -1) { url += ":" +
+ * String.valueOf(uri.getPort()); } if (uri.getPath() != null) { url +=
+ * uri.getPath(); } else { url += "/"; } et.setText(url); et =
+ * (EditText) findViewById(R.id.newSession_username); if
+ * (uri.getAuthority() != null) { if (uri.getUserInfo().indexOf(':') !=
+ * -1) { et.setText(uri.getUserInfo().substring(0,
+ * uri.getUserInfo().indexOf(':'))); et = (EditText)
+ * findViewById(R.id.newSession_password);
+ * et.setText(uri.getUserInfo().substring
+ * (uri.getUserInfo().indexOf(':')+1)); } else {
+ * et.setText(uri.getUserInfo()); } }
+ *
+ * } catch (URISyntaxException e) { Log.e(TAG, "Incorrect URI syntax " +
+ * e.getLocalizedMessage()); } }
+ *
+ * mReturnData = new Intent(); setResult(Activity.RESULT_OK,
+ * mReturnData); ((Button)
+ * findViewById(R.id.button1)).setOnClickListener(this); ((Button)
+ * findViewById(R.id.button2)).setOnClickListener(this);
+ */
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ }
+
+ public void onClick(View v) {
+ /*
+ * switch (v.getId()) { case R.id.button1: Intent intent = new Intent();
+ * if (getIntent().hasExtra("sessionId")) { intent.putExtra("sessionId",
+ * getIntent().getIntExtra("sessionId", -1)); } //String sessionName =
+ * ((EditText)
+ * findViewById(R.id.newSession_sessionName)).getText().toString(); //
+ * if (sessionName.trim().equals("") || !isNameValid(sessionName)) { //
+ * Toast.makeText(this, R.string.new_session_session_name_error,
+ * Toast.LENGTH_LONG).show(); // break; // } URI uri = prepareURI(); if
+ * (uri != null) { //intent.putExtra("sessionName", sessionName);
+ * intent.putExtra("sessionURL", uri.toString());
+ * setResult(Activity.RESULT_OK, intent); AccountManager accMgr =
+ * AccountManager.get(this); Account a = new Account("OwnCloud",
+ * AccountAuthenticatorService.ACCOUNT_TYPE);
+ * accMgr.addAccountExplicitly(a, "asd", null); finish(); } break; case
+ * R.id.button2: setResult(Activity.RESULT_CANCELED); finish(); break; }
+ */
+ }
+
+ /*
+ * private URI prepareURI() { URI uri = null; String url = ""; try { String
+ * username = ((EditText)
+ * findViewById(R.id.newSession_username)).getText().toString().trim();
+ * String password = ((EditText)
+ * findViewById(R.id.newSession_password)).getText().toString().trim();
+ * String hostname = ((EditText)
+ * findViewById(R.id.newSession_URL)).getText().toString().trim(); String
+ * scheme; if (hostname.matches("[A-Za-z]://")) { scheme =
+ * hostname.substring(0, hostname.indexOf("://")+3); hostname =
+ * hostname.substring(hostname.indexOf("://")+3); } else { scheme =
+ * "http://"; } if (!username.equals("")) { if (!password.equals("")) {
+ * username += ":" + password + "@"; } else { username += "@"; } } url =
+ * scheme + username + hostname; Log.i(TAG, url); uri = new URI(url); }
+ * catch (URISyntaxException e) { Log.e(TAG, "Incorrect URI syntax " +
+ * e.getLocalizedMessage()); Toast.makeText(this,
+ * R.string.new_session_uri_error, Toast.LENGTH_LONG).show(); } return uri;
+ * }
+ *
+ * private boolean isNameValid(String string) { return
+ * string.matches("[A-Za-z0-9 _-]*"); }
+ */
+
+ @Override
+ public void onBackPressed() {
+ setResult(Activity.RESULT_CANCELED);
+ super.onBackPressed();
+ }
+
+}
diff --git a/src/com/owncloud/android/ui/adapter/FileListActionListAdapter.java b/src/com/owncloud/android/ui/adapter/FileListActionListAdapter.java
new file mode 100644
index 00000000..872b8132
--- /dev/null
+++ b/src/com/owncloud/android/ui/adapter/FileListActionListAdapter.java
@@ -0,0 +1,173 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.ui.adapter;
+
+import java.io.File;
+
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
+
+import com.owncloud.android.R;
+import eu.alefzero.webdav.WebdavUtils;
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+public class FileListActionListAdapter implements ListAdapter {
+
+ private Context mContext;
+ private Account mAccount;
+ private String mFilename, mFileType, mFilePath, mFileStoragePath;
+
+ private final int ITEM_DOWNLOAD = 0;
+
+ // private final int ITEM_SHARE = 1;
+
+ public FileListActionListAdapter(Cursor c, Context co, Account account) {
+ mContext = co;
+ mFilename = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_NAME));
+ mFileType = c.getString(c
+ .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE));
+ mFilePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PATH));
+ mFileStoragePath = c.getString(c
+ .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
+ // mItemId = c.getString(c.getColumnIndex(ProviderTableMeta._ID));
+ mAccount = account;
+ }
+
+ public boolean areAllItemsEnabled() {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ public boolean isEnabled(int position) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ public int getCount() {
+ // TODO Auto-generated method stub
+ return 1;
+ }
+
+ public Object getItem(int position) {
+ if (position == 0) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ if (TextUtils.isEmpty(mFileStoragePath)) {
+ intent.putExtra("toDownload", true);
+ AccountManager accm = (AccountManager) mContext
+ .getSystemService(Context.ACCOUNT_SERVICE);
+ String ocurl = accm.getUserData(mAccount,
+ AccountAuthenticator.KEY_OC_URL);
+ ocurl += WebdavUtils.encodePath(mFilePath + mFilename);
+ intent.setData(Uri.parse(ocurl));
+ } else {
+ intent.putExtra("toDownload", false);
+ intent.setDataAndType(Uri.fromFile(new File(mFileStoragePath)),
+ mFileType);
+ }
+ return intent;
+ }
+ return null;
+ }
+
+ public long getItemId(int position) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getItemViewType(int position) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = (LayoutInflater) mContext
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = vi.inflate(R.layout.file_display_action_list_element, null);
+ }
+
+ TextView tv;
+ ImageView iv;
+ switch (position) {
+ case ITEM_DOWNLOAD:
+ tv = (TextView) v.findViewById(R.id.textView1);
+ if (mFileStoragePath == null) {
+ tv.setText("Download");
+ } else {
+ setActionName(tv);
+ }
+ iv = (ImageView) v.findViewById(R.id.imageView1);
+ iv.setImageResource(R.drawable.download);
+ break;
+ }
+
+ return v;
+ }
+
+ public int getViewTypeCount() {
+ // TODO Auto-generated method stub
+ return 2;
+ }
+
+ public boolean hasStableIds() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isEmpty() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void registerDataSetObserver(DataSetObserver observer) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void unregisterDataSetObserver(DataSetObserver observer) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private void setActionName(TextView tv) {
+ if (mFileType.matches("image/.*")) {
+ tv.setText("View");
+ } else if (mFileType.matches("audio/.*")
+ || mFileType.matches("video/.*")) {
+ tv.setText("Play");
+ } else {
+ tv.setText("Open");
+ }
+ }
+
+}
diff --git a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java
new file mode 100644
index 00000000..ade2e5e4
--- /dev/null
+++ b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java
@@ -0,0 +1,202 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.ui.adapter;
+
+import java.util.Vector;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.DisplayUtils;
+import com.owncloud.android.datamodel.DataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.services.FileDownloader;
+import com.owncloud.android.files.services.FileUploader;
+
+import com.owncloud.android.R;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.database.DataSetObserver;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+/**
+ * This Adapter populates a ListView with all files and folders in an ownCloud
+ * instance.
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class FileListListAdapter implements ListAdapter {
+ private Context mContext;
+ private OCFile mFile;
+ private Vector mFiles;
+ private DataStorageManager mStorageManager;
+ private Account mAccount;
+
+ public FileListListAdapter(OCFile file, DataStorageManager storage_man,
+ Context context) {
+ mFile = file;
+ mStorageManager = storage_man;
+ mFiles = mStorageManager.getDirectoryContent(mFile);
+ mContext = context;
+ mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ @Override
+ public int getCount() {
+ return mFiles != null ? mFiles.size() : 0;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ if (mFiles.size() <= position)
+ return null;
+ return mFiles.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return mFiles != null ? mFiles.get(position).getFileId() : 0;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View view = convertView;
+ if (view == null) {
+ LayoutInflater inflator = (LayoutInflater) mContext
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ view = inflator.inflate(R.layout.list_layout, null);
+ }
+ if (mFiles.size() > position) {
+ OCFile file = mFiles.get(position);
+ TextView fileName = (TextView) view.findViewById(R.id.Filename);
+ String name = file.getFileName();
+
+ fileName.setText(name);
+ ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);
+ if (file.getMimetype() == null || !file.getMimetype().equals("DIR")) {
+ fileIcon.setImageResource(R.drawable.file);
+ } else {
+ fileIcon.setImageResource(R.drawable.ic_menu_archive);
+ }
+ ImageView localStateView = (ImageView) view.findViewById(R.id.imageView2);
+ if (FileDownloader.isDownloading(mAccount, file.getRemotePath())) {
+ localStateView.setImageResource(R.drawable.downloading_file_indicator);
+ localStateView.setVisibility(View.VISIBLE);
+ } else if (FileUploader.isUploading(mAccount, file.getRemotePath())) {
+ localStateView.setImageResource(R.drawable.uploading_file_indicator);
+ localStateView.setVisibility(View.VISIBLE);
+ } else if (file.isDown()) {
+ localStateView.setImageResource(R.drawable.local_file_indicator);
+ localStateView.setVisibility(View.VISIBLE);
+ } else {
+ localStateView.setVisibility(View.INVISIBLE);
+ }
+ /*
+ ImageView down = (ImageView) view.findViewById(R.id.imageView2);
+ ImageView downloading = (ImageView) view.findViewById(R.id.imageView4);
+ ImageView uploading = (ImageView) view.findViewById(R.id.imageView5);
+ if (FileDownloader.isDownloading(mAccount, file.getRemotePath())) {
+ down.setVisibility(View.INVISIBLE);
+ downloading.setVisibility(View.VISIBLE);
+ uploading.setVisibility(View.INVISIBLE);
+ } else if (FileUploader.isUploading(mAccount, file.getRemotePath())) {
+ down.setVisibility(View.INVISIBLE);
+ downloading.setVisibility(View.INVISIBLE);
+ uploading.setVisibility(View.VISIBLE);
+ } else if (file.isDown()) {
+ down.setVisibility(View.VISIBLE);
+ downloading.setVisibility(View.INVISIBLE);
+ uploading.setVisibility(View.INVISIBLE);
+ } else {
+ down.setVisibility(View.INVISIBLE);
+ downloading.setVisibility(View.INVISIBLE);
+ uploading.setVisibility(View.INVISIBLE);
+ }*/
+
+ if (!file.isDirectory()) {
+ view.findViewById(R.id.file_size).setVisibility(View.VISIBLE);
+ view.findViewById(R.id.last_mod).setVisibility(View.VISIBLE);
+ ((TextView)view.findViewById(R.id.file_size)).setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));
+ ((TextView)view.findViewById(R.id.last_mod)).setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()));
+ // this if-else is needed even thoe fav icon is visible by default
+ // because android reuses views in listview
+ if (!file.keepInSync()) {
+ view.findViewById(R.id.imageView3).setVisibility(View.GONE);
+ } else {
+ view.findViewById(R.id.imageView3).setVisibility(View.VISIBLE);
+ }
+ } else {
+ view.findViewById(R.id.file_size).setVisibility(View.GONE);
+ view.findViewById(R.id.last_mod).setVisibility(View.GONE);
+ view.findViewById(R.id.imageView3).setVisibility(View.GONE);
+ }
+ }
+
+ return view;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 4;
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return mFiles != null ? mFiles.isEmpty() : false;
+ }
+
+ @Override
+ public void registerDataSetObserver(DataSetObserver observer) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void unregisterDataSetObserver(DataSetObserver observer) {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/src/com/owncloud/android/ui/adapter/LandingScreenAdapter.java b/src/com/owncloud/android/ui/adapter/LandingScreenAdapter.java
new file mode 100644
index 00000000..8bc56754
--- /dev/null
+++ b/src/com/owncloud/android/ui/adapter/LandingScreenAdapter.java
@@ -0,0 +1,112 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.ui.adapter;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.ui.activity.FileDisplayActivity;
+import com.owncloud.android.ui.activity.Preferences;
+
+import android.content.Context;
+import android.content.Intent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.owncloud.android.R;
+
+/**
+ * Populates the landing screen icons.
+ *
+ * @author Lennart Rosam
+ *
+ */
+public class LandingScreenAdapter extends BaseAdapter {
+
+ private Context mContext;
+
+ private final Integer[] mLandingScreenIcons = { R.drawable.home,
+ R.drawable.music, R.drawable.contacts, R.drawable.calendar,
+ android.R.drawable.ic_menu_agenda, R.drawable.settings };
+
+ private final Integer[] mLandingScreenTexts = { R.string.main_files,
+ R.string.main_music, R.string.main_contacts,
+ R.string.main_calendar, R.string.main_bookmarks,
+ R.string.main_settings };
+
+ public LandingScreenAdapter(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public int getCount() {
+ return mLandingScreenIcons.length;
+ }
+
+ @Override
+ /**
+ * Returns the Intent associated with this object
+ * or null if the functionality is not yet implemented
+ */
+ public Object getItem(int position) {
+ Intent intent = new Intent();
+
+ switch (position) {
+ case 0:
+ /*
+ * The FileDisplayActivity requires the ownCloud account as an
+ * parcableExtra. We will put in the one that is selected in the
+ * preferences
+ */
+ intent.setClass(mContext, FileDisplayActivity.class);
+ intent.putExtra("ACCOUNT",
+ AccountUtils.getCurrentOwnCloudAccount(mContext));
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ break;
+ case 5:
+ intent.setClass(mContext, Preferences.class);
+ break;
+ default:
+ intent = null;
+ }
+ return intent;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ LayoutInflater inflator = LayoutInflater.from(mContext);
+ convertView = inflator.inflate(R.layout.landing_page_item, null);
+
+ ImageView icon = (ImageView) convertView
+ .findViewById(R.id.gridImage);
+ TextView iconText = (TextView) convertView
+ .findViewById(R.id.gridText);
+
+ icon.setImageResource(mLandingScreenIcons[position]);
+ iconText.setText(mLandingScreenTexts[position]);
+ }
+ return convertView;
+ }
+}
diff --git a/src/com/owncloud/android/ui/fragment/AuthenticatorAccountDetailsFragment.java b/src/com/owncloud/android/ui/fragment/AuthenticatorAccountDetailsFragment.java
new file mode 100644
index 00000000..9517fcd3
--- /dev/null
+++ b/src/com/owncloud/android/ui/fragment/AuthenticatorAccountDetailsFragment.java
@@ -0,0 +1,7 @@
+package com.owncloud.android.ui.fragment;
+
+import com.actionbarsherlock.app.SherlockFragment;
+
+public class AuthenticatorAccountDetailsFragment extends SherlockFragment {
+
+}
diff --git a/src/com/owncloud/android/ui/fragment/AuthenticatorGetStartedFragment.java b/src/com/owncloud/android/ui/fragment/AuthenticatorGetStartedFragment.java
new file mode 100644
index 00000000..f321aa9f
--- /dev/null
+++ b/src/com/owncloud/android/ui/fragment/AuthenticatorGetStartedFragment.java
@@ -0,0 +1,7 @@
+package com.owncloud.android.ui.fragment;
+
+import com.actionbarsherlock.app.SherlockFragment;
+
+public class AuthenticatorGetStartedFragment extends SherlockFragment {
+
+}
diff --git a/src/com/owncloud/android/ui/fragment/ConfirmationDialogFragment.java b/src/com/owncloud/android/ui/fragment/ConfirmationDialogFragment.java
new file mode 100644
index 00000000..62a68d58
--- /dev/null
+++ b/src/com/owncloud/android/ui/fragment/ConfirmationDialogFragment.java
@@ -0,0 +1,92 @@
+package com.owncloud.android.ui.fragment;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.actionbarsherlock.app.SherlockDialogFragment;
+
+public class ConfirmationDialogFragment extends SherlockDialogFragment {
+
+ public final static String ARG_CONF_RESOURCE_ID = "resource_id";
+ public final static String ARG_CONF_ARGUMENTS = "string_array";
+
+ public final static String ARG_POSITIVE_BTN_RES = "positive_btn_res";
+ public final static String ARG_NEUTRAL_BTN_RES = "neutral_btn_res";
+ public final static String ARG_NEGATIVE_BTN_RES = "negative_btn_res";
+
+ private ConfirmationDialogFragmentListener mListener;
+
+ public static ConfirmationDialogFragment newInstance(int string_id, String[] arguments, int posBtn, int neuBtn, int negBtn) {
+ ConfirmationDialogFragment frag = new ConfirmationDialogFragment();
+ Bundle args = new Bundle();
+ args.putInt(ARG_CONF_RESOURCE_ID, string_id);
+ args.putStringArray(ARG_CONF_ARGUMENTS, arguments);
+ args.putInt(ARG_POSITIVE_BTN_RES, posBtn);
+ args.putInt(ARG_NEUTRAL_BTN_RES, neuBtn);
+ args.putInt(ARG_NEGATIVE_BTN_RES, negBtn);
+ frag.setArguments(args);
+ return frag;
+ }
+
+ public void setOnConfirmationListener(ConfirmationDialogFragmentListener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Object[] confirmationTarget = getArguments().getStringArray(ARG_CONF_ARGUMENTS);
+ int resourceId = getArguments().getInt(ARG_CONF_RESOURCE_ID, -1);
+ int posBtn = getArguments().getInt(ARG_POSITIVE_BTN_RES, -1);
+ int neuBtn = getArguments().getInt(ARG_NEUTRAL_BTN_RES, -1);
+ int negBtn = getArguments().getInt(ARG_NEGATIVE_BTN_RES, -1);
+
+ if (confirmationTarget == null || resourceId == -1) {
+ Log.wtf(getTag(), "Calling confirmation dialog without resource or arguments");
+ return null;
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setMessage(String.format(getString(resourceId), confirmationTarget))
+ .setTitle(android.R.string.dialog_alert_title);
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+ builder.setIconAttribute(android.R.attr.alertDialogIcon);
+ }
+
+ if (posBtn != -1)
+ builder.setPositiveButton(posBtn,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ mListener.onConfirmation(getTag());
+ }
+ });
+ if (neuBtn != -1)
+ builder.setNeutralButton(neuBtn,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ mListener.onNeutral(getTag());
+ }
+ });
+ if (negBtn != -1)
+ builder.setNegativeButton(negBtn,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mListener.onCancel(getTag());
+ }
+ });
+ return builder.create();
+ }
+
+
+ public interface ConfirmationDialogFragmentListener {
+ public void onConfirmation(String callerTag);
+ public void onNeutral(String callerTag);
+ public void onCancel(String callerTag);
+ }
+
+}
+
diff --git a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java
new file mode 100644
index 00000000..ae38a0a0
--- /dev/null
+++ b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java
@@ -0,0 +1,1126 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.ui.fragment;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
+import org.apache.http.HttpStatus;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
+import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
+import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources.NotFoundException;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapFactory.Options;
+import android.graphics.Point;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.app.FragmentTransaction;
+import android.util.Log;
+import android.view.Display;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.view.WindowManager.LayoutParams;
+import android.webkit.MimeTypeMap;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.actionbarsherlock.app.SherlockDialogFragment;
+import com.actionbarsherlock.app.SherlockFragment;
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.DisplayUtils;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.services.FileDownloader;
+import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.ui.activity.FileDetailActivity;
+import com.owncloud.android.ui.activity.FileDisplayActivity;
+import com.owncloud.android.utils.OwnCloudVersion;
+
+import com.owncloud.android.R;
+import eu.alefzero.webdav.WebdavClient;
+import eu.alefzero.webdav.WebdavUtils;
+
+/**
+ * This Fragment is used to display the details about a file.
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class FileDetailFragment extends SherlockFragment implements
+ OnClickListener, ConfirmationDialogFragment.ConfirmationDialogFragmentListener {
+
+ public static final String EXTRA_FILE = "FILE";
+ public static final String EXTRA_ACCOUNT = "ACCOUNT";
+
+ private FileDetailFragment.ContainerActivity mContainerActivity;
+
+ private int mLayout;
+ private View mView;
+ private OCFile mFile;
+ private Account mAccount;
+ private ImageView mPreview;
+
+ private DownloadFinishReceiver mDownloadFinishReceiver;
+ private UploadFinishReceiver mUploadFinishReceiver;
+
+ private static final String TAG = "FileDetailFragment";
+ public static final String FTAG = "FileDetails";
+ public static final String FTAG_CONFIRMATION = "REMOVE_CONFIRMATION_FRAGMENT";
+
+
+ /**
+ * Creates an empty details fragment.
+ *
+ * It's necessary to keep a public constructor without parameters; the system uses it when tries to reinstantiate a fragment automatically.
+ */
+ public FileDetailFragment() {
+ mFile = null;
+ mAccount = null;
+ mLayout = R.layout.file_details_empty;
+ }
+
+
+ /**
+ * Creates a details fragment.
+ *
+ * When 'fileToDetail' or 'ocAccount' are null, creates a dummy layout (to use when a file wasn't tapped before).
+ *
+ * @param fileToDetail An {@link OCFile} to show in the fragment
+ * @param ocAccount An ownCloud account; needed to start downloads
+ */
+ public FileDetailFragment(OCFile fileToDetail, Account ocAccount){
+ mFile = fileToDetail;
+ mAccount = ocAccount;
+ mLayout = R.layout.file_details_empty;
+
+ if(fileToDetail != null && ocAccount != null) {
+ mLayout = R.layout.file_details_fragment;
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ mContainerActivity = (ContainerActivity) activity;
+ } catch (ClassCastException e) {
+ throw new ClassCastException(activity.toString() + " must implement FileListFragment.ContainerActivity");
+ }
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+
+ if (savedInstanceState != null) {
+ mFile = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_FILE);
+ mAccount = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_ACCOUNT);
+ }
+
+ View view = null;
+ view = inflater.inflate(mLayout, container, false);
+ mView = view;
+
+ if (mLayout == R.layout.file_details_fragment) {
+ mView.findViewById(R.id.fdKeepInSync).setOnClickListener(this);
+ mView.findViewById(R.id.fdRenameBtn).setOnClickListener(this);
+ mView.findViewById(R.id.fdDownloadBtn).setOnClickListener(this);
+ mView.findViewById(R.id.fdOpenBtn).setOnClickListener(this);
+ mView.findViewById(R.id.fdRemoveBtn).setOnClickListener(this);
+ //mView.findViewById(R.id.fdShareBtn).setOnClickListener(this);
+ mPreview = (ImageView)mView.findViewById(R.id.fdPreview);
+ }
+
+ updateFileDetails();
+ return view;
+ }
+
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ Log.i(getClass().toString(), "onSaveInstanceState() start");
+ super.onSaveInstanceState(outState);
+ outState.putParcelable(FileDetailFragment.EXTRA_FILE, mFile);
+ outState.putParcelable(FileDetailFragment.EXTRA_ACCOUNT, mAccount);
+ Log.i(getClass().toString(), "onSaveInstanceState() end");
+ }
+
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ mDownloadFinishReceiver = new DownloadFinishReceiver();
+ IntentFilter filter = new IntentFilter(
+ FileDownloader.DOWNLOAD_FINISH_MESSAGE);
+ getActivity().registerReceiver(mDownloadFinishReceiver, filter);
+
+ mUploadFinishReceiver = new UploadFinishReceiver();
+ filter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
+ getActivity().registerReceiver(mUploadFinishReceiver, filter);
+
+ mPreview = (ImageView)mView.findViewById(R.id.fdPreview);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ getActivity().unregisterReceiver(mDownloadFinishReceiver);
+ mDownloadFinishReceiver = null;
+
+ getActivity().unregisterReceiver(mUploadFinishReceiver);
+ mUploadFinishReceiver = null;
+
+ if (mPreview != null) {
+ mPreview = null;
+ }
+ }
+
+ @Override
+ public View getView() {
+ return super.getView() == null ? mView : super.getView();
+ }
+
+
+
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.fdDownloadBtn: {
+ Intent i = new Intent(getActivity(), FileDownloader.class);
+ i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
+ i.putExtra(FileDownloader.EXTRA_REMOTE_PATH, mFile.getRemotePath());
+ i.putExtra(FileDownloader.EXTRA_FILE_PATH, mFile.getRemotePath());
+ i.putExtra(FileDownloader.EXTRA_FILE_SIZE, mFile.getFileLength());
+
+ // update ui
+ setButtonsForTransferring();
+
+ getActivity().startService(i);
+ mContainerActivity.onFileStateChanged(); // this is not working; it is performed before the fileDownloadService registers it as 'in progress'
+ break;
+ }
+ case R.id.fdKeepInSync: {
+ CheckBox cb = (CheckBox) getView().findViewById(R.id.fdKeepInSync);
+ mFile.setKeepInSync(cb.isChecked());
+ FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());
+ fdsm.saveFile(mFile);
+ if (mFile.keepInSync()) {
+ onClick(getView().findViewById(R.id.fdDownloadBtn));
+ } else {
+ mContainerActivity.onFileStateChanged(); // put inside 'else' to not call it twice (here, and in the virtual click on fdDownloadBtn)
+ }
+ break;
+ }
+ case R.id.fdRenameBtn: {
+ EditNameFragment dialog = EditNameFragment.newInstance(mFile.getFileName());
+ dialog.show(getFragmentManager(), "nameeditdialog");
+ dialog.setOnDismissListener(this);
+ break;
+ }
+ case R.id.fdRemoveBtn: {
+ ConfirmationDialogFragment confDialog = ConfirmationDialogFragment.newInstance(
+ R.string.confirmation_remove_alert,
+ new String[]{mFile.getFileName()},
+ mFile.isDown() ? R.string.confirmation_remove_remote_and_local : R.string.confirmation_remove_remote,
+ mFile.isDown() ? R.string.confirmation_remove_local : -1,
+ R.string.common_cancel);
+ confDialog.setOnConfirmationListener(this);
+ confDialog.show(getFragmentManager(), FTAG_CONFIRMATION);
+ break;
+ }
+ case R.id.fdOpenBtn: {
+ String storagePath = mFile.getStoragePath();
+ String encodedStoragePath = WebdavUtils.encodePath(storagePath);
+ try {
+ Intent i = new Intent(Intent.ACTION_VIEW);
+ i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), mFile.getMimetype());
+ i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ startActivity(i);
+
+ } catch (Throwable t) {
+ Log.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mFile.getMimetype());
+ boolean toastIt = true;
+ String mimeType = "";
+ try {
+ Intent i = new Intent(Intent.ACTION_VIEW);
+ mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1));
+ if (mimeType != null && !mimeType.equals(mFile.getMimetype())) {
+ i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), mimeType);
+ i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ startActivity(i);
+ toastIt = false;
+ }
+
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);
+
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");
+
+ } catch (Throwable th) {
+ Log.e(TAG, "Unexpected problem when opening: " + storagePath, th);
+
+ } finally {
+ if (toastIt) {
+ Toast.makeText(getActivity(), "There is no application to handle file " + mFile.getFileName(), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ }
+ break;
+ }
+ default:
+ Log.e(TAG, "Incorrect view clicked!");
+ }
+
+ /* else if (v.getId() == R.id.fdShareBtn) {
+ Thread t = new Thread(new ShareRunnable(mFile.getRemotePath()));
+ t.start();
+ }*/
+ }
+
+
+ @Override
+ public void onConfirmation(String callerTag) {
+ if (callerTag.equals(FTAG_CONFIRMATION)) {
+ FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
+ if (fdsm.getFileById(mFile.getFileId()) != null) {
+ new Thread(new RemoveRunnable(mFile, mAccount, new Handler())).start();
+ boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
+ getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
+ }
+ }
+ }
+
+ @Override
+ public void onNeutral(String callerTag) {
+ FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
+ File f = null;
+ if (mFile.isDown() && (f = new File(mFile.getStoragePath())).exists()) {
+ f.delete();
+ mFile.setStoragePath(null);
+ fdsm.saveFile(mFile);
+ updateFileDetails(mFile, mAccount);
+ }
+ }
+
+ @Override
+ public void onCancel(String callerTag) {
+ Log.d(TAG, "REMOVAL CANCELED");
+ }
+
+
+ /**
+ * Check if the fragment was created with an empty layout. An empty fragment can't show file details, must be replaced.
+ *
+ * @return True when the fragment was created with the empty layout.
+ */
+ public boolean isEmpty() {
+ return mLayout == R.layout.file_details_empty;
+ }
+
+
+ /**
+ * Can be used to get the file that is currently being displayed.
+ * @return The file on the screen.
+ */
+ public OCFile getDisplayedFile(){
+ return mFile;
+ }
+
+ /**
+ * Use this method to signal this Activity that it shall update its view.
+ *
+ * @param file : An {@link OCFile}
+ */
+ public void updateFileDetails(OCFile file, Account ocAccount) {
+ mFile = file;
+ mAccount = ocAccount;
+ updateFileDetails();
+ }
+
+
+ /**
+ * Updates the view with all relevant details about that file.
+ */
+ public void updateFileDetails() {
+
+ if (mFile != null && mAccount != null && mLayout == R.layout.file_details_fragment) {
+
+ // set file details
+ setFilename(mFile.getFileName());
+ setFiletype(DisplayUtils.convertMIMEtoPrettyPrint(mFile
+ .getMimetype()));
+ setFilesize(mFile.getFileLength());
+ if(ocVersionSupportsTimeCreated()){
+ setTimeCreated(mFile.getCreationTimestamp());
+ }
+
+ setTimeModified(mFile.getModificationTimestamp());
+
+ CheckBox cb = (CheckBox)getView().findViewById(R.id.fdKeepInSync);
+ cb.setChecked(mFile.keepInSync());
+
+ // configure UI for depending upon local state of the file
+ if (FileDownloader.isDownloading(mAccount, mFile.getRemotePath()) || FileUploader.isUploading(mAccount, mFile.getRemotePath())) {
+ setButtonsForTransferring();
+
+ } else if (mFile.isDown()) {
+ // Update preview
+ if (mFile.getMimetype().startsWith("image/")) {
+ BitmapLoader bl = new BitmapLoader();
+ bl.execute(new String[]{mFile.getStoragePath()});
+ }
+
+ setButtonsForDown();
+
+ } else {
+ setButtonsForRemote();
+ }
+ }
+ }
+
+
+ /**
+ * Updates the filename in view
+ * @param filename to set
+ */
+ private void setFilename(String filename) {
+ TextView tv = (TextView) getView().findViewById(R.id.fdFilename);
+ if (tv != null)
+ tv.setText(filename);
+ }
+
+ /**
+ * Updates the MIME type in view
+ * @param mimetype to set
+ */
+ private void setFiletype(String mimetype) {
+ TextView tv = (TextView) getView().findViewById(R.id.fdType);
+ if (tv != null)
+ tv.setText(mimetype);
+ }
+
+ /**
+ * Updates the file size in view
+ * @param filesize in bytes to set
+ */
+ private void setFilesize(long filesize) {
+ TextView tv = (TextView) getView().findViewById(R.id.fdSize);
+ if (tv != null)
+ tv.setText(DisplayUtils.bytesToHumanReadable(filesize));
+ }
+
+ /**
+ * Updates the time that the file was created in view
+ * @param milliseconds Unix time to set
+ */
+ private void setTimeCreated(long milliseconds){
+ TextView tv = (TextView) getView().findViewById(R.id.fdCreated);
+ TextView tvLabel = (TextView) getView().findViewById(R.id.fdCreatedLabel);
+ if(tv != null){
+ tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));
+ tv.setVisibility(View.VISIBLE);
+ tvLabel.setVisibility(View.VISIBLE);
+ }
+ }
+
+ /**
+ * Updates the time that the file was last modified
+ * @param milliseconds Unix time to set
+ */
+ private void setTimeModified(long milliseconds){
+ TextView tv = (TextView) getView().findViewById(R.id.fdModified);
+ if(tv != null){
+ tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));
+ }
+ }
+
+ /**
+ * Enables or disables buttons for a file being downloaded
+ */
+ private void setButtonsForTransferring() {
+ if (!isEmpty()) {
+ Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);
+ //downloadButton.setText(R.string.filedetails_download_in_progress); // ugly
+ downloadButton.setEnabled(false); // TODO replace it with a 'cancel download' button
+
+ // let's protect the user from himself ;)
+ ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(false);
+ ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(false);
+ ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(false);
+ }
+ }
+
+ /**
+ * Enables or disables buttons for a file locally available
+ */
+ private void setButtonsForDown() {
+ if (!isEmpty()) {
+ Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);
+ //downloadButton.setText(R.string.filedetails_redownload); // ugly
+ downloadButton.setEnabled(true);
+
+ ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(true);
+ ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(true);
+ ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(true);
+ }
+ }
+
+ /**
+ * Enables or disables buttons for a file not locally available
+ */
+ private void setButtonsForRemote() {
+ if (!isEmpty()) {
+ Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);
+ //downloadButton.setText(R.string.filedetails_download); // unnecessary
+ downloadButton.setEnabled(true);
+
+ ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(false);
+ ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(true);
+ ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(true);
+ }
+ }
+
+
+ /**
+ * In ownCloud 3.X.X and 4.X.X there is a bug that SabreDAV does not return
+ * the time that the file was created. There is a chance that this will
+ * be fixed in future versions. Use this method to check if this version of
+ * ownCloud has this fix.
+ * @return True, if ownCloud the ownCloud version is supporting creation time
+ */
+ private boolean ocVersionSupportsTimeCreated(){
+ /*if(mAccount != null){
+ AccountManager accManager = (AccountManager) getActivity().getSystemService(Context.ACCOUNT_SERVICE);
+ OwnCloudVersion ocVersion = new OwnCloudVersion(accManager
+ .getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));
+ if(ocVersion.compareTo(new OwnCloudVersion(0x030000)) < 0) {
+ return true;
+ }
+ }*/
+ return false;
+ }
+
+
+ /**
+ * Interface to implement by any Activity that includes some instance of FileDetailFragment
+ *
+ * @author David A. Velasco
+ */
+ public interface ContainerActivity {
+
+ /**
+ * Callback method invoked when the detail fragment wants to notice its container
+ * activity about a relevant state the file shown by the fragment.
+ *
+ * Added to notify to FileDisplayActivity about the need of refresh the files list.
+ *
+ * Currently called when:
+ * - a download is started;
+ * - a rename is completed;
+ * - a deletion is completed;
+ * - the 'inSync' flag is changed;
+ */
+ public void onFileStateChanged();
+
+ }
+
+
+ /**
+ * Once the file download has finished -> update view
+ * @author Bartek Przybylski
+ */
+ private class DownloadFinishReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);
+
+ if (!isEmpty() && accountName.equals(mAccount.name)) {
+ boolean downloadWasFine = intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false);
+ String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
+ if (mFile.getRemotePath().equals(downloadedRemotePath)) {
+ if (downloadWasFine) {
+ mFile.setStoragePath(intent.getStringExtra(FileDownloader.EXTRA_FILE_PATH)); // updates the local object without accessing the database again
+ }
+ updateFileDetails(); // it updates the buttons; must be called although !downloadWasFine
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Once the file upload has finished -> update view
+ *
+ * Being notified about the finish of an upload is necessary for the next sequence:
+ * 1. Upload a big file.
+ * 2. Force a synchronization; if it finished before the upload, the file in transfer will be included in the local database and in the file list
+ * of its containing folder; the the server includes it in the PROPFIND requests although it's not fully upload.
+ * 3. Click the file in the list to see its details.
+ * 4. Wait for the upload finishes; at this moment, the details view must be refreshed to enable the action buttons.
+ */
+ private class UploadFinishReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);
+
+ if (!isEmpty() && accountName.equals(mAccount.name)) {
+ boolean uploadWasFine = intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false);
+ String uploadRemotePath = intent.getStringExtra(FileUploader.EXTRA_REMOTE_PATH);
+ if (mFile.getRemotePath().equals(uploadRemotePath)) {
+ if (uploadWasFine) {
+ FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());
+ mFile = fdsm.getFileByPath(mFile.getRemotePath());
+ }
+ updateFileDetails(); // it updates the buttons; must be called although !uploadWasFine; interrupted uploads still leave an incomplete file in the server
+ }
+ }
+ }
+ }
+
+
+ // this is a temporary class for sharing purposes, it need to be replaced in transfer service
+ private class ShareRunnable implements Runnable {
+ private String mPath;
+
+ public ShareRunnable(String path) {
+ mPath = path;
+ }
+
+ public void run() {
+ AccountManager am = AccountManager.get(getActivity());
+ Account account = AccountUtils.getCurrentOwnCloudAccount(getActivity());
+ OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION));
+ String url = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + AccountUtils.getWebdavPath(ocv);
+
+ Log.d("share", "sharing for version " + ocv.toString());
+
+ if (ocv.compareTo(new OwnCloudVersion(0x040000)) >= 0) {
+ String APPS_PATH = "/apps/files_sharing/";
+ String SHARE_PATH = "ajax/share.php";
+
+ String SHARED_PATH = "/apps/files_sharing/get.php?token=";
+
+ final String WEBDAV_SCRIPT = "webdav.php";
+ final String WEBDAV_FILES_LOCATION = "/files/";
+
+ WebdavClient wc = new WebdavClient();
+ HttpConnectionManagerParams params = new HttpConnectionManagerParams();
+ params.setMaxConnectionsPerHost(wc.getHostConfiguration(), 5);
+
+ //wc.getParams().setParameter("http.protocol.single-cookie-header", true);
+ //wc.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
+
+ PostMethod post = new PostMethod(am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + APPS_PATH + SHARE_PATH);
+
+ post.addRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8" );
+ post.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));
+ List formparams = new ArrayList();
+ Log.d("share", mPath+"");
+ formparams.add(new BasicNameValuePair("sources",mPath));
+ formparams.add(new BasicNameValuePair("uid_shared_with", "public"));
+ formparams.add(new BasicNameValuePair("permissions", "0"));
+ post.setRequestEntity(new StringRequestEntity(URLEncodedUtils.format(formparams, HTTP.UTF_8)));
+
+ int status;
+ try {
+ PropFindMethod find = new PropFindMethod(url+"/");
+ find.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));
+ Log.d("sharer", ""+ url+"/");
+ wc.setCredentials(account.name.substring(0, account.name.lastIndexOf('@')), am.getPassword(account));
+
+ for (org.apache.commons.httpclient.Header a : find.getRequestHeaders()) {
+ Log.d("sharer-h", a.getName() + ":"+a.getValue());
+ }
+
+ int status2 = wc.executeMethod(find);
+
+ Log.d("sharer", "propstatus "+status2);
+
+ GetMethod get = new GetMethod(am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + "/");
+ get.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));
+
+ status2 = wc.executeMethod(get);
+
+ Log.d("sharer", "getstatus "+status2);
+ Log.d("sharer", "" + get.getResponseBodyAsString());
+
+ for (org.apache.commons.httpclient.Header a : get.getResponseHeaders()) {
+ Log.d("sharer", a.getName() + ":"+a.getValue());
+ }
+
+ status = wc.executeMethod(post);
+ for (org.apache.commons.httpclient.Header a : post.getRequestHeaders()) {
+ Log.d("sharer-h", a.getName() + ":"+a.getValue());
+ }
+ for (org.apache.commons.httpclient.Header a : post.getResponseHeaders()) {
+ Log.d("sharer", a.getName() + ":"+a.getValue());
+ }
+ String resp = post.getResponseBodyAsString();
+ Log.d("share", ""+post.getURI().toString());
+ Log.d("share", "returned status " + status);
+ Log.d("share", " " +resp);
+
+ if(status != HttpStatus.SC_OK ||resp == null || resp.equals("") || resp.startsWith("false")) {
+ return;
+ }
+
+ JSONObject jsonObject = new JSONObject (resp);
+ String jsonStatus = jsonObject.getString("status");
+ if(!jsonStatus.equals("success")) throw new Exception("Error while sharing file status != success");
+
+ String token = jsonObject.getString("data");
+ String uri = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + SHARED_PATH + token;
+ Log.d("Actions:shareFile ok", "url: " + uri);
+
+ } catch (HttpException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (JSONException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ } else if (ocv.compareTo(new OwnCloudVersion(0x030000)) >= 0) {
+
+ }
+ }
+ }
+
+ public void onDismiss(EditNameFragment dialog) {
+ if (dialog instanceof EditNameFragment) {
+ if (((EditNameFragment)dialog).getResult()) {
+ String newFilename = ((EditNameFragment)dialog).getNewFilename();
+ Log.d(TAG, "name edit dialog dismissed with new name " + newFilename);
+ if (!newFilename.equals(mFile.getFileName())) {
+ FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
+ if (fdsm.getFileById(mFile.getFileId()) != null) {
+ OCFile newFile = new OCFile(fdsm.getFileById(mFile.getParentId()).getRemotePath() + newFilename);
+ newFile.setCreationTimestamp(mFile.getCreationTimestamp());
+ newFile.setFileId(mFile.getFileId());
+ newFile.setFileLength(mFile.getFileLength());
+ newFile.setKeepInSync(mFile.keepInSync());
+ newFile.setLastSyncDate(mFile.getLastSyncDate());
+ newFile.setMimetype(mFile.getMimetype());
+ newFile.setModificationTimestamp(mFile.getModificationTimestamp());
+ newFile.setParentId(mFile.getParentId());
+ boolean localRenameFails = false;
+ if (mFile.isDown()) {
+ File f = new File(mFile.getStoragePath());
+ Log.e(TAG, f.getAbsolutePath());
+ localRenameFails = !(f.renameTo(new File(f.getParent() + File.separator + newFilename)));
+ Log.e(TAG, f.getParent() + File.separator + newFilename);
+ newFile.setStoragePath(f.getParent() + File.separator + newFilename);
+ }
+
+ if (localRenameFails) {
+ Toast msg = Toast.makeText(getActivity(), R.string.rename_local_fail_msg, Toast.LENGTH_LONG);
+ msg.show();
+
+ } else {
+ new Thread(new RenameRunnable(mFile, newFile, mAccount, new Handler())).start();
+ boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
+ getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
+ }
+
+ }
+ }
+ }
+ } else {
+ Log.e(TAG, "Unknown dialog instance passed to onDismissDalog: " + dialog.getClass().getCanonicalName());
+ }
+
+ }
+
+ private class RenameRunnable implements Runnable {
+
+ Account mAccount;
+ OCFile mOld, mNew;
+ Handler mHandler;
+
+ public RenameRunnable(OCFile oldFile, OCFile newFile, Account account, Handler handler) {
+ mOld = oldFile;
+ mNew = newFile;
+ mAccount = account;
+ mHandler = handler;
+ }
+
+ public void run() {
+ WebdavClient wc = new WebdavClient(mAccount, getSherlockActivity().getApplicationContext());
+ wc.allowSelfsignedCertificates();
+ AccountManager am = AccountManager.get(getSherlockActivity());
+ String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);
+ OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));
+ String webdav_path = AccountUtils.getWebdavPath(ocv);
+ Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encodePath(mOld.getRemotePath()));
+
+ Log.e("ASD", Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encodePath(mNew.getRemotePath()));
+ LocalMoveMethod move = new LocalMoveMethod(baseUrl + webdav_path + WebdavUtils.encodePath(mOld.getRemotePath()),
+ Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encodePath(mNew.getRemotePath()));
+
+ boolean success = false;
+ try {
+ int status = wc.executeMethod(move);
+ success = move.succeeded();
+ Log.d(TAG, "Move returned status: " + status);
+
+ } catch (HttpException e) {
+ Log.e(TAG, "HTTP Exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e);
+
+ } catch (IOException e) {
+ Log.e(TAG, "I/O Exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e);
+
+ } catch (Exception e) {
+ Log.e(TAG, "Unexpected exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e);
+ }
+
+ if (success) {
+ FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
+ fdsm.removeFile(mOld);
+ fdsm.saveFile(mNew);
+ mFile = mNew;
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
+ getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
+ updateFileDetails(mFile, mAccount);
+ mContainerActivity.onFileStateChanged();
+ }
+ });
+
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ // undo the local rename
+ if (mNew.isDown()) {
+ File f = new File(mNew.getStoragePath());
+ if (!f.renameTo(new File(mOld.getStoragePath()))) {
+ // the local rename undoing failed; last chance: save the new local storage path in the old file
+ mFile.setStoragePath(mNew.getStoragePath());
+ FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
+ fdsm.saveFile(mFile);
+ }
+ }
+ boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
+ getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
+ try {
+ Toast msg = Toast.makeText(getActivity(), R.string.rename_server_fail_msg, Toast.LENGTH_LONG);
+ msg.show();
+
+ } catch (NotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+ }
+ private class LocalMoveMethod extends DavMethodBase {
+
+ public LocalMoveMethod(String uri, String dest) {
+ super(uri);
+ addRequestHeader(new org.apache.commons.httpclient.Header("Destination", dest));
+ }
+
+ @Override
+ public String getName() {
+ return "MOVE";
+ }
+
+ @Override
+ protected boolean isSuccess(int status) {
+ return status == 201 || status == 204;
+ }
+
+ }
+ }
+
+ private static class EditNameFragment extends SherlockDialogFragment implements OnClickListener {
+
+ private String mNewFilename;
+ private boolean mResult;
+ private FileDetailFragment mListener;
+
+ static public EditNameFragment newInstance(String filename) {
+ EditNameFragment f = new EditNameFragment();
+ Bundle args = new Bundle();
+ args.putString("filename", filename);
+ f.setArguments(args);
+ return f;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View v = inflater.inflate(R.layout.edit_box_dialog, container, false);
+
+ String currentName = getArguments().getString("filename");
+ if (currentName == null)
+ currentName = "";
+
+ ((Button)v.findViewById(R.id.cancel)).setOnClickListener(this);
+ ((Button)v.findViewById(R.id.ok)).setOnClickListener(this);
+ ((TextView)v.findViewById(R.id.user_input)).setText(currentName);
+ ((TextView)v.findViewById(R.id.user_input)).requestFocus();
+ getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+
+ mResult = false;
+ return v;
+ }
+
+ @Override
+ public void onClick(View view) {
+ switch (view.getId()) {
+ case R.id.ok: {
+ mNewFilename = ((TextView)getView().findViewById(R.id.user_input)).getText().toString();
+ mResult = true;
+ }
+ case R.id.cancel: { // fallthought
+ dismiss();
+ mListener.onDismiss(this);
+ }
+ }
+ }
+
+ void setOnDismissListener(FileDetailFragment listener) {
+ mListener = listener;
+ }
+
+ public String getNewFilename() {
+ return mNewFilename;
+ }
+
+ // true if user click ok
+ public boolean getResult() {
+ return mResult;
+ }
+
+ }
+
+ private class RemoveRunnable implements Runnable {
+
+ Account mAccount;
+ OCFile mFileToRemove;
+ Handler mHandler;
+
+ public RemoveRunnable(OCFile fileToRemove, Account account, Handler handler) {
+ mFileToRemove = fileToRemove;
+ mAccount = account;
+ mHandler = handler;
+ }
+
+ public void run() {
+ WebdavClient wc = new WebdavClient(mAccount, getSherlockActivity().getApplicationContext());
+ wc.allowSelfsignedCertificates();
+ AccountManager am = AccountManager.get(getSherlockActivity());
+ String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);
+ OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));
+ String webdav_path = AccountUtils.getWebdavPath(ocv);
+ Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encodePath(mFileToRemove.getRemotePath()));
+
+ DeleteMethod delete = new DeleteMethod(baseUrl + webdav_path + WebdavUtils.encodePath(mFileToRemove.getRemotePath()));
+
+ boolean success = false;
+ int status = -1;
+ try {
+ status = wc.executeMethod(delete);
+ success = (delete.succeeded());
+ Log.d(TAG, "Delete: returned status " + status);
+
+ } catch (HttpException e) {
+ Log.e(TAG, "HTTP Exception removing file " + mFileToRemove.getRemotePath(), e);
+
+ } catch (IOException e) {
+ Log.e(TAG, "I/O Exception removing file " + mFileToRemove.getRemotePath(), e);
+
+ } catch (Exception e) {
+ Log.e(TAG, "Unexpected exception removing file " + mFileToRemove.getRemotePath(), e);
+ }
+
+ if (success) {
+ FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
+ fdsm.removeFile(mFileToRemove);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
+ getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
+ try {
+ Toast msg = Toast.makeText(getActivity().getApplicationContext(), R.string.remove_success_msg, Toast.LENGTH_LONG);
+ msg.show();
+ if (inDisplayActivity) {
+ // double pane
+ FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
+ transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment
+ transaction.commit();
+ mContainerActivity.onFileStateChanged();
+
+ } else {
+ getActivity().finish();
+ }
+
+ } catch (NotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
+ getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
+ try {
+ Toast msg = Toast.makeText(getActivity(), R.string.remove_fail_msg, Toast.LENGTH_LONG);
+ msg.show();
+
+ } catch (NotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+ }
+
+ }
+
+ class BitmapLoader extends AsyncTask {
+ @SuppressLint({ "NewApi", "NewApi", "NewApi" }) // to avoid Lint errors since Android SDK r20
+ @Override
+ protected Bitmap doInBackground(String... params) {
+ Bitmap result = null;
+ if (params.length != 1) return result;
+ String storagePath = params[0];
+ try {
+
+ BitmapFactory.Options options = new Options();
+ options.inScaled = true;
+ options.inPurgeable = true;
+ options.inJustDecodeBounds = true;
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
+ options.inPreferQualityOverSpeed = false;
+ }
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+ options.inMutable = false;
+ }
+
+ result = BitmapFactory.decodeFile(storagePath, options);
+ options.inJustDecodeBounds = false;
+
+ int width = options.outWidth;
+ int height = options.outHeight;
+ int scale = 1;
+ if (width >= 2048 || height >= 2048) {
+ scale = (int) Math.ceil((Math.ceil(Math.max(height, width) / 2048.)));
+ options.inSampleSize = scale;
+ }
+ Display display = getActivity().getWindowManager().getDefaultDisplay();
+ Point size = new Point();
+ int screenwidth;
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2) {
+ display.getSize(size);
+ screenwidth = size.x;
+ } else {
+ screenwidth = display.getWidth();
+ }
+
+ Log.e("ASD", "W " + width + " SW " + screenwidth);
+
+ if (width > screenwidth) {
+ scale = (int) Math.ceil((float)width / screenwidth);
+ options.inSampleSize = scale;
+ }
+
+ result = BitmapFactory.decodeFile(storagePath, options);
+
+ Log.e("ASD", "W " + options.outWidth + " SW " + options.outHeight);
+
+ } catch (OutOfMemoryError e) {
+ result = null;
+ Log.e(TAG, "Out of memory occured for file with size " + storagePath);
+
+ } catch (NoSuchFieldError e) {
+ result = null;
+ Log.e(TAG, "Error from access to unexisting field despite protection " + storagePath);
+
+ } catch (Throwable t) {
+ result = null;
+ Log.e(TAG, "Unexpected error while creating image preview " + storagePath, t);
+ }
+ return result;
+ }
+ @Override
+ protected void onPostExecute(Bitmap result) {
+ if (result != null && mPreview != null) {
+ mPreview.setImageBitmap(result);
+ }
+ }
+
+ }
+
+
+}
diff --git a/src/com/owncloud/android/ui/fragment/FileListFragment.java b/src/com/owncloud/android/ui/fragment/FileListFragment.java
new file mode 100644
index 00000000..5d1a8d1b
--- /dev/null
+++ b/src/com/owncloud/android/ui/fragment/FileListFragment.java
@@ -0,0 +1,205 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.ui.fragment;
+
+import java.util.Vector;
+
+import com.owncloud.android.datamodel.DataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.ui.FragmentListView;
+import com.owncloud.android.ui.adapter.FileListListAdapter;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import com.owncloud.android.R;
+
+/**
+ * A Fragment that lists all files and folders in a given path.
+ *
+ * @author Bartek Przybylski
+ *
+ */
+public class FileListFragment extends FragmentListView {
+ private static final String TAG = "FileListFragment";
+
+ private FileListFragment.ContainerActivity mContainerActivity;
+
+ private OCFile mFile = null;
+ private FileListListAdapter mAdapter;
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ mContainerActivity = (ContainerActivity) activity;
+ } catch (ClassCastException e) {
+ throw new ClassCastException(activity.toString() + " must implement FileListFragment.ContainerActivity");
+ }
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ Log.i(getClass().toString(), "onCreateView() start");
+ super.onCreateView(inflater, container, savedInstanceState);
+ getListView().setDivider(getResources().getDrawable(R.drawable.uploader_list_separator));
+ getListView().setDividerHeight(1);
+
+ Log.i(getClass().toString(), "onCreateView() end");
+ return getListView();
+ }
+
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ Log.i(getClass().toString(), "onActivityCreated() start");
+
+ super.onCreate(savedInstanceState);
+ //mAdapter = new FileListListAdapter();
+
+ Log.i(getClass().toString(), "onActivityCreated() stop");
+ }
+
+
+ @Override
+ public void onItemClick(AdapterView> l, View v, int position, long id) {
+ OCFile file = (OCFile) mAdapter.getItem(position);
+ if (file != null) {
+ /// Click on a directory
+ if (file.getMimetype().equals("DIR")) {
+ // just local updates
+ mFile = file;
+ listDirectory(file);
+ // any other updates are let to the container Activity
+ mContainerActivity.onDirectoryClick(file);
+
+ } else { /// Click on a file
+ mContainerActivity.onFileClick(file);
+ }
+
+ } else {
+ Log.d(TAG, "Null object in ListAdapter!!");
+ }
+
+ }
+
+ /**
+ * Call this, when the user presses the up button
+ */
+ public void onNavigateUp() {
+ OCFile parentDir = null;
+
+ if(mFile != null){
+ DataStorageManager storageManager = mContainerActivity.getStorageManager();
+ parentDir = storageManager.getFileById(mFile.getParentId());
+ mFile = parentDir;
+ }
+ listDirectory(parentDir);
+ }
+
+ /**
+ * Use this to query the {@link OCFile} that is currently
+ * being displayed by this fragment
+ * @return The currently viewed OCFile
+ */
+ public OCFile getCurrentFile(){
+ return mFile;
+ }
+
+ /**
+ * Calls {@link FileListFragment#listDirectory(OCFile)} with a null parameter
+ */
+ public void listDirectory(){
+ listDirectory(null);
+ }
+
+ /**
+ * Lists the given directory on the view. When the input parameter is null,
+ * it will either refresh the last known directory, or list the root
+ * if there never was a directory.
+ *
+ * @param directory File to be listed
+ */
+ public void listDirectory(OCFile directory) {
+
+ DataStorageManager storageManager = mContainerActivity.getStorageManager();
+
+ // Check input parameters for null
+ if(directory == null){
+ if(mFile != null){
+ directory = mFile;
+ } else {
+ directory = storageManager.getFileByPath("/");
+ if (directory == null) return; // no files, wait for sync
+ }
+ }
+
+
+ // If that's not a directory -> List its parent
+ if(!directory.isDirectory()){
+ Log.w(TAG, "You see, that is not a directory -> " + directory.toString());
+ directory = storageManager.getFileById(directory.getParentId());
+ }
+
+ mFile = directory;
+
+ mAdapter = new FileListListAdapter(directory, storageManager, getActivity());
+ setListAdapter(mAdapter);
+ }
+
+
+
+ /**
+ * Interface to implement by any Activity that includes some instance of FileListFragment
+ *
+ * @author David A. Velasco
+ */
+ public interface ContainerActivity {
+
+ /**
+ * Callback method invoked when a directory is clicked by the user on the files list
+ *
+ * @param file
+ */
+ public void onDirectoryClick(OCFile file);
+
+ /**
+ * Callback method invoked when a file (non directory) is clicked by the user on the files list
+ *
+ * @param file
+ */
+ public void onFileClick(OCFile file);
+
+ /**
+ * Getter for the current DataStorageManager in the container activity
+ */
+ public DataStorageManager getStorageManager();
+
+ }
+
+}
diff --git a/src/com/owncloud/android/ui/fragment/LandingPageFragment.java b/src/com/owncloud/android/ui/fragment/LandingPageFragment.java
new file mode 100644
index 00000000..a021afbf
--- /dev/null
+++ b/src/com/owncloud/android/ui/fragment/LandingPageFragment.java
@@ -0,0 +1,58 @@
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.owncloud.android.ui.fragment;
+
+import com.actionbarsherlock.app.SherlockFragment;
+import com.owncloud.android.ui.activity.LandingActivity;
+import com.owncloud.android.ui.adapter.LandingScreenAdapter;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+import com.owncloud.android.R;
+
+/**
+ * Used on the Landing page to display what Components of the ownCloud there
+ * are. Like Files, Music, Contacts, etc.
+ *
+ * @author Lennart Rosam
+ *
+ */
+public class LandingPageFragment extends SherlockFragment {
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View root = inflater.inflate(R.layout.landing_page_fragment, container);
+ return root;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ ListView landingScreenItems = (ListView) getView().findViewById(
+ R.id.homeScreenList);
+ landingScreenItems.setAdapter(new LandingScreenAdapter(getActivity()));
+ landingScreenItems
+ .setOnItemClickListener((LandingActivity) getActivity());
+ }
+
+}
diff --git a/src/com/owncloud/android/utils/OwnCloudVersion.java b/src/com/owncloud/android/utils/OwnCloudVersion.java
new file mode 100644
index 00000000..b96a9df1
--- /dev/null
+++ b/src/com/owncloud/android/utils/OwnCloudVersion.java
@@ -0,0 +1,83 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.utils;
+
+public class OwnCloudVersion implements Comparable {
+ public static final OwnCloudVersion owncloud_v1 = new OwnCloudVersion(
+ 0x010000);
+ public static final OwnCloudVersion owncloud_v2 = new OwnCloudVersion(
+ 0x020000);
+ public static final OwnCloudVersion owncloud_v3 = new OwnCloudVersion(
+ 0x030000);
+ public static final OwnCloudVersion owncloud_v4 = new OwnCloudVersion(
+ 0x040000);
+
+ // format is in version
+ // 0xAABBCC
+ // for version AA.BB.CC
+ // ie version 3.0.3 will be stored as 0x030003
+ private int mVersion;
+ private boolean mIsValid;
+
+ public OwnCloudVersion(int version) {
+ mVersion = version;
+ mIsValid = true;
+ }
+
+ public OwnCloudVersion(String version) {
+ mVersion = 0;
+ mIsValid = false;
+ parseVersionString(version);
+ }
+
+ public String toString() {
+ return ((mVersion >> 16) % 256) + "." + ((mVersion >> 8) % 256) + "."
+ + ((mVersion) % 256);
+ }
+
+ public boolean isVersionValid() {
+ return mIsValid;
+ }
+
+ @Override
+ public int compareTo(OwnCloudVersion another) {
+ return another.mVersion == mVersion ? 0
+ : another.mVersion < mVersion ? 1 : -1;
+ }
+
+ private void parseVersionString(String version) {
+ try {
+ String[] nums = version.split("\\.");
+ if (nums.length > 0) {
+ mVersion += Integer.parseInt(nums[0]);
+ }
+ mVersion = mVersion << 8;
+ if (nums.length > 1) {
+ mVersion += Integer.parseInt(nums[1]);
+ }
+ mVersion = mVersion << 8;
+ if (nums.length > 2) {
+ mVersion += Integer.parseInt(nums[2]);
+ }
+ mIsValid = true;
+ } catch (Exception e) {
+ mIsValid = false;
+ }
+ }
+}
diff --git a/src/com/owncloud/android/widgets/ActionEditText.java b/src/com/owncloud/android/widgets/ActionEditText.java
new file mode 100644
index 00000000..be3abfb6
--- /dev/null
+++ b/src/com/owncloud/android/widgets/ActionEditText.java
@@ -0,0 +1,127 @@
+package com.owncloud.android.widgets;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import com.owncloud.android.R;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.EditText;
+
+public class ActionEditText extends EditText {
+ private String s;
+ private String optionOneString;
+ private int optionOneColor;
+ private String optionTwoString;
+ private int optionTwoColor;
+ private Rect mTextBounds, mButtonRect;
+
+ private String badgeClickCallback;
+ private Rect btn_rect;
+
+ public ActionEditText(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ getAttrs(attrs);
+ s = optionOneString;
+ mTextBounds = new Rect();
+ mButtonRect = new Rect();
+ }
+
+ public ActionEditText(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ getAttrs(attrs);
+ s = optionOneString;
+ mTextBounds = new Rect();
+ mButtonRect = new Rect();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ Paint p = getPaint();
+
+ p.getTextBounds(s, 0, s.length(), mTextBounds);
+
+ getDrawingRect(mButtonRect);
+ mButtonRect.top += 10;
+ mButtonRect.bottom -= 10;
+ mButtonRect.left = (int) (getWidth() - mTextBounds.width() - 18);
+ mButtonRect.right = getWidth() - 10;
+ btn_rect = mButtonRect;
+
+ if (s.equals(optionOneString))
+ p.setColor(optionOneColor);
+ else
+ p.setColor(optionTwoColor);
+ canvas.drawRect(mButtonRect, p);
+ p.setColor(Color.GRAY);
+
+ canvas.drawText(s, mButtonRect.left + 3, mButtonRect.bottom
+ - (mTextBounds.height() / 2), p);
+
+ invalidate();
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ int touchX = (int) event.getX();
+ int touchY = (int) event.getY();
+ boolean r = super.onTouchEvent(event);
+ if (event.getAction() == MotionEvent.ACTION_UP) {
+ if (btn_rect.contains(touchX, touchY)) {
+ if (s.equals(optionTwoString))
+ s = optionOneString;
+ else
+ s = optionTwoString;
+ if (badgeClickCallback != null) {
+ @SuppressWarnings("rawtypes")
+ Class[] paramtypes = new Class[2];
+ paramtypes[0] = android.view.View.class;
+ paramtypes[1] = String.class;
+ Method method;
+ try {
+
+ method = getContext().getClass().getMethod(
+ badgeClickCallback, paramtypes);
+ method.invoke(getContext(), this, s);
+
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ }
+
+ invalidate();
+ }
+ }
+ }
+ return r;
+ }
+
+ private void getAttrs(AttributeSet attr) {
+ TypedArray a = getContext().obtainStyledAttributes(attr,
+ R.styleable.ActionEditText);
+ optionOneString = a
+ .getString(R.styleable.ActionEditText_optionOneString);
+ optionTwoString = a
+ .getString(R.styleable.ActionEditText_optionTwoString);
+ optionOneColor = a.getColor(R.styleable.ActionEditText_optionOneColor,
+ 0x00ff00);
+ optionTwoColor = a.getColor(R.styleable.ActionEditText_optionTwoColor,
+ 0xff0000);
+ badgeClickCallback = a
+ .getString(R.styleable.ActionEditText_onBadgeClick);
+ }
+
+}
diff --git a/src/eu/alefzero/owncloud/AccountUtils.java b/src/eu/alefzero/owncloud/AccountUtils.java
deleted file mode 100644
index d088d2ce..00000000
--- a/src/eu/alefzero/owncloud/AccountUtils.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud;
-
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.utils.OwnCloudVersion;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-
-public class AccountUtils {
- public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php";
- public static final String WEBDAV_PATH_2_0 = "/files/webdav.php";
- public static final String WEBDAV_PATH_4_0 = "/remote.php/webdav";
- public static final String CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php";
- public static final String CARDDAV_PATH_4_0 = "/remote/carddav.php";
- public static final String STATUS_PATH = "/status.php";
-
- /**
- * Can be used to get the currently selected ownCloud account in the
- * preferences
- *
- * @param context The current appContext
- * @return The current account or first available, if none is available,
- * then null.
- */
- public static Account getCurrentOwnCloudAccount(Context context) {
- Account[] ocAccounts = AccountManager.get(context).getAccountsByType(
- AccountAuthenticator.ACCOUNT_TYPE);
- Account defaultAccount = null;
-
- SharedPreferences appPreferences = PreferenceManager
- .getDefaultSharedPreferences(context);
- String accountName = appPreferences
- .getString("select_oc_account", null);
-
- if (accountName != null) {
- for (Account account : ocAccounts) {
- if (account.name.equals(accountName)) {
- defaultAccount = account;
- break;
- }
- }
- } else if (ocAccounts.length != 0) {
- // we at least need to take first account as fallback
- defaultAccount = ocAccounts[0];
- }
-
- return defaultAccount;
- }
-
-
-
- /**
- * Checks, whether or not there are any ownCloud accounts setup.
- *
- * @return true, if there is at least one account.
- */
- public static boolean accountsAreSetup(Context context) {
- AccountManager accMan = AccountManager.get(context);
- Account[] accounts = accMan
- .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
- return accounts.length > 0;
- }
-
-
- public static void setCurrentOwnCloudAccount(Context context, String name) {
- SharedPreferences.Editor appPrefs = PreferenceManager
- .getDefaultSharedPreferences(context).edit();
- appPrefs.putString("select_oc_account", name);
- appPrefs.commit();
- }
-
- /**
- *
- * @param version version of owncloud
- * @return webdav path for given OC version, null if OC version unknown
- */
- public static String getWebdavPath(OwnCloudVersion version) {
- if (version.compareTo(OwnCloudVersion.owncloud_v4) >= 0)
- return WEBDAV_PATH_4_0;
- if (version.compareTo(OwnCloudVersion.owncloud_v3) >= 0
- || version.compareTo(OwnCloudVersion.owncloud_v2) >= 0)
- return WEBDAV_PATH_2_0;
- if (version.compareTo(OwnCloudVersion.owncloud_v1) >= 0)
- return WEBDAV_PATH_1_2;
- return null;
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/CrashHandler.java b/src/eu/alefzero/owncloud/CrashHandler.java
deleted file mode 100644
index 99cd0444..00000000
--- a/src/eu/alefzero/owncloud/CrashHandler.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.Thread.UncaughtExceptionHandler;
-import java.util.LinkedList;
-import java.util.List;
-
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.net.ConnectivityManager;
-import android.os.Environment;
-import android.util.Log;
-
-public class CrashHandler implements UncaughtExceptionHandler {
-
- public static final String KEY_CRASH_FILENAME = "KEY_CRASH_FILENAME";
-
- private Context mContext;
- private static final String TAG = "CrashHandler";
- private static final String crash_filename_template = "crash";
- private static List TAGS;
- private UncaughtExceptionHandler defaultUEH;
-
- // TODO: create base activity which will register for crashlog tag automaticly
- static {
- TAGS = new LinkedList();
- TAGS.add("AccountAuthenticator");
- TAGS.add("AccountAuthenticator");
- TAGS.add("ConnectionCheckerRunnable");
- TAGS.add("EasySSLSocketFactory");
- TAGS.add("FileDataStorageManager");
- TAGS.add("PhotoTakenBroadcastReceiver");
- TAGS.add("InstantUploadService");
- TAGS.add("FileDownloader");
- TAGS.add("FileUploader");
- TAGS.add("LocationUpdateService");
- TAGS.add("FileSyncAdapter");
- TAGS.add("AuthActivity");
- TAGS.add("OwnCloudPreferences");
- TAGS.add("FileDetailFragment");
- TAGS.add("FileListFragment");
- TAGS.add("ownCloudUploader");
- TAGS.add("WebdavClient");
- }
-
- public CrashHandler(Context context) {
- mContext = context;
- defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
- }
-
- @Override
- public void uncaughtException(Thread thread, Throwable ex) {
- final Writer writer = new StringWriter();
- final PrintWriter printwriter = new PrintWriter(writer);
- ex.printStackTrace(printwriter);
- final String startrace = writer.toString();
- printwriter.close();
- File ocdir = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), "owncloud");
- ocdir.mkdirs();
-
- String crash_filename = crash_filename_template + System.currentTimeMillis() + ".txt";
- File crashfile = new File(ocdir, crash_filename);
- try {
- PackageInfo pi = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
- ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- String header = String.format("Model: %s, SDK: %d, Current net: %s AppVersion: %s\n\n",
- android.os.Build.MODEL,
- android.os.Build.VERSION.SDK_INT,
- cm.getActiveNetworkInfo() != null ? cm.getActiveNetworkInfo().getTypeName() : "NONE",
- pi.versionName);
- Account account = AccountUtils.getCurrentOwnCloudAccount(mContext);
- AccountManager am = AccountManager.get(mContext);
- String header2 = String.format("Account: %s, OCUrl: %s, OCVersion: %s\n\n",
- account.name,
- am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL),
- am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION));
-
- crashfile.createNewFile();
- FileWriter fw = new FileWriter(crashfile);
- fw.write(header);
- fw.write(header2);
- fw.write(startrace);
- fw.write("\n\n");
-
- String logcat = "logcat -d *:S ";
-
- for (String s : TAGS)
- logcat += s + ":V ";
-
- Process process = Runtime.getRuntime().exec(logcat);
- BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
- String logline;
- while ((logline = br.readLine()) != null)
- fw.write(logline+"\n");
-
- br.close();
- fw.close();
-
- Intent dataintent = new Intent(mContext, CrashlogSendActivity.class);
- dataintent.putExtra(KEY_CRASH_FILENAME, crashfile.getAbsolutePath());
- PendingIntent intent;
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
- intent = PendingIntent.getActivity(mContext.getApplicationContext(), 0, dataintent, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- } else {
- intent = PendingIntent.getActivity(mContext.getApplicationContext(), 0, dataintent, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- }
- AlarmManager mngr = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
- if (mngr == null) {
- Log.e(TAG, "Couldn't retrieve alarm manager!");
- defaultUEH.uncaughtException(thread, ex);
- return;
- }
- mngr.set(AlarmManager.RTC, System.currentTimeMillis(), intent);
- System.exit(2);
- } catch (Exception e1) {
- Log.e(TAG, "Crash handler failed!");
- Log.e(TAG, e1.toString());
- defaultUEH.uncaughtException(thread, ex);
- return;
- }
- }
-}
diff --git a/src/eu/alefzero/owncloud/CrashlogSendActivity.java b/src/eu/alefzero/owncloud/CrashlogSendActivity.java
deleted file mode 100644
index 9ff83f67..00000000
--- a/src/eu/alefzero/owncloud/CrashlogSendActivity.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpException;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.httpclient.methods.multipart.FilePart;
-import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
-import org.apache.commons.httpclient.methods.multipart.Part;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.actionbarsherlock.app.SherlockActivity;
-
-import eu.alefzero.webdav.FileRequestEntity;
-
-public class CrashlogSendActivity extends SherlockActivity implements OnClickListener, OnCancelListener {
-
- private static final String TAG = "CrashlogSendActivity";
- private static final String CRASHLOG_SUBMIT_URL = "http://alefzero.eu/a/crashlog/";
- private static final int DIALOG_SUBMIT = 5;
-
- private String mLogFilename;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mLogFilename = getIntent().getStringExtra(CrashHandler.KEY_CRASH_FILENAME);
- if (mLogFilename == null) {
- Log.wtf(TAG, "No file crashlog path given!");
- finish();
- return;
- }
- Log.i(TAG, "crashlog file path " + mLogFilename);
-
- showDialog(DIALOG_SUBMIT);
- }
-
-
- @Override
- protected Dialog onCreateDialog(int id) {
- if (id == DIALOG_SUBMIT) {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setMessage(R.string.crashlog_message);
- builder.setNegativeButton(R.string.crashlog_dont_send_report, this);
- builder.setPositiveButton(R.string.crashlog_send_report, this);
- builder.setCancelable(true);
- builder.setOnCancelListener(this);
- return builder.create();
- }
- return super.onCreateDialog(id);
- }
-
-
- @Override
- public void onClick(DialogInterface dialog, final int which) {
- new Thread(new Runnable() {
-
- @Override
- public void run() {
- // TODO Auto-generated method stub
- File file = new File(mLogFilename);
- if (which == Dialog.BUTTON_POSITIVE) {
- try {
- HttpClient client = new HttpClient();
- PostMethod post = new PostMethod(CRASHLOG_SUBMIT_URL);
- Part[] parts = {new FilePart("crashfile", file)};
- post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
- client.executeMethod(post);
- post.releaseConnection();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- file.delete();
- finish();
- }
- }).start();
- }
-
-
- @Override
- public void onCancel(DialogInterface dialog) {
- new File(mLogFilename).delete();
- finish();
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/DisplayUtils.java b/src/eu/alefzero/owncloud/DisplayUtils.java
deleted file mode 100644
index 3e9f778e..00000000
--- a/src/eu/alefzero/owncloud/DisplayUtils.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud;
-
-import java.util.Date;
-import java.util.HashMap;
-
-/**
- * A helper class for some string operations.
- *
- * @author Bartek Przybylski
- *
- */
-public class DisplayUtils {
-
- private static final String[] suffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
-
- private static HashMap mimeType2HUmanReadable;
- static {
- mimeType2HUmanReadable = new HashMap();
- // images
- mimeType2HUmanReadable.put("image/jpeg", "JPEG image");
- mimeType2HUmanReadable.put("image/jpg", "JPEG image");
- mimeType2HUmanReadable.put("image/png", "PNG image");
- mimeType2HUmanReadable.put("image/bmp", "Bitmap image");
- mimeType2HUmanReadable.put("image/gif", "GIF image");
- mimeType2HUmanReadable.put("image/svg+xml", "JPEG image");
- mimeType2HUmanReadable.put("image/tiff", "TIFF image");
- // music
- mimeType2HUmanReadable.put("audio/mpeg", "MP3 music file");
- mimeType2HUmanReadable.put("application/ogg", "OGG music file");
-
- }
-
- /**
- * Converts the file size in bytes to human readable output.
- *
- * @param bytes Input file size
- * @return Like something readable like "12 MB"
- */
- public static String bytesToHumanReadable(long bytes) {
- double result = bytes;
- int attachedsuff = 0;
- while (result > 1024 && attachedsuff < suffixes.length) {
- result /= 1024.;
- attachedsuff++;
- }
- result = ((int) (result * 100)) / 100.;
- return result + " " + suffixes[attachedsuff];
- }
-
- /**
- * Removes special HTML entities from a string
- *
- * @param s Input string
- * @return A cleaned version of the string
- */
- public static String HtmlDecode(String s) {
- /*
- * TODO: Perhaps we should use something more proven like:
- * http://commons.apache.org/lang/api-2.6/org/apache/commons/lang/StringEscapeUtils.html#unescapeHtml%28java.lang.String%29
- */
-
- String ret = "";
- for (int i = 0; i < s.length(); ++i) {
- if (s.charAt(i) == '%') {
- ret += (char) Integer.parseInt(s.substring(i + 1, i + 3), 16);
- i += 2;
- } else {
- ret += s.charAt(i);
- }
- }
- return ret;
- }
-
- /**
- * Converts MIME types like "image/jpg" to more end user friendly output
- * like "JPG image".
- *
- * @param mimetype MIME type to convert
- * @return A human friendly version of the MIME type
- */
- public static String convertMIMEtoPrettyPrint(String mimetype) {
- if (mimeType2HUmanReadable.containsKey(mimetype)) {
- return mimeType2HUmanReadable.get(mimetype);
- }
- if (mimetype.split("/").length >= 2)
- return mimetype.split("/")[1].toUpperCase() + " file";
- return "Unknown type";
- }
-
- /**
- * Converts Unix time to human readable format
- * @param miliseconds that have passed since 01/01/1970
- * @return The human readable time for the users locale
- */
- public static String unixTimeToHumanReadable(long milliseconds) {
- Date date = new Date(milliseconds);
- return date.toLocaleString();
- }
-}
diff --git a/src/eu/alefzero/owncloud/OwnCloudSession.java b/src/eu/alefzero/owncloud/OwnCloudSession.java
deleted file mode 100644
index 0a090d69..00000000
--- a/src/eu/alefzero/owncloud/OwnCloudSession.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud;
-
-/**
- * Represents a session to an ownCloud instance
- *
- * @author Bartek Przybylski
- *
- */
-public class OwnCloudSession {
- private String mSessionName;
- private String mSessionUrl;
- private int mEntryId;
-
- public OwnCloudSession(String name, String url, int entryId) {
- mSessionName = name;
- mSessionUrl = url;
- mEntryId = entryId;
- }
-
- public void setName(String name) {
- mSessionName = name;
- }
-
- public String getName() {
- return mSessionName;
- }
-
- public void setUrl(String url) {
- mSessionUrl = url;
- }
-
- public String getUrl() {
- return mSessionUrl;
- }
-
- public int getEntryId() {
- return mEntryId;
- }
-}
diff --git a/src/eu/alefzero/owncloud/Uploader.java b/src/eu/alefzero/owncloud/Uploader.java
deleted file mode 100644
index 523db940..00000000
--- a/src/eu/alefzero/owncloud/Uploader.java
+++ /dev/null
@@ -1,413 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Stack;
-import java.util.Vector;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.AlertDialog;
-import android.app.AlertDialog.Builder;
-import android.app.Dialog;
-import android.app.ListActivity;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.provider.MediaStore.Images.Media;
-import android.util.Log;
-import android.view.View;
-import android.view.Window;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.SimpleAdapter;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.datamodel.DataStorageManager;
-import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
-import eu.alefzero.owncloud.datamodel.OCFile;
-import eu.alefzero.owncloud.files.services.FileUploader;
-import eu.alefzero.webdav.WebdavClient;
-
-/**
- * This can be used to upload things to an ownCloud instance.
- *
- * @author Bartek Przybylski
- *
- */
-public class Uploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {
- private static final String TAG = "ownCloudUploader";
-
- private Account mAccount;
- private AccountManager mAccountManager;
- private Stack mParents;
- private ArrayList mStreamsToUpload;
- private boolean mCreateDir;
- private String mUploadPath;
- private static final String[] CONTENT_PROJECTION = { Media.DATA, Media.DISPLAY_NAME, Media.MIME_TYPE, Media.SIZE };
- private DataStorageManager mStorageManager;
- private OCFile mFile;
-
- private final static int DIALOG_NO_ACCOUNT = 0;
- private final static int DIALOG_WAITING = 1;
- private final static int DIALOG_NO_STREAM = 2;
- private final static int DIALOG_MULTIPLE_ACCOUNT = 3;
- private final static int DIALOG_GET_DIRNAME = 4;
-
- private final static int REQUEST_CODE_SETUP_ACCOUNT = 0;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getWindow().requestFeature(Window.FEATURE_NO_TITLE);
- mParents = new Stack();
- mParents.add("");
- if (getIntent().hasExtra(Intent.EXTRA_STREAM)) {
- prepareStreamsToUpload();
- mAccountManager = (AccountManager) getSystemService(Context.ACCOUNT_SERVICE);
- Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
- if (accounts.length == 0) {
- Log.i(TAG, "No ownCloud account is available");
- showDialog(DIALOG_NO_ACCOUNT);
- } else if (accounts.length > 1) {
- Log.i(TAG, "More then one ownCloud is available");
- showDialog(DIALOG_MULTIPLE_ACCOUNT);
- } else {
- mAccount = accounts[0];
- setContentView(R.layout.uploader_layout);
- mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
- populateDirectoryList();
- }
- } else {
- showDialog(DIALOG_NO_STREAM);
- }
- }
-
- @Override
- protected Dialog onCreateDialog(final int id) {
- final AlertDialog.Builder builder = new Builder(this);
- switch (id) {
- case DIALOG_WAITING:
- ProgressDialog pDialog = new ProgressDialog(this);
- pDialog.setIndeterminate(false);
- pDialog.setCancelable(false);
- pDialog.setMessage(getResources().getString(R.string.uploader_info_uploading));
- return pDialog;
- case DIALOG_NO_ACCOUNT:
- builder.setIcon(android.R.drawable.ic_dialog_alert);
- builder.setTitle(R.string.uploader_wrn_no_account_title);
- builder.setMessage(R.string.uploader_wrn_no_account_text);
- builder.setCancelable(false);
- builder.setPositiveButton(R.string.uploader_wrn_no_account_setup_btn_text, new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ECLAIR_MR1) {
- // using string value since in API7 this
- // constatn is not defined
- // in API7 < this constatant is defined in
- // Settings.ADD_ACCOUNT_SETTINGS
- // and Settings.EXTRA_AUTHORITIES
- Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
- intent.putExtra("authorities", new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
- startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
- } else {
- // since in API7 there is no direct call for
- // account setup, so we need to
- // show our own AccountSetupAcricity, get
- // desired results and setup
- // everything for ourself
- Intent intent = new Intent(getBaseContext(), AccountAuthenticator.class);
- startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
- }
- }
- });
- builder.setNegativeButton(R.string.uploader_wrn_no_account_quit_btn_text, new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- finish();
- }
- });
- return builder.create();
- /*case DIALOG_GET_DIRNAME:
- final EditText dirName = new EditText(getBaseContext());
- builder.setView(dirName);
- builder.setTitle(R.string.uploader_info_dirname);
- String pathToUpload;
- if (mParents.empty()) {
- pathToUpload = "/";
- } else {
- mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()), null,
- null, null, null);
- mCursor.moveToFirst();
- pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH))
- + mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20"); // TODO don't make this ; use WebdavUtils.encode in the right moment
- }
- a a = new a(pathToUpload, dirName);
- builder.setPositiveButton(R.string.common_ok, a);
- builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- });
- return builder.create();*/
- case DIALOG_MULTIPLE_ACCOUNT:
- CharSequence ac[] = new CharSequence[mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];
- for (int i = 0; i < ac.length; ++i) {
- ac[i] = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[i].name;
- }
- builder.setTitle(R.string.common_choose_account);
- builder.setItems(ac, new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- mAccount = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[which];
- mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
- populateDirectoryList();
- }
- });
- builder.setCancelable(true);
- builder.setOnCancelListener(new OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- dialog.cancel();
- finish();
- }
- });
- return builder.create();
- default:
- throw new IllegalArgumentException("Unknown dialog id: " + id);
- }
- }
-
- class a implements OnClickListener {
- String mPath;
- EditText mDirname;
-
- public a(String path, EditText dirname) {
- mPath = path;
- mDirname = dirname;
- }
-
- public void onClick(DialogInterface dialog, int which) {
- Uploader.this.mUploadPath = mPath + mDirname.getText().toString();
- Uploader.this.mCreateDir = true;
- uploadFiles();
- }
- }
-
- @Override
- public void onBackPressed() {
-
- if (mParents.size() <= 1) {
- super.onBackPressed();
- return;
- } else {
- mParents.pop();
- populateDirectoryList();
- }
- }
-
- public void onItemClick(AdapterView> parent, View view, int position, long id) {
- // click on folder in the list
- Log.d(TAG, "on item click");
- Vector tmpfiles = mStorageManager.getDirectoryContent(mFile);
- if (tmpfiles == null) return;
- // filter on dirtype
- Vector files = new Vector();
- for (OCFile f : tmpfiles)
- if (f.isDirectory())
- files.add(f);
- if (files.size() < position) {
- throw new IndexOutOfBoundsException("Incorrect item selected");
- }
- mParents.push(files.get(position).getFileName());
- populateDirectoryList();
- }
-
- public void onClick(View v) {
- // click on button
- switch (v.getId()) {
- case R.id.uploader_choose_folder:
- mUploadPath = ""; // first element in mParents is root dir, represented by ""; init mUploadPath with "/" results in a "//" prefix
- for (String p : mParents)
- mUploadPath += p + OCFile.PATH_SEPARATOR;
- Log.d(TAG, "Uploading file to dir " + mUploadPath);
-
- uploadFiles();
-
- break;
- case android.R.id.button1: // dynamic action for create aditional dir
- showDialog(DIALOG_GET_DIRNAME);
- break;
- default:
- throw new IllegalArgumentException("Wrong element clicked");
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- Log.i(TAG, "result received. req: " + requestCode + " res: " + resultCode);
- if (requestCode == REQUEST_CODE_SETUP_ACCOUNT) {
- dismissDialog(DIALOG_NO_ACCOUNT);
- if (resultCode == RESULT_CANCELED) {
- finish();
- }
- Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.AUTH_TOKEN_TYPE);
- if (accounts.length == 0) {
- showDialog(DIALOG_NO_ACCOUNT);
- } else {
- // there is no need for checking for is there more then one
- // account at this point
- // since account setup can set only one account at time
- mAccount = accounts[0];
- populateDirectoryList();
- }
- }
- }
-
- private void populateDirectoryList() {
- setContentView(R.layout.uploader_layout);
-
- String full_path = "";
- for (String a : mParents)
- full_path += a + "/";
-
- Log.d(TAG, "Populating view with content of : " + full_path);
-
- mFile = mStorageManager.getFileByPath(full_path);
- if (mFile != null) {
- Vector files = mStorageManager.getDirectoryContent(mFile);
- if (files != null) {
- List> data = new LinkedList>();
- for (OCFile f : files) {
- HashMap h = new HashMap();
- if (f.isDirectory()) {
- h.put("dirname", f.getFileName());
- data.add(h);
- }
- }
- SimpleAdapter sa = new SimpleAdapter(this,
- data,
- R.layout.uploader_list_item_layout,
- new String[] {"dirname"},
- new int[] {R.id.textView1});
- setListAdapter(sa);
- Button btn = (Button) findViewById(R.id.uploader_choose_folder);
- btn.setOnClickListener(this);
- getListView().setOnItemClickListener(this);
- }
- }
- /*
- mCursor = managedQuery(ProviderMeta.ProviderTableMeta.CONTENT_URI, null, ProviderTableMeta.FILE_NAME
- + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", new String[] { "/", mAccount.name }, null);
-
- if (mCursor.moveToFirst()) {
- mCursor = managedQuery(
- ProviderMeta.ProviderTableMeta.CONTENT_URI,
- null,
- ProviderTableMeta.FILE_CONTENT_TYPE + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND "
- + ProviderTableMeta.FILE_PARENT + "=?",
- new String[] { "DIR", mAccount.name,
- mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID)) }, null);
-
- ListView lv = getListView();
- lv.setOnItemClickListener(this);
- SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout, mCursor,
- new String[] { ProviderTableMeta.FILE_NAME }, new int[] { R.id.textView1 });
- setListAdapter(sca);
- Button btn = (Button) findViewById(R.id.uploader_choose_folder);
- btn.setOnClickListener(this);
- /*
- * disable this until new server interaction service wont be created
- * // insert create new directory for multiple items uploading if
- * (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
- * Button createDirBtn = new Button(this);
- * createDirBtn.setId(android.R.id.button1);
- * createDirBtn.setText(R.string.uploader_btn_create_dir_text);
- * createDirBtn.setOnClickListener(this); ((LinearLayout)
- * findViewById(R.id.linearLayout1)).addView( createDirBtn,
- * LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); }
- *
- }*/
- }
-
- private void prepareStreamsToUpload() {
- if (getIntent().getAction().equals(Intent.ACTION_SEND)) {
- mStreamsToUpload = new ArrayList();
- mStreamsToUpload.add(getIntent().getParcelableExtra(Intent.EXTRA_STREAM));
- } else if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
- mStreamsToUpload = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM);
- } else {
- // unknow action inserted
- throw new IllegalArgumentException("Unknown action given: " + getIntent().getAction());
- }
- }
-
- public void uploadFiles() {
- WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());
- wdc.allowSelfsignedCertificates();
-
- // create last directory in path if nessesary
- if (mCreateDir) {
- wdc.createDirectory(mUploadPath);
- }
-
- String[] local = new String[mStreamsToUpload.size()], remote = new String[mStreamsToUpload.size()];
-
- for (int i = 0; i < mStreamsToUpload.size(); ++i) {
- Uri uri = (Uri) mStreamsToUpload.get(i);
- if (uri.getScheme().equals("content")) {
- Cursor c = getContentResolver().query((Uri) mStreamsToUpload.get(i),
- CONTENT_PROJECTION,
- null,
- null,
- null);
-
- if (!c.moveToFirst())
- continue;
-
- final String display_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
- data = c.getString(c.getColumnIndex(Media.DATA));
- local[i] = data;
- remote[i] = mUploadPath + display_name;
- } else if (uri.getScheme().equals("file")) {
- final File file = new File(Uri.decode(uri.toString()).replace(uri.getScheme() + "://", ""));
- local[i] = file.getAbsolutePath();
- remote[i] = mUploadPath + file.getName();
- }
-
- }
- Intent intent = new Intent(getApplicationContext(), FileUploader.class);
- intent.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_MULTIPLE_FILES);
- intent.putExtra(FileUploader.KEY_LOCAL_FILE, local);
- intent.putExtra(FileUploader.KEY_REMOTE_FILE, remote);
- intent.putExtra(FileUploader.KEY_ACCOUNT, mAccount);
- startService(intent);
- finish();
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/authenticator/AccountAuthenticator.java b/src/eu/alefzero/owncloud/authenticator/AccountAuthenticator.java
deleted file mode 100644
index be0b8e00..00000000
--- a/src/eu/alefzero/owncloud/authenticator/AccountAuthenticator.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.authenticator;
-
-import eu.alefzero.owncloud.ui.activity.AuthenticatorActivity;
-import android.accounts.*;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-
-public class AccountAuthenticator extends AbstractAccountAuthenticator {
- /**
- * Is used by android system to assign accounts to authenticators. Should be
- * used by application and all extensions.
- */
- public static final String ACCOUNT_TYPE = "owncloud";
- public static final String AUTH_TOKEN_TYPE = "org.owncloud";
-
- public static final String KEY_AUTH_TOKEN_TYPE = "authTokenType";
- public static final String KEY_REQUIRED_FEATURES = "requiredFeatures";
- public static final String KEY_LOGIN_OPTIONS = "loginOptions";
- public static final String KEY_ACCOUNT = "account";
- /**
- * Value under this key should handle path to webdav php script. Will be
- * removed and usage should be replaced by combining
- * {@link eu.alefzero.owncloud.authenticator.KEY_OC_BASE_URL} and
- * {@link eu.alefzero.owncloud.utils.OwnCloudVersion}
- *
- * @deprecated
- */
- public static final String KEY_OC_URL = "oc_url";
- /**
- * Version should be 3 numbers separated by dot so it can be parsed by
- * {@link eu.alefzero.owncloud.utils.OwnCloudVersion}
- */
- public static final String KEY_OC_VERSION = "oc_version";
- /**
- * Base url should point to owncloud installation without trailing / ie:
- * http://server/path or https://owncloud.server
- */
- public static final String KEY_OC_BASE_URL = "oc_base_url";
-
- private static final String TAG = "AccountAuthenticator";
- private Context mContext;
-
- public AccountAuthenticator(Context context) {
- super(context);
- mContext = context;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Bundle addAccount(AccountAuthenticatorResponse response,
- String accountType, String authTokenType,
- String[] requiredFeatures, Bundle options)
- throws NetworkErrorException {
- Log.i(TAG, "Adding account with type " + accountType
- + " and auth token " + authTokenType);
- try {
- validateAccountType(accountType);
- } catch (AuthenticatorException e) {
- Log.e(TAG, "Failed to validate account type " + accountType + ": "
- + e.getMessage());
- e.printStackTrace();
- return e.getFailureBundle();
- }
- final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
- intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
- response);
- intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
- intent.putExtra(KEY_REQUIRED_FEATURES, requiredFeatures);
- intent.putExtra(KEY_LOGIN_OPTIONS, options);
-
- setIntentFlags(intent);
- final Bundle bundle = new Bundle();
- bundle.putParcelable(AccountManager.KEY_INTENT, intent);
- return bundle;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Bundle confirmCredentials(AccountAuthenticatorResponse response,
- Account account, Bundle options) throws NetworkErrorException {
- try {
- validateAccountType(account.type);
- } catch (AuthenticatorException e) {
- Log.e(TAG, "Failed to validate account type " + account.type + ": "
- + e.getMessage());
- e.printStackTrace();
- return e.getFailureBundle();
- }
- Intent intent = new Intent(mContext, AuthenticatorActivity.class);
- intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
- response);
- intent.putExtra(KEY_ACCOUNT, account);
- intent.putExtra(KEY_LOGIN_OPTIONS, options);
-
- setIntentFlags(intent);
-
- Bundle resultBundle = new Bundle();
- resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);
- return resultBundle;
- }
-
- @Override
- public Bundle editProperties(AccountAuthenticatorResponse response,
- String accountType) {
- return null;
- }
-
- @Override
- public Bundle getAuthToken(AccountAuthenticatorResponse response,
- Account account, String authTokenType, Bundle options)
- throws NetworkErrorException {
- try {
- validateAccountType(account.type);
- validateAuthTokenType(authTokenType);
- } catch (AuthenticatorException e) {
- Log.e(TAG, "Failed to validate account type " + account.type + ": "
- + e.getMessage());
- e.printStackTrace();
- return e.getFailureBundle();
- }
- final AccountManager am = AccountManager.get(mContext);
- final String password = am.getPassword(account);
- if (password != null) {
- final Bundle result = new Bundle();
- result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
- result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
- result.putString(AccountManager.KEY_AUTHTOKEN, password);
- return result;
- }
-
- final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
- intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
- response);
- intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
- intent.putExtra(KEY_LOGIN_OPTIONS, options);
- intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
-
- final Bundle bundle = new Bundle();
- bundle.putParcelable(AccountManager.KEY_INTENT, intent);
- return bundle;
- }
-
- @Override
- public String getAuthTokenLabel(String authTokenType) {
- return null;
- }
-
- @Override
- public Bundle hasFeatures(AccountAuthenticatorResponse response,
- Account account, String[] features) throws NetworkErrorException {
- final Bundle result = new Bundle();
- result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
- return result;
- }
-
- @Override
- public Bundle updateCredentials(AccountAuthenticatorResponse response,
- Account account, String authTokenType, Bundle options)
- throws NetworkErrorException {
- final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
- intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
- response);
- intent.putExtra(KEY_ACCOUNT, account);
- intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
- intent.putExtra(KEY_LOGIN_OPTIONS, options);
- setIntentFlags(intent);
-
- final Bundle bundle = new Bundle();
- bundle.putParcelable(AccountManager.KEY_INTENT, intent);
- return bundle;
- }
-
- @Override
- public Bundle getAccountRemovalAllowed(
- AccountAuthenticatorResponse response, Account account)
- throws NetworkErrorException {
- return super.getAccountRemovalAllowed(response, account);
- }
-
- private void setIntentFlags(Intent intent) {
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
- intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
- intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
- }
-
- private void validateAccountType(String type)
- throws UnsupportedAccountTypeException {
- if (!type.equals(ACCOUNT_TYPE)) {
- throw new UnsupportedAccountTypeException();
- }
- }
-
- private void validateAuthTokenType(String authTokenType)
- throws UnsupportedAuthTokenTypeException {
- if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {
- throw new UnsupportedAuthTokenTypeException();
- }
- }
-
- public static class AuthenticatorException extends Exception {
- private static final long serialVersionUID = 1L;
- private Bundle mFailureBundle;
-
- public AuthenticatorException(int code, String errorMsg) {
- mFailureBundle = new Bundle();
- mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);
- mFailureBundle
- .putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
- }
-
- public Bundle getFailureBundle() {
- return mFailureBundle;
- }
- }
-
- public static class UnsupportedAccountTypeException extends
- AuthenticatorException {
- private static final long serialVersionUID = 1L;
-
- public UnsupportedAccountTypeException() {
- super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
- "Unsupported account type");
- }
- }
-
- public static class UnsupportedAuthTokenTypeException extends
- AuthenticatorException {
- private static final long serialVersionUID = 1L;
-
- public UnsupportedAuthTokenTypeException() {
- super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
- "Unsupported auth token type");
- }
- }
-
- public static class UnsupportedFeaturesException extends
- AuthenticatorException {
- public static final long serialVersionUID = 1L;
-
- public UnsupportedFeaturesException() {
- super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
- "Unsupported features");
- }
- }
-
- public static class AccessDeniedException extends AuthenticatorException {
- public AccessDeniedException(int code, String errorMsg) {
- super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");
- }
-
- private static final long serialVersionUID = 1L;
-
- }
-}
diff --git a/src/eu/alefzero/owncloud/authenticator/AccountAuthenticatorService.java b/src/eu/alefzero/owncloud/authenticator/AccountAuthenticatorService.java
deleted file mode 100644
index 69e88476..00000000
--- a/src/eu/alefzero/owncloud/authenticator/AccountAuthenticatorService.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.authenticator;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-public class AccountAuthenticatorService extends Service {
-
- private AccountAuthenticator mAuthenticator;
- static final public String ACCOUNT_TYPE = "owncloud";
-
- @Override
- public void onCreate() {
- super.onCreate();
- mAuthenticator = new AccountAuthenticator(this);
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return mAuthenticator.getIBinder();
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/authenticator/AuthenticationRunnable.java b/src/eu/alefzero/owncloud/authenticator/AuthenticationRunnable.java
deleted file mode 100644
index 691c93e6..00000000
--- a/src/eu/alefzero/owncloud/authenticator/AuthenticationRunnable.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.authenticator;
-
-import java.net.URL;
-
-import org.apache.commons.httpclient.HttpStatus;
-
-import eu.alefzero.webdav.WebdavClient;
-
-import android.net.Uri;
-import android.os.Handler;
-
-public class AuthenticationRunnable implements Runnable {
-
- private OnAuthenticationResultListener mListener;
- private Handler mHandler;
- private URL mUrl;
- private String mUsername;
- private String mPassword;
-
- public AuthenticationRunnable(URL url, String username, String password) {
- mListener = null;
- mUrl = url;
- mUsername = username;
- mPassword = password;
- }
-
- public void setOnAuthenticationResultListener(
- OnAuthenticationResultListener listener, Handler handler) {
- mListener = listener;
- mHandler = handler;
- }
-
- @Override
- public void run() {
- Uri uri;
- uri = Uri.parse(mUrl.toString());
- int login_result = WebdavClient.tryToLogin(uri, mUsername, mPassword);
- switch (login_result) {
- case HttpStatus.SC_OK:
- postResult(true, uri.toString());
- break;
- case HttpStatus.SC_UNAUTHORIZED:
- postResult(false, "Invalid login or/and password");
- break;
- case HttpStatus.SC_NOT_FOUND:
- postResult(false, "Wrong path given");
- break;
- default:
- postResult(false, "Internal server error, code: " + login_result);
- }
- }
-
- private void postResult(final boolean success, final String message) {
- if (mHandler != null && mListener != null) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mListener.onAuthenticationResult(success, message);
- }
- });
- }
- }
-}
diff --git a/src/eu/alefzero/owncloud/authenticator/ConnectionCheckerRunnable.java b/src/eu/alefzero/owncloud/authenticator/ConnectionCheckerRunnable.java
deleted file mode 100644
index 119b2422..00000000
--- a/src/eu/alefzero/owncloud/authenticator/ConnectionCheckerRunnable.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.authenticator;
-
-import java.net.ConnectException;
-import java.net.SocketTimeoutException;
-import java.net.UnknownHostException;
-
-import javax.net.ssl.SSLHandshakeException;
-
-import org.apache.commons.httpclient.HttpStatus;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.authenticator.OnConnectCheckListener.ResultType;
-import eu.alefzero.owncloud.utils.OwnCloudVersion;
-import eu.alefzero.webdav.WebdavClient;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.Uri;
-import android.os.Handler;
-import android.util.Log;
-
-public class ConnectionCheckerRunnable implements Runnable {
-
- /** Maximum time to wait for a response from the server when the connection is being tested, in MILLISECONDs. */
- public static final int TRY_CONNECTION_TIMEOUT = 5000;
-
- private static final String TAG = "ConnectionCheckerRunnable";
- private OnConnectCheckListener mListener;
- private String mUrl;
- private Handler mHandler;
- private ResultType mLatestResult;
- private Context mContext;
- private OwnCloudVersion mOCVersion;
-
- public void setListener(OnConnectCheckListener listener, Handler handler) {
- mListener = listener;
- mHandler = handler;
- }
-
- public ConnectionCheckerRunnable(String url, Context context) {
- mListener = null;
- mHandler = null;
- mUrl = url;
- mContext = context;
- mOCVersion = null;
- }
-
- @Override
- public void run() {
-
- if (!isOnline()) {
- postResult(ResultType.NO_NETWORK_CONNECTION);
- return;
- }
- if (mUrl.startsWith("http://") || mUrl.startsWith("https://")) {
- mLatestResult = (mUrl.startsWith("https://"))? ResultType.OK_SSL : ResultType.OK_NO_SSL;
- tryConnection(Uri.parse(mUrl + AccountUtils.STATUS_PATH));
- postResult(mLatestResult);
- } else {
- Uri uri = Uri.parse("https://" + mUrl + AccountUtils.STATUS_PATH);
- if (tryConnection(uri)) {
- postResult(ResultType.OK_SSL);
- return;
- }
- Log.d(TAG,
- "establishing secure connection failed, trying non secure connection");
- uri = Uri.parse("http://" + mUrl + AccountUtils.STATUS_PATH);
-
- if (tryConnection(uri)) {
- postResult(ResultType.OK_NO_SSL);
- return;
- }
- postResult(mLatestResult);
- }
- }
-
- public OwnCloudVersion getDiscoveredVersion() {
- return mOCVersion;
- }
-
- private boolean tryConnection(Uri uri) {
- WebdavClient wc = new WebdavClient();
- wc.allowSelfsignedCertificates();
- GetMethod get = new GetMethod(uri.toString());
- boolean retval = false;
- try {
- int status = wc.executeMethod(get, TRY_CONNECTION_TIMEOUT);
- switch (status) {
- case HttpStatus.SC_OK: {
- String response = get.getResponseBodyAsString();
- JSONObject json = new JSONObject(response);
- if (!json.getBoolean("installed")) {
- mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
- break;
- }
- mOCVersion = new OwnCloudVersion(json.getString("version"));
- if (!mOCVersion.isVersionValid())
- break;
- retval = true;
- break;
- }
- case HttpStatus.SC_NOT_FOUND:
- mLatestResult = ResultType.FILE_NOT_FOUND;
- break;
- case HttpStatus.SC_INTERNAL_SERVER_ERROR:
- mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
- break;
- default:
- mLatestResult = ResultType.UNKNOWN_ERROR;
- Log.e(TAG, "Not handled status received from server: " + status);
- }
-
- } catch (Exception e) {
- if (e instanceof UnknownHostException
- || e instanceof ConnectException
- || e instanceof SocketTimeoutException) {
- mLatestResult = ResultType.HOST_NOT_AVAILABLE;
- } else if (e instanceof JSONException) {
- mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
- } else if (e instanceof SSLHandshakeException) {
- mLatestResult = ResultType.SSL_INIT_ERROR;
- } else {
- mLatestResult = ResultType.UNKNOWN_ERROR;
- }
- e.printStackTrace();
- }
-
- return retval;
- }
-
- private boolean isOnline() {
- ConnectivityManager cm = (ConnectivityManager) mContext
- .getSystemService(Context.CONNECTIVITY_SERVICE);
- return cm != null && cm.getActiveNetworkInfo() != null
- && cm.getActiveNetworkInfo().isConnectedOrConnecting();
- }
-
- private void postResult(final ResultType result) {
- if (mHandler != null && mListener != null) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mListener.onConnectionCheckResult(result);
- }
- });
- }
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java b/src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java
deleted file mode 100644
index f1de8f5f..00000000
--- a/src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * $HeadURL$
- * $Revision$
- * $Date$
- *
- * ====================================================================
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * .
- *
- */
-
-package eu.alefzero.owncloud.authenticator;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.UnknownHostException;
-
-import javax.net.SocketFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-
-import org.apache.commons.httpclient.ConnectTimeoutException;
-import org.apache.commons.httpclient.HttpClientError;
-import org.apache.commons.httpclient.params.HttpConnectionParams;
-import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
-import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
-
-import android.util.Log;
-
-/**
- *
- * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s that
- * accept self-signed certificates.
- *
- *
- * This socket factory SHOULD NOT be used for productive systems due to security
- * reasons, unless it is a concious decision and you are perfectly aware of
- * security implications of accepting self-signed certificates
- *
- *
- *
- * Example of using custom protocol socket factory for a specific host:
- *
- *
- * Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(),
- * 443);
- *
- * URI uri = new URI("https://localhost/", true);
- * // use relative url only
- * GetMethod httpget = new GetMethod(uri.getPathQuery());
- * HostConfiguration hc = new HostConfiguration();
- * hc.setHost(uri.getHost(), uri.getPort(), easyhttps);
- * HttpClient client = new HttpClient();
- * client.executeMethod(hc, httpget);
- *
- *
- *
- *
- * Example of using custom protocol socket factory per default instead of the
- * standard one:
- *
- *
- * Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(),
- * 443);
- * Protocol.registerProtocol("https", easyhttps);
- *
- * HttpClient client = new HttpClient();
- * GetMethod httpget = new GetMethod("https://localhost/");
- * client.executeMethod(httpget);
- *
- *
- *
- *
- * @author Oleg Kalnichevski
- *
- *
- * DISCLAIMER: HttpClient developers DO NOT actively support this
- * component. The component is provided as a reference material, which
- * may be inappropriate for use without additional customization.
- *
- */
-
-public class EasySSLSocketFactory implements ProtocolSocketFactory {
-
- private static final String TAG = "EasySSLSocketFactory";
- private SSLContext sslcontext = null;
-
- /**
- * Constructor for EasySSLProtocolSocketFactory.
- */
- public EasySSLSocketFactory() {
- super();
- }
-
- private static SSLContext createEasySSLContext() {
- try {
- SSLContext context = SSLContext.getInstance("TLS");
- context.init(null, new TrustManager[] { new EasyX509TrustManager(
- null) }, null);
- return context;
- } catch (Exception er) {
- Log.e(TAG, er.getMessage() + "");
- throw new HttpClientError(er.toString());
- }
- }
-
- private SSLContext getSSLContext() {
- if (this.sslcontext == null) {
- this.sslcontext = createEasySSLContext();
- }
- return this.sslcontext;
- }
-
- /**
- * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
- */
- public Socket createSocket(String host, int port, InetAddress clientHost,
- int clientPort) throws IOException, UnknownHostException {
-
- return getSSLContext().getSocketFactory().createSocket(host, port,
- clientHost, clientPort);
- }
-
- /**
- * Attempts to get a new socket connection to the given host within the
- * given time limit.
- *
- * To circumvent the limitations of older JREs that do not support connect
- * timeout a controller thread is executed. The controller thread attempts
- * to create a new socket within the given limit of time. If socket
- * constructor does not return until the timeout expires, the controller
- * terminates and throws an {@link ConnectTimeoutException}
- *
- *
- * @param host the host name/IP
- * @param port the port on the host
- * @param clientHost the local host name/IP to bind the socket to
- * @param clientPort the port on the local machine
- * @param params {@link HttpConnectionParams Http connection parameters}
- *
- * @return Socket a new socket
- *
- * @throws IOException if an I/O error occurs while creating the socket
- * @throws UnknownHostException if the IP address of the host cannot be
- * determined
- */
- public Socket createSocket(final String host, final int port,
- final InetAddress localAddress, final int localPort,
- final HttpConnectionParams params) throws IOException,
- UnknownHostException, ConnectTimeoutException {
- if (params == null) {
- throw new IllegalArgumentException("Parameters may not be null");
- }
- int timeout = params.getConnectionTimeout();
- SocketFactory socketfactory = getSSLContext().getSocketFactory();
- if (timeout == 0) {
- Socket socket = socketfactory.createSocket(host, port, localAddress,
- localPort);
- socket.setSoTimeout(params.getSoTimeout());
- return socket;
- } else {
- Socket socket = socketfactory.createSocket();
- SocketAddress localaddr = new InetSocketAddress(localAddress,
- localPort);
- SocketAddress remoteaddr = new InetSocketAddress(host, port);
- socket.setSoTimeout(params.getSoTimeout());
- socket.bind(localaddr);
- socket.connect(remoteaddr, timeout);
- return socket;
- }
- }
-
- /**
- * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
- */
- public Socket createSocket(String host, int port) throws IOException,
- UnknownHostException {
- return getSSLContext().getSocketFactory().createSocket(host, port);
- }
-
- /**
- * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
- */
- public Socket createSocket(Socket socket, String host, int port,
- boolean autoClose) throws IOException, UnknownHostException {
- return getSSLContext().getSocketFactory().createSocket(socket, host,
- port, autoClose);
- }
-
- public boolean equals(Object obj) {
- return ((obj != null) && obj.getClass().equals(
- EasySSLSocketFactory.class));
- }
-
- public int hashCode() {
- return EasySSLSocketFactory.class.hashCode();
- }
-
-}
\ No newline at end of file
diff --git a/src/eu/alefzero/owncloud/authenticator/EasyX509TrustManager.java b/src/eu/alefzero/owncloud/authenticator/EasyX509TrustManager.java
deleted file mode 100644
index bdd659d7..00000000
--- a/src/eu/alefzero/owncloud/authenticator/EasyX509TrustManager.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package eu.alefzero.owncloud.authenticator;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
-/**
- * @author olamy
- * @version $Id: EasyX509TrustManager.java 765355 2009-04-15 20:59:07Z evenisse
- * $
- * @since 1.2.3
- */
-public class EasyX509TrustManager implements X509TrustManager {
-
- private X509TrustManager standardTrustManager = null;
-
- /**
- * Constructor for EasyX509TrustManager.
- */
- public EasyX509TrustManager(KeyStore keystore)
- throws NoSuchAlgorithmException, KeyStoreException {
- super();
- TrustManagerFactory factory = TrustManagerFactory
- .getInstance(TrustManagerFactory.getDefaultAlgorithm());
- factory.init(keystore);
- TrustManager[] trustmanagers = factory.getTrustManagers();
- if (trustmanagers.length == 0) {
- throw new NoSuchAlgorithmException("no trust manager found");
- }
- this.standardTrustManager = (X509TrustManager) trustmanagers[0];
- }
-
- /**
- * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],
- * String authType)
- */
- public void checkClientTrusted(X509Certificate[] certificates,
- String authType) throws CertificateException {
- standardTrustManager.checkClientTrusted(certificates, authType);
- }
-
- /**
- * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],
- * String authType)
- */
- public void checkServerTrusted(X509Certificate[] certificates,
- String authType) throws CertificateException {
- if ((certificates != null) && (certificates.length == 1)) {
- certificates[0].checkValidity();
- } else {
- // standardTrustManager.checkServerTrusted( certificates, authType
- // );
- }
- }
-
- /**
- * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
- */
- public X509Certificate[] getAcceptedIssuers() {
- return this.standardTrustManager.getAcceptedIssuers();
- }
-
-}
\ No newline at end of file
diff --git a/src/eu/alefzero/owncloud/authenticator/OnAuthenticationResultListener.java b/src/eu/alefzero/owncloud/authenticator/OnAuthenticationResultListener.java
deleted file mode 100644
index a8764eef..00000000
--- a/src/eu/alefzero/owncloud/authenticator/OnAuthenticationResultListener.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package eu.alefzero.owncloud.authenticator;
-
-public interface OnAuthenticationResultListener {
-
- public void onAuthenticationResult(boolean success, String message);
-
-}
diff --git a/src/eu/alefzero/owncloud/authenticator/OnConnectCheckListener.java b/src/eu/alefzero/owncloud/authenticator/OnConnectCheckListener.java
deleted file mode 100644
index f7da0da0..00000000
--- a/src/eu/alefzero/owncloud/authenticator/OnConnectCheckListener.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package eu.alefzero.owncloud.authenticator;
-
-public interface OnConnectCheckListener {
-
- enum ResultType {
- OK_SSL, OK_NO_SSL, SSL_INIT_ERROR, HOST_NOT_AVAILABLE, TIMEOUT, NO_NETWORK_CONNECTION, INORRECT_ADDRESS, INSTANCE_NOT_CONFIGURED, FILE_NOT_FOUND, UNKNOWN_ERROR
- }
-
- public void onConnectionCheckResult(ResultType type);
-
-}
diff --git a/src/eu/alefzero/owncloud/datamodel/DataStorageManager.java b/src/eu/alefzero/owncloud/datamodel/DataStorageManager.java
deleted file mode 100644
index 9f1d89bd..00000000
--- a/src/eu/alefzero/owncloud/datamodel/DataStorageManager.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.datamodel;
-
-import java.util.List;
-import java.util.Vector;
-
-public interface DataStorageManager {
-
- public OCFile getFileByPath(String path);
-
- public OCFile getFileById(long id);
-
- public boolean fileExists(String path);
-
- public boolean fileExists(long id);
-
- public boolean saveFile(OCFile file);
-
- public void saveFiles(List files);
-
- public Vector getDirectoryContent(OCFile f);
-
- public void removeFile(OCFile file);
-}
diff --git a/src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java b/src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java
deleted file mode 100644
index f0d0db25..00000000
--- a/src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java
+++ /dev/null
@@ -1,421 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.datamodel;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Vector;
-
-import eu.alefzero.owncloud.db.ProviderMeta;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-import eu.alefzero.owncloud.files.services.FileDownloader;
-import android.accounts.Account;
-import android.content.ContentProviderClient;
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.OperationApplicationException;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.RemoteException;
-import android.util.Log;
-
-public class FileDataStorageManager implements DataStorageManager {
-
- private ContentResolver mContentResolver;
- private ContentProviderClient mContentProvider;
- private Account mAccount;
-
- private static String TAG = "FileDataStorageManager";
-
- public FileDataStorageManager(Account account, ContentResolver cr) {
- mContentProvider = null;
- mContentResolver = cr;
- mAccount = account;
- }
-
- public FileDataStorageManager(Account account, ContentProviderClient cp) {
- mContentProvider = cp;
- mContentResolver = null;
- mAccount = account;
- }
-
- @Override
- public OCFile getFileByPath(String path) {
- Cursor c = getCursorForValue(ProviderTableMeta.FILE_PATH, path);
- OCFile file = null;
- if (c.moveToFirst()) {
- file = createFileInstance(c);
- }
- c.close();
- return file;
- }
-
- @Override
- public OCFile getFileById(long id) {
- Cursor c = getCursorForValue(ProviderTableMeta._ID, String.valueOf(id));
- OCFile file = null;
- if (c.moveToFirst()) {
- file = createFileInstance(c);
- }
- c.close();
- return file;
- }
-
- @Override
- public boolean fileExists(long id) {
- return fileExists(ProviderTableMeta._ID, String.valueOf(id));
- }
-
- @Override
- public boolean fileExists(String path) {
- return fileExists(ProviderTableMeta.FILE_PATH, path);
- }
-
- @Override
- public boolean saveFile(OCFile file) {
- boolean overriden = false;
- ContentValues cv = new ContentValues();
- cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
- cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
- cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
- cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
- cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
- if (file.getParentId() != 0)
- cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
- cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
- if (!file.isDirectory())
- cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
- cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
- cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDate());
- cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
-
- if (fileExists(file.getRemotePath())) {
- OCFile oldFile = getFileByPath(file.getRemotePath());
- if (file.getStoragePath() == null && oldFile.getStoragePath() != null)
- file.setStoragePath(oldFile.getStoragePath());
- if (!file.isDirectory());
- cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
- file.setFileId(oldFile.getFileId());
-
- overriden = true;
- if (getContentResolver() != null) {
- getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv,
- ProviderTableMeta._ID + "=?",
- new String[] { String.valueOf(file.getFileId()) });
- } else {
- try {
- getContentProvider().update(ProviderTableMeta.CONTENT_URI,
- cv, ProviderTableMeta._ID + "=?",
- new String[] { String.valueOf(file.getFileId()) });
- } catch (RemoteException e) {
- Log.e(TAG,
- "Fail to insert insert file to database "
- + e.getMessage());
- }
- }
- } else {
- Uri result_uri = null;
- if (getContentResolver() != null) {
- result_uri = getContentResolver().insert(
- ProviderTableMeta.CONTENT_URI_FILE, cv);
- } else {
- try {
- result_uri = getContentProvider().insert(
- ProviderTableMeta.CONTENT_URI_FILE, cv);
- } catch (RemoteException e) {
- Log.e(TAG,
- "Fail to insert insert file to database "
- + e.getMessage());
- }
- }
- if (result_uri != null) {
- long new_id = Long.parseLong(result_uri.getPathSegments()
- .get(1));
- file.setFileId(new_id);
- }
- }
-
- if (file.isDirectory() && file.needsUpdatingWhileSaving())
- for (OCFile f : getDirectoryContent(file))
- saveFile(f);
-
- return overriden;
- }
-
-
- @Override
- public void saveFiles(List files) {
-
- Iterator filesIt = files.iterator();
- ArrayList operations = new ArrayList(files.size());
- OCFile file = null;
-
- // prepare operations to perform
- while (filesIt.hasNext()) {
- file = filesIt.next();
- ContentValues cv = new ContentValues();
- cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
- cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
- cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
- cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
- cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
- if (file.getParentId() != 0)
- cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
- cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
- if (!file.isDirectory())
- cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
- cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
- cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDate());
- cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
-
- if (fileExists(file.getRemotePath())) {
- OCFile tmpfile = getFileByPath(file.getRemotePath());
- file.setStoragePath(tmpfile.getStoragePath());
- if (!file.isDirectory());
- cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
- file.setFileId(tmpfile.getFileId());
-
- operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
- withValues(cv).
- withSelection( ProviderTableMeta._ID + "=?",
- new String[] { String.valueOf(file.getFileId()) })
- .build());
-
- } else {
- operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
- }
- }
-
- // apply operations in batch
- ContentProviderResult[] results = null;
- try {
- if (getContentResolver() != null) {
- results = getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations);
-
- } else {
- results = getContentProvider().applyBatch(operations);
- }
-
- } catch (OperationApplicationException e) {
- Log.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
-
- } catch (RemoteException e) {
- Log.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
- }
-
- // update new id in file objects for insertions
- if (results != null) {
- long newId;
- for (int i=0; i getDirectoryContent(OCFile f) {
- if (f != null && f.isDirectory() && f.getFileId() != -1) {
- Vector ret = new Vector();
-
- Uri req_uri = Uri.withAppendedPath(
- ProviderTableMeta.CONTENT_URI_DIR,
- String.valueOf(f.getFileId()));
- Cursor c = null;
-
- if (getContentProvider() != null) {
- try {
- c = getContentProvider().query(req_uri, null,
- ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
- new String[] { mAccount.name }, null);
- } catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
- return ret;
- }
- } else {
- c = getContentResolver().query(req_uri, null,
- ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
- new String[] { mAccount.name }, null);
- }
-
- if (c.moveToFirst()) {
- do {
- OCFile child = createFileInstance(c);
- ret.add(child);
- } while (c.moveToNext());
- }
-
- c.close();
-
- Collections.sort(ret);
-
- return ret;
- }
- return null;
- }
-
- private boolean fileExists(String cmp_key, String value) {
- Cursor c;
- if (getContentResolver() != null) {
- c = getContentResolver()
- .query(ProviderTableMeta.CONTENT_URI,
- null,
- cmp_key + "=? AND "
- + ProviderTableMeta.FILE_ACCOUNT_OWNER
- + "=?",
- new String[] { value, mAccount.name }, null);
- } else {
- try {
- c = getContentProvider().query(
- ProviderTableMeta.CONTENT_URI,
- null,
- cmp_key + "=? AND "
- + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
- new String[] { value, mAccount.name }, null);
- } catch (RemoteException e) {
- Log.e(TAG,
- "Couldn't determine file existance, assuming non existance: "
- + e.getMessage());
- return false;
- }
- }
- boolean retval = c.moveToFirst();
- c.close();
- return retval;
- }
-
- private Cursor getCursorForValue(String key, String value) {
- Cursor c = null;
- if (getContentResolver() != null) {
- c = getContentResolver()
- .query(ProviderTableMeta.CONTENT_URI,
- null,
- key + "=? AND "
- + ProviderTableMeta.FILE_ACCOUNT_OWNER
- + "=?",
- new String[] { value, mAccount.name }, null);
- } else {
- try {
- c = getContentProvider().query(
- ProviderTableMeta.CONTENT_URI,
- null,
- key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER
- + "=?", new String[] { value, mAccount.name },
- null);
- } catch (RemoteException e) {
- Log.e(TAG, "Could not get file details: " + e.getMessage());
- c = null;
- }
- }
- return c;
- }
-
- private OCFile createFileInstance(Cursor c) {
- OCFile file = null;
- if (c != null) {
- file = new OCFile(c.getString(c
- .getColumnIndex(ProviderTableMeta.FILE_PATH)));
- file.setFileId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
- file.setParentId(c.getLong(c
- .getColumnIndex(ProviderTableMeta.FILE_PARENT)));
- file.setMimetype(c.getString(c
- .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)));
- if (!file.isDirectory()) {
- file.setStoragePath(c.getString(c
- .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));
- if (file.getStoragePath() == null) {
- // try to find existing file and bind it with current account
- File f = new File(FileDownloader.getSavePath(mAccount.name) + file.getRemotePath());
- if (f.exists())
- file.setStoragePath(f.getAbsolutePath());
- }
- }
- file.setFileLength(c.getLong(c
- .getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH)));
- file.setCreationTimestamp(c.getLong(c
- .getColumnIndex(ProviderTableMeta.FILE_CREATION)));
- file.setModificationTimestamp(c.getLong(c
- .getColumnIndex(ProviderTableMeta.FILE_MODIFIED)));
- file.setLastSyncDate(c.getLong(c
- .getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE)));
- file.setKeepInSync(c.getInt(
- c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false);
- }
- return file;
- }
-
- public void removeFile(OCFile file) {
- Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, ""+file.getFileId());
- if (getContentProvider() != null) {
- try {
- getContentProvider().delete(file_uri,
- ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
- new String[]{mAccount.name});
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- } else {
- getContentResolver().delete(file_uri,
- ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
- new String[]{mAccount.name});
- }
- if (file.isDown()) {
- new File(file.getStoragePath()).delete();
- }
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/datamodel/OCFile.java b/src/eu/alefzero/owncloud/datamodel/OCFile.java
deleted file mode 100644
index 01a1f58f..00000000
--- a/src/eu/alefzero/owncloud/datamodel/OCFile.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.datamodel;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import eu.alefzero.owncloud.files.services.FileDownloader;
-
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class OCFile implements Parcelable, Comparable {
-
- public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
- @Override
- public OCFile createFromParcel(Parcel source) {
- return new OCFile(source);
- }
-
- @Override
- public OCFile[] newArray(int size) {
- return new OCFile[size];
- }
- };
-
- public static final String PATH_SEPARATOR = "/";
-
- private long mId;
- private long mParentId;
- private long mLength;
- private long mCreationTimestamp;
- private long mModifiedTimestamp;
- private String mRemotePath;
- private String mLocalPath;
- private String mMimeType;
- private boolean mNeedsUpdating;
- private long mLastSyncDate;
- private boolean mKeepInSync;
-
- /**
- * Create new {@link OCFile} with given path.
- *
- * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'.
- *
- * @param path The remote path of the file.
- */
- public OCFile(String path) {
- resetData();
- mNeedsUpdating = false;
- if (path == null || path.length() <= 0 || !path.startsWith(PATH_SEPARATOR)) {
- throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path);
- }
- mRemotePath = path;
- }
-
- /**
- * Reconstruct from parcel
- *
- * @param source The source parcel
- */
- private OCFile(Parcel source) {
- mId = source.readLong();
- mParentId = source.readLong();
- mLength = source.readLong();
- mCreationTimestamp = source.readLong();
- mModifiedTimestamp = source.readLong();
- mRemotePath = source.readString();
- mLocalPath = source.readString();
- mMimeType = source.readString();
- mNeedsUpdating = source.readInt() == 0;
- mKeepInSync = source.readInt() == 1;
- mLastSyncDate = source.readLong();
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(mId);
- dest.writeLong(mParentId);
- dest.writeLong(mLength);
- dest.writeLong(mCreationTimestamp);
- dest.writeLong(mModifiedTimestamp);
- dest.writeString(mRemotePath);
- dest.writeString(mLocalPath);
- dest.writeString(mMimeType);
- dest.writeInt(mNeedsUpdating ? 1 : 0);
- dest.writeInt(mKeepInSync ? 1 : 0);
- dest.writeLong(mLastSyncDate);
- }
-
- /**
- * Gets the ID of the file
- *
- * @return the file ID
- */
- public long getFileId() {
- return mId;
- }
-
- /**
- * Returns the remote path of the file on ownCloud
- *
- * @return The remote path to the file
- */
- public String getRemotePath() {
- return mRemotePath;
- }
-
- /**
- * Can be used to check, whether or not this file exists in the database
- * already
- *
- * @return true, if the file exists in the database
- */
- public boolean fileExists() {
- return mId != -1;
- }
-
- /**
- * Use this to find out if this file is a Directory
- *
- * @return true if it is a directory
- */
- public boolean isDirectory() {
- return mMimeType != null && mMimeType.equals("DIR");
- }
-
- /**
- * Use this to check if this file is available locally
- *
- * @return true if it is
- */
- public boolean isDown() {
- if (mLocalPath != null && mLocalPath.length() > 0) {
- File file = new File(mLocalPath);
- return (file.exists());
- }
- return false;
- }
-
- /**
- * The path, where the file is stored locally
- *
- * @return The local path to the file
- */
- public String getStoragePath() {
- return mLocalPath;
- }
-
- /**
- * Can be used to set the path where the file is stored
- *
- * @param storage_path to set
- */
- public void setStoragePath(String storage_path) {
- mLocalPath = storage_path;
- }
-
- /**
- * Get a UNIX timestamp of the file creation time
- *
- * @return A UNIX timestamp of the time that file was created
- */
- public long getCreationTimestamp() {
- return mCreationTimestamp;
- }
-
- /**
- * Set a UNIX timestamp of the time the file was created
- *
- * @param creation_timestamp to set
- */
- public void setCreationTimestamp(long creation_timestamp) {
- mCreationTimestamp = creation_timestamp;
- }
-
- /**
- * Get a UNIX timestamp of the file modification time
- *
- * @return A UNIX timestamp of the modification time
- */
- public long getModificationTimestamp() {
- return mModifiedTimestamp;
- }
-
- /**
- * Set a UNIX timestamp of the time the time the file was modified.
- *
- * @param modification_timestamp to set
- */
- public void setModificationTimestamp(long modification_timestamp) {
- mModifiedTimestamp = modification_timestamp;
- }
-
- /**
- * Returns the filename and "/" for the root directory
- *
- * @return The name of the file
- */
- public String getFileName() {
- File f = new File(getRemotePath());
- return f.getName().length() == 0 ? "/" : f.getName();
- }
-
- /**
- * Can be used to get the Mimetype
- *
- * @return the Mimetype as a String
- */
- public String getMimetype() {
- return mMimeType;
- }
-
- /**
- * Adds a file to this directory. If this file is not a directory, an
- * exception gets thrown.
- *
- * @param file to add
- * @throws IllegalStateException if you try to add a something and this is
- * not a directory
- */
- public void addFile(OCFile file) throws IllegalStateException {
- if (isDirectory()) {
- file.mParentId = mId;
- mNeedsUpdating = true;
- return;
- }
- throw new IllegalStateException(
- "This is not a directory where you can add stuff to!");
- }
-
- /**
- * Used internally. Reset all file properties
- */
- private void resetData() {
- mId = -1;
- mRemotePath = null;
- mParentId = 0;
- mLocalPath = null;
- mMimeType = null;
- mLength = 0;
- mCreationTimestamp = 0;
- mModifiedTimestamp = 0;
- mLastSyncDate = 0;
- mKeepInSync = false;
- mNeedsUpdating = false;
- }
-
- /**
- * Sets the ID of the file
- *
- * @param file_id to set
- */
- public void setFileId(long file_id) {
- mId = file_id;
- }
-
- /**
- * Sets the Mime-Type of the
- *
- * @param mimetype to set
- */
- public void setMimetype(String mimetype) {
- mMimeType = mimetype;
- }
-
- /**
- * Sets the ID of the parent folder
- *
- * @param parent_id to set
- */
- public void setParentId(long parent_id) {
- mParentId = parent_id;
- }
-
- /**
- * Sets the file size in bytes
- *
- * @param file_len to set
- */
- public void setFileLength(long file_len) {
- mLength = file_len;
- }
-
- /**
- * Returns the size of the file in bytes
- *
- * @return The filesize in bytes
- */
- public long getFileLength() {
- return mLength;
- }
-
- /**
- * Returns the ID of the parent Folder
- *
- * @return The ID
- */
- public long getParentId() {
- return mParentId;
- }
-
- /**
- * Check, if this file needs updating
- *
- * @return
- */
- public boolean needsUpdatingWhileSaving() {
- return mNeedsUpdating;
- }
-
- public long getLastSyncDate() {
- return mLastSyncDate;
- }
-
- public void setLastSyncDate(long lastSyncDate) {
- mLastSyncDate = lastSyncDate;
- }
-
- public void setKeepInSync(boolean keepInSync) {
- mKeepInSync = keepInSync;
- }
-
- public boolean keepInSync() {
- return mKeepInSync;
- }
-
- @Override
- public int describeContents() {
- return this.hashCode();
- }
-
- @Override
- public int compareTo(OCFile another) {
- if (isDirectory() && another.isDirectory()) {
- return getRemotePath().toLowerCase().compareTo(another.getRemotePath().toLowerCase());
- } else if (isDirectory()) {
- return -1;
- } else if (another.isDirectory()) {
- return 1;
- }
- return getRemotePath().toLowerCase().compareTo(another.getRemotePath().toLowerCase());
- }
-
- public boolean equals(Object o) {
- if(o instanceof OCFile){
- OCFile that = (OCFile) o;
- if(that != null){
- return this.mId == that.mId;
- }
- }
-
- return false;
- }
-
- @Override
- public String toString() {
- String asString = "[id=%s, name=%s, mime=%s, downloaded=%s, local=%s, remote=%s, parentId=%s, keepInSinc=%s]";
- asString = String.format(asString, new Long(mId), getFileName(), mMimeType, isDown(), mLocalPath, mRemotePath, new Long(mParentId), new Boolean(mKeepInSync));
- return asString;
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/db/DbHandler.java b/src/eu/alefzero/owncloud/db/DbHandler.java
deleted file mode 100644
index 23b8bb6e..00000000
--- a/src/eu/alefzero/owncloud/db/DbHandler.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.db;
-
-import java.util.Vector;
-
-import eu.alefzero.owncloud.OwnCloudSession;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-
-/**
- * Custom database helper for ownCloud
- *
- * @author Bartek Przybylski
- *
- */
-public class DbHandler {
- private SQLiteDatabase mDB;
- private OpenerHepler mHelper;
- private final String mDatabaseName = "ownCloud";
- private final String TABLE_SESSIONS = "sessions";
- private final int mDatabaseVersion = 1;
-
- private final String TABLE_INSTANT_UPLOAD = "instant_upload";
-
- public DbHandler(Context context) {
- mHelper = new OpenerHepler(context);
- mDB = mHelper.getWritableDatabase();
- }
-
- public void close() {
- mDB.close();
- }
-
- public boolean putFileForLater(String filepath, String account) {
- ContentValues cv = new ContentValues();
- cv.put("path", filepath);
- cv.put("account", account);
- return mDB.insert(TABLE_INSTANT_UPLOAD, null, cv) != -1;
- }
-
- public Cursor getAwaitingFiles() {
- return mDB.query(TABLE_INSTANT_UPLOAD, null, null, null, null, null, null);
- }
-
- public void clearFiles() {
- mDB.delete(TABLE_INSTANT_UPLOAD, null, null);
- }
-
- private class OpenerHepler extends SQLiteOpenHelper {
- public OpenerHepler(Context context) {
- super(context, mDatabaseName, null, mDatabaseVersion);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE " + TABLE_INSTANT_UPLOAD + " ("
- + " _id INTEGET PRIMARY KEY, "
- + " path TEXT,"
- + " account TEXT);");
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- }
- }
-}
diff --git a/src/eu/alefzero/owncloud/db/ProviderMeta.java b/src/eu/alefzero/owncloud/db/ProviderMeta.java
deleted file mode 100644
index 62c0ace5..00000000
--- a/src/eu/alefzero/owncloud/db/ProviderMeta.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.db;
-
-import android.net.Uri;
-import android.provider.BaseColumns;
-
-/**
- * Meta-Class that holds various static field information
- *
- * @author Bartek Przybylski
- *
- */
-public class ProviderMeta {
-
- public static final String AUTHORITY_FILES = "org.owncloud";
- public static final String DB_FILE = "owncloud.db";
- public static final String DB_NAME = "filelist";
- public static final int DB_VERSION = 2;
-
- private ProviderMeta() {
- }
-
- static public class ProviderTableMeta implements BaseColumns {
- public static final String DB_NAME = "filelist";
- public static final Uri CONTENT_URI = Uri.parse("content://"
- + AUTHORITY_FILES + "/");
- public static final Uri CONTENT_URI_FILE = Uri.parse("content://"
- + AUTHORITY_FILES + "/file");
- public static final Uri CONTENT_URI_DIR = Uri.parse("content://"
- + AUTHORITY_FILES + "/dir");
-
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.owncloud.file";
- public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.owncloud.file";
-
- public static final String FILE_PARENT = "parent";
- public static final String FILE_NAME = "filename";
- public static final String FILE_CREATION = "created";
- public static final String FILE_MODIFIED = "modified";
- public static final String FILE_CONTENT_LENGTH = "content_length";
- public static final String FILE_CONTENT_TYPE = "content_type";
- public static final String FILE_STORAGE_PATH = "media_path";
- public static final String FILE_PATH = "path";
- public static final String FILE_ACCOUNT_OWNER = "file_owner";
- public static final String FILE_LAST_SYNC_DATE = "last_sync_date";
- public static final String FILE_KEEP_IN_SYNC = "keep_in_sync";
-
- public static final String DEFAULT_SORT_ORDER = FILE_NAME
- + " collate nocase asc";
-
- }
-}
diff --git a/src/eu/alefzero/owncloud/extensions/ExtensionsAvailableActivity.java b/src/eu/alefzero/owncloud/extensions/ExtensionsAvailableActivity.java
deleted file mode 100644
index 3d2554dd..00000000
--- a/src/eu/alefzero/owncloud/extensions/ExtensionsAvailableActivity.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package eu.alefzero.owncloud.extensions;
-
-import android.os.Bundle;
-import android.support.v4.app.FragmentManager;
-
-import com.actionbarsherlock.app.SherlockFragmentActivity;
-
-public class ExtensionsAvailableActivity extends SherlockFragmentActivity {
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- FragmentManager fm = getSupportFragmentManager();
- ExtensionsAvailableDialog ead = new ExtensionsAvailableDialog();
- ead.show(fm, "extensions_available_dialog");
- }
-}
diff --git a/src/eu/alefzero/owncloud/extensions/ExtensionsAvailableDialog.java b/src/eu/alefzero/owncloud/extensions/ExtensionsAvailableDialog.java
deleted file mode 100644
index 202acf25..00000000
--- a/src/eu/alefzero/owncloud/extensions/ExtensionsAvailableDialog.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package eu.alefzero.owncloud.extensions;
-
-import eu.alefzero.owncloud.R;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-
-public class ExtensionsAvailableDialog extends DialogFragment implements
- OnClickListener {
-
- public ExtensionsAvailableDialog() {
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.extensions_available_dialog,
- container);
- Button btnYes = (Button) view.findViewById(R.id.buttonYes);
- Button btnNo = (Button) view.findViewById(R.id.buttonNo);
- btnYes.setOnClickListener(this);
- btnNo.setOnClickListener(this);
- getDialog().setTitle(R.string.extensions_avail_title);
- return view;
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.buttonYes: {
- Intent i = new Intent(getActivity(), ExtensionsListActivity.class);
- startActivity(i);
- getActivity().finish();
- }
- break;
- case R.id.buttonNo:
- getActivity().finish();
- break;
- default:
- Log.e("EAD", "Button with unknown id clicked " + v.getId());
- }
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/extensions/ExtensionsListActivity.java b/src/eu/alefzero/owncloud/extensions/ExtensionsListActivity.java
deleted file mode 100644
index ec7d8bb3..00000000
--- a/src/eu/alefzero/owncloud/extensions/ExtensionsListActivity.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package eu.alefzero.owncloud.extensions;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Vector;
-
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import eu.alefzero.owncloud.utils.OwnCloudVersion;
-
-import android.R;
-import android.app.Activity;
-import android.app.ListActivity;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.widget.SimpleAdapter;
-
-public class ExtensionsListActivity extends ListActivity {
-
- private static final String packages_url = "http://alefzero.eu/a/packages.php";
-
- private Thread mGetterThread;
- private final Handler mHandler = new Handler();
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mGetterThread = new Thread(new JsonGetter());
- mGetterThread.start();
- }
-
- public void done(JSONArray a) {
- LinkedList> ll = new LinkedList>();
- for (int i = 0; i < a.length(); ++i) {
- try {
- ExtensionApplicationEntry ela = new ExtensionApplicationEntry(
- ((JSONObject) a.get(i)));
- HashMap ss = new HashMap();
- ss.put("NAME", ela.getName());
- ss.put("DESC", ela.getDescription());
- ll.add(ss);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- setListAdapter(new SimpleAdapter(this, ll, R.layout.simple_list_item_2,
- new String[] { "NAME", "DESC" }, new int[] {
- android.R.id.text1, android.R.id.text2 }));
-
- }
-
- private class JsonGetter implements Runnable {
-
- @Override
- public void run() {
- HttpClient hc = new HttpClient();
- GetMethod gm = new GetMethod(packages_url);
- final JSONArray ar;
- try {
- hc.executeMethod(gm);
- Log.e("ASD", gm.getResponseBodyAsString() + "");
- ar = new JSONObject(gm.getResponseBodyAsString())
- .getJSONArray("apps");
- } catch (Exception e) {
- e.printStackTrace();
- return;
- }
-
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- done(ar);
- }
- });
-
- }
-
- }
-
- private class ExtensionApplicationEntry {
- private static final String APP_NAME = "name";
- private static final String APP_VERSION = "version";
- private static final String APP_DESC = "description";
- private static final String APP_ICON = "icon";
- private static final String APP_URL = "download";
- private static final String APP_PLAYID = "play_id";
-
- private String mName, mDescription, mIcon, mDownload, mPlayId;
- private OwnCloudVersion mVersion;
-
- public ExtensionApplicationEntry(JSONObject appentry) {
- try {
- mName = appentry.getString(APP_NAME);
- mDescription = appentry.getString(APP_DESC);
- mIcon = appentry.getString(APP_ICON);
- mDownload = appentry.getString(APP_URL);
- mPlayId = appentry.getString(APP_PLAYID);
- mVersion = new OwnCloudVersion(appentry.getString(APP_VERSION));
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
-
- public String getName() {
- return mName;
- }
-
- public String getDescription() {
- return mDescription;
- }
-
- public String getIcon() {
- return mIcon;
- }
-
- public String getDownload() {
- return mDownload;
- }
-
- public String getPlayId() {
- return mPlayId;
- }
-
- public OwnCloudVersion getVersion() {
- return mVersion;
- }
- }
-}
diff --git a/src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java b/src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java
deleted file mode 100644
index c89a825c..00000000
--- a/src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.files;
-
-import java.io.File;
-
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.db.DbHandler;
-import eu.alefzero.owncloud.files.services.InstantUploadService;
-import android.accounts.Account;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.ConnectivityManager;
-import android.preference.Preference;
-import android.preference.PreferenceManager;
-import android.provider.MediaStore.Images.Media;
-import android.util.Log;
-import android.webkit.MimeTypeMap;
-
-public class PhotoTakenBroadcastReceiver extends BroadcastReceiver {
-
- private static String TAG = "PhotoTakenBroadcastReceiver";
- private static final String[] CONTENT_PROJECTION = { Media.DATA, Media.DISPLAY_NAME, Media.MIME_TYPE, Media.SIZE };
-
- private static String NEW_PHOTO_ACTION = "com.android.camera.NEW_PICTURE";
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_uploading", false)) {
- Log.d(TAG, "Instant upload disabled, abording uploading");
- return;
- }
- if (intent.getAction().equals(android.net.ConnectivityManager.CONNECTIVITY_ACTION)) {
- handleConnectivityAction(context, intent);
- } else if (intent.getAction().equals(NEW_PHOTO_ACTION)) {
- handleNewPhontoAction(context, intent);
- } else {
- Log.e(TAG, "Incorrect intent sent: " + intent.getAction());
- }
- }
-
- private void handleNewPhontoAction(Context context, Intent intent) {
- Account account = AccountUtils.getCurrentOwnCloudAccount(context);
- if (account == null) {
- Log.w(TAG, "No owncloud account found for instant upload, abording");
- return;
- }
-
- Cursor c = context.getContentResolver().query(intent.getData(), CONTENT_PROJECTION, null, null, null);
-
- if (!c.moveToFirst()) {
- Log.e(TAG, "Couldn't resolve given uri!");
- return;
- }
-
- String file_path = c.getString(c.getColumnIndex(Media.DATA));
- String file_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME));
- String mime_type = c.getString(c.getColumnIndex(Media.MIME_TYPE));
- long file_size = c.getLong(c.getColumnIndex(Media.SIZE));
-
- c.close();
-
- if (!isOnline(context)) {
- DbHandler db = new DbHandler(context);
- db.putFileForLater(file_path, account.name);
- db.close();
- return;
- }
-
- Intent upload_intent = new Intent(context, InstantUploadService.class);
- upload_intent.putExtra(InstantUploadService.KEY_ACCOUNT, account);
- upload_intent.putExtra(InstantUploadService.KEY_FILE_PATH, file_path);
- upload_intent.putExtra(InstantUploadService.KEY_DISPLAY_NAME, file_name);
- upload_intent.putExtra(InstantUploadService.KEY_FILE_SIZE, file_size);
- upload_intent.putExtra(InstantUploadService.KEY_MIME_TYPE, mime_type);
-
- context.startService(upload_intent);
- }
-
- private void handleConnectivityAction(Context context, Intent intent) {
- if (!intent.hasExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY) ||
- isOnline(context)) {
- DbHandler db = new DbHandler(context);
- Cursor c = db.getAwaitingFiles();
- if (c.moveToFirst()) {
- do {
- String account_name = c.getString(c.getColumnIndex("account"));
- String file_path = c.getString(c.getColumnIndex("path"));
- File f = new File(file_path);
- if (f.exists()) {
- Intent upload_intent = new Intent(context, InstantUploadService.class);
- Account account = new Account(account_name, AccountAuthenticator.ACCOUNT_TYPE);
-
- String mimeType = null;
- try {
- mimeType = MimeTypeMap.getSingleton()
- .getMimeTypeFromExtension(
- f.getName().substring(f.getName().lastIndexOf('.') + 1));
-
- } catch (IndexOutOfBoundsException e) {
- Log.e(TAG, "Trying to find out MIME type of a file without extension: " + f.getName());
- }
- if (mimeType == null)
- mimeType = "application/octet-stream";
-
- upload_intent.putExtra(InstantUploadService.KEY_ACCOUNT, account);
- upload_intent.putExtra(InstantUploadService.KEY_FILE_PATH, file_path);
- upload_intent.putExtra(InstantUploadService.KEY_DISPLAY_NAME, f.getName());
- upload_intent.putExtra(InstantUploadService.KEY_FILE_SIZE, f.length());
- upload_intent.putExtra(InstantUploadService.KEY_MIME_TYPE, mimeType);
-
- context.startService(upload_intent);
- } else {
- Log.w(TAG, "Instant upload file " + f.getName() + " dont exist anymore");
- }
- } while(c.moveToNext());
- c.close();
- }
- db.clearFiles();
- db.close();
- }
-
- }
-
- private boolean isOnline(Context context) {
- ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/files/interfaces/OnDatatransferProgressListener.java b/src/eu/alefzero/owncloud/files/interfaces/OnDatatransferProgressListener.java
deleted file mode 100644
index 4a897dd7..00000000
--- a/src/eu/alefzero/owncloud/files/interfaces/OnDatatransferProgressListener.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package eu.alefzero.owncloud.files.interfaces;
-
-public interface OnDatatransferProgressListener {
- void transferProgress(long progressRate);
-
-}
diff --git a/src/eu/alefzero/owncloud/files/services/FileDownloader.java b/src/eu/alefzero/owncloud/files/services/FileDownloader.java
deleted file mode 100644
index b0dd2b26..00000000
--- a/src/eu/alefzero/owncloud/files/services/FileDownloader.java
+++ /dev/null
@@ -1,252 +0,0 @@
-package eu.alefzero.owncloud.files.services;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
-import android.util.Log;
-import android.widget.RemoteViews;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-import eu.alefzero.owncloud.files.interfaces.OnDatatransferProgressListener;
-import eu.alefzero.webdav.WebdavClient;
-
-public class FileDownloader extends Service implements OnDatatransferProgressListener {
- public static final String DOWNLOAD_FINISH_MESSAGE = "DOWNLOAD_FINISH";
- public static final String EXTRA_DOWNLOAD_RESULT = "RESULT";
- public static final String EXTRA_ACCOUNT = "ACCOUNT";
- public static final String EXTRA_FILE_PATH = "FILE_PATH";
- public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
- public static final String EXTRA_FILE_SIZE = "FILE_SIZE";
- public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
-
- private static final String TAG = "FileDownloader";
-
- private NotificationManager mNotificationMngr;
- private Looper mServiceLooper;
- private ServiceHandler mServiceHandler;
- private Account mAccount;
- private String mFilePath;
- private String mRemotePath;
- private int mLastPercent;
- private long mTotalDownloadSize;
- private long mCurrentDownloadSize;
- private Notification mNotification;
-
- /**
- * Static map with the files being download and the path to the temporal file were are download
- */
- private static Map mDownloadsInProgress = Collections.synchronizedMap(new HashMap());
-
- /**
- * Returns True when the file referred by 'remotePath' in the ownCloud account 'account' is downloading
- */
- public static boolean isDownloading(Account account, String remotePath) {
- return (mDownloadsInProgress.get(buildRemoteName(account.name, remotePath)) != null);
- }
-
- /**
- * Builds a key for mDownloadsInProgress from the accountName and remotePath
- */
- private static String buildRemoteName(String accountName, String remotePath) {
- return accountName + remotePath;
- }
-
-
- private final class ServiceHandler extends Handler {
- public ServiceHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- downloadFile();
- stopSelf(msg.arg1);
- }
- }
-
- public static final String getSavePath(String accountName) {
- File sdCard = Environment.getExternalStorageDirectory();
- return sdCard.getAbsolutePath() + "/owncloud/" + Uri.encode(accountName, "@");
- // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B
- }
-
- public static final String getTemporalPath(String accountName) {
- File sdCard = Environment.getExternalStorageDirectory();
- return sdCard.getAbsolutePath() + "/owncloud/tmp/" + Uri.encode(accountName, "@");
- // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- mNotificationMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
- HandlerThread thread = new HandlerThread("FileDownladerThread",
- Process.THREAD_PRIORITY_BACKGROUND);
- thread.start();
- mServiceLooper = thread.getLooper();
- mServiceHandler = new ServiceHandler(mServiceLooper);
- }
-
- @Override
- public IBinder onBind(Intent arg0) {
- return null;
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- if ( !intent.hasExtra(EXTRA_ACCOUNT) ||
- !intent.hasExtra(EXTRA_FILE_PATH) ||
- !intent.hasExtra(EXTRA_REMOTE_PATH)
- ) {
- Log.e(TAG, "Not enough information provided in intent");
- return START_NOT_STICKY;
- }
- mAccount = intent.getParcelableExtra(EXTRA_ACCOUNT);
- mFilePath = intent.getStringExtra(EXTRA_FILE_PATH);
- mRemotePath = intent.getStringExtra(EXTRA_REMOTE_PATH);
- mTotalDownloadSize = intent.getLongExtra(EXTRA_FILE_SIZE, -1);
- mCurrentDownloadSize = mLastPercent = 0;
-
- Message msg = mServiceHandler.obtainMessage();
- msg.arg1 = startId;
- mServiceHandler.sendMessage(msg);
-
- return START_NOT_STICKY;
- }
-
- /**
- * Core download method: requests the file to download and stores it.
- */
- private void downloadFile() {
- boolean downloadResult = false;
-
- /// prepare client object to send the request to the ownCloud server
- AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
- WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());
- String username = mAccount.name.split("@")[0];
- String password = null;
- try {
- password = am.blockingGetAuthToken(mAccount,
- AccountAuthenticator.AUTH_TOKEN_TYPE, true);
- } catch (Exception e) {
- Log.e(TAG, "Access to account credentials failed", e);
- sendFinalBroadcast(downloadResult, null);
- return;
- }
- wdc.setCredentials(username, password);
- wdc.allowSelfsignedCertificates();
- wdc.setDataTransferProgressListener(this);
-
-
- /// download will be in a temporal file
- File tmpFile = new File(getTemporalPath(mAccount.name) + mFilePath);
-
- /// create status notification to show the download progress
- mNotification = new Notification(R.drawable.icon, getString(R.string.downloader_download_in_progress_ticker), System.currentTimeMillis());
- mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
- mNotification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.progressbar_layout);
- mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, mTotalDownloadSize == -1);
- mNotification.contentView.setTextViewText(R.id.status_text, String.format(getString(R.string.downloader_download_in_progress_content), 0, tmpFile.getName()));
- mNotification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon);
- // TODO put something smart in the contentIntent below
- mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
- mNotificationMngr.notify(R.string.downloader_download_in_progress_ticker, mNotification);
-
-
- /// perform the download
- tmpFile.getParentFile().mkdirs();
- mDownloadsInProgress.put(buildRemoteName(mAccount.name, mRemotePath), tmpFile.getAbsolutePath());
- File newFile = null;
- try {
- if (wdc.downloadFile(mRemotePath, tmpFile)) {
- newFile = new File(getSavePath(mAccount.name) + mFilePath);
- newFile.getParentFile().mkdirs();
- boolean moved = tmpFile.renameTo(newFile);
-
- if (moved) {
- ContentValues cv = new ContentValues();
- cv.put(ProviderTableMeta.FILE_STORAGE_PATH, newFile.getAbsolutePath());
- getContentResolver().update(
- ProviderTableMeta.CONTENT_URI,
- cv,
- ProviderTableMeta.FILE_NAME + "=? AND "
- + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
- new String[] {
- mFilePath.substring(mFilePath.lastIndexOf('/') + 1),
- mAccount.name });
- downloadResult = true;
- }
- }
- } finally {
- mDownloadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePath));
- }
-
-
- /// notify result
- mNotificationMngr.cancel(R.string.downloader_download_in_progress_ticker);
- int tickerId = (downloadResult) ? R.string.downloader_download_succeeded_ticker : R.string.downloader_download_failed_ticker;
- int contentId = (downloadResult) ? R.string.downloader_download_succeeded_content : R.string.downloader_download_failed_content;
- Notification finalNotification = new Notification(R.drawable.icon, getString(tickerId), System.currentTimeMillis());
- finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;
- // TODO put something smart in the contentIntent below
- finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
- finalNotification.setLatestEventInfo(getApplicationContext(), getString(tickerId), String.format(getString(contentId), tmpFile.getName()), finalNotification.contentIntent);
- mNotificationMngr.notify(tickerId, finalNotification);
-
- sendFinalBroadcast(downloadResult, (downloadResult)?newFile.getAbsolutePath():null);
- }
-
- /**
- * Callback method to update the progress bar in the status notification.
- */
- @Override
- public void transferProgress(long progressRate) {
- mCurrentDownloadSize += progressRate;
- int percent = (int)(100.0*((double)mCurrentDownloadSize)/((double)mTotalDownloadSize));
- if (percent != mLastPercent) {
- mNotification.contentView.setProgressBar(R.id.status_progress, 100, (int)(100*mCurrentDownloadSize/mTotalDownloadSize), mTotalDownloadSize == -1);
- mNotification.contentView.setTextViewText(R.id.status_text, String.format(getString(R.string.downloader_download_in_progress_content), percent, new File(mFilePath).getName()));
- mNotificationMngr.notify(R.string.downloader_download_in_progress_ticker, mNotification);
- }
-
- mLastPercent = percent;
- }
-
-
- /**
- * Sends a broadcast in order to the interested activities can update their view
- *
- * @param downloadResult 'True' if the download was successful
- * @param newFilePath Absolute path to the download file
- */
- private void sendFinalBroadcast(boolean downloadResult, String newFilePath) {
- Intent end = new Intent(DOWNLOAD_FINISH_MESSAGE);
- end.putExtra(EXTRA_DOWNLOAD_RESULT, downloadResult);
- end.putExtra(ACCOUNT_NAME, mAccount.name);
- end.putExtra(EXTRA_REMOTE_PATH, mRemotePath);
- if (downloadResult) {
- end.putExtra(EXTRA_FILE_PATH, newFilePath);
- }
- sendBroadcast(end);
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/files/services/FileOperation.java b/src/eu/alefzero/owncloud/files/services/FileOperation.java
deleted file mode 100644
index b0e9d4a5..00000000
--- a/src/eu/alefzero/owncloud/files/services/FileOperation.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.files.services;
-
-import java.io.File;
-
-import android.accounts.Account;
-import android.content.Context;
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.datamodel.OCFile;
-import eu.alefzero.webdav.WebdavClient;
-
-public class FileOperation {
-
- Context mContext;
-
- public FileOperation(Context contex){
- this.mContext = contex;
- }
-
- /**
- * Deletes a file from ownCloud - locally and remote.
- * @param file The file to delete
- * @return True on success, otherwise false
- */
- public boolean delete(OCFile file){
-
- Account account = AccountUtils.getCurrentOwnCloudAccount(mContext);
- WebdavClient client = new WebdavClient(account, mContext);
- if(client.deleteFile(file.getRemotePath())){
- File localFile = new File(file.getStoragePath());
- return localFile.delete();
- }
-
- return false;
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/files/services/FileUploader.java b/src/eu/alefzero/owncloud/files/services/FileUploader.java
deleted file mode 100644
index 3f30f1bf..00000000
--- a/src/eu/alefzero/owncloud/files/services/FileUploader.java
+++ /dev/null
@@ -1,326 +0,0 @@
-package eu.alefzero.owncloud.files.services;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import android.accounts.Account;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
-import android.util.Log;
-import android.webkit.MimeTypeMap;
-import android.widget.RemoteViews;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
-import eu.alefzero.owncloud.datamodel.OCFile;
-import eu.alefzero.owncloud.files.interfaces.OnDatatransferProgressListener;
-import eu.alefzero.webdav.WebdavClient;
-
-public class FileUploader extends Service implements OnDatatransferProgressListener {
-
- public static final String UPLOAD_FINISH_MESSAGE = "UPLOAD_FINISH";
- public static final String EXTRA_PARENT_DIR_ID = "PARENT_DIR_ID";
- public static final String EXTRA_UPLOAD_RESULT = "RESULT";
- public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
- public static final String EXTRA_FILE_PATH = "FILE_PATH";
-
- public static final String KEY_LOCAL_FILE = "LOCAL_FILE";
- public static final String KEY_REMOTE_FILE = "REMOTE_FILE";
- public static final String KEY_ACCOUNT = "ACCOUNT";
- public static final String KEY_UPLOAD_TYPE = "UPLOAD_TYPE";
- public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
-
- public static final int UPLOAD_SINGLE_FILE = 0;
- public static final int UPLOAD_MULTIPLE_FILES = 1;
-
- private static final String TAG = "FileUploader";
-
- private NotificationManager mNotificationManager;
- private Looper mServiceLooper;
- private ServiceHandler mServiceHandler;
- private Account mAccount;
- private String[] mLocalPaths, mRemotePaths;
- private int mUploadType;
- private Notification mNotification;
- private long mTotalDataToSend, mSendData;
- private int mCurrentIndexUpload, mPreviousPercent;
- private int mSuccessCounter;
-
- /**
- * Static map with the files being download and the path to the temporal file were are download
- */
- private static Map mUploadsInProgress = Collections.synchronizedMap(new HashMap());
-
- /**
- * Returns True when the file referred by 'remotePath' in the ownCloud account 'account' is downloading
- */
- public static boolean isUploading(Account account, String remotePath) {
- return (mUploadsInProgress.get(buildRemoteName(account.name, remotePath)) != null);
- }
-
- /**
- * Builds a key for mUplaodsInProgress from the accountName and remotePath
- */
- private static String buildRemoteName(String accountName, String remotePath) {
- return accountName + remotePath;
- }
-
-
-
-
- @Override
- public IBinder onBind(Intent arg0) {
- return null;
- }
-
- private final class ServiceHandler extends Handler {
- public ServiceHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- uploadFile();
- stopSelf(msg.arg1);
- }
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
- HandlerThread thread = new HandlerThread("FileUploaderThread",
- Process.THREAD_PRIORITY_BACKGROUND);
- thread.start();
- mServiceLooper = thread.getLooper();
- mServiceHandler = new ServiceHandler(mServiceLooper);
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- if (!intent.hasExtra(KEY_ACCOUNT) && !intent.hasExtra(KEY_UPLOAD_TYPE)) {
- Log.e(TAG, "Not enough information provided in intent");
- return Service.START_NOT_STICKY;
- }
- mAccount = intent.getParcelableExtra(KEY_ACCOUNT);
- mUploadType = intent.getIntExtra(KEY_UPLOAD_TYPE, -1);
- if (mUploadType == -1) {
- Log.e(TAG, "Incorrect upload type provided");
- return Service.START_NOT_STICKY;
- }
- if (mUploadType == UPLOAD_SINGLE_FILE) {
- mLocalPaths = new String[] { intent.getStringExtra(KEY_LOCAL_FILE) };
- mRemotePaths = new String[] { intent
- .getStringExtra(KEY_REMOTE_FILE) };
- } else { // mUploadType == UPLOAD_MULTIPLE_FILES
- mLocalPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
- mRemotePaths = intent.getStringArrayExtra(KEY_REMOTE_FILE);
- }
-
- if (mLocalPaths.length != mRemotePaths.length) {
- Log.e(TAG, "Different number of remote paths and local paths!");
- return Service.START_NOT_STICKY;
- }
-
- Message msg = mServiceHandler.obtainMessage();
- msg.arg1 = startId;
- mServiceHandler.sendMessage(msg);
-
- return Service.START_NOT_STICKY;
- }
-
-
- /**
- * Core upload method: sends the file(s) to upload
- */
- public void uploadFile() {
- FileDataStorageManager storageManager = new FileDataStorageManager(mAccount, getContentResolver());
-
- mTotalDataToSend = mSendData = mPreviousPercent = 0;
-
- /// prepare client object to send the request to the ownCloud server
- WebdavClient wc = new WebdavClient(mAccount, getApplicationContext());
- wc.allowSelfsignedCertificates();
- wc.setDataTransferProgressListener(this);
-
- /// create status notification to show the upload progress
- mNotification = new Notification(eu.alefzero.owncloud.R.drawable.icon, getString(R.string.uploader_upload_in_progress_ticker), System.currentTimeMillis());
- mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
- RemoteViews oldContentView = mNotification.contentView;
- mNotification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.progressbar_layout);
- mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, false);
- mNotification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon);
- // dvelasco ; contentIntent MUST be assigned to avoid app crashes in versions previous to Android 4.x ;
- // BUT an empty Intent is not a very elegant solution; something smart should happen when a user 'clicks' on an upload in the notification bar
- mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
- mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification);
-
-
- /// perform the upload
- File [] localFiles = new File[mLocalPaths.length];
- for (int i = 0; i < mLocalPaths.length; ++i) {
- localFiles[i] = new File(mLocalPaths[i]);
- mTotalDataToSend += localFiles[i].length();
- }
- Log.d(TAG, "Will upload " + mTotalDataToSend + " bytes, with " + mLocalPaths.length + " files");
- mSuccessCounter = 0;
- for (int i = 0; i < mLocalPaths.length; ++i) {
- String mimeType = null;
- try {
- mimeType = MimeTypeMap.getSingleton()
- .getMimeTypeFromExtension(
- mLocalPaths[i].substring(mLocalPaths[i]
- .lastIndexOf('.') + 1));
- } catch (IndexOutOfBoundsException e) {
- Log.e(TAG, "Trying to find out MIME type of a file without extension: " + mLocalPaths[i]);
- }
- if (mimeType == null)
- mimeType = "application/octet-stream";
- mCurrentIndexUpload = i;
- long parentDirId = -1;
- boolean uploadResult = false;
- String availablePath = getAvailableRemotePath(wc, mRemotePaths[i]);
- try {
- File f = new File(mRemotePaths[i]);
- parentDirId = storageManager.getFileByPath(f.getParent().endsWith("/")?f.getParent():f.getParent()+"/").getFileId();
- if(availablePath != null) {
- mRemotePaths[i] = availablePath;
- mUploadsInProgress.put(buildRemoteName(mAccount.name, mRemotePaths[i]), mLocalPaths[i]);
- if (wc.putFile(mLocalPaths[i], mRemotePaths[i], mimeType)) {
- OCFile new_file = new OCFile(mRemotePaths[i]);
- new_file.setMimetype(mimeType);
- new_file.setFileLength(localFiles[i].length());
- new_file.setModificationTimestamp(System.currentTimeMillis());
- new_file.setLastSyncDate(0);
- new_file.setStoragePath(mLocalPaths[i]);
- new_file.setParentId(parentDirId);
- storageManager.saveFile(new_file);
- mSuccessCounter++;
- uploadResult = true;
- }
- }
- } finally {
- mUploadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePaths[i]));
-
- /// notify upload (or fail) of EACH file to activities interested
- Intent end = new Intent(UPLOAD_FINISH_MESSAGE);
- end.putExtra(EXTRA_PARENT_DIR_ID, parentDirId);
- end.putExtra(EXTRA_UPLOAD_RESULT, uploadResult);
- end.putExtra(EXTRA_REMOTE_PATH, mRemotePaths[i]);
- end.putExtra(EXTRA_FILE_PATH, mLocalPaths[i]);
- end.putExtra(ACCOUNT_NAME, mAccount.name);
- sendBroadcast(end);
- }
-
- }
-
- /// notify final result
- if (mSuccessCounter == mLocalPaths.length) { // success
- //Notification finalNotification = new Notification(R.drawable.icon, getString(R.string.uploader_upload_succeeded_ticker), System.currentTimeMillis());
- mNotification.flags ^= Notification.FLAG_ONGOING_EVENT; // remove the ongoing flag
- mNotification.flags |= Notification.FLAG_AUTO_CANCEL;
- mNotification.contentView = oldContentView;
- // TODO put something smart in the contentIntent below
- mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
- if (mLocalPaths.length == 1) {
- mNotification.setLatestEventInfo( getApplicationContext(),
- getString(R.string.uploader_upload_succeeded_ticker),
- String.format(getString(R.string.uploader_upload_succeeded_content_single), localFiles[0].getName()),
- mNotification.contentIntent);
- } else {
- mNotification.setLatestEventInfo( getApplicationContext(),
- getString(R.string.uploader_upload_succeeded_ticker),
- String.format(getString(R.string.uploader_upload_succeeded_content_multiple), mSuccessCounter),
- mNotification.contentIntent);
- }
- mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification); // NOT AN ERROR; uploader_upload_in_progress_ticker is the target, not a new notification
-
- } else {
- mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);
- Notification finalNotification = new Notification(R.drawable.icon, getString(R.string.uploader_upload_failed_ticker), System.currentTimeMillis());
- finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;
- // TODO put something smart in the contentIntent below
- finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
- if (mLocalPaths.length == 1) {
- finalNotification.setLatestEventInfo( getApplicationContext(),
- getString(R.string.uploader_upload_failed_ticker),
- String.format(getString(R.string.uploader_upload_failed_content_single), localFiles[0].getName()),
- finalNotification.contentIntent);
- } else {
- finalNotification.setLatestEventInfo( getApplicationContext(),
- getString(R.string.uploader_upload_failed_ticker),
- String.format(getString(R.string.uploader_upload_failed_content_multiple), mSuccessCounter, mLocalPaths.length),
- finalNotification.contentIntent);
- }
- mNotificationManager.notify(R.string.uploader_upload_failed_ticker, finalNotification);
- }
-
- }
-
- /**
- * Checks if remotePath does not exist in the server and returns it, or adds a suffix to it in order to avoid the server
- * file is overwritten.
- *
- * @param string
- * @return
- */
- private String getAvailableRemotePath(WebdavClient wc, String remotePath) {
- Boolean check = wc.existsFile(remotePath);
- if (check == null) { // null means fail
- return null;
- } else if (!check) {
- return remotePath;
- }
-
- int pos = remotePath.lastIndexOf(".");
- String suffix = "";
- String extension = "";
- if (pos >= 0) {
- extension = remotePath.substring(pos+1);
- remotePath = remotePath.substring(0, pos);
- }
- int count = 2;
- while (check != null && check) {
- suffix = " (" + count + ")";
- if (pos >= 0)
- check = wc.existsFile(remotePath + suffix + "." + extension);
- else
- check = wc.existsFile(remotePath + suffix);
- count++;
- }
- if (check == null) {
- return null;
- } else if (pos >=0) {
- return remotePath + suffix + "." + extension;
- } else {
- return remotePath + suffix;
- }
- }
-
-
- /**
- * Callback method to update the progress bar in the status notification.
- */
- @Override
- public void transferProgress(long progressRate) {
- mSendData += progressRate;
- int percent = (int)(100*((double)mSendData)/((double)mTotalDataToSend));
- if (percent != mPreviousPercent) {
- String text = String.format(getString(R.string.uploader_upload_in_progress_content), percent, new File(mLocalPaths[mCurrentIndexUpload]).getName());
- mNotification.contentView.setProgressBar(R.id.status_progress, 100, percent, false);
- mNotification.contentView.setTextViewText(R.id.status_text, text);
- mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification);
- }
- mPreviousPercent = percent;
- }
-}
diff --git a/src/eu/alefzero/owncloud/files/services/InstantUploadService.java b/src/eu/alefzero/owncloud/files/services/InstantUploadService.java
deleted file mode 100644
index b666e593..00000000
--- a/src/eu/alefzero/owncloud/files/services/InstantUploadService.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.files.services;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.commons.httpclient.HttpException;
-import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
-
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.utils.OwnCloudVersion;
-import eu.alefzero.webdav.WebdavClient;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.Service;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.IBinder;
-import android.util.Log;
-
-public class InstantUploadService extends Service {
-
- public static String KEY_FILE_PATH = "KEY_FILEPATH";
- public static String KEY_FILE_SIZE = "KEY_FILESIZE";
- public static String KEY_MIME_TYPE = "KEY_MIMETYPE";
- public static String KEY_DISPLAY_NAME = "KEY_FILENAME";
- public static String KEY_ACCOUNT = "KEY_ACCOUNT";
-
- private static String TAG = "InstantUploadService";
- private static String INSTANT_UPLOAD_DIR = "/InstantUpload";
- private UploaderRunnable mUploaderRunnable;
-
- @Override
- public IBinder onBind(Intent arg0) {
- return null;
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- if (intent == null ||
- !intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_DISPLAY_NAME) ||
- !intent.hasExtra(KEY_FILE_PATH) || !intent.hasExtra(KEY_FILE_SIZE) ||
- !intent.hasExtra(KEY_MIME_TYPE)) {
- Log.w(TAG, "Not all required information was provided, abording");
- return Service.START_NOT_STICKY;
- }
-
- if (mUploaderRunnable == null) {
- mUploaderRunnable = new UploaderRunnable();
- }
-
- String filename = intent.getStringExtra(KEY_DISPLAY_NAME);
- String filepath = intent.getStringExtra(KEY_FILE_PATH);
- String mimetype = intent.getStringExtra(KEY_MIME_TYPE);
- Account account = intent.getParcelableExtra(KEY_ACCOUNT);
- long filesize = intent.getLongExtra(KEY_FILE_SIZE, -1);
-
- mUploaderRunnable.addElementToQueue(filename, filepath, mimetype, filesize, account);
-
- // starting new thread for new download doesnt seems like a good idea
- // maybe some thread pool or single background thread would be better
- Log.d(TAG, "Starting instant upload thread");
- new Thread(mUploaderRunnable).start();
-
- return Service.START_STICKY;
- }
-
- private class UploaderRunnable implements Runnable {
-
- Object mLock;
- List> mHashMapList;
-
- public UploaderRunnable() {
- mHashMapList = new LinkedList>();
- mLock = new Object();
- }
-
- public void addElementToQueue(String filename,
- String filepath,
- String mimetype,
- long length,
- Account account) {
- HashMap new_map = new HashMap();
- new_map.put(KEY_ACCOUNT, account);
- new_map.put(KEY_DISPLAY_NAME, filename);
- new_map.put(KEY_FILE_PATH, filepath);
- new_map.put(KEY_MIME_TYPE, mimetype);
- new_map.put(KEY_FILE_SIZE, length);
-
- synchronized (mLock) {
- mHashMapList.add(new_map);
- }
- }
-
- private HashMap getFirstObject() {
- synchronized (mLock) {
- if (mHashMapList.size() == 0)
- return null;
- HashMap ret = mHashMapList.get(0);
- mHashMapList.remove(0);
- return ret;
- }
- }
-
- public void run() {
- HashMap working_map;
- AccountManager am = AccountManager.get(getApplicationContext());
-
- while ((working_map = getFirstObject()) != null) {
- Account account = (Account) working_map.get(KEY_ACCOUNT);
- String username = account.name.substring(0, account.name.lastIndexOf('@'));
- String password = am.getPassword(account);
- String filename = (String) working_map.get(KEY_DISPLAY_NAME);
- String filepath = (String) working_map.get(KEY_FILE_PATH);
- String mimetype = (String) working_map.get(KEY_MIME_TYPE);
-
- String oc_base_url = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL);
- String oc_version = am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION);
- OwnCloudVersion ocv = new OwnCloudVersion(oc_version);
- String webdav_path = AccountUtils.getWebdavPath(ocv);
- WebdavClient wdc = new WebdavClient(account, getApplicationContext());
- wdc.allowSelfsignedCertificates();
- wdc.setCredentials(username, password);
-
- MkColMethod mkcol = new MkColMethod(oc_base_url+webdav_path+INSTANT_UPLOAD_DIR);
- int status = 0;
- try {
- status = wdc.executeMethod(mkcol);
- Log.e(TAG, "mkcol returned " + status);
- wdc.putFile(filepath, INSTANT_UPLOAD_DIR + "/" + filename, mimetype);
- } catch (HttpException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/files/services/OnUploadCompletedListener.java b/src/eu/alefzero/owncloud/files/services/OnUploadCompletedListener.java
deleted file mode 100644
index 99d0bfa3..00000000
--- a/src/eu/alefzero/owncloud/files/services/OnUploadCompletedListener.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package eu.alefzero.owncloud.files.services;
-
-public interface OnUploadCompletedListener extends Runnable {
-
- public boolean getUploadResult();
-
- public void setUploadResult(boolean result);
-}
diff --git a/src/eu/alefzero/owncloud/location/LocationServiceLauncherReciever.java b/src/eu/alefzero/owncloud/location/LocationServiceLauncherReciever.java
deleted file mode 100644
index a435414b..00000000
--- a/src/eu/alefzero/owncloud/location/LocationServiceLauncherReciever.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.location;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningServiceInfo;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
-public class LocationServiceLauncherReciever extends BroadcastReceiver {
-
- private final String TAG = getClass().getSimpleName();
-
- @Override
- public void onReceive(Context context, Intent intent) {
- Intent deviceTrackingIntent = new Intent();
- deviceTrackingIntent
- .setAction("eu.alefzero.owncloud.location.LocationUpdateService");
- SharedPreferences preferences = PreferenceManager
- .getDefaultSharedPreferences(context);
- boolean trackDevice = preferences.getBoolean("enable_devicetracking",
- true);
-
- // Used in Preferences activity so that tracking is disabled or
- // reenabled
- if (intent.hasExtra("TRACKING_SETTING")) {
- trackDevice = intent.getBooleanExtra("TRACKING_SETTING", true);
- }
-
- startOrStopDeviceTracking(context, trackDevice);
- }
-
- /**
- * Used internally. Starts or stops the device tracking service
- *
- * @param trackDevice true to start the service, false to stop it
- */
- private void startOrStopDeviceTracking(Context context, boolean trackDevice) {
- Intent deviceTrackingIntent = new Intent();
- deviceTrackingIntent
- .setAction("eu.alefzero.owncloud.location.LocationUpdateService");
- if (!isDeviceTrackingServiceRunning(context) && trackDevice) {
- Log.d(TAG, "Starting device tracker service");
- context.startService(deviceTrackingIntent);
- } else if (isDeviceTrackingServiceRunning(context) && !trackDevice) {
- Log.d(TAG, "Stopping device tracker service");
- context.stopService(deviceTrackingIntent);
- }
- }
-
- /**
- * Checks to see whether or not the LocationUpdateService is running
- *
- * @return true, if it is. Otherwise false
- */
- private boolean isDeviceTrackingServiceRunning(Context context) {
- ActivityManager manager = (ActivityManager) context
- .getSystemService(Context.ACTIVITY_SERVICE);
- for (RunningServiceInfo service : manager
- .getRunningServices(Integer.MAX_VALUE)) {
- if (getClass().getName().equals(service.service.getClassName())) {
- return true;
- }
- }
- return false;
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/location/LocationUpdateService.java b/src/eu/alefzero/owncloud/location/LocationUpdateService.java
deleted file mode 100644
index 96ae329f..00000000
--- a/src/eu/alefzero/owncloud/location/LocationUpdateService.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.location;
-
-import android.app.IntentService;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.location.Criteria;
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.location.LocationProvider;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.util.Log;
-import android.widget.Toast;
-
-public class LocationUpdateService extends IntentService implements
- LocationListener {
-
- public static final String TAG = "LocationUpdateService";
-
- private LocationManager mLocationManager;
- private LocationProvider mLocationProvider;
- private SharedPreferences mPreferences;
-
- public LocationUpdateService() {
- super(TAG);
- }
-
- @Override
- protected void onHandleIntent(Intent intent) {
- mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
- // Determine, how we can track the device
- Criteria criteria = new Criteria();
- criteria.setAccuracy(Criteria.ACCURACY_FINE);
- criteria.setPowerRequirement(Criteria.POWER_LOW);
- mLocationProvider = mLocationManager.getProvider(mLocationManager
- .getBestProvider(criteria, true));
-
- // Notify user if there is no way to track the device
- if (mLocationProvider == null) {
- Toast.makeText(this,
- eu.alefzero.owncloud.R.string.location_no_provider,
- Toast.LENGTH_LONG);
- stopSelf();
- return;
- }
-
- // Get preferences for device tracking
- mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
- boolean trackDevice = mPreferences.getBoolean("enable_devicetracking",
- true);
- int updateIntervall = Integer.parseInt(mPreferences.getString(
- "devicetracking_update_intervall", "30")) * 60 * 1000;
- int distanceBetweenLocationChecks = 50;
-
- // If we do shall track the device -> Stop
- if (!trackDevice) {
- Log.d(TAG, "Devicetracking is disabled");
- stopSelf();
- return;
- }
-
- mLocationManager.requestLocationUpdates(mLocationProvider.getName(),
- updateIntervall, distanceBetweenLocationChecks, this);
- }
-
- @Override
- public void onLocationChanged(Location location) {
- Log.d(TAG, "Location changed: " + location);
-
- }
-
- @Override
- public void onProviderDisabled(String arg0) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onProviderEnabled(String arg0) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
- // TODO Auto-generated method stub
-
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/providers/FileContentProvider.java b/src/eu/alefzero/owncloud/providers/FileContentProvider.java
deleted file mode 100644
index 7ed73a9f..00000000
--- a/src/eu/alefzero/owncloud/providers/FileContentProvider.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.providers;
-
-import java.util.HashMap;
-
-import eu.alefzero.owncloud.db.ProviderMeta;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-
-import android.content.ContentProvider;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.UriMatcher;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.net.Uri;
-import android.text.TextUtils;
-import android.util.Log;
-
-/**
- * The ContentProvider for the ownCloud App.
- *
- * @author Bartek Przybylski
- *
- */
-public class FileContentProvider extends ContentProvider {
-
- private DataBaseHelper mDbHelper;
-
- private static HashMap mProjectionMap;
- static {
- mProjectionMap = new HashMap();
- mProjectionMap.put(ProviderTableMeta._ID, ProviderTableMeta._ID);
- mProjectionMap.put(ProviderTableMeta.FILE_PARENT,
- ProviderTableMeta.FILE_PARENT);
- mProjectionMap.put(ProviderTableMeta.FILE_PATH,
- ProviderTableMeta.FILE_PATH);
- mProjectionMap.put(ProviderTableMeta.FILE_NAME,
- ProviderTableMeta.FILE_NAME);
- mProjectionMap.put(ProviderTableMeta.FILE_CREATION,
- ProviderTableMeta.FILE_CREATION);
- mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED,
- ProviderTableMeta.FILE_MODIFIED);
- mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_LENGTH,
- ProviderTableMeta.FILE_CONTENT_LENGTH);
- mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_TYPE,
- ProviderTableMeta.FILE_CONTENT_TYPE);
- mProjectionMap.put(ProviderTableMeta.FILE_STORAGE_PATH,
- ProviderTableMeta.FILE_STORAGE_PATH);
- mProjectionMap.put(ProviderTableMeta.FILE_LAST_SYNC_DATE,
- ProviderTableMeta.FILE_LAST_SYNC_DATE);
- mProjectionMap.put(ProviderTableMeta.FILE_KEEP_IN_SYNC,
- ProviderTableMeta.FILE_KEEP_IN_SYNC);
- }
-
- private static final int SINGLE_FILE = 1;
- private static final int DIRECTORY = 2;
- private static final int ROOT_DIRECTORY = 3;
- private static final UriMatcher mUriMatcher;
- static {
- mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
- mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "/", ROOT_DIRECTORY);
- mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/", SINGLE_FILE);
- mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/#", SINGLE_FILE);
- mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/#", DIRECTORY);
- }
-
- @Override
- public int delete(Uri uri, String where, String[] whereArgs) {
- SQLiteDatabase db = mDbHelper.getWritableDatabase();
- int count = 0;
- switch (mUriMatcher.match(uri)) {
- case SINGLE_FILE:
- count = db.delete(ProviderTableMeta.DB_NAME,
- ProviderTableMeta._ID
- + "="
- + uri.getPathSegments().get(1)
- + (!TextUtils.isEmpty(where) ? " AND (" + where
- + ")" : ""), whereArgs);
- break;
- case ROOT_DIRECTORY:
- count = db.delete(ProviderTableMeta.DB_NAME, where, whereArgs);
- break;
- default:
- throw new IllegalArgumentException("Unknown uri: " + uri.toString());
- }
- getContext().getContentResolver().notifyChange(uri, null);
- return count;
- }
-
- @Override
- public String getType(Uri uri) {
- switch (mUriMatcher.match(uri)) {
- case ROOT_DIRECTORY:
- return ProviderTableMeta.CONTENT_TYPE;
- case SINGLE_FILE:
- return ProviderTableMeta.CONTENT_TYPE_ITEM;
- default:
- throw new IllegalArgumentException("Unknown Uri id."
- + uri.toString());
- }
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- if (mUriMatcher.match(uri) != SINGLE_FILE &&
- mUriMatcher.match(uri) != ROOT_DIRECTORY) {
-
- throw new IllegalArgumentException("Unknown uri id: " + uri);
- }
-
- SQLiteDatabase db = mDbHelper.getWritableDatabase();
- long rowId = db.insert(ProviderTableMeta.DB_NAME, null, values);
- if (rowId > 0) {
- Uri insertedFileUri = ContentUris.withAppendedId(
- ProviderTableMeta.CONTENT_URI_FILE, rowId);
- getContext().getContentResolver().notifyChange(insertedFileUri,
- null);
- return insertedFileUri;
- }
- throw new SQLException("ERROR " + uri);
- }
-
- @Override
- public boolean onCreate() {
- mDbHelper = new DataBaseHelper(getContext());
- return true;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();
-
- sqlQuery.setTables(ProviderTableMeta.DB_NAME);
- sqlQuery.setProjectionMap(mProjectionMap);
-
- switch (mUriMatcher.match(uri)) {
- case ROOT_DIRECTORY:
- break;
- case DIRECTORY:
- sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="
- + uri.getPathSegments().get(1));
- break;
- case SINGLE_FILE:
- if (uri.getPathSegments().size() > 1) {
- sqlQuery.appendWhere(ProviderTableMeta._ID + "="
- + uri.getPathSegments().get(1));
- }
- break;
- default:
- throw new IllegalArgumentException("Unknown uri id: " + uri);
- }
-
- String order;
- if (TextUtils.isEmpty(sortOrder)) {
- order = ProviderTableMeta.DEFAULT_SORT_ORDER;
- } else {
- order = sortOrder;
- }
-
- SQLiteDatabase db = mDbHelper.getReadableDatabase();
- Cursor c = sqlQuery.query(db, projection, selection, selectionArgs,
- null, null, order);
-
- c.setNotificationUri(getContext().getContentResolver(), uri);
-
- return c;
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String selection,
- String[] selectionArgs) {
- return mDbHelper.getWritableDatabase().update(
- ProviderTableMeta.DB_NAME, values, selection, selectionArgs);
- }
-
- class DataBaseHelper extends SQLiteOpenHelper {
-
- public DataBaseHelper(Context context) {
- super(context, ProviderMeta.DB_NAME, null, ProviderMeta.DB_VERSION);
-
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- // files table
- Log.i("SQL", "Entering in onCreate");
- db.execSQL("CREATE TABLE " + ProviderTableMeta.DB_NAME + "("
- + ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "
- + ProviderTableMeta.FILE_NAME + " TEXT, "
- + ProviderTableMeta.FILE_PATH + " TEXT, "
- + ProviderTableMeta.FILE_PARENT + " INTEGER, "
- + ProviderTableMeta.FILE_CREATION + " INTEGER, "
- + ProviderTableMeta.FILE_MODIFIED + " INTEGER, "
- + ProviderTableMeta.FILE_CONTENT_TYPE + " TEXT, "
- + ProviderTableMeta.FILE_CONTENT_LENGTH + " INTEGER, "
- + ProviderTableMeta.FILE_STORAGE_PATH + " TEXT, "
- + ProviderTableMeta.FILE_ACCOUNT_OWNER + " TEXT, "
- + ProviderTableMeta.FILE_LAST_SYNC_DATE + " INTEGER, "
- + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER );");
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- Log.i("SQL", "Entering in onUpgrade");
- if (oldVersion == 1 && newVersion >= 2) {
- Log.i("SQL", "Entering in the ADD in onUpgrade");
- db.execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +
- " ADD COLUMN " + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER " +
- " DEFAULT 0");
- } else Log.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion + ", newVersion == " + newVersion);
- }
-
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/syncadapter/AbstractOwnCloudSyncAdapter.java b/src/eu/alefzero/owncloud/syncadapter/AbstractOwnCloudSyncAdapter.java
deleted file mode 100644
index fa982e7e..00000000
--- a/src/eu/alefzero/owncloud/syncadapter/AbstractOwnCloudSyncAdapter.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.syncadapter;
-
-import java.io.IOException;
-import java.net.UnknownHostException;
-import java.util.Date;
-
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.conn.ConnectionKeepAliveStrategy;
-import org.apache.http.protocol.HttpContext;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.content.AbstractThreadedSyncAdapter;
-import android.content.ContentProviderClient;
-import android.content.Context;
-import android.net.Uri;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.datamodel.DataStorageManager;
-import eu.alefzero.webdav.WebdavClient;
-
-/**
- * Base SyncAdapter for OwnCloud Designed to be subclassed for the concrete
- * SyncAdapter, like ConcatsSync, CalendarSync, FileSync etc..
- *
- * @author sassman
- *
- */
-public abstract class AbstractOwnCloudSyncAdapter extends
- AbstractThreadedSyncAdapter {
-
- private AccountManager accountManager;
- private Account account;
- private ContentProviderClient contentProvider;
- private Date lastUpdated;
- private DataStorageManager mStoreManager;
-
- private WebdavClient mClient = null;
-
- public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize) {
- super(context, autoInitialize);
- this.setAccountManager(AccountManager.get(context));
- }
-
- public AccountManager getAccountManager() {
- return accountManager;
- }
-
- public void setAccountManager(AccountManager accountManager) {
- this.accountManager = accountManager;
- }
-
- public Account getAccount() {
- return account;
- }
-
- public void setAccount(Account account) {
- this.account = account;
- }
-
- public ContentProviderClient getContentProvider() {
- return contentProvider;
- }
-
- public void setContentProvider(ContentProviderClient contentProvider) {
- this.contentProvider = contentProvider;
- }
-
- public Date getLastUpdated() {
- return lastUpdated;
- }
-
- public void setLastUpdated(Date lastUpdated) {
- this.lastUpdated = lastUpdated;
- }
-
- public void setStorageManager(DataStorageManager storage_manager) {
- mStoreManager = storage_manager;
- }
-
- public DataStorageManager getStorageManager() {
- return mStoreManager;
- }
-
- protected ConnectionKeepAliveStrategy getKeepAliveStrategy() {
- return new ConnectionKeepAliveStrategy() {
- public long getKeepAliveDuration(HttpResponse response,
- HttpContext context) {
- // Change keep alive straategy basing on response: ie
- // forbidden/not found/etc
- // should have keep alive 0
- // default return: 5s
- int statusCode = response.getStatusLine().getStatusCode();
-
- // HTTP 400, 500 Errors as well as HTTP 118 - Connection timed
- // out
- if ((statusCode >= 400 && statusCode <= 418)
- || (statusCode >= 421 && statusCode <= 426)
- || (statusCode >= 500 && statusCode <= 510)
- || statusCode == 118) {
- return 0;
- }
-
- return 5 * 1000;
- }
- };
- }
-
- protected HttpResponse fireRawRequest(HttpRequest query)
- throws ClientProtocolException, OperationCanceledException,
- AuthenticatorException, IOException {
- /*
- * BasicHttpContext httpContext = new BasicHttpContext(); BasicScheme
- * basicAuth = new BasicScheme();
- * httpContext.setAttribute("preemptive-auth", basicAuth);
- *
- * HttpResponse response = getClient().execute(mHost, query,
- * httpContext);
- */
- return null;
- }
-
- protected Uri getUri() {
- return Uri.parse(this.getAccountManager().getUserData(getAccount(),
- AccountAuthenticator.KEY_OC_URL));
- }
-
- protected WebdavClient getClient() throws OperationCanceledException,
- AuthenticatorException, IOException {
- if (mClient == null) {
- if (this.getAccountManager().getUserData(getAccount(),
- AccountAuthenticator.KEY_OC_URL) == null) {
- throw new UnknownHostException();
- }
- mClient = new WebdavClient(account, getContext());
- mClient.allowSelfsignedCertificates();
- // mHost = mClient.getTargetHost();
- }
-
- return mClient;
- }
-}
\ No newline at end of file
diff --git a/src/eu/alefzero/owncloud/syncadapter/ContactSyncAdapter.java b/src/eu/alefzero/owncloud/syncadapter/ContactSyncAdapter.java
deleted file mode 100644
index b0ab9569..00000000
--- a/src/eu/alefzero/owncloud/syncadapter/ContactSyncAdapter.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package eu.alefzero.owncloud.syncadapter;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.entity.ByteArrayEntity;
-
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.db.ProviderMeta;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.content.ContentProviderClient;
-import android.content.Context;
-import android.content.SyncResult;
-import android.content.res.AssetFileDescriptor;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.ContactsContract;
-import android.util.Log;
-
-public class ContactSyncAdapter extends AbstractOwnCloudSyncAdapter {
- private String mAddrBookUri;
-
- public ContactSyncAdapter(Context context, boolean autoInitialize) {
- super(context, autoInitialize);
- mAddrBookUri = null;
- }
-
- @Override
- public void onPerformSync(Account account, Bundle extras, String authority,
- ContentProviderClient provider, SyncResult syncResult) {
- setAccount(account);
- setContentProvider(provider);
- Cursor c = getLocalContacts(false);
- if (c.moveToFirst()) {
- do {
- String lookup = c.getString(c
- .getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
- String a = getAddressBookUri();
- String uri = a + lookup + ".vcf";
- FileInputStream f;
- try {
- f = getContactVcard(lookup);
- HttpPut query = new HttpPut(uri);
- byte[] b = new byte[f.available()];
- f.read(b);
- query.setEntity(new ByteArrayEntity(b));
- HttpResponse response = fireRawRequest(query);
- } catch (IOException e) {
- e.printStackTrace();
- return;
- } catch (OperationCanceledException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (AuthenticatorException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- } while (c.moveToNext());
- // } while (c.moveToNext());
- }
-
- }
-
- private String getAddressBookUri() {
- if (mAddrBookUri != null)
- return mAddrBookUri;
-
- AccountManager am = getAccountManager();
- String uri = am.getUserData(getAccount(),
- AccountAuthenticator.KEY_OC_URL).replace(
- AccountUtils.WEBDAV_PATH_2_0, AccountUtils.CARDDAV_PATH_2_0);
- uri += "/addressbooks/"
- + getAccount().name.substring(0,
- getAccount().name.lastIndexOf('@')) + "/default/";
- mAddrBookUri = uri;
- return uri;
- }
-
- private FileInputStream getContactVcard(String lookupKey)
- throws IOException {
- Uri uri = Uri.withAppendedPath(
- ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
- AssetFileDescriptor fd = getContext().getContentResolver()
- .openAssetFileDescriptor(uri, "r");
- return fd.createInputStream();
- }
-
- private Cursor getLocalContacts(boolean include_hidden_contacts) {
- return getContext().getContentResolver().query(
- ContactsContract.Contacts.CONTENT_URI,
- new String[] { ContactsContract.Contacts._ID,
- ContactsContract.Contacts.LOOKUP_KEY },
- ContactsContract.Contacts.IN_VISIBLE_GROUP + " = ?",
- new String[] { (include_hidden_contacts ? "0" : "1") },
- ContactsContract.Contacts._ID + " DESC");
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/syncadapter/ContactSyncService.java b/src/eu/alefzero/owncloud/syncadapter/ContactSyncService.java
deleted file mode 100644
index 465a9406..00000000
--- a/src/eu/alefzero/owncloud/syncadapter/ContactSyncService.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package eu.alefzero.owncloud.syncadapter;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-public class ContactSyncService extends Service {
- private static final Object syncAdapterLock = new Object();
- private static AbstractOwnCloudSyncAdapter mSyncAdapter = null;
-
- @Override
- public void onCreate() {
- synchronized (syncAdapterLock) {
- if (mSyncAdapter == null) {
- mSyncAdapter = new ContactSyncAdapter(getApplicationContext(),
- true);
- }
- }
- }
-
- @Override
- public IBinder onBind(Intent arg0) {
- return mSyncAdapter.getSyncAdapterBinder();
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java b/src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java
deleted file mode 100644
index 8be8dff9..00000000
--- a/src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.syncadapter;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Vector;
-
-import org.apache.jackrabbit.webdav.DavException;
-import org.apache.jackrabbit.webdav.MultiStatus;
-import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
-
-import android.accounts.Account;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.content.ContentProviderClient;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SyncResult;
-import android.os.Bundle;
-import android.util.Log;
-import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
-import eu.alefzero.owncloud.datamodel.OCFile;
-import eu.alefzero.owncloud.files.services.FileDownloader;
-import eu.alefzero.webdav.WebdavEntry;
-import eu.alefzero.webdav.WebdavUtils;
-
-/**
- * SyncAdapter implementation for syncing sample SyncAdapter contacts to the
- * platform ContactOperations provider.
- *
- * @author Bartek Przybylski
- */
-public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
-
- private final static String TAG = "FileSyncAdapter";
-
- /* Commented code for ugly performance tests
- private final static int MAX_DELAYS = 100;
- private static long[] mResponseDelays = new long[MAX_DELAYS];
- private static long[] mSaveDelays = new long[MAX_DELAYS];
- private int mDelaysIndex = 0;
- private int mDelaysCount = 0;
- */
-
- private long mCurrentSyncTime;
- private boolean mCancellation;
- private Account mAccount;
-
- public FileSyncAdapter(Context context, boolean autoInitialize) {
- super(context, autoInitialize);
- }
-
- @Override
- public synchronized void onPerformSync(Account account, Bundle extras,
- String authority, ContentProviderClient provider,
- SyncResult syncResult) {
-
- mCancellation = false;
- mAccount = account;
-
- this.setAccount(mAccount);
- this.setContentProvider(provider);
- this.setStorageManager(new FileDataStorageManager(mAccount,
- getContentProvider()));
-
- /* Commented code for ugly performance tests
- mDelaysIndex = 0;
- mDelaysCount = 0;
- */
-
-
- Log.d(TAG, "syncing owncloud account " + mAccount.name);
-
- sendStickyBroadcast(true, null); // message to signal the start to the UI
-
- PropFindMethod query;
- try {
- mCurrentSyncTime = System.currentTimeMillis();
- query = new PropFindMethod(getUri().toString() + "/");
- getClient().executeMethod(query);
- MultiStatus resp = null;
- resp = query.getResponseBodyAsMultiStatus();
-
- if (resp.getResponses().length > 0) {
- WebdavEntry we = new WebdavEntry(resp.getResponses()[0], getUri().getPath());
- OCFile file = fillOCFile(we);
- file.setParentId(0);
- getStorageManager().saveFile(file);
- if (!mCancellation) {
- fetchData(getUri().toString(), syncResult, file.getFileId());
- }
- }
- } catch (OperationCanceledException e) {
- e.printStackTrace();
- } catch (AuthenticatorException e) {
- syncResult.stats.numAuthExceptions++;
- e.printStackTrace();
- } catch (IOException e) {
- syncResult.stats.numIoExceptions++;
- e.printStackTrace();
- } catch (DavException e) {
- syncResult.stats.numIoExceptions++;
- e.printStackTrace();
- } catch (Throwable t) {
- // TODO update syncResult
- Log.e(TAG, "problem while synchronizing owncloud account " + account.name, t);
- t.printStackTrace();
- }
-
- /* Commented code for ugly performance tests
- long sum = 0, mean = 0, max = 0, min = Long.MAX_VALUE;
- for (int i=0; i updatedFiles = new Vector(resp.getResponses().length - 1);
- for (int i = 1; i < resp.getResponses().length; ++i) {
- WebdavEntry we = new WebdavEntry(resp.getResponses()[i], getUri().getPath());
- OCFile file = fillOCFile(we);
- file.setParentId(parentId);
- if (getStorageManager().getFileByPath(file.getRemotePath()) != null &&
- getStorageManager().getFileByPath(file.getRemotePath()).keepInSync() &&
- file.getModificationTimestamp() > getStorageManager().getFileByPath(file.getRemotePath())
- .getModificationTimestamp()) {
- Intent intent = new Intent(this.getContext(), FileDownloader.class);
- intent.putExtra(FileDownloader.EXTRA_ACCOUNT, getAccount());
- intent.putExtra(FileDownloader.EXTRA_FILE_PATH, file.getRemotePath());
- intent.putExtra(FileDownloader.EXTRA_REMOTE_PATH, file.getRemotePath());
- intent.putExtra(FileDownloader.EXTRA_FILE_SIZE, file.getFileLength());
- file.setKeepInSync(true);
- getContext().startService(intent);
- }
- if (getStorageManager().getFileByPath(file.getRemotePath()) != null)
- file.setKeepInSync(getStorageManager().getFileByPath(file.getRemotePath()).keepInSync());
-
- //Log.v(TAG, "adding file: " + file);
- updatedFiles.add(file);
- if (parentId == 0)
- parentId = file.getFileId();
- }
- /* Commented code for ugly performance tests
- long saveDelay = System.currentTimeMillis();
- */
- getStorageManager().saveFiles(updatedFiles); // all "at once" ; trying to get a best performance in database update
- /* Commented code for ugly performance tests
- saveDelay = System.currentTimeMillis() - saveDelay;
- Log.e(TAG, "syncing: SAVE TIME for " + uri + " contents, " + mSaveDelays[mDelaysIndex] + "ms");
- */
-
- // removal of obsolete files
- Vector files = getStorageManager().getDirectoryContent(
- getStorageManager().getFileById(parentId));
- OCFile file;
- for (int i=0; i < files.size(); ) {
- file = files.get(i);
- if (file.getLastSyncDate() != mCurrentSyncTime) {
- Log.v(TAG, "removing file: " + file);
- getStorageManager().removeFile(file);
- files.remove(i);
- } else {
- i++;
- }
- }
-
- // synchronized folder -> notice to UI
- sendStickyBroadcast(true, getStorageManager().getFileById(parentId).getRemotePath());
-
- // recursive fetch
- for (int i=0; i < files.size() && !mCancellation; i++) {
- OCFile newFile = files.get(i);
- if (newFile.getMimetype().equals("DIR")) {
- fetchData(getUri().toString() + WebdavUtils.encodePath(newFile.getRemotePath()), syncResult, newFile.getFileId());
- }
- }
- if (mCancellation) Log.d(TAG, "Leaving " + uri + " because cancelation request");
-
- /* Commented code for ugly performance tests
- mResponseDelays[mDelaysIndex] = responseDelay;
- mSaveDelays[mDelaysIndex] = saveDelay;
- mDelaysCount++;
- mDelaysIndex++;
- if (mDelaysIndex >= MAX_DELAYS)
- mDelaysIndex = 0;
- */
-
-
-
- } catch (OperationCanceledException e) {
- e.printStackTrace();
- } catch (AuthenticatorException e) {
- syncResult.stats.numAuthExceptions++;
- e.printStackTrace();
- } catch (IOException e) {
- syncResult.stats.numIoExceptions++;
- e.printStackTrace();
- } catch (DavException e) {
- syncResult.stats.numIoExceptions++;
- e.printStackTrace();
- } catch (Throwable t) {
- // TODO update syncResult
- Log.e(TAG, "problem while synchronizing owncloud account " + mAccount.name, t);
- t.printStackTrace();
- }
- }
-
- private OCFile fillOCFile(WebdavEntry we) {
- OCFile file = new OCFile(we.decodedPath());
- file.setCreationTimestamp(we.createTimestamp());
- file.setFileLength(we.contentLength());
- file.setMimetype(we.contentType());
- file.setModificationTimestamp(we.modifiedTimesamp());
- file.setLastSyncDate(mCurrentSyncTime);
- return file;
- }
-
-
- private void sendStickyBroadcast(boolean inProgress, String dirRemotePath) {
- Intent i = new Intent(FileSyncService.SYNC_MESSAGE);
- i.putExtra(FileSyncService.IN_PROGRESS, inProgress);
- i.putExtra(FileSyncService.ACCOUNT_NAME, getAccount().name);
- if (dirRemotePath != null) {
- i.putExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH, dirRemotePath);
- }
- getContext().sendStickyBroadcast(i);
- }
-
- /**
- * Called by system SyncManager when a synchronization is required to be cancelled.
- *
- * Sets the mCancellation flag to 'true'. THe synchronization will be stopped when before a new folder is fetched. Data of the last folder
- * fetched will be still saved in the database. See onPerformSync implementation.
- */
- @Override
- public void onSyncCanceled() {
- Log.d(TAG, "Synchronization of " + mAccount.name + " has been requested to cancell");
- mCancellation = true;
- super.onSyncCanceled();
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/syncadapter/FileSyncService.java b/src/eu/alefzero/owncloud/syncadapter/FileSyncService.java
deleted file mode 100644
index 5396f582..00000000
--- a/src/eu/alefzero/owncloud/syncadapter/FileSyncService.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.syncadapter;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-/**
- * Background service for syncing files to our local Database
- *
- * @author Bartek Przybylski
- *
- */
-public class FileSyncService extends Service {
- public static final String SYNC_MESSAGE = "ACCOUNT_SYNC";
- public static final String SYNC_FOLDER_REMOTE_PATH = "SYNC_FOLDER_REMOTE_PATH";
- public static final String IN_PROGRESS = "SYNC_IN_PROGRESS";
- public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
-
- /*
- * {@inheritDoc}
- */
- @Override
- public void onCreate() {
- }
-
- /*
- * {@inheritDoc}
- */
- @Override
- public IBinder onBind(Intent intent) {
- return new FileSyncAdapter(getApplicationContext(), true).getSyncAdapterBinder();
- }
-}
diff --git a/src/eu/alefzero/owncloud/ui/ActionItem.java b/src/eu/alefzero/owncloud/ui/ActionItem.java
deleted file mode 100644
index 6f96f194..00000000
--- a/src/eu/alefzero/owncloud/ui/ActionItem.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.ui;
-
-import android.graphics.drawable.Drawable;
-import android.view.View.OnClickListener;
-
-/**
- * Represents an Item on the ActionBar.
- *
- * @author Bartek Przybylski
- *
- */
-public class ActionItem {
- private Drawable mIcon;
- private String mTitle;
- private OnClickListener mClickListener;
-
- public ActionItem() {
- }
-
- public void setTitle(String title) {
- mTitle = title;
- }
-
- public String getTitle() {
- return mTitle;
- }
-
- public void setIcon(Drawable icon) {
- mIcon = icon;
- }
-
- public Drawable getIcon() {
- return mIcon;
- }
-
- public void setOnClickListener(OnClickListener listener) {
- mClickListener = listener;
- }
-
- public OnClickListener getOnClickListerner() {
- return mClickListener;
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/CustomPopup.java b/src/eu/alefzero/owncloud/ui/CustomPopup.java
deleted file mode 100644
index cd8d8459..00000000
--- a/src/eu/alefzero/owncloud/ui/CustomPopup.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.ui;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.view.View.OnTouchListener;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.PopupWindow;
-
-/**
- * Represents a custom PopupWindows
- *
- * @author Lorensius. W. T
- *
- */
-public class CustomPopup {
- protected final View mAnchor;
- protected final PopupWindow mWindow;
- private View root;
- private Drawable background = null;
- protected final WindowManager mWManager;
-
- public CustomPopup(View anchor) {
- mAnchor = anchor;
- mWindow = new PopupWindow(anchor.getContext());
-
- mWindow.setTouchInterceptor(new OnTouchListener() {
-
- public boolean onTouch(View v, MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
- CustomPopup.this.dismiss();
- return true;
- }
- return false;
- }
- });
-
- mWManager = (WindowManager) anchor.getContext().getSystemService(
- Context.WINDOW_SERVICE);
- onCreate();
- }
-
- public void onCreate() {
- }
-
- public void onShow() {
- }
-
- public void preShow() {
- if (root == null) {
- throw new IllegalStateException(
- "setContentView called with a view to display");
- }
-
- onShow();
-
- if (background == null) {
- mWindow.setBackgroundDrawable(new BitmapDrawable());
- } else {
- mWindow.setBackgroundDrawable(background);
- }
-
- mWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
- mWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
- mWindow.setTouchable(true);
- mWindow.setFocusable(true);
- mWindow.setOutsideTouchable(true);
-
- mWindow.setContentView(root);
- }
-
- public void setBackgroundDrawable(Drawable background) {
- this.background = background;
- }
-
- public void setContentView(View root) {
- this.root = root;
- mWindow.setContentView(root);
- }
-
- public void setContentView(int layoutResId) {
- LayoutInflater inflater = (LayoutInflater) mAnchor.getContext()
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- setContentView(inflater.inflate(layoutResId, null));
- }
-
- public void showDropDown() {
- showDropDown(0, 0);
- }
-
- public void showDropDown(int x, int y) {
- preShow();
- mWindow.setAnimationStyle(android.R.style.Animation_Dialog);
- mWindow.showAsDropDown(mAnchor, x, y);
- }
-
- public void showLikeQuickAction() {
- showLikeQuickAction(0, 0);
- }
-
- public void showLikeQuickAction(int x, int y) {
- preShow();
-
- mWindow.setAnimationStyle(android.R.style.Animation_Dialog);
- int[] location = new int[2];
- mAnchor.getLocationOnScreen(location);
-
- Rect anchorRect = new Rect(location[0], location[1], location[0]
- + mAnchor.getWidth(), location[1] + mAnchor.getHeight());
-
- root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT));
- root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
-
- int rootW = root.getWidth(), rootH = root.getHeight();
- int screenW = mWManager.getDefaultDisplay().getWidth();
-
- int xpos = ((screenW - rootW) / 2) + x;
- int ypos = anchorRect.top - rootH + y;
-
- if (rootH > anchorRect.top) {
- ypos = anchorRect.bottom + y;
- }
- mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xpos, ypos);
- }
-
- public void dismiss() {
- mWindow.dismiss();
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/FragmentListView.java b/src/eu/alefzero/owncloud/ui/FragmentListView.java
deleted file mode 100644
index 17e64835..00000000
--- a/src/eu/alefzero/owncloud/ui/FragmentListView.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package eu.alefzero.owncloud.ui;
-
-import com.actionbarsherlock.app.SherlockFragment;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.AdapterView.OnItemClickListener;
-
-public class FragmentListView extends SherlockFragment implements
- OnItemClickListener, OnItemLongClickListener {
- ListView mList;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
-
- public void setListAdapter(ListAdapter listAdapter) {
- mList.setAdapter(listAdapter);
- mList.invalidate();
- }
-
- public ListView getListView() {
- return mList;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- mList = new ListView(getActivity());
- mList.setOnItemClickListener(this);
- mList.setOnItemLongClickListener(this);
- return mList;
- // return super.onCreateView(inflater, container, savedInstanceState);
- }
-
- public void onItemClick(AdapterView> arg0, View arg1, int arg2, long arg3) {
- }
-
- @Override
- public boolean onItemLongClick(AdapterView> arg0, View arg1, int arg2,
- long arg3) {
- return false;
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/QuickAction.java b/src/eu/alefzero/owncloud/ui/QuickAction.java
deleted file mode 100644
index e1d97d22..00000000
--- a/src/eu/alefzero/owncloud/ui/QuickAction.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.ui;
-
-import android.content.Context;
-
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.LinearLayout;
-import android.widget.ScrollView;
-
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewGroup;
-
-import java.util.ArrayList;
-
-import eu.alefzero.owncloud.R;
-
-/**
- * Popup window, shows action list as icon and text like the one in Gallery3D
- * app.
- *
- * @author Lorensius. W. T
- */
-public class QuickAction extends CustomPopup {
- private final View root;
- private final ImageView mArrowUp;
- private final ImageView mArrowDown;
- private final LayoutInflater inflater;
- private final Context context;
-
- protected static final int ANIM_GROW_FROM_LEFT = 1;
- protected static final int ANIM_GROW_FROM_RIGHT = 2;
- protected static final int ANIM_GROW_FROM_CENTER = 3;
- protected static final int ANIM_REFLECT = 4;
- protected static final int ANIM_AUTO = 5;
-
- private int animStyle;
- private ViewGroup mTrack;
- private ScrollView scroller;
- private ArrayList actionList;
-
- /**
- * Constructor
- *
- * @param anchor {@link View} on where the popup window should be displayed
- */
- public QuickAction(View anchor) {
- super(anchor);
-
- actionList = new ArrayList();
- context = anchor.getContext();
- inflater = (LayoutInflater) context
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- root = (ViewGroup) inflater.inflate(R.layout.popup, null);
-
- mArrowDown = (ImageView) root.findViewById(R.id.arrow_down);
- mArrowUp = (ImageView) root.findViewById(R.id.arrow_up);
-
- setContentView(root);
-
- mTrack = (ViewGroup) root.findViewById(R.id.tracks);
- scroller = (ScrollView) root.findViewById(R.id.scroller);
- animStyle = ANIM_AUTO;
- }
-
- /**
- * Set animation style
- *
- * @param animStyle animation style, default is set to ANIM_AUTO
- */
- public void setAnimStyle(int animStyle) {
- this.animStyle = animStyle;
- }
-
- /**
- * Add action item
- *
- * @param action {@link ActionItem} object
- */
- public void addActionItem(ActionItem action) {
- actionList.add(action);
- }
-
- /**
- * Show popup window. Popup is automatically positioned, on top or bottom of
- * anchor view.
- *
- */
- public void show() {
- preShow();
-
- int xPos, yPos;
-
- int[] location = new int[2];
-
- mAnchor.getLocationOnScreen(location);
-
- Rect anchorRect = new Rect(location[0], location[1], location[0]
- + mAnchor.getWidth(), location[1] + mAnchor.getHeight());
-
- createActionList();
-
- root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT));
- root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
-
- int rootHeight = root.getMeasuredHeight();
- int rootWidth = root.getMeasuredWidth();
-
- int screenWidth = mWManager.getDefaultDisplay().getWidth();
- int screenHeight = mWManager.getDefaultDisplay().getHeight();
-
- // automatically get X coord of popup (top left)
- if ((anchorRect.left + rootWidth) > screenWidth) {
- xPos = anchorRect.left - (rootWidth - mAnchor.getWidth());
- } else {
- if (mAnchor.getWidth() > rootWidth) {
- xPos = anchorRect.centerX() - (rootWidth / 2);
- } else {
- xPos = anchorRect.left;
- }
- }
-
- int dyTop = anchorRect.top;
- int dyBottom = screenHeight - anchorRect.bottom;
-
- boolean onTop = (dyTop > dyBottom) ? true : false;
-
- if (onTop) {
- if (rootHeight > dyTop) {
- yPos = 15;
- LayoutParams l = scroller.getLayoutParams();
- l.height = dyTop - mAnchor.getHeight();
- } else {
- yPos = anchorRect.top - rootHeight;
- }
- } else {
- yPos = anchorRect.bottom;
-
- if (rootHeight > dyBottom) {
- LayoutParams l = scroller.getLayoutParams();
- l.height = dyBottom;
- }
- }
-
- showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up),
- anchorRect.centerX() - xPos);
-
- setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
-
- mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xPos, yPos);
- }
-
- /**
- * Set animation style
- *
- * @param screenWidth screen width
- * @param requestedX distance from left edge
- * @param onTop flag to indicate where the popup should be displayed. Set
- * TRUE if displayed on top of anchor view and vice versa
- */
- private void setAnimationStyle(int screenWidth, int requestedX,
- boolean onTop) {
- int arrowPos = requestedX - mArrowUp.getMeasuredWidth() / 2;
-
- switch (animStyle) {
- case ANIM_GROW_FROM_LEFT:
- mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
- : R.style.Animations_PopDownMenu_Left);
- break;
-
- case ANIM_GROW_FROM_RIGHT:
- mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
- : R.style.Animations_PopDownMenu_Right);
- break;
-
- case ANIM_GROW_FROM_CENTER:
- mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
- : R.style.Animations_PopDownMenu_Center);
- break;
-
- case ANIM_REFLECT:
- mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect
- : R.style.Animations_PopDownMenu_Reflect);
- break;
-
- case ANIM_AUTO:
- if (arrowPos <= screenWidth / 4) {
- mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
- : R.style.Animations_PopDownMenu_Left);
- } else if (arrowPos > screenWidth / 4
- && arrowPos < 3 * (screenWidth / 4)) {
- mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
- : R.style.Animations_PopDownMenu_Center);
- } else {
- mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
- : R.style.Animations_PopDownMenu_Right);
- }
-
- break;
- }
- }
-
- /**
- * Create action list
- */
- private void createActionList() {
- View view;
- String title;
- Drawable icon;
- OnClickListener listener;
-
- for (int i = 0; i < actionList.size(); i++) {
- title = actionList.get(i).getTitle();
- icon = actionList.get(i).getIcon();
- listener = actionList.get(i).getOnClickListerner();
-
- view = getActionItem(title, icon, listener);
-
- view.setFocusable(true);
- view.setClickable(true);
-
- mTrack.addView(view);
- }
- }
-
- /**
- * Get action item {@link View}
- *
- * @param title action item title
- * @param icon {@link Drawable} action item icon
- * @param listener {@link View.OnClickListener} action item listener
- * @return action item {@link View}
- */
- private View getActionItem(String title, Drawable icon,
- OnClickListener listener) {
- LinearLayout container = (LinearLayout) inflater.inflate(
- R.layout.action_item, null);
-
- ImageView img = (ImageView) container.findViewById(R.id.icon);
- TextView text = (TextView) container.findViewById(R.id.title);
-
- if (icon != null) {
- img.setImageDrawable(icon);
- }
-
- if (title != null) {
- text.setText(title);
- }
-
- if (listener != null) {
- container.setOnClickListener(listener);
- }
-
- return container;
- }
-
- /**
- * Show arrow
- *
- * @param whichArrow arrow type resource id
- * @param requestedX distance from left screen
- */
- private void showArrow(int whichArrow, int requestedX) {
- final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp
- : mArrowDown;
- final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown
- : mArrowUp;
-
- final int arrowWidth = mArrowUp.getMeasuredWidth();
-
- showArrow.setVisibility(View.VISIBLE);
-
- ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams) showArrow
- .getLayoutParams();
-
- param.leftMargin = requestedX - arrowWidth / 2;
-
- hideArrow.setVisibility(View.INVISIBLE);
- }
-}
\ No newline at end of file
diff --git a/src/eu/alefzero/owncloud/ui/activity/AccountSelectActivity.java b/src/eu/alefzero/owncloud/ui/activity/AccountSelectActivity.java
deleted file mode 100644
index 8600a473..00000000
--- a/src/eu/alefzero/owncloud/ui/activity/AccountSelectActivity.java
+++ /dev/null
@@ -1,189 +0,0 @@
-package eu.alefzero.owncloud.ui.activity;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AccountManagerCallback;
-import android.accounts.AccountManagerFuture;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.widget.AdapterView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.CheckedTextView;
-import android.widget.ListView;
-import android.widget.SimpleAdapter;
-import android.widget.TextView;
-
-import com.actionbarsherlock.app.ActionBar;
-import com.actionbarsherlock.app.SherlockListActivity;
-import com.actionbarsherlock.view.Menu;
-import com.actionbarsherlock.view.MenuInflater;
-import com.actionbarsherlock.view.MenuItem;
-
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.R;
-
-public class AccountSelectActivity extends SherlockListActivity implements
- AccountManagerCallback {
-
- private final Handler mHandler = new Handler();
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- ActionBar action_bar = getSupportActionBar();
- action_bar.setDisplayShowTitleEnabled(true);
- action_bar.setDisplayHomeAsUpEnabled(false);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- populateAccountList();
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getSherlock().getMenuInflater();
- inflater.inflate(eu.alefzero.owncloud.R.menu.account_picker, menu);
- return true;
- }
-
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
- getMenuInflater().inflate(R.menu.account_picker_long_click, menu);
- super.onCreateContextMenu(menu, v, menuInfo);
- }
-
- @Override
- protected void onListItemClick(ListView l, View v, int position, long id) {
- String accountName = ((TextView) v.findViewById(android.R.id.text1))
- .getText().toString();
- AccountUtils.setCurrentOwnCloudAccount(this, accountName);
-
- // trigger synchronization when current account is changed
- ContentResolver.cancelSync(null, "org.owncloud");
- Bundle bundle = new Bundle();
- bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
- ContentResolver.requestSync(AccountUtils.getCurrentOwnCloudAccount(this), "org.owncloud", bundle);
-
- Intent i = new Intent(this, FileDisplayActivity.class);
- i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(i);
- finish();
- }
-
- @Override
- public boolean onMenuItemSelected(int featureId, MenuItem item) {
- if (item.getItemId() == R.id.createAccount) {
- Intent intent = new Intent(
- android.provider.Settings.ACTION_ADD_ACCOUNT);
- intent.putExtra("authorities",
- new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
- startActivity(intent);
- return true;
- }
- return false;
- }
-
- @Override
- public boolean onContextItemSelected(android.view.MenuItem item) {
- AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
- .getMenuInfo();
- int index = info.position;
- HashMap map = (HashMap) getListAdapter()
- .getItem(index);
- String accountName = map.get("NAME");
- AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
- Account accounts[] = am
- .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
- for (Account a : accounts) {
- if (a.name.equals(accountName)) {
- am.removeAccount(a, this, mHandler);
- }
- }
-
- return false;
- }
-
- private void populateAccountList() {
- AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
- Account accounts[] = am
- .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
- LinkedList> ll = new LinkedList>();
- for (Account a : accounts) {
- HashMap h = new HashMap();
- h.put("NAME", a.name);
- h.put("VER",
- "ownCloud version: "
- + am.getUserData(a,
- AccountAuthenticator.KEY_OC_VERSION));
- ll.add(h);
- }
-
- setListAdapter(new AccountCheckedSimpleAdepter(this, ll,
- android.R.layout.simple_list_item_single_choice,
- new String[] { "NAME" }, new int[] { android.R.id.text1 }));
- registerForContextMenu(getListView());
- }
-
- @Override
- public void run(AccountManagerFuture future) {
- if (future.isDone()) {
- Account a = AccountUtils.getCurrentOwnCloudAccount(this);
- String accountName = "";
- if (a == null) {
- Account[] accounts = AccountManager.get(this)
- .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
- if (accounts.length != 0)
- accountName = accounts[0].name;
- AccountUtils.setCurrentOwnCloudAccount(this, accountName);
- }
- populateAccountList();
- }
- }
-
- private class AccountCheckedSimpleAdepter extends SimpleAdapter {
- private Account mCurrentAccount;
- private List extends Map> mPrivateData;
-
- public AccountCheckedSimpleAdepter(Context context,
- List extends Map> data, int resource,
- String[] from, int[] to) {
- super(context, data, resource, from, to);
- mCurrentAccount = AccountUtils
- .getCurrentOwnCloudAccount(AccountSelectActivity.this);
- mPrivateData = data;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View v = super.getView(position, convertView, parent);
- CheckedTextView ctv = (CheckedTextView) v
- .findViewById(android.R.id.text1);
- if (mPrivateData.get(position).get("NAME")
- .equals(mCurrentAccount.name)) {
- ctv.setChecked(true);
- }
- return v;
- }
-
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java b/src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java
deleted file mode 100644
index caa9820a..00000000
--- a/src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.ui.activity;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLEncoder;
-
-import android.accounts.Account;
-import android.accounts.AccountAuthenticatorActivity;
-import android.accounts.AccountManager;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.ContentResolver;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.os.Handler;
-import android.preference.PreferenceManager;
-import android.text.InputType;
-import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnFocusChangeListener;
-import android.view.Window;
-import android.widget.ImageView;
-import android.widget.TextView;
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.authenticator.AuthenticationRunnable;
-import eu.alefzero.owncloud.authenticator.ConnectionCheckerRunnable;
-import eu.alefzero.owncloud.authenticator.OnAuthenticationResultListener;
-import eu.alefzero.owncloud.authenticator.OnConnectCheckListener;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-import eu.alefzero.owncloud.extensions.ExtensionsAvailableActivity;
-import eu.alefzero.owncloud.utils.OwnCloudVersion;
-
-/**
- * This Activity is used to add an ownCloud account to the App
- *
- * @author Bartek Przybylski
- *
- */
-public class AuthenticatorActivity extends AccountAuthenticatorActivity
- implements OnAuthenticationResultListener, OnConnectCheckListener,
- OnFocusChangeListener, OnClickListener {
- private static final int DIALOG_LOGIN_PROGRESS = 0;
-
- private static final String TAG = "AuthActivity";
-
- private Thread mAuthThread;
- private AuthenticationRunnable mAuthRunnable;
- private ConnectionCheckerRunnable mConnChkRunnable;
- private final Handler mHandler = new Handler();
- private String mBaseUrl;
-
- private static final String STATUS_TEXT = "STATUS_TEXT";
- private static final String STATUS_ICON = "STATUS_ICON";
- private static final String STATUS_CORRECT = "STATUS_CORRECT";
- private static final String IS_SSL_CONN = "IS_SSL_CONN";
- private int mStatusText, mStatusIcon;
- private boolean mStatusCorrect, mIsSslConn;
-
- public static final String PARAM_USERNAME = "param_Username";
- public static final String PARAM_HOSTNAME = "param_Hostname";
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getWindow().requestFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.account_setup);
- ImageView iv = (ImageView) findViewById(R.id.refreshButton);
- ImageView iv2 = (ImageView) findViewById(R.id.viewPassword);
- TextView tv = (TextView) findViewById(R.id.host_URL);
- TextView tv2 = (TextView) findViewById(R.id.account_password);
-
- if (savedInstanceState != null) {
- mStatusIcon = savedInstanceState.getInt(STATUS_ICON);
- mStatusText = savedInstanceState.getInt(STATUS_TEXT);
- mStatusCorrect = savedInstanceState.getBoolean(STATUS_CORRECT);
- mIsSslConn = savedInstanceState.getBoolean(IS_SSL_CONN);
- setResultIconAndText(mStatusIcon, mStatusText);
- findViewById(R.id.buttonOK).setEnabled(mStatusCorrect);
- if (!mStatusCorrect)
- iv.setVisibility(View.VISIBLE);
- else
- iv.setVisibility(View.INVISIBLE);
-
- } else {
- mStatusText = mStatusIcon = 0;
- mStatusCorrect = false;
- mIsSslConn = false;
- }
- iv.setOnClickListener(this);
- iv2.setOnClickListener(this);
- tv.setOnFocusChangeListener(this);
- tv2.setOnFocusChangeListener(this);
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- outState.putInt(STATUS_ICON, mStatusIcon);
- outState.putInt(STATUS_TEXT, mStatusText);
- outState.putBoolean(STATUS_CORRECT, mStatusCorrect);
- super.onSaveInstanceState(outState);
- }
-
- @Override
- protected Dialog onCreateDialog(int id) {
- Dialog dialog = null;
- switch (id) {
- case DIALOG_LOGIN_PROGRESS: {
- ProgressDialog working_dialog = new ProgressDialog(this);
- working_dialog.setMessage(getResources().getString(
- R.string.auth_trying_to_login));
- working_dialog.setIndeterminate(true);
- working_dialog.setCancelable(true);
- working_dialog
- .setOnCancelListener(new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- Log.i(TAG, "Login canceled");
- if (mAuthThread != null) {
- mAuthThread.interrupt();
- finish();
- }
- }
- });
- dialog = working_dialog;
- break;
- }
- default:
- Log.e(TAG, "Incorrect dialog called with id = " + id);
- }
- return dialog;
- }
-
- public void onAuthenticationResult(boolean success, String message) {
- if (success) {
- TextView username_text = (TextView) findViewById(R.id.account_username), password_text = (TextView) findViewById(R.id.account_password);
-
- URL url;
- try {
- url = new URL(message);
- } catch (MalformedURLException e) {
- // should never happen
- Log.e(getClass().getName(), "Malformed URL: " + message);
- return;
- }
-
- String username = username_text.getText().toString().trim();
- String accountName = username + "@" + url.getHost();
- if (url.getPort() >= 0) {
- accountName += ":" + url.getPort();
- }
- Account account = new Account(accountName,
- AccountAuthenticator.ACCOUNT_TYPE);
- AccountManager accManager = AccountManager.get(this);
- accManager.addAccountExplicitly(account, password_text.getText()
- .toString(), null);
-
- // Add this account as default in the preferences, if there is none
- // already
- Account defaultAccount = AccountUtils
- .getCurrentOwnCloudAccount(this);
- if (defaultAccount == null) {
- SharedPreferences.Editor editor = PreferenceManager
- .getDefaultSharedPreferences(this).edit();
- editor.putString("select_oc_account", accountName);
- editor.commit();
- }
-
- final Intent intent = new Intent();
- intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE,
- AccountAuthenticator.ACCOUNT_TYPE);
- intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
- intent.putExtra(AccountManager.KEY_AUTHTOKEN,
- AccountAuthenticator.ACCOUNT_TYPE);
- intent.putExtra(AccountManager.KEY_USERDATA, username);
-
- accManager.setUserData(account, AccountAuthenticator.KEY_OC_URL,
- url.toString());
- accManager.setUserData(account,
- AccountAuthenticator.KEY_OC_VERSION, mConnChkRunnable
- .getDiscoveredVersion().toString());
- accManager.setUserData(account,
- AccountAuthenticator.KEY_OC_BASE_URL, mBaseUrl);
-
- setAccountAuthenticatorResult(intent.getExtras());
- setResult(RESULT_OK, intent);
- Bundle bundle = new Bundle();
- bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
- //getContentResolver().startSync(ProviderTableMeta.CONTENT_URI,
- // bundle);
- ContentResolver.requestSync(account, "org.owncloud", bundle);
-
- /*
- * if
- * (mConnChkRunnable.getDiscoveredVersion().compareTo(OwnCloudVersion
- * .owncloud_v2) >= 0) { Intent i = new Intent(this,
- * ExtensionsAvailableActivity.class); startActivity(i); }
- */
-
- finish();
- } else {
- dismissDialog(DIALOG_LOGIN_PROGRESS);
- TextView tv = (TextView) findViewById(R.id.account_username);
- tv.setError(message);
- }
- }
- public void onCancelClick(View view) {
- finish();
- }
-
- public void onOkClick(View view) {
- String prefix = "";
- String url = ((TextView) findViewById(R.id.host_URL)).getText()
- .toString();
- if (mIsSslConn) {
- prefix = "https://";
- } else {
- prefix = "http://";
- }
- if (url.toLowerCase().startsWith("http://")
- || url.toLowerCase().startsWith("https://")) {
- prefix = "";
- }
- continueConnection(prefix);
- }
-
- private void continueConnection(String prefix) {
- String url = ((TextView) findViewById(R.id.host_URL)).getText()
- .toString();
- String username = ((TextView) findViewById(R.id.account_username))
- .getText().toString();
- String password = ((TextView) findViewById(R.id.account_password))
- .getText().toString();
- if (url.endsWith("/"))
- url = url.substring(0, url.length() - 1);
-
- URL uri = null;
- String webdav_path = AccountUtils.getWebdavPath(mConnChkRunnable
- .getDiscoveredVersion());
-
- try {
- mBaseUrl = prefix + url;
- String url_str = prefix + url + webdav_path;
- uri = new URL(url_str);
- } catch (MalformedURLException e) {
- // should not happend
- e.printStackTrace();
- }
-
- showDialog(DIALOG_LOGIN_PROGRESS);
- mAuthRunnable = new AuthenticationRunnable(uri, username, password);
- mAuthRunnable.setOnAuthenticationResultListener(this, mHandler);
- mAuthThread = new Thread(mAuthRunnable);
- mAuthThread.start();
- }
-
- @Override
- public void onConnectionCheckResult(ResultType type) {
- mStatusText = mStatusIcon = 0;
- mStatusCorrect = false;
- String t_url = ((TextView) findViewById(R.id.host_URL)).getText()
- .toString().toLowerCase();
-
- switch (type) {
- case OK_SSL:
- mIsSslConn = true;
- mStatusIcon = android.R.drawable.ic_secure;
- mStatusText = R.string.auth_secure_connection;
- mStatusCorrect = true;
- break;
- case OK_NO_SSL:
- mIsSslConn = false;
- mStatusCorrect = true;
- if (t_url.startsWith("http://") ) {
- mStatusText = R.string.auth_connection_established;
- mStatusIcon = R.drawable.ic_ok;
- } else {
- mStatusText = R.string.auth_nossl_plain_ok_title;
- mStatusIcon = android.R.drawable.ic_partial_secure;
- }
- break;
- case TIMEOUT:
- case INORRECT_ADDRESS:
- case SSL_INIT_ERROR:
- case HOST_NOT_AVAILABLE:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_unknow_host_title;
- break;
- case NO_NETWORK_CONNECTION:
- mStatusIcon = R.drawable.no_network;
- mStatusText = R.string.auth_no_net_conn_title;
- break;
- case INSTANCE_NOT_CONFIGURED:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_not_configured_title;
- break;
- case UNKNOWN_ERROR:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_unknow_error;
- break;
- case FILE_NOT_FOUND:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_incorrect_path_title;
- break;
- default:
- Log.e(TAG, "Incorrect connection checker result type: " + type);
- }
- setResultIconAndText(mStatusIcon, mStatusText);
- if (!mStatusCorrect)
- findViewById(R.id.refreshButton).setVisibility(View.VISIBLE);
- else
- findViewById(R.id.refreshButton).setVisibility(View.INVISIBLE);
- findViewById(R.id.buttonOK).setEnabled(mStatusCorrect);
- }
-
- @Override
- public void onFocusChange(View view, boolean hasFocus) {
- if (view.getId() == R.id.host_URL) {
- if (!hasFocus) {
- TextView tv = ((TextView) findViewById(R.id.host_URL));
- String uri = tv.getText().toString();
- if (uri.length() != 0) {
- setResultIconAndText(R.drawable.progress_small,
- R.string.auth_testing_connection);
- findViewById(R.id.buttonOK).setEnabled(false); // avoid connect can be clicked if the test was previously passed
- mConnChkRunnable = new ConnectionCheckerRunnable(uri, this);
- mConnChkRunnable.setListener(this, mHandler);
- mAuthThread = new Thread(mConnChkRunnable);
- mAuthThread.start();
- } else {
- findViewById(R.id.refreshButton).setVisibility(
- View.INVISIBLE);
- setResultIconAndText(0, 0);
- }
- }
- } else if (view.getId() == R.id.account_password) {
- ImageView iv = (ImageView) findViewById(R.id.viewPassword);
- if (hasFocus) {
- iv.setVisibility(View.VISIBLE);
- } else {
- TextView v = (TextView) findViewById(R.id.account_password);
- int input_type = InputType.TYPE_CLASS_TEXT
- | InputType.TYPE_TEXT_VARIATION_PASSWORD;
- v.setInputType(input_type);
- iv.setVisibility(View.INVISIBLE);
- }
- }
- }
-
- private void setResultIconAndText(int drawable_id, int text_id) {
- ImageView iv = (ImageView) findViewById(R.id.action_indicator);
- TextView tv = (TextView) findViewById(R.id.status_text);
-
- if (drawable_id == 0 && text_id == 0) {
- iv.setVisibility(View.INVISIBLE);
- tv.setVisibility(View.INVISIBLE);
- } else {
- iv.setImageResource(drawable_id);
- tv.setText(text_id);
- iv.setVisibility(View.VISIBLE);
- tv.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.refreshButton) {
- onFocusChange(findViewById(R.id.host_URL), false);
- } else if (v.getId() == R.id.viewPassword) {
- TextView view = (TextView) findViewById(R.id.account_password);
- int input_type = InputType.TYPE_CLASS_TEXT
- | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
- view.setInputType(input_type);
- }
- }
-}
diff --git a/src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java b/src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java
deleted file mode 100644
index 461485c5..00000000
--- a/src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.ui.activity;
-
-import android.accounts.Account;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.support.v4.app.FragmentTransaction;
-
-import com.actionbarsherlock.app.ActionBar;
-import com.actionbarsherlock.app.SherlockFragmentActivity;
-import com.actionbarsherlock.view.MenuItem;
-
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.datamodel.OCFile;
-import eu.alefzero.owncloud.files.services.FileDownloader;
-import eu.alefzero.owncloud.ui.fragment.FileDetailFragment;
-
-/**
- * This activity displays the details of a file like its name, its size and so
- * on.
- *
- * @author Bartek Przybylski
- *
- */
-public class FileDetailActivity extends SherlockFragmentActivity implements FileDetailFragment.ContainerActivity {
-
- public static final int DIALOG_SHORT_WAIT = 0;
-
- private boolean mConfigurationChangedToLandscape = false;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // check if configuration changed to large-land ; for a tablet being changed from portrait to landscape when in FileDetailActivity
- Configuration conf = getResources().getConfiguration();
- mConfigurationChangedToLandscape = (conf.orientation == Configuration.ORIENTATION_LANDSCAPE &&
- (conf.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
- );
-
- if (!mConfigurationChangedToLandscape) {
- setContentView(R.layout.file_activity_details);
-
- ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
-
- OCFile file = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);
- Account account = getIntent().getParcelableExtra(FileDownloader.EXTRA_ACCOUNT);
- FileDetailFragment mFileDetail = new FileDetailFragment(file, account);
-
- FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
- ft.replace(R.id.fragment, mFileDetail, FileDetailFragment.FTAG);
- ft.commit();
-
- } else {
- backToDisplayActivity(); // the 'back' won't be effective until this.onStart() and this.onResume() are completed;
- }
-
-
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- boolean returnValue = false;
-
- switch(item.getItemId()){
- case android.R.id.home:
- backToDisplayActivity();
- returnValue = true;
- }
-
- return returnValue;
- }
-
-
-
- @Override
- protected void onResume() {
-
- super.onResume();
- if (!mConfigurationChangedToLandscape) {
- FileDetailFragment fragment = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
- fragment.updateFileDetails();
- }
- }
-
-
- private void backToDisplayActivity() {
- Intent intent = new Intent(this, FileDisplayActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.putExtra(FileDetailFragment.EXTRA_FILE, getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE));
- startActivity(intent);
- finish();
- }
-
-
- @Override
- protected Dialog onCreateDialog(int id) {
- Dialog dialog = null;
- switch (id) {
- case DIALOG_SHORT_WAIT: {
- ProgressDialog working_dialog = new ProgressDialog(this);
- working_dialog.setMessage(getResources().getString(
- R.string.wait_a_moment));
- working_dialog.setIndeterminate(true);
- working_dialog.setCancelable(false);
- dialog = working_dialog;
- break;
- }
- default:
- dialog = null;
- }
- return dialog;
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onFileStateChanged() {
- // nothing to do here!
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java b/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java
deleted file mode 100644
index c440847c..00000000
--- a/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java
+++ /dev/null
@@ -1,886 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.ui.activity;
-
-import java.io.File;
-import java.util.ArrayList;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.AlertDialog;
-import android.app.ProgressDialog;
-import android.app.AlertDialog.Builder;
-import android.app.Dialog;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources.NotFoundException;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.preference.PreferenceManager;
-import android.provider.MediaStore;
-import android.support.v4.app.FragmentTransaction;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.EditText;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.actionbarsherlock.app.ActionBar;
-import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
-import com.actionbarsherlock.app.SherlockFragmentActivity;
-import com.actionbarsherlock.view.Menu;
-import com.actionbarsherlock.view.MenuInflater;
-import com.actionbarsherlock.view.MenuItem;
-import com.actionbarsherlock.view.Window;
-
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.CrashHandler;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.datamodel.DataStorageManager;
-import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
-import eu.alefzero.owncloud.datamodel.OCFile;
-import eu.alefzero.owncloud.files.services.FileDownloader;
-import eu.alefzero.owncloud.files.services.FileUploader;
-import eu.alefzero.owncloud.syncadapter.FileSyncService;
-import eu.alefzero.owncloud.ui.fragment.FileDetailFragment;
-import eu.alefzero.owncloud.ui.fragment.FileListFragment;
-import eu.alefzero.webdav.WebdavClient;
-
-/**
- * Displays, what files the user has available in his ownCloud.
- *
- * @author Bartek Przybylski
- *
- */
-
-public class FileDisplayActivity extends SherlockFragmentActivity implements
- FileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNavigationListener, OnClickListener, android.view.View.OnClickListener {
-
- private ArrayAdapter mDirectories;
- private OCFile mCurrentDir;
- private String[] mDirs = null;
-
- private DataStorageManager mStorageManager;
- private SyncBroadcastReceiver mSyncBroadcastReceiver;
- private UploadFinishReceiver mUploadFinishReceiver;
- private DownloadFinishReceiver mDownloadFinishReceiver;
-
- private View mLayoutView = null;
- private FileListFragment mFileList;
-
- private boolean mDualPane;
-
- private boolean mForcedLoginToCreateFirstAccount = false;
-
- private static final String KEY_DIR_ARRAY = "DIR_ARRAY";
- private static final String KEY_CURRENT_DIR = "DIR";
-
- private static final int DIALOG_SETUP_ACCOUNT = 0;
- private static final int DIALOG_CREATE_DIR = 1;
- private static final int DIALOG_ABOUT_APP = 2;
- public static final int DIALOG_SHORT_WAIT = 3;
-
- private static final int ACTION_SELECT_FILE = 1;
-
- private static final String TAG = "FileDisplayActivity";
-
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- Log.i(getClass().toString(), "onCreate() start");
- super.onCreate(savedInstanceState);
-
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
-
- Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(getApplicationContext()));
-
- if(savedInstanceState != null) {
- mDirs = savedInstanceState.getStringArray(KEY_DIR_ARRAY);
- mDirectories = new CustomArrayAdapter(this, R.layout.sherlock_spinner_dropdown_item);
- mDirectories.add(OCFile.PATH_SEPARATOR);
- if (mDirs != null)
- for (String s : mDirs)
- mDirectories.insert(s, 0);
- mCurrentDir = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_FILE);
- }
-
- mLayoutView = getLayoutInflater().inflate(R.layout.files, null); // always inflate this at onCreate() ; just once!
-
- if (AccountUtils.accountsAreSetup(this)) {
-
- initDelayedTilAccountAvailabe();
-
- // PIN CODE request ; best location is to decide, let's try this first
- //if (savedInstanceState == null) {
- if (getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_MAIN) && savedInstanceState == null) {
- requestPinCode();
- }
-
-
- } else {
-
- setContentView(R.layout.no_account_available);
- getSupportActionBar().setNavigationMode(ActionBar.DISPLAY_SHOW_TITLE);
- findViewById(R.id.setup_account).setOnClickListener(this);
-
- setSupportProgressBarIndeterminateVisibility(false);
-
- Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
- intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
- startActivity(intent); // although the code is here, the activity won't be created until this.onStart() and this.onResume() are finished;
- mForcedLoginToCreateFirstAccount = true;
- }
-
- Log.i(getClass().toString(), "onCreate() end");
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getSherlock().getMenuInflater();
- inflater.inflate(R.menu.menu, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- boolean retval = true;
- switch (item.getItemId()) {
- case R.id.createDirectoryItem: {
- showDialog(DIALOG_CREATE_DIR);
- break;
- }
- case R.id.startSync: {
- ContentResolver.cancelSync(null, "org.owncloud"); // cancel the current synchronizations of any ownCloud account
- Bundle bundle = new Bundle();
- bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
- ContentResolver.requestSync(
- AccountUtils.getCurrentOwnCloudAccount(this),
- "org.owncloud", bundle);
- break;
- }
- case R.id.action_upload: {
- Intent action = new Intent(Intent.ACTION_GET_CONTENT);
- action = action.setType("*/*")
- .addCategory(Intent.CATEGORY_OPENABLE);
- startActivityForResult(
- Intent.createChooser(action, getString(R.string.upload_chooser_title)),
- ACTION_SELECT_FILE);
- break;
- }
- case R.id.action_settings: {
- Intent settingsIntent = new Intent(this, Preferences.class);
- startActivity(settingsIntent);
- break;
- }
- case R.id.about_app : {
- showDialog(DIALOG_ABOUT_APP);
- break;
- }
- case android.R.id.home: {
- if(mCurrentDir != null && mCurrentDir.getParentId() != 0){
- onBackPressed();
- }
- break;
- }
- default:
- retval = false;
- }
- return retval;
- }
-
- @Override
- public boolean onNavigationItemSelected(int itemPosition, long itemId) {
- int i = itemPosition;
- while (i-- != 0) {
- onBackPressed();
- }
- return true;
- }
-
- /**
- * Called, when the user selected something for uploading
- */
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == ACTION_SELECT_FILE) {
- if (resultCode == RESULT_OK) {
- String filepath = null;
- try {
- Uri selectedImageUri = data.getData();
-
- String filemanagerstring = selectedImageUri.getPath();
- String selectedImagePath = getPath(selectedImageUri);
-
- if (selectedImagePath != null)
- filepath = selectedImagePath;
- else
- filepath = filemanagerstring;
-
- } catch (Exception e) {
- Log.e("FileDisplay", "Unexpected exception when trying to read the result of Intent.ACTION_GET_CONTENT", e);
- e.printStackTrace();
-
- } finally {
- if (filepath == null) {
- Log.e("FileDisplay", "Couldnt resolve path to file");
- Toast t = Toast.makeText(this, getString(R.string.filedisplay_unexpected_bad_get_content), Toast.LENGTH_LONG);
- t.show();
- return;
- }
- }
-
- Intent i = new Intent(this, FileUploader.class);
- i.putExtra(FileUploader.KEY_ACCOUNT,
- AccountUtils.getCurrentOwnCloudAccount(this));
- String remotepath = new String();
- for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
- remotepath += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
- }
- if (!remotepath.endsWith(OCFile.PATH_SEPARATOR))
- remotepath += OCFile.PATH_SEPARATOR;
- remotepath += new File(filepath).getName();
-
- i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);
- i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);
- i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
- startService(i);
- }
-
- }/* dvelasco: WIP - not working as expected ... yet :)
- else if (requestCode == ACTION_CREATE_FIRST_ACCOUNT) {
- if (resultCode != RESULT_OK) {
- finish(); // the user cancelled the AuthenticatorActivity
- }
- }*/
- }
-
- @Override
- public void onBackPressed() {
- if (mDirectories == null || mDirectories.getCount() <= 1) {
- finish();
- return;
- }
- popDirname();
- mFileList.onNavigateUp();
- mCurrentDir = mFileList.getCurrentFile();
-
- if(mCurrentDir.getParentId() == 0){
- ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayHomeAsUpEnabled(false);
- }
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- // responsability of restore is prefered in onCreate() before than in onRestoreInstanceState when there are Fragments involved
- Log.i(getClass().toString(), "onSaveInstanceState() start");
- super.onSaveInstanceState(outState);
- if(mDirectories != null && mDirectories.getCount() != 0){
- mDirs = new String[mDirectories.getCount()-1];
- for (int j = mDirectories.getCount() - 2, i = 0; j >= 0; --j, ++i) {
- mDirs[i] = mDirectories.getItem(j);
- }
- }
- outState.putStringArray(KEY_DIR_ARRAY, mDirs);
- outState.putParcelable(FileDetailFragment.EXTRA_FILE, mCurrentDir);
- Log.i(getClass().toString(), "onSaveInstanceState() end");
- }
-
- @Override
- protected void onResume() {
- Log.i(getClass().toString(), "onResume() start");
- super.onResume();
-
- if (AccountUtils.accountsAreSetup(this)) {
- // at least an account exist: normal operation
-
- // set the layout only if it couldn't be set in onCreate
- if (mForcedLoginToCreateFirstAccount) {
- initDelayedTilAccountAvailabe();
- mForcedLoginToCreateFirstAccount = false;
- }
-
- // Listen for sync messages
- IntentFilter syncIntentFilter = new IntentFilter(FileSyncService.SYNC_MESSAGE);
- mSyncBroadcastReceiver = new SyncBroadcastReceiver();
- registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
-
- // Listen for upload messages
- IntentFilter uploadIntentFilter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
- mUploadFinishReceiver = new UploadFinishReceiver();
- registerReceiver(mUploadFinishReceiver, uploadIntentFilter);
-
- // Listen for download messages
- IntentFilter downloadIntentFilter = new IntentFilter(FileDownloader.DOWNLOAD_FINISH_MESSAGE);
- mDownloadFinishReceiver = new DownloadFinishReceiver();
- registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);
-
- // Storage manager initialization
- mStorageManager = new FileDataStorageManager(
- AccountUtils.getCurrentOwnCloudAccount(this),
- getContentResolver());
-
- // File list fragments
- mFileList = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
-
-
- // Figure out what directory to list.
- // Priority: Intent (here), savedInstanceState (onCreate), root dir (dir is null)
- if(getIntent().hasExtra(FileDetailFragment.EXTRA_FILE)){
- mCurrentDir = (OCFile) getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);
- if(mCurrentDir != null && !mCurrentDir.isDirectory()){
- mCurrentDir = mStorageManager.getFileById(mCurrentDir.getParentId());
- }
-
- // Clear intent extra, so rotating the screen will not return us to this directory
- getIntent().removeExtra(FileDetailFragment.EXTRA_FILE);
- }
-
- if (mCurrentDir == null)
- mCurrentDir = mStorageManager.getFileByPath("/");
-
- // Drop-Down navigation and file list restore
- mDirectories = new CustomArrayAdapter(this, R.layout.sherlock_spinner_dropdown_item);
-
-
- // Given the case we have a file to display:
- if(mCurrentDir != null){
- ArrayList files = new ArrayList();
- OCFile currFile = mCurrentDir;
- while(currFile != null){
- files.add(currFile);
- currFile = mStorageManager.getFileById(currFile.getParentId());
- }
-
- // Insert in mDirs
- mDirs = new String[files.size()];
- for(int i = files.size() - 1; i >= 0; i--){
- mDirs[i] = files.get(i).getFileName();
- }
- }
-
- if (mDirs != null) {
- for (String s : mDirs)
- mDirectories.add(s);
- } else {
- mDirectories.add(OCFile.PATH_SEPARATOR);
- }
-
- // Actionbar setup
- ActionBar action_bar = getSupportActionBar();
- action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
- action_bar.setDisplayShowTitleEnabled(false);
- action_bar.setListNavigationCallbacks(mDirectories, this);
- if(mCurrentDir != null && mCurrentDir.getParentId() != 0){
- action_bar.setDisplayHomeAsUpEnabled(true);
- } else {
- action_bar.setDisplayHomeAsUpEnabled(false);
- }
-
- // List dir here
- mFileList.listDirectory(mCurrentDir);
- }
- Log.i(getClass().toString(), "onResume() end");
- }
-
- @Override
- protected void onPause() {
- Log.i(getClass().toString(), "onPause() start");
- super.onPause();
- if (mSyncBroadcastReceiver != null) {
- unregisterReceiver(mSyncBroadcastReceiver);
- mSyncBroadcastReceiver = null;
- }
- if (mUploadFinishReceiver != null) {
- unregisterReceiver(mUploadFinishReceiver);
- mUploadFinishReceiver = null;
- }
- if (mDownloadFinishReceiver != null) {
- unregisterReceiver(mDownloadFinishReceiver);
- mDownloadFinishReceiver = null;
- }
-
- getIntent().putExtra(FileDetailFragment.EXTRA_FILE, mCurrentDir);
- Log.i(getClass().toString(), "onPause() end");
- }
-
- @Override
- protected Dialog onCreateDialog(int id) {
- Dialog dialog = null;
- AlertDialog.Builder builder;
- switch (id) {
- case DIALOG_SETUP_ACCOUNT:
- builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.main_tit_accsetup);
- builder.setMessage(R.string.main_wrn_accsetup);
- builder.setCancelable(false);
- builder.setPositiveButton(android.R.string.ok, this);
- builder.setNegativeButton(android.R.string.cancel, this);
- dialog = builder.create();
- break;
- case DIALOG_ABOUT_APP: {
- builder = new AlertDialog.Builder(this);
- builder.setTitle(getString(R.string.about_title));
- PackageInfo pkg;
- try {
- pkg = getPackageManager().getPackageInfo(getPackageName(), 0);
- builder.setMessage("ownCloud android client\n\nversion: " + pkg.versionName );
- builder.setIcon(android.R.drawable.ic_menu_info_details);
- dialog = builder.create();
- } catch (NameNotFoundException e) {
- builder = null;
- dialog = null;
- Log.e(TAG, "Error while showing about dialog", e);
- }
- break;
- }
- case DIALOG_CREATE_DIR: {
- builder = new Builder(this);
- final EditText dirNameInput = new EditText(getBaseContext());
- final Account a = AccountUtils.getCurrentOwnCloudAccount(this);
- builder.setView(dirNameInput);
- builder.setTitle(R.string.uploader_info_dirname);
- int typed_color = getResources().getColor(R.color.setup_text_typed);
- dirNameInput.setTextColor(typed_color);
- builder.setPositiveButton(android.R.string.ok,
- new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- String directoryName = dirNameInput.getText().toString();
- if (directoryName.trim().length() == 0) {
- dialog.cancel();
- return;
- }
-
- // Figure out the path where the dir needs to be created
- String path;
- if (mCurrentDir == null) {
- // this is just a patch; we should ensure that mCurrentDir never is null
- if (!mStorageManager.fileExists(OCFile.PATH_SEPARATOR)) {
- OCFile file = new OCFile(OCFile.PATH_SEPARATOR);
- mStorageManager.saveFile(file);
- }
- mCurrentDir = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);
- }
- path = FileDisplayActivity.this.mCurrentDir.getRemotePath();
-
- // Create directory
- path += directoryName + OCFile.PATH_SEPARATOR;
- Thread thread = new Thread(new DirectoryCreator(path, a, new Handler()));
- thread.start();
-
- dialog.dismiss();
-
- showDialog(DIALOG_SHORT_WAIT);
- }
- });
- builder.setNegativeButton(R.string.common_cancel,
- new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- });
- dialog = builder.create();
- break;
- }
- case DIALOG_SHORT_WAIT: {
- ProgressDialog working_dialog = new ProgressDialog(this);
- working_dialog.setMessage(getResources().getString(
- R.string.wait_a_moment));
- working_dialog.setIndeterminate(true);
- working_dialog.setCancelable(false);
- dialog = working_dialog;
- break;
- }
- default:
- dialog = null;
- }
-
- return dialog;
- }
-
-
- /**
- * Responds to the "There are no ownCloud Accounts setup" dialog
- * TODO: Dialog is 100% useless -> Remove
- */
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // In any case - we won't need it anymore
- dialog.dismiss();
- switch (which) {
- case DialogInterface.BUTTON_POSITIVE:
- Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
- intent.putExtra("authorities",
- new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
- startActivity(intent);
- break;
- case DialogInterface.BUTTON_NEGATIVE:
- finish();
- }
-
- }
-
- /**
- * Translates a content URI of an image to a physical path
- * on the disk
- * @param uri The URI to resolve
- * @return The path to the image or null if it could not be found
- */
- public String getPath(Uri uri) {
- String[] projection = { MediaStore.Images.Media.DATA };
- Cursor cursor = managedQuery(uri, projection, null, null, null);
- if (cursor != null) {
- int column_index = cursor
- .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
- cursor.moveToFirst();
- return cursor.getString(column_index);
- }
- return null;
- }
-
- /**
- * Pushes a directory to the drop down list
- * @param directory to push
- * @throws IllegalArgumentException If the {@link OCFile#isDirectory()} returns false.
- */
- public void pushDirname(OCFile directory) {
- if(!directory.isDirectory()){
- throw new IllegalArgumentException("Only directories may be pushed!");
- }
- mDirectories.insert(directory.getFileName(), 0);
- mCurrentDir = directory;
- }
-
- /**
- * Pops a directory name from the drop down list
- * @return True, unless the stack is empty
- */
- public boolean popDirname() {
- mDirectories.remove(mDirectories.getItem(0));
- return !mDirectories.isEmpty();
- }
-
- private class DirectoryCreator implements Runnable {
- private String mTargetPath;
- private Account mAccount;
- private AccountManager mAm;
- private Handler mHandler;
-
- public DirectoryCreator(String targetPath, Account account, Handler handler) {
- mTargetPath = targetPath;
- mAccount = account;
- mAm = (AccountManager) getSystemService(ACCOUNT_SERVICE);
- mHandler = handler;
- }
-
- @Override
- public void run() {
- WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());
-
- String username = mAccount.name.substring(0,
- mAccount.name.lastIndexOf('@'));
- String password = mAm.getPassword(mAccount);
-
- wdc.setCredentials(username, password);
- wdc.allowSelfsignedCertificates();
- boolean created = wdc.createDirectory(mTargetPath);
- if (created) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- dismissDialog(DIALOG_SHORT_WAIT);
-
- // Save new directory in local database
- OCFile newDir = new OCFile(mTargetPath);
- newDir.setMimetype("DIR");
- newDir.setParentId(mCurrentDir.getFileId());
- mStorageManager.saveFile(newDir);
-
- // Display the new folder right away
- mFileList.listDirectory(mCurrentDir);
- }
- });
-
- } else {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- dismissDialog(DIALOG_SHORT_WAIT);
- try {
- Toast msg = Toast.makeText(FileDisplayActivity.this, R.string.create_dir_fail_msg, Toast.LENGTH_LONG);
- msg.show();
-
- } catch (NotFoundException e) {
- Log.e(TAG, "Error while trying to show fail message " , e);
- }
- }
- });
- }
- }
-
- }
-
- // Custom array adapter to override text colors
- private class CustomArrayAdapter extends ArrayAdapter {
-
- public CustomArrayAdapter(FileDisplayActivity ctx, int view) {
- super(ctx, view);
- }
-
- public View getView(int position, View convertView, ViewGroup parent) {
- View v = super.getView(position, convertView, parent);
-
- ((TextView) v).setTextColor(getResources().getColorStateList(
- android.R.color.white));
- return v;
- }
-
- public View getDropDownView(int position, View convertView,
- ViewGroup parent) {
- View v = super.getDropDownView(position, convertView, parent);
-
- ((TextView) v).setTextColor(getResources().getColorStateList(
- android.R.color.white));
-
- return v;
- }
-
- }
-
- private class SyncBroadcastReceiver extends BroadcastReceiver {
- /**
- * {@link BroadcastReceiver} to enable syncing feedback in UI
- */
- @Override
- public void onReceive(Context context, Intent intent) {
- boolean inProgress = intent.getBooleanExtra(
- FileSyncService.IN_PROGRESS, false);
- String accountName = intent
- .getStringExtra(FileSyncService.ACCOUNT_NAME);
-
- Log.d("FileDisplay", "sync of account " + accountName
- + " is in_progress: " + inProgress);
-
- if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name)) {
-
- String synchFolderRemotePath = intent.getStringExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH);
-
- boolean fillBlankRoot = false;
- if (mCurrentDir == null) {
- mCurrentDir = mStorageManager.getFileByPath("/");
- fillBlankRoot = (mCurrentDir != null);
- }
-
- if ((synchFolderRemotePath != null && mCurrentDir != null && (mCurrentDir.getRemotePath().equals(synchFolderRemotePath)))
- || fillBlankRoot ) {
- if (!fillBlankRoot)
- mCurrentDir = getStorageManager().getFileByPath(synchFolderRemotePath);
- FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager()
- .findFragmentById(R.id.fileList);
- if (fileListFragment != null) {
- fileListFragment.listDirectory(mCurrentDir);
- }
- }
-
- setSupportProgressBarIndeterminateVisibility(inProgress);
-
- }
- }
- }
-
-
- private class UploadFinishReceiver extends BroadcastReceiver {
- /**
- * Once the file upload has finished -> update view
- * @author David A. Velasco
- * {@link BroadcastReceiver} to enable upload feedback in UI
- */
- @Override
- public void onReceive(Context context, Intent intent) {
- long parentDirId = intent.getLongExtra(FileUploader.EXTRA_PARENT_DIR_ID, -1);
- OCFile parentDir = mStorageManager.getFileById(parentDirId);
- String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);
-
- if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name) &&
- parentDir != null &&
- ( (mCurrentDir == null && parentDir.getFileName().equals("/")) ||
- parentDir.equals(mCurrentDir)
- )
- ) {
- FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
- if (fileListFragment != null) {
- fileListFragment.listDirectory();
- }
- }
- }
-
- }
-
-
- /**
- * Once the file download has finished -> update view
- */
- private class DownloadFinishReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
- String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);
-
- if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name) &&
- mCurrentDir != null && mCurrentDir.getFileId() == mStorageManager.getFileByPath(downloadedRemotePath).getParentId()) {
- FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
- if (fileListFragment != null) {
- fileListFragment.listDirectory();
- }
- }
- }
- }
-
-
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.setup_account) {
- Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
- intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
- startActivity(intent);
- mForcedLoginToCreateFirstAccount = true;
- }
- }
-
-
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public DataStorageManager getStorageManager() {
- return mStorageManager;
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onDirectoryClick(OCFile directory) {
- pushDirname(directory);
- ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
-
- if (mDualPane) {
- // Resets the FileDetailsFragment on Tablets so that it always displays
- FileDetailFragment fileDetails = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
- if (fileDetails != null) {
- FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
- transaction.remove(fileDetails);
- transaction.add(R.id.file_details_container, new FileDetailFragment(null, null));
- transaction.commit();
- }
- }
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onFileClick(OCFile file) {
-
- // If we are on a large device -> update fragment
- if (mDualPane) {
- // buttons in the details view are problematic when trying to reuse an existing fragment; create always a new one solves some of them, BUT no all; downloads are 'dangerous'
- FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
- transaction.replace(R.id.file_details_container, new FileDetailFragment(file, AccountUtils.getCurrentOwnCloudAccount(this)), FileDetailFragment.FTAG);
- transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
- transaction.commit();
-
- } else { // small or medium screen device -> new Activity
- Intent showDetailsIntent = new Intent(this, FileDetailActivity.class);
- showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, file);
- showDetailsIntent.putExtra(FileDownloader.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
- startActivity(showDetailsIntent);
- }
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onFileStateChanged() {
- FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
- if (fileListFragment != null) {
- fileListFragment.listDirectory();
- }
- }
-
-
- /**
- * Operations in this method should be preferably performed in onCreate to have a lighter onResume method.
- *
- * But we need to delay them to onResume for the first start of the application, when no account exists and the login activity must be shown; and
- * put instead the ugly view that shows the 'Setup' button to restart the login activity.
- *
- * In other way, if the users cancels or presses BACK in the login page that first time (users can be cruel sometimes) would show a blank view (the
- * FragmentList view empty).
- *
- * This is temporal, until we found out how to get a result in this activity after launching the ADD_ACCOUNT Intent with startActivityForResult (not trivial)
- */
- private void initDelayedTilAccountAvailabe() {
- setContentView(mLayoutView);
- mDualPane = (findViewById(R.id.file_details_container) != null);
- if (mDualPane && getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG) == null) {
- FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
- transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment
- transaction.commit();
- }
- setSupportProgressBarIndeterminateVisibility(false);
- }
-
-
- /**
- * Launch an intent to request the PIN code to the user before letting him use the app
- */
- private void requestPinCode() {
- boolean pinStart = false;
- SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
- pinStart = appPrefs.getBoolean("set_pincode", false);
- if (pinStart) {
- Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);
- i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "FileDisplayActivity");
- startActivity(i);
- }
- }
-
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/activity/LandingActivity.java b/src/eu/alefzero/owncloud/ui/activity/LandingActivity.java
deleted file mode 100644
index d40d8d75..00000000
--- a/src/eu/alefzero/owncloud/ui/activity/LandingActivity.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.ui.activity;
-
-import com.actionbarsherlock.app.SherlockFragmentActivity;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.GridView;
-import android.widget.Toast;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.ui.adapter.LandingScreenAdapter;
-
-/**
- * This activity is used as a landing page when the user first opens this app.
- *
- * @author Lennart Rosam
- *
- */
-public class LandingActivity extends SherlockFragmentActivity implements
- OnClickListener, OnItemClickListener {
-
- public static final int DIALOG_SETUP_ACCOUNT = 1;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- // Fill the grid view of the landing screen with icons
- GridView landingScreenItems = (GridView) findViewById(R.id.homeScreenGrid);
- landingScreenItems.setAdapter(new LandingScreenAdapter(this));
- landingScreenItems.setOnItemClickListener(this);
-
- // Check, if there are ownCloud accounts
- if (!accountsAreSetup()) {
- showDialog(DIALOG_SETUP_ACCOUNT);
- } else {
- // Start device tracking service
- Intent locationServiceIntent = new Intent();
- locationServiceIntent
- .setAction("eu.alefzero.owncloud.location.LocationLauncher");
- sendBroadcast(locationServiceIntent);
- }
-
- }
-
- @Override
- protected void onRestart() {
- super.onRestart();
- // Check, if there are ownCloud accounts
- if (!accountsAreSetup()) {
- showDialog(DIALOG_SETUP_ACCOUNT);
- }
- }
-
- @Override
- protected void onRestoreInstanceState(Bundle savedInstanceState) {
- super.onRestoreInstanceState(savedInstanceState);
- // Check, if there are ownCloud accounts
- if (!accountsAreSetup()) {
- showDialog(DIALOG_SETUP_ACCOUNT);
- }
- }
-
- @Override
- protected Dialog onCreateDialog(int id) {
- Dialog dialog;
- switch (id) {
- case DIALOG_SETUP_ACCOUNT:
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.main_tit_accsetup);
- builder.setMessage(R.string.main_wrn_accsetup);
- builder.setCancelable(false);
- builder.setPositiveButton(R.string.common_ok, this);
- builder.setNegativeButton(R.string.common_cancel, this);
- dialog = builder.create();
- break;
- default:
- dialog = null;
- }
-
- return dialog;
- }
-
- public void onClick(DialogInterface dialog, int which) {
- // In any case - we won't need it anymore
- dialog.dismiss();
- switch (which) {
- case DialogInterface.BUTTON_POSITIVE:
- Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
- intent.putExtra("authorities",
- new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
- startActivity(intent);
- break;
- case DialogInterface.BUTTON_NEGATIVE:
- finish();
- }
-
- }
-
- @Override
- /**
- * Start an activity based on the selection
- * the user made
- */
- public void onItemClick(AdapterView> parent, View view, int position,
- long id) {
- Intent intent;
- intent = (Intent) parent.getAdapter().getItem(position);
- if (intent != null) {
- startActivity(intent);
- } else {
- // TODO: Implement all of this and make this text go away ;-)
- Toast toast = Toast.makeText(this, "Not yet implemented!",
- Toast.LENGTH_SHORT);
- toast.show();
- }
- }
-
- /**
- * Checks, whether or not there are any ownCloud accounts setup.
- *
- * @return true, if there is at least one account.
- */
- private boolean accountsAreSetup() {
- AccountManager accMan = AccountManager.get(this);
- Account[] accounts = accMan
- .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
- return accounts.length > 0;
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/activity/PinCodeActivity.java b/src/eu/alefzero/owncloud/ui/activity/PinCodeActivity.java
deleted file mode 100644
index 5fd7213a..00000000
--- a/src/eu/alefzero/owncloud/ui/activity/PinCodeActivity.java
+++ /dev/null
@@ -1,653 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.ui.activity;
-
-import java.util.Arrays;
-
-import com.actionbarsherlock.app.SherlockFragmentActivity;
-
-import eu.alefzero.owncloud.R;
-
-
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.graphics.Typeface;
-import android.os.Bundle;
-import android.os.Handler;
-import android.preference.PreferenceManager;
-import android.text.Editable;
-import android.text.InputType;
-import android.text.TextWatcher;
-import android.text.method.PasswordTransformationMethod;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnFocusChangeListener;
-import android.view.View.OnKeyListener;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-
-
-public class PinCodeActivity extends SherlockFragmentActivity {
-
-
- public final static String EXTRA_ACTIVITY = "eu.alefzero.owncloud.ui.activity.PinCodeActivity.ACTIVITY";
- public final static String EXTRA_NEW_STATE = "eu.alefzero.owncloud.ui.activity.PinCodeActivity.NEW_STATE";
-
- Button bCancel;
- TextView mPinHdr;
- EditText mText1;
- EditText mText2;
- EditText mText3;
- EditText mText4;
-
- String [] tempText ={"","","",""};
-
- String activity;
-
- boolean confirmingPinCode = false;
- boolean pinCodeChecked = false;
- boolean newPasswordEntered = false;
- boolean bChange = true; // to control that only one blocks jump
- int tCounter ; // Count the number of attempts an user could introduce the PIN code
-
-
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.pincodelock);
-
- Intent intent = getIntent();
- activity = intent.getStringExtra(EXTRA_ACTIVITY);
-
- bCancel = (Button) findViewById(R.id.cancel);
- mPinHdr = (TextView) findViewById(R.id.pinHdr);
- mText1 = (EditText) findViewById(R.id.txt1);
- mText1.requestFocus();
- getWindow().setSoftInputMode(android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
- mText2 = (EditText) findViewById(R.id.txt2);
- mText3 = (EditText) findViewById(R.id.txt3);
- mText4 = (EditText) findViewById(R.id.txt4);
-
-
-
- SharedPreferences appPrefs = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext());
-
-
- // Not PIN Code defined yet.
- // In a previous version settings is allow from start
- if ( (appPrefs.getString("PrefPinCode1", null) == null ) ){
- setChangePincodeView(true);
- pinCodeChecked = true;
- newPasswordEntered = true;
-
- }else{
-
- if (appPrefs.getBoolean("set_pincode", false)){
- // pincode activated
- if (activity.equals("preferences")){
- // PIN has been activated yet
- mPinHdr.setText(R.string.pincode_configure_your_pin);
- pinCodeChecked = true ; // No need to check it
- setChangePincodeView(true);
- }else{
- // PIN active
- bCancel.setVisibility(View.INVISIBLE);
- bCancel.setVisibility(View.GONE);
- mPinHdr.setText(R.string.pincode_enter_pin_code);
- setChangePincodeView(false);
- }
-
- }else {
- // pincode removal
- mPinHdr.setText(R.string.pincode_remove_your_pincode);
- pinCodeChecked = false;
- setChangePincodeView(true);
- }
-
- }
- setTextListeners();
-
-
- }
-
-
-
- protected void setInitVars(){
- confirmingPinCode = false;
- pinCodeChecked = false;
- newPasswordEntered = false;
-
- }
-
- protected void setInitView(){
- bCancel.setVisibility(View.INVISIBLE);
- bCancel.setVisibility(View.GONE);
- mPinHdr.setText(R.string.pincode_enter_pin_code);
- }
-
-
- protected void setChangePincodeView(boolean state){
-
- if(state){
- bCancel.setVisibility(View.VISIBLE);
- bCancel.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
-
- SharedPreferences.Editor appPrefsE = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext()).edit();
-
- SharedPreferences appPrefs = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext());
-
- boolean state = appPrefs.getBoolean("set_pincode", false);
- appPrefsE.putBoolean("set_pincode",!state);
- appPrefsE.commit();
- setInitVars();
- finish();
- }
- });
- }
-
- }
-
-
-
- /*
- *
- */
- protected void setTextListeners(){
-
- /*------------------------------------------------
- * FIRST BOX
- -------------------------------------------------*/
-
- mText1.addTextChangedListener(new TextWatcher() {
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before,
- int count) {
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) {
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- if (s.length() > 0) {
- if (!confirmingPinCode){
- tempText[0] = mText1.getText().toString();
-
- }
- mText2.requestFocus();
- }
- }
- });
-
-
-
- /*------------------------------------------------
- * SECOND BOX
- -------------------------------------------------*/
- mText2.addTextChangedListener(new TextWatcher() {
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before,
- int count) {
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) {
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- if (s.length() > 0) {
- if (!confirmingPinCode){
- tempText[1] = mText2.getText().toString();
- }
-
- mText3.requestFocus();
- }
- }
- });
-
- mText2.setOnKeyListener(new OnKeyListener() {
-
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- // TODO Auto-generated method stub
-
- if (keyCode == KeyEvent.KEYCODE_DEL && bChange) {
-
- mText1.setText("");
- mText1.requestFocus();
- if (!confirmingPinCode)
- tempText[0] = "";
- bChange= false;
-
- }else if(!bChange){
- bChange=true;
-
- }
- return false;
- }
- });
-
- mText2.setOnFocusChangeListener(new OnFocusChangeListener() {
-
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- // TODO Auto-generated method stub
-
- mText2.setCursorVisible(true);
- if (mText1.getText().toString().equals("")){
- mText2.setSelected(false);
- mText2.setCursorVisible(false);
- mText1.requestFocus();
- mText1.setSelected(true);
- mText1.setSelection(0);
- }
-
- }
- });
-
-
- /*------------------------------------------------
- * THIRD BOX
- -------------------------------------------------*/
- mText3.addTextChangedListener(new TextWatcher() {
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before,
- int count) {
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) {
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- if (s.length() > 0) {
- if (!confirmingPinCode){
- tempText[2] = mText3.getText().toString();
- }
- mText4.requestFocus();
- }
- }
- });
-
- mText3.setOnKeyListener(new OnKeyListener() {
-
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- // TODO Auto-generated method stub
-
- if (keyCode == KeyEvent.KEYCODE_DEL && bChange) {
- mText2.requestFocus();
- if (!confirmingPinCode)
- tempText[1] = "";
- mText2.setText("");
- bChange= false;
-
- }else if(!bChange){
- bChange=true;
-
- }
- return false;
- }
- });
-
- mText3.setOnFocusChangeListener(new OnFocusChangeListener() {
-
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- // TODO Auto-generated method stub
- mText3.setCursorVisible(true);
- if (mText1.getText().toString().equals("")){
- mText3.setSelected(false);
- mText3.setCursorVisible(false);
- mText1.requestFocus();
- mText1.setSelected(true);
- mText1.setSelection(0);
- }else if (mText2.getText().toString().equals("")){
- mText3.setSelected(false);
- mText3.setCursorVisible(false);
- mText2.requestFocus();
- mText2.setSelected(true);
- mText2.setSelection(0);
- }
-
- }
- });
-
- /*------------------------------------------------
- * FOURTH BOX
- -------------------------------------------------*/
- mText4.addTextChangedListener(new TextWatcher() {
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before,
- int count) {
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) {
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- if (s.length() > 0) {
-
- if (!confirmingPinCode){
- tempText[3] = mText4.getText().toString();
- }
- mText1.requestFocus();
-
- if (!pinCodeChecked){
- pinCodeChecked = checkPincode();
- }
-
- if (pinCodeChecked && activity.equals("FileDisplayActivity")){
- finish();
- } else if (pinCodeChecked){
-
- Intent intent = getIntent();
- String newState = intent.getStringExtra(EXTRA_NEW_STATE);
-
- if (newState.equals("false")){
- SharedPreferences.Editor appPrefs = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext()).edit();
- appPrefs.putBoolean("set_pincode",false);
- appPrefs.commit();
-
- setInitVars();
- pinCodeEnd(false);
-
- }else{
-
- if (!confirmingPinCode){
- pinCodeChangeRequest();
-
- } else {
- confirmPincode();
- }
- }
-
-
- }
- }
- }
- });
-
-
-
- mText4.setOnKeyListener(new OnKeyListener() {
-
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- // TODO Auto-generated method stub
-
- if (keyCode == KeyEvent.KEYCODE_DEL && bChange) {
- mText3.requestFocus();
- if (!confirmingPinCode)
- tempText[2]="";
- mText3.setText("");
- bChange= false;
-
- }else if(!bChange){
- bChange=true;
- }
- return false;
- }
- });
-
- mText4.setOnFocusChangeListener(new OnFocusChangeListener() {
-
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- // TODO Auto-generated method stub
-
- mText4.setCursorVisible(true);
-
- if (mText1.getText().toString().equals("")){
- mText4.setSelected(false);
- mText4.setCursorVisible(false);
- mText1.requestFocus();
- mText1.setSelected(true);
- mText1.setSelection(0);
- }else if (mText2.getText().toString().equals("")){
- mText4.setSelected(false);
- mText4.setCursorVisible(false);
- mText2.requestFocus();
- mText2.setSelected(true);
- mText2.setSelection(0);
- }else if (mText3.getText().toString().equals("")){
- mText4.setSelected(false);
- mText4.setCursorVisible(false);
- mText3.requestFocus();
- mText3.setSelected(true);
- mText3.setSelection(0);
- }
-
- }
- });
-
-
-
- } // end setTextListener
-
-
- protected void pinCodeChangeRequest(){
-
- clearBoxes();
- mPinHdr.setText(R.string.pincode_reenter_your_pincode);
- confirmingPinCode =true;
-
- }
-
-
- protected boolean checkPincode(){
-
-
- SharedPreferences appPrefs = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext());
-
- String pText1 = appPrefs.getString("PrefPinCode1", null);
- String pText2 = appPrefs.getString("PrefPinCode2", null);
- String pText3 = appPrefs.getString("PrefPinCode3", null);
- String pText4 = appPrefs.getString("PrefPinCode4", null);
-
- if ( tempText[0].equals(pText1) &&
- tempText[1].equals(pText2) &&
- tempText[2].equals(pText3) &&
- tempText[3].equals(pText4) ) {
-
- return true;
-
-
- }else {
- Arrays.fill(tempText, null);
- AlertDialog aDialog = new AlertDialog.Builder(this).create();
- CharSequence errorSeq = getString(R.string.common_error);
- aDialog.setTitle(errorSeq);
- CharSequence cseq = getString(R.string.pincode_wrong);
- aDialog.setMessage(cseq);
- CharSequence okSeq = getString(R.string.common_ok);
- aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // TODO Auto-generated method stub("");
- return;
- }
-
- });
- aDialog.show();
- clearBoxes();
- mPinHdr.setText(R.string.pincode_enter_pin_code);
- newPasswordEntered = true;
- confirmingPinCode = false;
-
- }
-
-
- return false;
- }
-
- protected void confirmPincode(){
-
- confirmingPinCode = false;
-
- String rText1 = mText1.getText().toString();
- String rText2 = mText2.getText().toString();
- String rText3 = mText3.getText().toString();
- String rText4 = mText4.getText().toString();
-
- if ( tempText[0].equals(rText1) &&
- tempText[1].equals(rText2) &&
- tempText[2].equals(rText3) &&
- tempText[3].equals(rText4) ) {
-
- savePincodeAndExit();
-
- } else {
-
- Arrays.fill(tempText, null);
- AlertDialog aDialog = new AlertDialog.Builder(this).create();
- CharSequence errorSeq = getString(R.string.common_error);
- aDialog.setTitle(errorSeq);
- CharSequence cseq = getString(R.string.pincode_mismatch);
- aDialog.setMessage(cseq);
- CharSequence okSeq = getString(R.string.common_ok);
- aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // TODO Auto-generated method stub("");
- return;
- }
-
- });
- aDialog.show();
- mPinHdr.setText(R.string.pincode_configure_your_pin);
- clearBoxes();
- }
-
- }
-
-
- protected void pinCodeEnd(boolean state){
- AlertDialog aDialog = new AlertDialog.Builder(this).create();
-
- if (state){
- CharSequence saveSeq = getString(R.string.common_save_exit);
- aDialog.setTitle(saveSeq);
- CharSequence cseq = getString(R.string.pincode_stored);
- aDialog.setMessage(cseq);
-
- }else{
- CharSequence saveSeq = getString(R.string.common_save_exit);
- aDialog.setTitle(saveSeq);
- CharSequence cseq = getString(R.string.pincode_removed);
- aDialog.setMessage(cseq);
-
- }
- CharSequence okSeq = getString(R.string.common_ok);
- aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // TODO Auto-generated method stub("");
- finish();
- return;
- }
-
- });
- aDialog.show();
- }
-
- protected void savePincodeAndExit(){
- SharedPreferences.Editor appPrefs = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext()).edit();
-
- appPrefs.putString("PrefPinCode1", tempText[0]);
- appPrefs.putString("PrefPinCode2",tempText[1]);
- appPrefs.putString("PrefPinCode3", tempText[2]);
- appPrefs.putString("PrefPinCode4", tempText[3]);
- appPrefs.putBoolean("set_pincode",true);
- appPrefs.commit();
-
- pinCodeEnd(true);
-
-
-
- }
-
-
- protected void clearBoxes(){
-
- mText1.setText("");
- mText2.setText("");
- mText3.setText("");
- mText4.setText("");
- mText1.requestFocus();
- }
-
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event){
- if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount()== 0){
-
- if (activity.equals("preferences")){
- SharedPreferences.Editor appPrefsE = PreferenceManager
-
- .getDefaultSharedPreferences(getApplicationContext()).edit();
-
- SharedPreferences appPrefs = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext());
-
- boolean state = appPrefs.getBoolean("set_pincode", false);
- appPrefsE.putBoolean("set_pincode",!state);
- appPrefsE.commit();
- setInitVars();
- finish();
- }
- return true;
-
- }
-
- return super.onKeyDown(keyCode, event);
- }
-
-
-
-
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/activity/Preferences.java b/src/eu/alefzero/owncloud/ui/activity/Preferences.java
deleted file mode 100644
index c2173956..00000000
--- a/src/eu/alefzero/owncloud/ui/activity/Preferences.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.ui.activity;
-
-import java.util.Vector;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.PreferenceManager;
-import android.preference.Preference.OnPreferenceChangeListener;
-import android.preference.Preference.OnPreferenceClickListener;
-import android.util.Log;
-
-import com.actionbarsherlock.app.ActionBar;
-import com.actionbarsherlock.app.SherlockPreferenceActivity;
-import com.actionbarsherlock.view.Menu;
-import com.actionbarsherlock.view.MenuItem;
-
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.OwnCloudSession;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.db.DbHandler;
-
-/**
- * An Activity that allows the user to change the application's settings.
- *
- * @author Bartek Przybylski
- *
- */
-public class Preferences extends SherlockPreferenceActivity implements
- OnPreferenceChangeListener{
- private static final String TAG = "OwnCloudPreferences";
- private final int mNewSession = 47;
- private final int mEditSession = 48;
- private DbHandler mDbHandler;
- private Vector mSessions;
- //private Account[] mAccounts;
- //private ListPreference mAccountList;
- private ListPreference mTrackingUpdateInterval;
- private CheckBoxPreference mDeviceTracking;
- private CheckBoxPreference pCode;
- private int mSelectedMenuItem;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mDbHandler = new DbHandler(getBaseContext());
- mSessions = new Vector();
- addPreferencesFromResource(R.xml.preferences);
- //populateAccountList();
- ActionBar actionBar = getSherlock().getActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
- Preference p = findPreference("manage_account");
- if (p != null)
- p.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- Intent i = new Intent(getApplicationContext(), AccountSelectActivity.class);
- startActivity(i);
- return true;
- }
- });
-
- pCode = (CheckBoxPreference) findPreference("set_pincode");
-
-
- if (pCode != null){
-
- pCode.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
-
- Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);
- i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "preferences");
- i.putExtra(PinCodeActivity.EXTRA_NEW_STATE, newValue.toString());
-
- startActivity(i);
-
- return true;
- }
- });
-
- }
-
- }
-
-
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- SharedPreferences appPrefs = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext());
-
- boolean state = appPrefs.getBoolean("set_pincode", false);
- pCode.setChecked(state);
-
- super.onResume();
- }
-
-
-
- /**
- * Populates the account selector
- *-/
- private void populateAccountList() {
- AccountManager accMan = AccountManager.get(this);
- mAccounts = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
- mAccountList = (ListPreference) findPreference("select_oc_account");
- mAccountList.setOnPreferenceChangeListener(this);
-
- // Display the name of the current account if there is any
- Account defaultAccount = AccountUtils.getCurrentOwnCloudAccount(this);
- if (defaultAccount != null) {
- mAccountList.setSummary(defaultAccount.name);
- }
-
- // Transform accounts into array of string for preferences to use
- String[] accNames = new String[mAccounts.length];
- for (int i = 0; i < mAccounts.length; i++) {
- Account account = mAccounts[i];
- accNames[i] = account.name;
- }
-
- mAccountList.setEntries(accNames);
- mAccountList.setEntryValues(accNames);
- }*/
-
-
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- //MenuInflater inflater = getSherlock().getMenuInflater();
- //inflater.inflate(R.menu.prefs_menu, menu);
- return true;
- }
-
- @Override
- public boolean onMenuItemSelected(int featureId, MenuItem item) {
- super.onMenuItemSelected(featureId, item);
- Intent intent;
-
- switch (item.getItemId()) {
- //case R.id.addSessionItem:
- case 1:
- intent = new Intent(this, PreferencesNewSession.class);
- startActivityForResult(intent, mNewSession);
- break;
- case R.id.SessionContextEdit:
- intent = new Intent(this, PreferencesNewSession.class);
- intent.putExtra("sessionId", mSessions.get(mSelectedMenuItem)
- .getEntryId());
- intent.putExtra("sessionName", mSessions.get(mSelectedMenuItem)
- .getName());
- intent.putExtra("sessionURL", mSessions.get(mSelectedMenuItem)
- .getUrl());
- startActivityForResult(intent, mEditSession);
- break;
- case android.R.id.home:
- intent = new Intent(getBaseContext(), FileDisplayActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- break;
- default:
- Log.w(TAG, "Unknown menu item triggered");
- return false;
- }
- return true;
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- }
-
- @Override
- protected void onDestroy() {
- mDbHandler.close();
- super.onDestroy();
- }
-
-
-
- @Override
- /**
- * Updates various summaries after updates. Also starts and stops
- * the
- */
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- // Update current account summary
- /*if (preference.equals(mAccountList)) {
- mAccountList.setSummary(newValue.toString());
- }
-
- // Update tracking interval summary
- else*/ if (preference.equals(mTrackingUpdateInterval)) {
- String trackingSummary = getResources().getString(
- R.string.prefs_trackmydevice_interval_summary);
- trackingSummary = String.format(trackingSummary,
- newValue.toString());
- mTrackingUpdateInterval.setSummary(trackingSummary);
- }
-
- // Start or stop tracking service
- else if (preference.equals(mDeviceTracking)) {
- Intent locationServiceIntent = new Intent();
- locationServiceIntent
- .setAction("eu.alefzero.owncloud.location.LocationLauncher");
- locationServiceIntent.putExtra("TRACKING_SETTING",
- (Boolean) newValue);
- sendBroadcast(locationServiceIntent);
- }
- return true;
- }
-
-
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/activity/PreferencesNewSession.java b/src/eu/alefzero/owncloud/ui/activity/PreferencesNewSession.java
deleted file mode 100644
index 35d65dae..00000000
--- a/src/eu/alefzero/owncloud/ui/activity/PreferencesNewSession.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package eu.alefzero.owncloud.ui.activity;
-
-import android.accounts.AccountAuthenticatorActivity;
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.View.OnClickListener;
-
-public class PreferencesNewSession extends AccountAuthenticatorActivity
- implements OnClickListener {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // setContentView(R.layout.add_new_session);
- /*
- * EditText et;// = (EditText)
- * findViewById(R.id.newSession_sessionName);
- *
- * et = (EditText) findViewById(R.id.newSession_URL); if
- * (getIntent().hasExtra("sessionURL")) { try { URI uri = new
- * URI(getIntent().getStringExtra("sessionURL")); String url =
- * uri.getHost(); if (uri.getPort() != -1) { url += ":" +
- * String.valueOf(uri.getPort()); } if (uri.getPath() != null) { url +=
- * uri.getPath(); } else { url += "/"; } et.setText(url); et =
- * (EditText) findViewById(R.id.newSession_username); if
- * (uri.getAuthority() != null) { if (uri.getUserInfo().indexOf(':') !=
- * -1) { et.setText(uri.getUserInfo().substring(0,
- * uri.getUserInfo().indexOf(':'))); et = (EditText)
- * findViewById(R.id.newSession_password);
- * et.setText(uri.getUserInfo().substring
- * (uri.getUserInfo().indexOf(':')+1)); } else {
- * et.setText(uri.getUserInfo()); } }
- *
- * } catch (URISyntaxException e) { Log.e(TAG, "Incorrect URI syntax " +
- * e.getLocalizedMessage()); } }
- *
- * mReturnData = new Intent(); setResult(Activity.RESULT_OK,
- * mReturnData); ((Button)
- * findViewById(R.id.button1)).setOnClickListener(this); ((Button)
- * findViewById(R.id.button2)).setOnClickListener(this);
- */
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- }
-
- public void onClick(View v) {
- /*
- * switch (v.getId()) { case R.id.button1: Intent intent = new Intent();
- * if (getIntent().hasExtra("sessionId")) { intent.putExtra("sessionId",
- * getIntent().getIntExtra("sessionId", -1)); } //String sessionName =
- * ((EditText)
- * findViewById(R.id.newSession_sessionName)).getText().toString(); //
- * if (sessionName.trim().equals("") || !isNameValid(sessionName)) { //
- * Toast.makeText(this, R.string.new_session_session_name_error,
- * Toast.LENGTH_LONG).show(); // break; // } URI uri = prepareURI(); if
- * (uri != null) { //intent.putExtra("sessionName", sessionName);
- * intent.putExtra("sessionURL", uri.toString());
- * setResult(Activity.RESULT_OK, intent); AccountManager accMgr =
- * AccountManager.get(this); Account a = new Account("OwnCloud",
- * AccountAuthenticatorService.ACCOUNT_TYPE);
- * accMgr.addAccountExplicitly(a, "asd", null); finish(); } break; case
- * R.id.button2: setResult(Activity.RESULT_CANCELED); finish(); break; }
- */
- }
-
- /*
- * private URI prepareURI() { URI uri = null; String url = ""; try { String
- * username = ((EditText)
- * findViewById(R.id.newSession_username)).getText().toString().trim();
- * String password = ((EditText)
- * findViewById(R.id.newSession_password)).getText().toString().trim();
- * String hostname = ((EditText)
- * findViewById(R.id.newSession_URL)).getText().toString().trim(); String
- * scheme; if (hostname.matches("[A-Za-z]://")) { scheme =
- * hostname.substring(0, hostname.indexOf("://")+3); hostname =
- * hostname.substring(hostname.indexOf("://")+3); } else { scheme =
- * "http://"; } if (!username.equals("")) { if (!password.equals("")) {
- * username += ":" + password + "@"; } else { username += "@"; } } url =
- * scheme + username + hostname; Log.i(TAG, url); uri = new URI(url); }
- * catch (URISyntaxException e) { Log.e(TAG, "Incorrect URI syntax " +
- * e.getLocalizedMessage()); Toast.makeText(this,
- * R.string.new_session_uri_error, Toast.LENGTH_LONG).show(); } return uri;
- * }
- *
- * private boolean isNameValid(String string) { return
- * string.matches("[A-Za-z0-9 _-]*"); }
- */
-
- @Override
- public void onBackPressed() {
- setResult(Activity.RESULT_CANCELED);
- super.onBackPressed();
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/adapter/FileListActionListAdapter.java b/src/eu/alefzero/owncloud/ui/adapter/FileListActionListAdapter.java
deleted file mode 100644
index 1556e0d8..00000000
--- a/src/eu/alefzero/owncloud/ui/adapter/FileListActionListAdapter.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.ui.adapter;
-
-import java.io.File;
-
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-import eu.alefzero.webdav.WebdavUtils;
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.database.DataSetObserver;
-import android.net.Uri;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.TextView;
-
-public class FileListActionListAdapter implements ListAdapter {
-
- private Context mContext;
- private Account mAccount;
- private String mFilename, mFileType, mFilePath, mFileStoragePath;
-
- private final int ITEM_DOWNLOAD = 0;
-
- // private final int ITEM_SHARE = 1;
-
- public FileListActionListAdapter(Cursor c, Context co, Account account) {
- mContext = co;
- mFilename = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_NAME));
- mFileType = c.getString(c
- .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE));
- mFilePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PATH));
- mFileStoragePath = c.getString(c
- .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
- // mItemId = c.getString(c.getColumnIndex(ProviderTableMeta._ID));
- mAccount = account;
- }
-
- public boolean areAllItemsEnabled() {
- // TODO Auto-generated method stub
- return true;
- }
-
- public boolean isEnabled(int position) {
- // TODO Auto-generated method stub
- return true;
- }
-
- public int getCount() {
- // TODO Auto-generated method stub
- return 1;
- }
-
- public Object getItem(int position) {
- if (position == 0) {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- if (TextUtils.isEmpty(mFileStoragePath)) {
- intent.putExtra("toDownload", true);
- AccountManager accm = (AccountManager) mContext
- .getSystemService(Context.ACCOUNT_SERVICE);
- String ocurl = accm.getUserData(mAccount,
- AccountAuthenticator.KEY_OC_URL);
- ocurl += WebdavUtils.encodePath(mFilePath + mFilename);
- intent.setData(Uri.parse(ocurl));
- } else {
- intent.putExtra("toDownload", false);
- intent.setDataAndType(Uri.fromFile(new File(mFileStoragePath)),
- mFileType);
- }
- return intent;
- }
- return null;
- }
-
- public long getItemId(int position) {
- // TODO Auto-generated method stub
- return 0;
- }
-
- public int getItemViewType(int position) {
- // TODO Auto-generated method stub
- return 0;
- }
-
- public View getView(int position, View convertView, ViewGroup parent) {
- View v = convertView;
- if (v == null) {
- LayoutInflater vi = (LayoutInflater) mContext
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- v = vi.inflate(R.layout.file_display_action_list_element, null);
- }
-
- TextView tv;
- ImageView iv;
- switch (position) {
- case ITEM_DOWNLOAD:
- tv = (TextView) v.findViewById(R.id.textView1);
- if (mFileStoragePath == null) {
- tv.setText("Download");
- } else {
- setActionName(tv);
- }
- iv = (ImageView) v.findViewById(R.id.imageView1);
- iv.setImageResource(R.drawable.download);
- break;
- }
-
- return v;
- }
-
- public int getViewTypeCount() {
- // TODO Auto-generated method stub
- return 2;
- }
-
- public boolean hasStableIds() {
- // TODO Auto-generated method stub
- return false;
- }
-
- public boolean isEmpty() {
- // TODO Auto-generated method stub
- return false;
- }
-
- public void registerDataSetObserver(DataSetObserver observer) {
- // TODO Auto-generated method stub
-
- }
-
- public void unregisterDataSetObserver(DataSetObserver observer) {
- // TODO Auto-generated method stub
-
- }
-
- private void setActionName(TextView tv) {
- if (mFileType.matches("image/.*")) {
- tv.setText("View");
- } else if (mFileType.matches("audio/.*")
- || mFileType.matches("video/.*")) {
- tv.setText("Play");
- } else {
- tv.setText("Open");
- }
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/adapter/FileListListAdapter.java b/src/eu/alefzero/owncloud/ui/adapter/FileListListAdapter.java
deleted file mode 100644
index 9ab68db4..00000000
--- a/src/eu/alefzero/owncloud/ui/adapter/FileListListAdapter.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.ui.adapter;
-
-import java.util.Vector;
-
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.DisplayUtils;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.datamodel.DataStorageManager;
-import eu.alefzero.owncloud.datamodel.OCFile;
-import eu.alefzero.owncloud.files.services.FileDownloader;
-import eu.alefzero.owncloud.files.services.FileUploader;
-
-import android.accounts.Account;
-import android.content.Context;
-import android.database.DataSetObserver;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.TextView;
-
-/**
- * This Adapter populates a ListView with all files and folders in an ownCloud
- * instance.
- *
- * @author Bartek Przybylski
- *
- */
-public class FileListListAdapter implements ListAdapter {
- private Context mContext;
- private OCFile mFile;
- private Vector mFiles;
- private DataStorageManager mStorageManager;
- private Account mAccount;
-
- public FileListListAdapter(OCFile file, DataStorageManager storage_man,
- Context context) {
- mFile = file;
- mStorageManager = storage_man;
- mFiles = mStorageManager.getDirectoryContent(mFile);
- mContext = context;
- mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);
- }
-
- @Override
- public boolean areAllItemsEnabled() {
- return true;
- }
-
- @Override
- public boolean isEnabled(int position) {
- // TODO Auto-generated method stub
- return true;
- }
-
- @Override
- public int getCount() {
- return mFiles != null ? mFiles.size() : 0;
- }
-
- @Override
- public Object getItem(int position) {
- if (mFiles.size() <= position)
- return null;
- return mFiles.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return mFiles != null ? mFiles.get(position).getFileId() : 0;
- }
-
- @Override
- public int getItemViewType(int position) {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View view = convertView;
- if (view == null) {
- LayoutInflater inflator = (LayoutInflater) mContext
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- view = inflator.inflate(R.layout.list_layout, null);
- }
- if (mFiles.size() > position) {
- OCFile file = mFiles.get(position);
- TextView fileName = (TextView) view.findViewById(R.id.Filename);
- String name = file.getFileName();
-
- fileName.setText(name);
- ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);
- if (file.getMimetype() == null || !file.getMimetype().equals("DIR")) {
- fileIcon.setImageResource(R.drawable.file);
- } else {
- fileIcon.setImageResource(R.drawable.ic_menu_archive);
- }
- ImageView localStateView = (ImageView) view.findViewById(R.id.imageView2);
- if (FileDownloader.isDownloading(mAccount, file.getRemotePath())) {
- localStateView.setImageResource(R.drawable.downloading_file_indicator);
- localStateView.setVisibility(View.VISIBLE);
- } else if (FileUploader.isUploading(mAccount, file.getRemotePath())) {
- localStateView.setImageResource(R.drawable.uploading_file_indicator);
- localStateView.setVisibility(View.VISIBLE);
- } else if (file.isDown()) {
- localStateView.setImageResource(R.drawable.local_file_indicator);
- localStateView.setVisibility(View.VISIBLE);
- } else {
- localStateView.setVisibility(View.INVISIBLE);
- }
- /*
- ImageView down = (ImageView) view.findViewById(R.id.imageView2);
- ImageView downloading = (ImageView) view.findViewById(R.id.imageView4);
- ImageView uploading = (ImageView) view.findViewById(R.id.imageView5);
- if (FileDownloader.isDownloading(mAccount, file.getRemotePath())) {
- down.setVisibility(View.INVISIBLE);
- downloading.setVisibility(View.VISIBLE);
- uploading.setVisibility(View.INVISIBLE);
- } else if (FileUploader.isUploading(mAccount, file.getRemotePath())) {
- down.setVisibility(View.INVISIBLE);
- downloading.setVisibility(View.INVISIBLE);
- uploading.setVisibility(View.VISIBLE);
- } else if (file.isDown()) {
- down.setVisibility(View.VISIBLE);
- downloading.setVisibility(View.INVISIBLE);
- uploading.setVisibility(View.INVISIBLE);
- } else {
- down.setVisibility(View.INVISIBLE);
- downloading.setVisibility(View.INVISIBLE);
- uploading.setVisibility(View.INVISIBLE);
- }*/
-
- if (!file.isDirectory()) {
- view.findViewById(R.id.file_size).setVisibility(View.VISIBLE);
- view.findViewById(R.id.last_mod).setVisibility(View.VISIBLE);
- ((TextView)view.findViewById(R.id.file_size)).setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));
- ((TextView)view.findViewById(R.id.last_mod)).setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()));
- // this if-else is needed even thoe fav icon is visible by default
- // because android reuses views in listview
- if (!file.keepInSync()) {
- view.findViewById(R.id.imageView3).setVisibility(View.GONE);
- } else {
- view.findViewById(R.id.imageView3).setVisibility(View.VISIBLE);
- }
- } else {
- view.findViewById(R.id.file_size).setVisibility(View.GONE);
- view.findViewById(R.id.last_mod).setVisibility(View.GONE);
- view.findViewById(R.id.imageView3).setVisibility(View.GONE);
- }
- }
-
- return view;
- }
-
- @Override
- public int getViewTypeCount() {
- return 4;
- }
-
- @Override
- public boolean hasStableIds() {
- return true;
- }
-
- @Override
- public boolean isEmpty() {
- return mFiles != null ? mFiles.isEmpty() : false;
- }
-
- @Override
- public void registerDataSetObserver(DataSetObserver observer) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void unregisterDataSetObserver(DataSetObserver observer) {
- // TODO Auto-generated method stub
-
- }
-}
diff --git a/src/eu/alefzero/owncloud/ui/adapter/LandingScreenAdapter.java b/src/eu/alefzero/owncloud/ui/adapter/LandingScreenAdapter.java
deleted file mode 100644
index 7128886c..00000000
--- a/src/eu/alefzero/owncloud/ui/adapter/LandingScreenAdapter.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.ui.adapter;
-
-import android.content.Context;
-import android.content.Intent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.ui.activity.FileDisplayActivity;
-import eu.alefzero.owncloud.ui.activity.Preferences;
-
-/**
- * Populates the landing screen icons.
- *
- * @author Lennart Rosam
- *
- */
-public class LandingScreenAdapter extends BaseAdapter {
-
- private Context mContext;
-
- private final Integer[] mLandingScreenIcons = { R.drawable.home,
- R.drawable.music, R.drawable.contacts, R.drawable.calendar,
- android.R.drawable.ic_menu_agenda, R.drawable.settings };
-
- private final Integer[] mLandingScreenTexts = { R.string.main_files,
- R.string.main_music, R.string.main_contacts,
- R.string.main_calendar, R.string.main_bookmarks,
- R.string.main_settings };
-
- public LandingScreenAdapter(Context context) {
- mContext = context;
- }
-
- @Override
- public int getCount() {
- return mLandingScreenIcons.length;
- }
-
- @Override
- /**
- * Returns the Intent associated with this object
- * or null if the functionality is not yet implemented
- */
- public Object getItem(int position) {
- Intent intent = new Intent();
-
- switch (position) {
- case 0:
- /*
- * The FileDisplayActivity requires the ownCloud account as an
- * parcableExtra. We will put in the one that is selected in the
- * preferences
- */
- intent.setClass(mContext, FileDisplayActivity.class);
- intent.putExtra("ACCOUNT",
- AccountUtils.getCurrentOwnCloudAccount(mContext));
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- break;
- case 5:
- intent.setClass(mContext, Preferences.class);
- break;
- default:
- intent = null;
- }
- return intent;
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- LayoutInflater inflator = LayoutInflater.from(mContext);
- convertView = inflator.inflate(R.layout.landing_page_item, null);
-
- ImageView icon = (ImageView) convertView
- .findViewById(R.id.gridImage);
- TextView iconText = (TextView) convertView
- .findViewById(R.id.gridText);
-
- icon.setImageResource(mLandingScreenIcons[position]);
- iconText.setText(mLandingScreenTexts[position]);
- }
- return convertView;
- }
-}
diff --git a/src/eu/alefzero/owncloud/ui/fragment/AuthenticatorAccountDetailsFragment.java b/src/eu/alefzero/owncloud/ui/fragment/AuthenticatorAccountDetailsFragment.java
deleted file mode 100644
index e17cf795..00000000
--- a/src/eu/alefzero/owncloud/ui/fragment/AuthenticatorAccountDetailsFragment.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package eu.alefzero.owncloud.ui.fragment;
-
-import com.actionbarsherlock.app.SherlockFragment;
-
-public class AuthenticatorAccountDetailsFragment extends SherlockFragment {
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/fragment/AuthenticatorGetStartedFragment.java b/src/eu/alefzero/owncloud/ui/fragment/AuthenticatorGetStartedFragment.java
deleted file mode 100644
index 84ef8875..00000000
--- a/src/eu/alefzero/owncloud/ui/fragment/AuthenticatorGetStartedFragment.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package eu.alefzero.owncloud.ui.fragment;
-
-import com.actionbarsherlock.app.SherlockFragment;
-
-public class AuthenticatorGetStartedFragment extends SherlockFragment {
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/fragment/ConfirmationDialogFragment.java b/src/eu/alefzero/owncloud/ui/fragment/ConfirmationDialogFragment.java
deleted file mode 100644
index cc6a0f7f..00000000
--- a/src/eu/alefzero/owncloud/ui/fragment/ConfirmationDialogFragment.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package eu.alefzero.owncloud.ui.fragment;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.actionbarsherlock.app.SherlockDialogFragment;
-
-import eu.alefzero.owncloud.R;
-
-public class ConfirmationDialogFragment extends SherlockDialogFragment {
-
- public final static String ARG_CONF_RESOURCE_ID = "resource_id";
- public final static String ARG_CONF_ARGUMENTS = "string_array";
-
- public final static String ARG_POSITIVE_BTN_RES = "positive_btn_res";
- public final static String ARG_NEUTRAL_BTN_RES = "neutral_btn_res";
- public final static String ARG_NEGATIVE_BTN_RES = "negative_btn_res";
-
- private ConfirmationDialogFragmentListener mListener;
-
- public static ConfirmationDialogFragment newInstance(int string_id, String[] arguments, int posBtn, int neuBtn, int negBtn) {
- ConfirmationDialogFragment frag = new ConfirmationDialogFragment();
- Bundle args = new Bundle();
- args.putInt(ARG_CONF_RESOURCE_ID, string_id);
- args.putStringArray(ARG_CONF_ARGUMENTS, arguments);
- args.putInt(ARG_POSITIVE_BTN_RES, posBtn);
- args.putInt(ARG_NEUTRAL_BTN_RES, neuBtn);
- args.putInt(ARG_NEGATIVE_BTN_RES, negBtn);
- frag.setArguments(args);
- return frag;
- }
-
- public void setOnConfirmationListener(ConfirmationDialogFragmentListener listener) {
- mListener = listener;
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- Object[] confirmationTarget = getArguments().getStringArray(ARG_CONF_ARGUMENTS);
- int resourceId = getArguments().getInt(ARG_CONF_RESOURCE_ID, -1);
- int posBtn = getArguments().getInt(ARG_POSITIVE_BTN_RES, -1);
- int neuBtn = getArguments().getInt(ARG_NEUTRAL_BTN_RES, -1);
- int negBtn = getArguments().getInt(ARG_NEGATIVE_BTN_RES, -1);
-
- if (confirmationTarget == null || resourceId == -1) {
- Log.wtf(getTag(), "Calling confirmation dialog without resource or arguments");
- return null;
- }
-
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setMessage(String.format(getString(resourceId), confirmationTarget))
- .setTitle(android.R.string.dialog_alert_title);
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
- builder.setIconAttribute(android.R.attr.alertDialogIcon);
- }
-
- if (posBtn != -1)
- builder.setPositiveButton(posBtn,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- mListener.onConfirmation(getTag());
- }
- });
- if (neuBtn != -1)
- builder.setNeutralButton(neuBtn,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- mListener.onNeutral(getTag());
- }
- });
- if (negBtn != -1)
- builder.setNegativeButton(negBtn,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mListener.onCancel(getTag());
- }
- });
- return builder.create();
- }
-
-
- public interface ConfirmationDialogFragmentListener {
- public void onConfirmation(String callerTag);
- public void onNeutral(String callerTag);
- public void onCancel(String callerTag);
- }
-
-}
-
diff --git a/src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java b/src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java
deleted file mode 100644
index f8f42061..00000000
--- a/src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java
+++ /dev/null
@@ -1,1126 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.ui.fragment;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.httpclient.HttpException;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.httpclient.methods.StringRequestEntity;
-import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
-import org.apache.http.HttpStatus;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.utils.URLEncodedUtils;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
-import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
-import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapFactory.Options;
-import android.graphics.Point;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v4.app.FragmentTransaction;
-import android.util.Log;
-import android.view.Display;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.WindowManager.LayoutParams;
-import android.webkit.MimeTypeMap;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.actionbarsherlock.app.SherlockDialogFragment;
-import com.actionbarsherlock.app.SherlockFragment;
-
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.DisplayUtils;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
-import eu.alefzero.owncloud.datamodel.OCFile;
-import eu.alefzero.owncloud.files.services.FileDownloader;
-import eu.alefzero.owncloud.files.services.FileUploader;
-import eu.alefzero.owncloud.ui.activity.FileDetailActivity;
-import eu.alefzero.owncloud.ui.activity.FileDisplayActivity;
-import eu.alefzero.owncloud.utils.OwnCloudVersion;
-import eu.alefzero.webdav.WebdavClient;
-import eu.alefzero.webdav.WebdavUtils;
-
-/**
- * This Fragment is used to display the details about a file.
- *
- * @author Bartek Przybylski
- *
- */
-public class FileDetailFragment extends SherlockFragment implements
- OnClickListener, ConfirmationDialogFragment.ConfirmationDialogFragmentListener {
-
- public static final String EXTRA_FILE = "FILE";
- public static final String EXTRA_ACCOUNT = "ACCOUNT";
-
- private FileDetailFragment.ContainerActivity mContainerActivity;
-
- private int mLayout;
- private View mView;
- private OCFile mFile;
- private Account mAccount;
- private ImageView mPreview;
-
- private DownloadFinishReceiver mDownloadFinishReceiver;
- private UploadFinishReceiver mUploadFinishReceiver;
-
- private static final String TAG = "FileDetailFragment";
- public static final String FTAG = "FileDetails";
- public static final String FTAG_CONFIRMATION = "REMOVE_CONFIRMATION_FRAGMENT";
-
-
- /**
- * Creates an empty details fragment.
- *
- * It's necessary to keep a public constructor without parameters; the system uses it when tries to reinstantiate a fragment automatically.
- */
- public FileDetailFragment() {
- mFile = null;
- mAccount = null;
- mLayout = R.layout.file_details_empty;
- }
-
-
- /**
- * Creates a details fragment.
- *
- * When 'fileToDetail' or 'ocAccount' are null, creates a dummy layout (to use when a file wasn't tapped before).
- *
- * @param fileToDetail An {@link OCFile} to show in the fragment
- * @param ocAccount An ownCloud account; needed to start downloads
- */
- public FileDetailFragment(OCFile fileToDetail, Account ocAccount){
- mFile = fileToDetail;
- mAccount = ocAccount;
- mLayout = R.layout.file_details_empty;
-
- if(fileToDetail != null && ocAccount != null) {
- mLayout = R.layout.file_details_fragment;
- }
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- try {
- mContainerActivity = (ContainerActivity) activity;
- } catch (ClassCastException e) {
- throw new ClassCastException(activity.toString() + " must implement FileListFragment.ContainerActivity");
- }
- }
-
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- super.onCreateView(inflater, container, savedInstanceState);
-
- if (savedInstanceState != null) {
- mFile = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_FILE);
- mAccount = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_ACCOUNT);
- }
-
- View view = null;
- view = inflater.inflate(mLayout, container, false);
- mView = view;
-
- if (mLayout == R.layout.file_details_fragment) {
- mView.findViewById(R.id.fdKeepInSync).setOnClickListener(this);
- mView.findViewById(R.id.fdRenameBtn).setOnClickListener(this);
- mView.findViewById(R.id.fdDownloadBtn).setOnClickListener(this);
- mView.findViewById(R.id.fdOpenBtn).setOnClickListener(this);
- mView.findViewById(R.id.fdRemoveBtn).setOnClickListener(this);
- //mView.findViewById(R.id.fdShareBtn).setOnClickListener(this);
- mPreview = (ImageView)mView.findViewById(R.id.fdPreview);
- }
-
- updateFileDetails();
- return view;
- }
-
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- Log.i(getClass().toString(), "onSaveInstanceState() start");
- super.onSaveInstanceState(outState);
- outState.putParcelable(FileDetailFragment.EXTRA_FILE, mFile);
- outState.putParcelable(FileDetailFragment.EXTRA_ACCOUNT, mAccount);
- Log.i(getClass().toString(), "onSaveInstanceState() end");
- }
-
-
- @Override
- public void onResume() {
- super.onResume();
-
- mDownloadFinishReceiver = new DownloadFinishReceiver();
- IntentFilter filter = new IntentFilter(
- FileDownloader.DOWNLOAD_FINISH_MESSAGE);
- getActivity().registerReceiver(mDownloadFinishReceiver, filter);
-
- mUploadFinishReceiver = new UploadFinishReceiver();
- filter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
- getActivity().registerReceiver(mUploadFinishReceiver, filter);
-
- mPreview = (ImageView)mView.findViewById(R.id.fdPreview);
- }
-
- @Override
- public void onPause() {
- super.onPause();
-
- getActivity().unregisterReceiver(mDownloadFinishReceiver);
- mDownloadFinishReceiver = null;
-
- getActivity().unregisterReceiver(mUploadFinishReceiver);
- mUploadFinishReceiver = null;
-
- if (mPreview != null) {
- mPreview = null;
- }
- }
-
- @Override
- public View getView() {
- return super.getView() == null ? mView : super.getView();
- }
-
-
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.fdDownloadBtn: {
- Intent i = new Intent(getActivity(), FileDownloader.class);
- i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
- i.putExtra(FileDownloader.EXTRA_REMOTE_PATH, mFile.getRemotePath());
- i.putExtra(FileDownloader.EXTRA_FILE_PATH, mFile.getRemotePath());
- i.putExtra(FileDownloader.EXTRA_FILE_SIZE, mFile.getFileLength());
-
- // update ui
- setButtonsForTransferring();
-
- getActivity().startService(i);
- mContainerActivity.onFileStateChanged(); // this is not working; it is performed before the fileDownloadService registers it as 'in progress'
- break;
- }
- case R.id.fdKeepInSync: {
- CheckBox cb = (CheckBox) getView().findViewById(R.id.fdKeepInSync);
- mFile.setKeepInSync(cb.isChecked());
- FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());
- fdsm.saveFile(mFile);
- if (mFile.keepInSync()) {
- onClick(getView().findViewById(R.id.fdDownloadBtn));
- } else {
- mContainerActivity.onFileStateChanged(); // put inside 'else' to not call it twice (here, and in the virtual click on fdDownloadBtn)
- }
- break;
- }
- case R.id.fdRenameBtn: {
- EditNameFragment dialog = EditNameFragment.newInstance(mFile.getFileName());
- dialog.show(getFragmentManager(), "nameeditdialog");
- dialog.setOnDismissListener(this);
- break;
- }
- case R.id.fdRemoveBtn: {
- ConfirmationDialogFragment confDialog = ConfirmationDialogFragment.newInstance(
- R.string.confirmation_remove_alert,
- new String[]{mFile.getFileName()},
- mFile.isDown() ? R.string.confirmation_remove_remote_and_local : R.string.confirmation_remove_remote,
- mFile.isDown() ? R.string.confirmation_remove_local : -1,
- R.string.common_cancel);
- confDialog.setOnConfirmationListener(this);
- confDialog.show(getFragmentManager(), FTAG_CONFIRMATION);
- break;
- }
- case R.id.fdOpenBtn: {
- String storagePath = mFile.getStoragePath();
- String encodedStoragePath = WebdavUtils.encodePath(storagePath);
- try {
- Intent i = new Intent(Intent.ACTION_VIEW);
- i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), mFile.getMimetype());
- i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- startActivity(i);
-
- } catch (Throwable t) {
- Log.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mFile.getMimetype());
- boolean toastIt = true;
- String mimeType = "";
- try {
- Intent i = new Intent(Intent.ACTION_VIEW);
- mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1));
- if (mimeType != null && !mimeType.equals(mFile.getMimetype())) {
- i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), mimeType);
- i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- startActivity(i);
- toastIt = false;
- }
-
- } catch (IndexOutOfBoundsException e) {
- Log.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);
-
- } catch (ActivityNotFoundException e) {
- Log.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");
-
- } catch (Throwable th) {
- Log.e(TAG, "Unexpected problem when opening: " + storagePath, th);
-
- } finally {
- if (toastIt) {
- Toast.makeText(getActivity(), "There is no application to handle file " + mFile.getFileName(), Toast.LENGTH_SHORT).show();
- }
- }
-
- }
- break;
- }
- default:
- Log.e(TAG, "Incorrect view clicked!");
- }
-
- /* else if (v.getId() == R.id.fdShareBtn) {
- Thread t = new Thread(new ShareRunnable(mFile.getRemotePath()));
- t.start();
- }*/
- }
-
-
- @Override
- public void onConfirmation(String callerTag) {
- if (callerTag.equals(FTAG_CONFIRMATION)) {
- FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
- if (fdsm.getFileById(mFile.getFileId()) != null) {
- new Thread(new RemoveRunnable(mFile, mAccount, new Handler())).start();
- boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
- getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
- }
- }
- }
-
- @Override
- public void onNeutral(String callerTag) {
- FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
- File f = null;
- if (mFile.isDown() && (f = new File(mFile.getStoragePath())).exists()) {
- f.delete();
- mFile.setStoragePath(null);
- fdsm.saveFile(mFile);
- updateFileDetails(mFile, mAccount);
- }
- }
-
- @Override
- public void onCancel(String callerTag) {
- Log.d(TAG, "REMOVAL CANCELED");
- }
-
-
- /**
- * Check if the fragment was created with an empty layout. An empty fragment can't show file details, must be replaced.
- *
- * @return True when the fragment was created with the empty layout.
- */
- public boolean isEmpty() {
- return mLayout == R.layout.file_details_empty;
- }
-
-
- /**
- * Can be used to get the file that is currently being displayed.
- * @return The file on the screen.
- */
- public OCFile getDisplayedFile(){
- return mFile;
- }
-
- /**
- * Use this method to signal this Activity that it shall update its view.
- *
- * @param file : An {@link OCFile}
- */
- public void updateFileDetails(OCFile file, Account ocAccount) {
- mFile = file;
- mAccount = ocAccount;
- updateFileDetails();
- }
-
-
- /**
- * Updates the view with all relevant details about that file.
- */
- public void updateFileDetails() {
-
- if (mFile != null && mAccount != null && mLayout == R.layout.file_details_fragment) {
-
- // set file details
- setFilename(mFile.getFileName());
- setFiletype(DisplayUtils.convertMIMEtoPrettyPrint(mFile
- .getMimetype()));
- setFilesize(mFile.getFileLength());
- if(ocVersionSupportsTimeCreated()){
- setTimeCreated(mFile.getCreationTimestamp());
- }
-
- setTimeModified(mFile.getModificationTimestamp());
-
- CheckBox cb = (CheckBox)getView().findViewById(R.id.fdKeepInSync);
- cb.setChecked(mFile.keepInSync());
-
- // configure UI for depending upon local state of the file
- if (FileDownloader.isDownloading(mAccount, mFile.getRemotePath()) || FileUploader.isUploading(mAccount, mFile.getRemotePath())) {
- setButtonsForTransferring();
-
- } else if (mFile.isDown()) {
- // Update preview
- if (mFile.getMimetype().startsWith("image/")) {
- BitmapLoader bl = new BitmapLoader();
- bl.execute(new String[]{mFile.getStoragePath()});
- }
-
- setButtonsForDown();
-
- } else {
- setButtonsForRemote();
- }
- }
- }
-
-
- /**
- * Updates the filename in view
- * @param filename to set
- */
- private void setFilename(String filename) {
- TextView tv = (TextView) getView().findViewById(R.id.fdFilename);
- if (tv != null)
- tv.setText(filename);
- }
-
- /**
- * Updates the MIME type in view
- * @param mimetype to set
- */
- private void setFiletype(String mimetype) {
- TextView tv = (TextView) getView().findViewById(R.id.fdType);
- if (tv != null)
- tv.setText(mimetype);
- }
-
- /**
- * Updates the file size in view
- * @param filesize in bytes to set
- */
- private void setFilesize(long filesize) {
- TextView tv = (TextView) getView().findViewById(R.id.fdSize);
- if (tv != null)
- tv.setText(DisplayUtils.bytesToHumanReadable(filesize));
- }
-
- /**
- * Updates the time that the file was created in view
- * @param milliseconds Unix time to set
- */
- private void setTimeCreated(long milliseconds){
- TextView tv = (TextView) getView().findViewById(R.id.fdCreated);
- TextView tvLabel = (TextView) getView().findViewById(R.id.fdCreatedLabel);
- if(tv != null){
- tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));
- tv.setVisibility(View.VISIBLE);
- tvLabel.setVisibility(View.VISIBLE);
- }
- }
-
- /**
- * Updates the time that the file was last modified
- * @param milliseconds Unix time to set
- */
- private void setTimeModified(long milliseconds){
- TextView tv = (TextView) getView().findViewById(R.id.fdModified);
- if(tv != null){
- tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));
- }
- }
-
- /**
- * Enables or disables buttons for a file being downloaded
- */
- private void setButtonsForTransferring() {
- if (!isEmpty()) {
- Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);
- //downloadButton.setText(R.string.filedetails_download_in_progress); // ugly
- downloadButton.setEnabled(false); // TODO replace it with a 'cancel download' button
-
- // let's protect the user from himself ;)
- ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(false);
- ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(false);
- ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(false);
- }
- }
-
- /**
- * Enables or disables buttons for a file locally available
- */
- private void setButtonsForDown() {
- if (!isEmpty()) {
- Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);
- //downloadButton.setText(R.string.filedetails_redownload); // ugly
- downloadButton.setEnabled(true);
-
- ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(true);
- ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(true);
- ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(true);
- }
- }
-
- /**
- * Enables or disables buttons for a file not locally available
- */
- private void setButtonsForRemote() {
- if (!isEmpty()) {
- Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);
- //downloadButton.setText(R.string.filedetails_download); // unnecessary
- downloadButton.setEnabled(true);
-
- ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(false);
- ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(true);
- ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(true);
- }
- }
-
-
- /**
- * In ownCloud 3.X.X and 4.X.X there is a bug that SabreDAV does not return
- * the time that the file was created. There is a chance that this will
- * be fixed in future versions. Use this method to check if this version of
- * ownCloud has this fix.
- * @return True, if ownCloud the ownCloud version is supporting creation time
- */
- private boolean ocVersionSupportsTimeCreated(){
- /*if(mAccount != null){
- AccountManager accManager = (AccountManager) getActivity().getSystemService(Context.ACCOUNT_SERVICE);
- OwnCloudVersion ocVersion = new OwnCloudVersion(accManager
- .getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));
- if(ocVersion.compareTo(new OwnCloudVersion(0x030000)) < 0) {
- return true;
- }
- }*/
- return false;
- }
-
-
- /**
- * Interface to implement by any Activity that includes some instance of FileDetailFragment
- *
- * @author David A. Velasco
- */
- public interface ContainerActivity {
-
- /**
- * Callback method invoked when the detail fragment wants to notice its container
- * activity about a relevant state the file shown by the fragment.
- *
- * Added to notify to FileDisplayActivity about the need of refresh the files list.
- *
- * Currently called when:
- * - a download is started;
- * - a rename is completed;
- * - a deletion is completed;
- * - the 'inSync' flag is changed;
- */
- public void onFileStateChanged();
-
- }
-
-
- /**
- * Once the file download has finished -> update view
- * @author Bartek Przybylski
- */
- private class DownloadFinishReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);
-
- if (!isEmpty() && accountName.equals(mAccount.name)) {
- boolean downloadWasFine = intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false);
- String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
- if (mFile.getRemotePath().equals(downloadedRemotePath)) {
- if (downloadWasFine) {
- mFile.setStoragePath(intent.getStringExtra(FileDownloader.EXTRA_FILE_PATH)); // updates the local object without accessing the database again
- }
- updateFileDetails(); // it updates the buttons; must be called although !downloadWasFine
- }
- }
- }
- }
-
-
- /**
- * Once the file upload has finished -> update view
- *
- * Being notified about the finish of an upload is necessary for the next sequence:
- * 1. Upload a big file.
- * 2. Force a synchronization; if it finished before the upload, the file in transfer will be included in the local database and in the file list
- * of its containing folder; the the server includes it in the PROPFIND requests although it's not fully upload.
- * 3. Click the file in the list to see its details.
- * 4. Wait for the upload finishes; at this moment, the details view must be refreshed to enable the action buttons.
- */
- private class UploadFinishReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);
-
- if (!isEmpty() && accountName.equals(mAccount.name)) {
- boolean uploadWasFine = intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false);
- String uploadRemotePath = intent.getStringExtra(FileUploader.EXTRA_REMOTE_PATH);
- if (mFile.getRemotePath().equals(uploadRemotePath)) {
- if (uploadWasFine) {
- FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());
- mFile = fdsm.getFileByPath(mFile.getRemotePath());
- }
- updateFileDetails(); // it updates the buttons; must be called although !uploadWasFine; interrupted uploads still leave an incomplete file in the server
- }
- }
- }
- }
-
-
- // this is a temporary class for sharing purposes, it need to be replaced in transfer service
- private class ShareRunnable implements Runnable {
- private String mPath;
-
- public ShareRunnable(String path) {
- mPath = path;
- }
-
- public void run() {
- AccountManager am = AccountManager.get(getActivity());
- Account account = AccountUtils.getCurrentOwnCloudAccount(getActivity());
- OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION));
- String url = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + AccountUtils.getWebdavPath(ocv);
-
- Log.d("share", "sharing for version " + ocv.toString());
-
- if (ocv.compareTo(new OwnCloudVersion(0x040000)) >= 0) {
- String APPS_PATH = "/apps/files_sharing/";
- String SHARE_PATH = "ajax/share.php";
-
- String SHARED_PATH = "/apps/files_sharing/get.php?token=";
-
- final String WEBDAV_SCRIPT = "webdav.php";
- final String WEBDAV_FILES_LOCATION = "/files/";
-
- WebdavClient wc = new WebdavClient();
- HttpConnectionManagerParams params = new HttpConnectionManagerParams();
- params.setMaxConnectionsPerHost(wc.getHostConfiguration(), 5);
-
- //wc.getParams().setParameter("http.protocol.single-cookie-header", true);
- //wc.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
-
- PostMethod post = new PostMethod(am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + APPS_PATH + SHARE_PATH);
-
- post.addRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8" );
- post.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));
- List formparams = new ArrayList();
- Log.d("share", mPath+"");
- formparams.add(new BasicNameValuePair("sources",mPath));
- formparams.add(new BasicNameValuePair("uid_shared_with", "public"));
- formparams.add(new BasicNameValuePair("permissions", "0"));
- post.setRequestEntity(new StringRequestEntity(URLEncodedUtils.format(formparams, HTTP.UTF_8)));
-
- int status;
- try {
- PropFindMethod find = new PropFindMethod(url+"/");
- find.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));
- Log.d("sharer", ""+ url+"/");
- wc.setCredentials(account.name.substring(0, account.name.lastIndexOf('@')), am.getPassword(account));
-
- for (org.apache.commons.httpclient.Header a : find.getRequestHeaders()) {
- Log.d("sharer-h", a.getName() + ":"+a.getValue());
- }
-
- int status2 = wc.executeMethod(find);
-
- Log.d("sharer", "propstatus "+status2);
-
- GetMethod get = new GetMethod(am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + "/");
- get.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));
-
- status2 = wc.executeMethod(get);
-
- Log.d("sharer", "getstatus "+status2);
- Log.d("sharer", "" + get.getResponseBodyAsString());
-
- for (org.apache.commons.httpclient.Header a : get.getResponseHeaders()) {
- Log.d("sharer", a.getName() + ":"+a.getValue());
- }
-
- status = wc.executeMethod(post);
- for (org.apache.commons.httpclient.Header a : post.getRequestHeaders()) {
- Log.d("sharer-h", a.getName() + ":"+a.getValue());
- }
- for (org.apache.commons.httpclient.Header a : post.getResponseHeaders()) {
- Log.d("sharer", a.getName() + ":"+a.getValue());
- }
- String resp = post.getResponseBodyAsString();
- Log.d("share", ""+post.getURI().toString());
- Log.d("share", "returned status " + status);
- Log.d("share", " " +resp);
-
- if(status != HttpStatus.SC_OK ||resp == null || resp.equals("") || resp.startsWith("false")) {
- return;
- }
-
- JSONObject jsonObject = new JSONObject (resp);
- String jsonStatus = jsonObject.getString("status");
- if(!jsonStatus.equals("success")) throw new Exception("Error while sharing file status != success");
-
- String token = jsonObject.getString("data");
- String uri = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + SHARED_PATH + token;
- Log.d("Actions:shareFile ok", "url: " + uri);
-
- } catch (HttpException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- } else if (ocv.compareTo(new OwnCloudVersion(0x030000)) >= 0) {
-
- }
- }
- }
-
- public void onDismiss(EditNameFragment dialog) {
- if (dialog instanceof EditNameFragment) {
- if (((EditNameFragment)dialog).getResult()) {
- String newFilename = ((EditNameFragment)dialog).getNewFilename();
- Log.d(TAG, "name edit dialog dismissed with new name " + newFilename);
- if (!newFilename.equals(mFile.getFileName())) {
- FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
- if (fdsm.getFileById(mFile.getFileId()) != null) {
- OCFile newFile = new OCFile(fdsm.getFileById(mFile.getParentId()).getRemotePath() + newFilename);
- newFile.setCreationTimestamp(mFile.getCreationTimestamp());
- newFile.setFileId(mFile.getFileId());
- newFile.setFileLength(mFile.getFileLength());
- newFile.setKeepInSync(mFile.keepInSync());
- newFile.setLastSyncDate(mFile.getLastSyncDate());
- newFile.setMimetype(mFile.getMimetype());
- newFile.setModificationTimestamp(mFile.getModificationTimestamp());
- newFile.setParentId(mFile.getParentId());
- boolean localRenameFails = false;
- if (mFile.isDown()) {
- File f = new File(mFile.getStoragePath());
- Log.e(TAG, f.getAbsolutePath());
- localRenameFails = !(f.renameTo(new File(f.getParent() + File.separator + newFilename)));
- Log.e(TAG, f.getParent() + File.separator + newFilename);
- newFile.setStoragePath(f.getParent() + File.separator + newFilename);
- }
-
- if (localRenameFails) {
- Toast msg = Toast.makeText(getActivity(), R.string.rename_local_fail_msg, Toast.LENGTH_LONG);
- msg.show();
-
- } else {
- new Thread(new RenameRunnable(mFile, newFile, mAccount, new Handler())).start();
- boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
- getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
- }
-
- }
- }
- }
- } else {
- Log.e(TAG, "Unknown dialog instance passed to onDismissDalog: " + dialog.getClass().getCanonicalName());
- }
-
- }
-
- private class RenameRunnable implements Runnable {
-
- Account mAccount;
- OCFile mOld, mNew;
- Handler mHandler;
-
- public RenameRunnable(OCFile oldFile, OCFile newFile, Account account, Handler handler) {
- mOld = oldFile;
- mNew = newFile;
- mAccount = account;
- mHandler = handler;
- }
-
- public void run() {
- WebdavClient wc = new WebdavClient(mAccount, getSherlockActivity().getApplicationContext());
- wc.allowSelfsignedCertificates();
- AccountManager am = AccountManager.get(getSherlockActivity());
- String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);
- OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));
- String webdav_path = AccountUtils.getWebdavPath(ocv);
- Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encodePath(mOld.getRemotePath()));
-
- Log.e("ASD", Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encodePath(mNew.getRemotePath()));
- LocalMoveMethod move = new LocalMoveMethod(baseUrl + webdav_path + WebdavUtils.encodePath(mOld.getRemotePath()),
- Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encodePath(mNew.getRemotePath()));
-
- boolean success = false;
- try {
- int status = wc.executeMethod(move);
- success = move.succeeded();
- Log.d(TAG, "Move returned status: " + status);
-
- } catch (HttpException e) {
- Log.e(TAG, "HTTP Exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e);
-
- } catch (IOException e) {
- Log.e(TAG, "I/O Exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e);
-
- } catch (Exception e) {
- Log.e(TAG, "Unexpected exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e);
- }
-
- if (success) {
- FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
- fdsm.removeFile(mOld);
- fdsm.saveFile(mNew);
- mFile = mNew;
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
- getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
- updateFileDetails(mFile, mAccount);
- mContainerActivity.onFileStateChanged();
- }
- });
-
- } else {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- // undo the local rename
- if (mNew.isDown()) {
- File f = new File(mNew.getStoragePath());
- if (!f.renameTo(new File(mOld.getStoragePath()))) {
- // the local rename undoing failed; last chance: save the new local storage path in the old file
- mFile.setStoragePath(mNew.getStoragePath());
- FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
- fdsm.saveFile(mFile);
- }
- }
- boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
- getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
- try {
- Toast msg = Toast.makeText(getActivity(), R.string.rename_server_fail_msg, Toast.LENGTH_LONG);
- msg.show();
-
- } catch (NotFoundException e) {
- e.printStackTrace();
- }
- }
- });
- }
- }
- private class LocalMoveMethod extends DavMethodBase {
-
- public LocalMoveMethod(String uri, String dest) {
- super(uri);
- addRequestHeader(new org.apache.commons.httpclient.Header("Destination", dest));
- }
-
- @Override
- public String getName() {
- return "MOVE";
- }
-
- @Override
- protected boolean isSuccess(int status) {
- return status == 201 || status == 204;
- }
-
- }
- }
-
- private static class EditNameFragment extends SherlockDialogFragment implements OnClickListener {
-
- private String mNewFilename;
- private boolean mResult;
- private FileDetailFragment mListener;
-
- static public EditNameFragment newInstance(String filename) {
- EditNameFragment f = new EditNameFragment();
- Bundle args = new Bundle();
- args.putString("filename", filename);
- f.setArguments(args);
- return f;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View v = inflater.inflate(R.layout.edit_box_dialog, container, false);
-
- String currentName = getArguments().getString("filename");
- if (currentName == null)
- currentName = "";
-
- ((Button)v.findViewById(R.id.cancel)).setOnClickListener(this);
- ((Button)v.findViewById(R.id.ok)).setOnClickListener(this);
- ((TextView)v.findViewById(R.id.user_input)).setText(currentName);
- ((TextView)v.findViewById(R.id.user_input)).requestFocus();
- getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
-
- mResult = false;
- return v;
- }
-
- @Override
- public void onClick(View view) {
- switch (view.getId()) {
- case R.id.ok: {
- mNewFilename = ((TextView)getView().findViewById(R.id.user_input)).getText().toString();
- mResult = true;
- }
- case R.id.cancel: { // fallthought
- dismiss();
- mListener.onDismiss(this);
- }
- }
- }
-
- void setOnDismissListener(FileDetailFragment listener) {
- mListener = listener;
- }
-
- public String getNewFilename() {
- return mNewFilename;
- }
-
- // true if user click ok
- public boolean getResult() {
- return mResult;
- }
-
- }
-
- private class RemoveRunnable implements Runnable {
-
- Account mAccount;
- OCFile mFileToRemove;
- Handler mHandler;
-
- public RemoveRunnable(OCFile fileToRemove, Account account, Handler handler) {
- mFileToRemove = fileToRemove;
- mAccount = account;
- mHandler = handler;
- }
-
- public void run() {
- WebdavClient wc = new WebdavClient(mAccount, getSherlockActivity().getApplicationContext());
- wc.allowSelfsignedCertificates();
- AccountManager am = AccountManager.get(getSherlockActivity());
- String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);
- OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));
- String webdav_path = AccountUtils.getWebdavPath(ocv);
- Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encodePath(mFileToRemove.getRemotePath()));
-
- DeleteMethod delete = new DeleteMethod(baseUrl + webdav_path + WebdavUtils.encodePath(mFileToRemove.getRemotePath()));
-
- boolean success = false;
- int status = -1;
- try {
- status = wc.executeMethod(delete);
- success = (delete.succeeded());
- Log.d(TAG, "Delete: returned status " + status);
-
- } catch (HttpException e) {
- Log.e(TAG, "HTTP Exception removing file " + mFileToRemove.getRemotePath(), e);
-
- } catch (IOException e) {
- Log.e(TAG, "I/O Exception removing file " + mFileToRemove.getRemotePath(), e);
-
- } catch (Exception e) {
- Log.e(TAG, "Unexpected exception removing file " + mFileToRemove.getRemotePath(), e);
- }
-
- if (success) {
- FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
- fdsm.removeFile(mFileToRemove);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
- getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
- try {
- Toast msg = Toast.makeText(getActivity().getApplicationContext(), R.string.remove_success_msg, Toast.LENGTH_LONG);
- msg.show();
- if (inDisplayActivity) {
- // double pane
- FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
- transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment
- transaction.commit();
- mContainerActivity.onFileStateChanged();
-
- } else {
- getActivity().finish();
- }
-
- } catch (NotFoundException e) {
- e.printStackTrace();
- }
- }
- });
-
- } else {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
- getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
- try {
- Toast msg = Toast.makeText(getActivity(), R.string.remove_fail_msg, Toast.LENGTH_LONG);
- msg.show();
-
- } catch (NotFoundException e) {
- e.printStackTrace();
- }
- }
- });
- }
- }
-
- }
-
- class BitmapLoader extends AsyncTask {
- @SuppressLint({ "NewApi", "NewApi", "NewApi" }) // to avoid Lint errors since Android SDK r20
- @Override
- protected Bitmap doInBackground(String... params) {
- Bitmap result = null;
- if (params.length != 1) return result;
- String storagePath = params[0];
- try {
-
- BitmapFactory.Options options = new Options();
- options.inScaled = true;
- options.inPurgeable = true;
- options.inJustDecodeBounds = true;
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
- options.inPreferQualityOverSpeed = false;
- }
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
- options.inMutable = false;
- }
-
- result = BitmapFactory.decodeFile(storagePath, options);
- options.inJustDecodeBounds = false;
-
- int width = options.outWidth;
- int height = options.outHeight;
- int scale = 1;
- if (width >= 2048 || height >= 2048) {
- scale = (int) Math.ceil((Math.ceil(Math.max(height, width) / 2048.)));
- options.inSampleSize = scale;
- }
- Display display = getActivity().getWindowManager().getDefaultDisplay();
- Point size = new Point();
- int screenwidth;
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2) {
- display.getSize(size);
- screenwidth = size.x;
- } else {
- screenwidth = display.getWidth();
- }
-
- Log.e("ASD", "W " + width + " SW " + screenwidth);
-
- if (width > screenwidth) {
- scale = (int) Math.ceil((float)width / screenwidth);
- options.inSampleSize = scale;
- }
-
- result = BitmapFactory.decodeFile(storagePath, options);
-
- Log.e("ASD", "W " + options.outWidth + " SW " + options.outHeight);
-
- } catch (OutOfMemoryError e) {
- result = null;
- Log.e(TAG, "Out of memory occured for file with size " + storagePath);
-
- } catch (NoSuchFieldError e) {
- result = null;
- Log.e(TAG, "Error from access to unexisting field despite protection " + storagePath);
-
- } catch (Throwable t) {
- result = null;
- Log.e(TAG, "Unexpected error while creating image preview " + storagePath, t);
- }
- return result;
- }
- @Override
- protected void onPostExecute(Bitmap result) {
- if (result != null && mPreview != null) {
- mPreview.setImageBitmap(result);
- }
- }
-
- }
-
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java b/src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java
deleted file mode 100644
index 66d0af84..00000000
--- a/src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.ui.fragment;
-
-import java.util.Vector;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.datamodel.DataStorageManager;
-import eu.alefzero.owncloud.datamodel.OCFile;
-import eu.alefzero.owncloud.ui.FragmentListView;
-import eu.alefzero.owncloud.ui.adapter.FileListListAdapter;
-
-/**
- * A Fragment that lists all files and folders in a given path.
- *
- * @author Bartek Przybylski
- *
- */
-public class FileListFragment extends FragmentListView {
- private static final String TAG = "FileListFragment";
-
- private FileListFragment.ContainerActivity mContainerActivity;
-
- private OCFile mFile = null;
- private FileListListAdapter mAdapter;
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- try {
- mContainerActivity = (ContainerActivity) activity;
- } catch (ClassCastException e) {
- throw new ClassCastException(activity.toString() + " must implement FileListFragment.ContainerActivity");
- }
- }
-
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- Log.i(getClass().toString(), "onCreateView() start");
- super.onCreateView(inflater, container, savedInstanceState);
- getListView().setDivider(getResources().getDrawable(R.drawable.uploader_list_separator));
- getListView().setDividerHeight(1);
-
- Log.i(getClass().toString(), "onCreateView() end");
- return getListView();
- }
-
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- Log.i(getClass().toString(), "onActivityCreated() start");
-
- super.onCreate(savedInstanceState);
- //mAdapter = new FileListListAdapter();
-
- Log.i(getClass().toString(), "onActivityCreated() stop");
- }
-
-
- @Override
- public void onItemClick(AdapterView> l, View v, int position, long id) {
- OCFile file = (OCFile) mAdapter.getItem(position);
- if (file != null) {
- /// Click on a directory
- if (file.getMimetype().equals("DIR")) {
- // just local updates
- mFile = file;
- listDirectory(file);
- // any other updates are let to the container Activity
- mContainerActivity.onDirectoryClick(file);
-
- } else { /// Click on a file
- mContainerActivity.onFileClick(file);
- }
-
- } else {
- Log.d(TAG, "Null object in ListAdapter!!");
- }
-
- }
-
- /**
- * Call this, when the user presses the up button
- */
- public void onNavigateUp() {
- OCFile parentDir = null;
-
- if(mFile != null){
- DataStorageManager storageManager = mContainerActivity.getStorageManager();
- parentDir = storageManager.getFileById(mFile.getParentId());
- mFile = parentDir;
- }
- listDirectory(parentDir);
- }
-
- /**
- * Use this to query the {@link OCFile} that is currently
- * being displayed by this fragment
- * @return The currently viewed OCFile
- */
- public OCFile getCurrentFile(){
- return mFile;
- }
-
- /**
- * Calls {@link FileListFragment#listDirectory(OCFile)} with a null parameter
- */
- public void listDirectory(){
- listDirectory(null);
- }
-
- /**
- * Lists the given directory on the view. When the input parameter is null,
- * it will either refresh the last known directory, or list the root
- * if there never was a directory.
- *
- * @param directory File to be listed
- */
- public void listDirectory(OCFile directory) {
-
- DataStorageManager storageManager = mContainerActivity.getStorageManager();
-
- // Check input parameters for null
- if(directory == null){
- if(mFile != null){
- directory = mFile;
- } else {
- directory = storageManager.getFileByPath("/");
- if (directory == null) return; // no files, wait for sync
- }
- }
-
-
- // If that's not a directory -> List its parent
- if(!directory.isDirectory()){
- Log.w(TAG, "You see, that is not a directory -> " + directory.toString());
- directory = storageManager.getFileById(directory.getParentId());
- }
-
- mFile = directory;
-
- mAdapter = new FileListListAdapter(directory, storageManager, getActivity());
- setListAdapter(mAdapter);
- }
-
-
-
- /**
- * Interface to implement by any Activity that includes some instance of FileListFragment
- *
- * @author David A. Velasco
- */
- public interface ContainerActivity {
-
- /**
- * Callback method invoked when a directory is clicked by the user on the files list
- *
- * @param file
- */
- public void onDirectoryClick(OCFile file);
-
- /**
- * Callback method invoked when a file (non directory) is clicked by the user on the files list
- *
- * @param file
- */
- public void onFileClick(OCFile file);
-
- /**
- * Getter for the current DataStorageManager in the container activity
- */
- public DataStorageManager getStorageManager();
-
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/fragment/LandingPageFragment.java b/src/eu/alefzero/owncloud/ui/fragment/LandingPageFragment.java
deleted file mode 100644
index f5649a08..00000000
--- a/src/eu/alefzero/owncloud/ui/fragment/LandingPageFragment.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package eu.alefzero.owncloud.ui.fragment;
-
-import com.actionbarsherlock.app.SherlockFragment;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListView;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.ui.activity.LandingActivity;
-import eu.alefzero.owncloud.ui.adapter.LandingScreenAdapter;
-
-/**
- * Used on the Landing page to display what Components of the ownCloud there
- * are. Like Files, Music, Contacts, etc.
- *
- * @author Lennart Rosam
- *
- */
-public class LandingPageFragment extends SherlockFragment {
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View root = inflater.inflate(R.layout.landing_page_fragment, container);
- return root;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- ListView landingScreenItems = (ListView) getView().findViewById(
- R.id.homeScreenList);
- landingScreenItems.setAdapter(new LandingScreenAdapter(getActivity()));
- landingScreenItems
- .setOnItemClickListener((LandingActivity) getActivity());
- }
-
-}
diff --git a/src/eu/alefzero/owncloud/utils/OwnCloudVersion.java b/src/eu/alefzero/owncloud/utils/OwnCloudVersion.java
deleted file mode 100644
index a7726672..00000000
--- a/src/eu/alefzero/owncloud/utils/OwnCloudVersion.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package eu.alefzero.owncloud.utils;
-
-public class OwnCloudVersion implements Comparable {
- public static final OwnCloudVersion owncloud_v1 = new OwnCloudVersion(
- 0x010000);
- public static final OwnCloudVersion owncloud_v2 = new OwnCloudVersion(
- 0x020000);
- public static final OwnCloudVersion owncloud_v3 = new OwnCloudVersion(
- 0x030000);
- public static final OwnCloudVersion owncloud_v4 = new OwnCloudVersion(
- 0x040000);
-
- // format is in version
- // 0xAABBCC
- // for version AA.BB.CC
- // ie version 3.0.3 will be stored as 0x030003
- private int mVersion;
- private boolean mIsValid;
-
- public OwnCloudVersion(int version) {
- mVersion = version;
- mIsValid = true;
- }
-
- public OwnCloudVersion(String version) {
- mVersion = 0;
- mIsValid = false;
- parseVersionString(version);
- }
-
- public String toString() {
- return ((mVersion >> 16) % 256) + "." + ((mVersion >> 8) % 256) + "."
- + ((mVersion) % 256);
- }
-
- public boolean isVersionValid() {
- return mIsValid;
- }
-
- @Override
- public int compareTo(OwnCloudVersion another) {
- return another.mVersion == mVersion ? 0
- : another.mVersion < mVersion ? 1 : -1;
- }
-
- private void parseVersionString(String version) {
- try {
- String[] nums = version.split("\\.");
- if (nums.length > 0) {
- mVersion += Integer.parseInt(nums[0]);
- }
- mVersion = mVersion << 8;
- if (nums.length > 1) {
- mVersion += Integer.parseInt(nums[1]);
- }
- mVersion = mVersion << 8;
- if (nums.length > 2) {
- mVersion += Integer.parseInt(nums[2]);
- }
- mIsValid = true;
- } catch (Exception e) {
- mIsValid = false;
- }
- }
-}
diff --git a/src/eu/alefzero/owncloud/widgets/ActionEditText.java b/src/eu/alefzero/owncloud/widgets/ActionEditText.java
deleted file mode 100644
index 4b11b6c4..00000000
--- a/src/eu/alefzero/owncloud/widgets/ActionEditText.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package eu.alefzero.owncloud.widgets;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import eu.alefzero.owncloud.R;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.widget.EditText;
-
-public class ActionEditText extends EditText {
- private String s;
- private String optionOneString;
- private int optionOneColor;
- private String optionTwoString;
- private int optionTwoColor;
- private Rect mTextBounds, mButtonRect;
-
- private String badgeClickCallback;
- private Rect btn_rect;
-
- public ActionEditText(Context context, AttributeSet attrs) {
- super(context, attrs);
- getAttrs(attrs);
- s = optionOneString;
- mTextBounds = new Rect();
- mButtonRect = new Rect();
- }
-
- public ActionEditText(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- getAttrs(attrs);
- s = optionOneString;
- mTextBounds = new Rect();
- mButtonRect = new Rect();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- Paint p = getPaint();
-
- p.getTextBounds(s, 0, s.length(), mTextBounds);
-
- getDrawingRect(mButtonRect);
- mButtonRect.top += 10;
- mButtonRect.bottom -= 10;
- mButtonRect.left = (int) (getWidth() - mTextBounds.width() - 18);
- mButtonRect.right = getWidth() - 10;
- btn_rect = mButtonRect;
-
- if (s.equals(optionOneString))
- p.setColor(optionOneColor);
- else
- p.setColor(optionTwoColor);
- canvas.drawRect(mButtonRect, p);
- p.setColor(Color.GRAY);
-
- canvas.drawText(s, mButtonRect.left + 3, mButtonRect.bottom
- - (mTextBounds.height() / 2), p);
-
- invalidate();
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- int touchX = (int) event.getX();
- int touchY = (int) event.getY();
- boolean r = super.onTouchEvent(event);
- if (event.getAction() == MotionEvent.ACTION_UP) {
- if (btn_rect.contains(touchX, touchY)) {
- if (s.equals(optionTwoString))
- s = optionOneString;
- else
- s = optionTwoString;
- if (badgeClickCallback != null) {
- @SuppressWarnings("rawtypes")
- Class[] paramtypes = new Class[2];
- paramtypes[0] = android.view.View.class;
- paramtypes[1] = String.class;
- Method method;
- try {
-
- method = getContext().getClass().getMethod(
- badgeClickCallback, paramtypes);
- method.invoke(getContext(), this, s);
-
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
-
- invalidate();
- }
- }
- }
- return r;
- }
-
- private void getAttrs(AttributeSet attr) {
- TypedArray a = getContext().obtainStyledAttributes(attr,
- R.styleable.ActionEditText);
- optionOneString = a
- .getString(R.styleable.ActionEditText_optionOneString);
- optionTwoString = a
- .getString(R.styleable.ActionEditText_optionTwoString);
- optionOneColor = a.getColor(R.styleable.ActionEditText_optionOneColor,
- 0x00ff00);
- optionTwoColor = a.getColor(R.styleable.ActionEditText_optionTwoColor,
- 0xff0000);
- badgeClickCallback = a
- .getString(R.styleable.ActionEditText_onBadgeClick);
- }
-
-}
diff --git a/src/eu/alefzero/webdav/FileRequestEntity.java b/src/eu/alefzero/webdav/FileRequestEntity.java
index 3e7977c4..61ba4565 100644
--- a/src/eu/alefzero/webdav/FileRequestEntity.java
+++ b/src/eu/alefzero/webdav/FileRequestEntity.java
@@ -8,9 +8,10 @@ import java.io.OutputStream;
import org.apache.commons.httpclient.methods.RequestEntity;
+import com.owncloud.android.files.interfaces.OnDatatransferProgressListener;
+
import android.util.Log;
-import eu.alefzero.owncloud.files.interfaces.OnDatatransferProgressListener;
/**
* A RequestEntity that represents a File.
diff --git a/src/eu/alefzero/webdav/WebdavClient.java b/src/eu/alefzero/webdav/WebdavClient.java
index 1135dafa..1e64bdfe 100644
--- a/src/eu/alefzero/webdav/WebdavClient.java
+++ b/src/eu/alefzero/webdav/WebdavClient.java
@@ -41,16 +41,17 @@ import org.apache.jackrabbit.webdav.client.methods.DavMethod;
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.authenticator.EasySSLSocketFactory;
+import com.owncloud.android.files.interfaces.OnDatatransferProgressListener;
+import com.owncloud.android.utils.OwnCloudVersion;
+
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.authenticator.EasySSLSocketFactory;
-import eu.alefzero.owncloud.files.interfaces.OnDatatransferProgressListener;
-import eu.alefzero.owncloud.utils.OwnCloudVersion;
public class WebdavClient extends HttpClient {
private Uri mUri;