https for unsigned certificates in logging and uploading
authorBartek Przybylski <bart.p.pl@gmail.com>
Sat, 24 Dec 2011 21:54:11 +0000 (22:54 +0100)
committerBartek Przybylski <bart.p.pl@gmail.com>
Sat, 24 Dec 2011 21:54:11 +0000 (22:54 +0100)
23 files changed:
.classpath
AndroidManifest.xml
default.properties [deleted file]
lib/android-support-v4.jar [new file with mode: 0644]
lib/commons-httpclient-contrib-3.0.jar [new file with mode: 0644]
lib/httpclient-4.1.2.jar [new file with mode: 0644]
lib/httpclient-cache-4.1.2.jar [new file with mode: 0644]
lib/httpcore-4.1.2.jar [new file with mode: 0644]
lib/httpmime-4.1.2.jar [new file with mode: 0644]
lib/not-yet-commons-ssl-0.3.11.jar [new file with mode: 0644]
project.properties [new file with mode: 0644]
src/eu/alefzero/owncloud/FileDownloader.java [new file with mode: 0644]
src/eu/alefzero/owncloud/FileListActionListAdapter.java
src/eu/alefzero/owncloud/OwnCloudMainScreen.java
src/eu/alefzero/owncloud/OwnCloudUploader.java [deleted file]
src/eu/alefzero/owncloud/Uploader.java [new file with mode: 0644]
src/eu/alefzero/owncloud/WebdavClient.java [new file with mode: 0644]
src/eu/alefzero/owncloud/authenticator/AuthUtils.java
src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java [new file with mode: 0644]
src/eu/alefzero/owncloud/authenticator/EasyX509TrustManager.java [new file with mode: 0644]
src/eu/alefzero/owncloud/cp2.java [deleted file]
src/eu/alefzero/owncloud/syncadapter/ContactSyncAdapter.java [deleted file]
src/eu/alefzero/owncloud/syncadapter/ContactSyncService.java [deleted file]

index f6f1092..8be29c7 100644 (file)
@@ -5,11 +5,13 @@
        <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
        <classpathentry kind="lib" path="lib/commons-codec-1.4.jar"/>
        <classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>
        <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
        <classpathentry kind="lib" path="lib/commons-codec-1.4.jar"/>
        <classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>
-       <classpathentry kind="lib" path="lib/httpclient-4.1.1.jar"/>
-       <classpathentry kind="lib" path="lib/httpclient-cache-4.1.1.jar"/>
-       <classpathentry kind="lib" path="lib/httpcore-4.1.jar"/>
-       <classpathentry kind="lib" path="lib/httpmime-4.1.1.jar"/>
        <classpathentry kind="lib" path="lib/commons-httpclient-3.0.1.jar"/>
        <classpathentry kind="lib" path="lib/commons-io-2.0.1.jar"/>
        <classpathentry kind="lib" path="lib/commons-httpclient-3.0.1.jar"/>
        <classpathentry kind="lib" path="lib/commons-io-2.0.1.jar"/>
-       <classpathentry kind="output" path="bin"/>
+       <classpathentry kind="lib" path="lib/android-support-v4.jar"/>
+       <classpathentry kind="lib" path="lib/commons-httpclient-contrib-3.0.jar"/>
+       <classpathentry kind="lib" path="lib/httpclient-4.1.2.jar"/>
+       <classpathentry kind="lib" path="lib/httpcore-4.1.2.jar"/>
+       <classpathentry kind="lib" path="lib/httpmime-4.1.2.jar"/>
+       <classpathentry kind="lib" path="lib/httpclient-cache-4.1.2.jar"/>
+       <classpathentry kind="output" path="bin/classes"/>
 </classpath>
 </classpath>
index a5281fc..a625c01 100644 (file)
     <uses-permission
         android:name="android.permission.WRITE_SETTINGS" />
     <uses-permission
     <uses-permission
         android:name="android.permission.WRITE_SETTINGS" />
     <uses-permission
-        android:name="android.permission.WRITE_SECURE_SETTINGS" />
-    <uses-permission
-        android:name="android.permission.READ_CONTACTS" />
-    <uses-permission
-        android:name="android.permission.WRITE_CONTACTS" />
-    <uses-permission
         android:name="android.permission.READ_SYNC_STATS" />
     <uses-permission
         android:name="android.permission.READ_SYNC_SETTINGS" />
         android:name="android.permission.READ_SYNC_STATS" />
     <uses-permission
         android:name="android.permission.READ_SYNC_SETTINGS" />
@@ -38,7 +32,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-        <activity android:name="OwnCloudUploader">
+        <activity android:name=".Uploader">
             <intent-filter>
                 <action android:name="android.intent.action.SEND"></action>
                 <category android:name="android.intent.category.DEFAULT"></category>
             <intent-filter>
                 <action android:name="android.intent.action.SEND"></action>
                 <category android:name="android.intent.category.DEFAULT"></category>
         </service>
          <provider android:name="cp" android:enabled="true" android:syncable="true" android:exported="false" android:authorities="org.owncloud" android:label="@string/sync_string_files"></provider>
          <activity android:name=".authenticator.AuthenticatorActivity"></activity>
         </service>
          <provider android:name="cp" android:enabled="true" android:syncable="true" android:exported="false" android:authorities="org.owncloud" android:label="@string/sync_string_files"></provider>
          <activity android:name=".authenticator.AuthenticatorActivity"></activity>
-         <provider android:label="@string/sync_string_contacts" android:name="cp2" android:syncable="true" android:enabled="true" android:exported="false" android:authorities=""></provider>
-         <service android:name=".syncadapter.ContactSyncService" android:exported="true">
-             <intent-filter>
-                 <action android:name="android.content.SyncAdapter"></action>
-             </intent-filter>
-             <meta-data android:resource="@xml/syncadapter_contacts" android:name="android.content.SyncAdapter"></meta-data>
+         <service android:name="FileDownloader">
          </service>
     </application>
 </manifest>
\ No newline at end of file
          </service>
     </application>
 </manifest>
\ No newline at end of file
diff --git a/default.properties b/default.properties
deleted file mode 100644 (file)
index 46769a7..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "build.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=android-7
diff --git a/lib/android-support-v4.jar b/lib/android-support-v4.jar
new file mode 100644 (file)
index 0000000..b254ef5
Binary files /dev/null and b/lib/android-support-v4.jar differ
diff --git a/lib/commons-httpclient-contrib-3.0.jar b/lib/commons-httpclient-contrib-3.0.jar
new file mode 100644 (file)
index 0000000..805ccee
Binary files /dev/null and b/lib/commons-httpclient-contrib-3.0.jar differ
diff --git a/lib/httpclient-4.1.2.jar b/lib/httpclient-4.1.2.jar
new file mode 100644 (file)
index 0000000..b3cdb4c
Binary files /dev/null and b/lib/httpclient-4.1.2.jar differ
diff --git a/lib/httpclient-cache-4.1.2.jar b/lib/httpclient-cache-4.1.2.jar
new file mode 100644 (file)
index 0000000..6b7bcce
Binary files /dev/null and b/lib/httpclient-cache-4.1.2.jar differ
diff --git a/lib/httpcore-4.1.2.jar b/lib/httpcore-4.1.2.jar
new file mode 100644 (file)
index 0000000..66ae90b
Binary files /dev/null and b/lib/httpcore-4.1.2.jar differ
diff --git a/lib/httpmime-4.1.2.jar b/lib/httpmime-4.1.2.jar
new file mode 100644 (file)
index 0000000..eea3b3f
Binary files /dev/null and b/lib/httpmime-4.1.2.jar differ
diff --git a/lib/not-yet-commons-ssl-0.3.11.jar b/lib/not-yet-commons-ssl-0.3.11.jar
new file mode 100644 (file)
index 0000000..7b56427
Binary files /dev/null and b/lib/not-yet-commons-ssl-0.3.11.jar differ
diff --git a/project.properties b/project.properties
new file mode 100644 (file)
index 0000000..5a70945
--- /dev/null
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-7
diff --git a/src/eu/alefzero/owncloud/FileDownloader.java b/src/eu/alefzero/owncloud/FileDownloader.java
new file mode 100644 (file)
index 0000000..1631f49
--- /dev/null
@@ -0,0 +1,141 @@
+package eu.alefzero.owncloud;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.UnknownHostException;
+import java.util.Date;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.protocol.BasicHttpContext;
+
+import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
+import eu.alefzero.webdav.HttpPropFind;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.IBinder;
+import android.util.Log;
+import android.widget.FrameLayout;
+
+public class FileDownloader extends Service {
+  static final String EXTRA_ACCOUNT = "ACCOUNT";
+  static final String EXTRA_FILE_PATH = "FILE_PATH";
+  static final String TAG = "OC_FileDownloader";
+  
+  NotificationManager nm;
+  
+  @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)) {
+      Log.e(TAG, "Not enough information provided in intent");
+      return START_NOT_STICKY;
+    }
+    
+    nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+    
+    Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
+    String file_path = intent.getStringExtra(EXTRA_FILE_PATH);
+    AccountManager am = (AccountManager)getSystemService(ACCOUNT_SERVICE);
+    Uri oc_url = Uri.parse(am.getUserData(account, AccountAuthenticator.KEY_OC_URL));
+
+    DefaultHttpClient client = new DefaultHttpClient();
+    Log.d(TAG,  oc_url.toString());
+    HttpGet query = new HttpGet(oc_url + file_path);
+    query.setHeader("Content-type", "text/xml");
+    query.setHeader("User-Agent", "Android-ownCloud");
+    
+    BasicHttpContext httpContext = new BasicHttpContext();
+    BasicScheme basicAuth = new BasicScheme();
+    httpContext.setAttribute("preemptive-auth", basicAuth);
+    
+    String username = account.name.split("@")[0];
+    String password = "";
+    try {
+      password = am.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE, true);
+    } catch (OperationCanceledException e1) {
+      // TODO Auto-generated catch block
+      e1.printStackTrace();
+    } catch (AuthenticatorException e1) {
+      // TODO Auto-generated catch block
+      e1.printStackTrace();
+    } catch (IOException e1) {
+      // TODO Auto-generated catch block
+      e1.printStackTrace();
+    }
+    if (am.getUserData(account, AccountAuthenticator.KEY_OC_URL) == null) {
+      
+    }
+
+    client.getCredentialsProvider().setCredentials(
+      new AuthScope(oc_url.getHost(), oc_url.getPort()==-1?80:oc_url.getPort()),
+      new UsernamePasswordCredentials(username, password)
+    );
+    
+    HttpHost host = new HttpHost(oc_url.getHost(), oc_url.getPort()==-1?80:oc_url.getPort());
+    
+    Notification n = new Notification(R.drawable.icon, "Downloading file", System.currentTimeMillis());
+    PendingIntent pi = PendingIntent.getActivity(this, 1, new Intent(this, OwnCloudMainScreen.class), 0);
+    n.setLatestEventInfo(this, "A", "B", pi);
+    nm.notify(1, n);
+    
+    HttpResponse response = null;
+    try {
+      response = client.execute(host, query, httpContext);
+    } catch (ClientProtocolException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    } catch (IOException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+    
+    File sdCard = Environment.getExternalStorageDirectory();
+    File dir = new File (sdCard.getAbsolutePath() + "/owncloud");
+    dir.mkdirs();
+    File file = new File(dir, "filename");
+
+    try {
+      FileOutputStream f = new FileOutputStream(file);
+      byte[] b = new byte[(int)response.getEntity().getContentLength()];
+      response.getEntity().getContent().read(b);
+      f.write(b);
+    } catch (FileNotFoundException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    } catch (IllegalStateException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    } catch (IOException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+    
+    
+    return START_NOT_STICKY;
+  }
+
+}
index 522257e..212a6f2 100644 (file)
@@ -21,7 +21,6 @@ package eu.alefzero.owncloud;
 import java.io.File;
 
 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
 import java.io.File;
 
 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 eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
 import android.accounts.Account;
 import android.accounts.AccountManager;
@@ -30,14 +29,10 @@ import android.content.Intent;
 import android.database.Cursor;
 import android.database.DataSetObserver;
 import android.net.Uri;
 import android.database.Cursor;
 import android.database.DataSetObserver;
 import android.net.Uri;
-import android.provider.MediaStore.Images.Media;
-import android.sax.StartElementListener;
 import android.text.TextUtils;
 import android.text.TextUtils;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.View.OnClickListener;
 import android.widget.ImageView;
 import android.widget.ListAdapter;
 import android.widget.TextView;
 import android.widget.ImageView;
 import android.widget.ListAdapter;
 import android.widget.TextView;
index 2eb478a..614058b 100644 (file)
 
 package eu.alefzero.owncloud;
 
 
 package eu.alefzero.owncloud;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.util.LinkedList;
 import java.util.Stack;
 
 import java.util.LinkedList;
 import java.util.Stack;
 
@@ -36,6 +40,7 @@ import android.graphics.BitmapFactory;
 import android.graphics.Matrix;
 import android.net.Uri;
 import android.os.Bundle;
 import android.graphics.Matrix;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Environment;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Menu;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Menu;
@@ -276,13 +281,33 @@ public class OwnCloudMainScreen extends ListActivity {
       try {
         Intent i = (Intent) getListAdapter().getItem(position);
         if (i.hasExtra("toDownload")) {
       try {
         Intent i = (Intent) getListAdapter().getItem(position);
         if (i.hasExtra("toDownload")) {
+          
+          Uri data = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath() + "/owncloud/filename");
+          Log.d("DUPA", data.toString());
+          File f = new File(data.toString());
+          FileInputStream fis = new FileInputStream(f);
+          byte buffer[] = new byte[512];
+          fis.read(buffer);
+          Log.d("DUPA", new String(buffer));
+          
+          //Intent intent = new Intent(this, FileDownloader.class);
+          /*intent.putExtra(FileDownloader.EXTRA_FILE_PATH, "/docsy.py");
+          intent.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
+          startService(intent);
+          /*
           if (i.getBooleanExtra("toDownload", false)) {
             startActivityForResult(i, 200);
           } else {
             startActivity(i);            
           if (i.getBooleanExtra("toDownload", false)) {
             startActivityForResult(i, 200);
           } else {
             startActivity(i);            
-          }
+          }*/
         }
         }
-      } catch (ClassCastException e) {}
+      } catch (ClassCastException e) {} catch (FileNotFoundException e) {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      } catch (IOException e) {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      }
     }
   }
   
     }
   }
   
diff --git a/src/eu/alefzero/owncloud/OwnCloudUploader.java b/src/eu/alefzero/owncloud/OwnCloudUploader.java
deleted file mode 100644 (file)
index 5f2c194..0000000
+++ /dev/null
@@ -1,495 +0,0 @@
-package eu.alefzero.owncloud;
-
-import java.io.File;
-import java.sql.Date;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Stack;
-
-import org.apache.http.HttpHost;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.entity.FileEntity;
-import org.apache.http.entity.mime.MultipartEntity;
-import org.apache.http.entity.mime.content.FileBody;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.protocol.BasicHttpContext;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.ListActivity;
-import android.app.ProgressDialog;
-import android.app.AlertDialog.Builder;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Parcelable;
-import android.provider.MediaStore.Images.Media;
-import android.util.Log;
-import android.view.View;
-import android.view.Window;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.AdapterView;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.SimpleCursorAdapter;
-import android.widget.Toast;
-import android.widget.AdapterView.OnItemClickListener;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.db.ProviderMeta;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-import eu.alefzero.webdav.HttpMkCol;
-import eu.alefzero.webdav.WebdavUtils;
-
-public class OwnCloudUploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {
-  private static final String TAG = "ownCloudUploader";
-
-  private Account mAccount;
-  private AccountManager mAccountManager;
-  private String mUsername, mPassword;
-  private Cursor mCursor;
-  private Stack<String> mParents;
-  private Thread mUploadThread;
-  private Handler mHandler;
-  private ArrayList<Parcelable> mStreamsToUpload;
-
-  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<String>();
-    mHandler = new Handler();
-    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);
-        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");
-        }
-        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];
-            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) {
-      showDialog(DIALOG_WAITING);
-      mUploadThread = new Thread(new BackgroundUploader(mPath+mDirname.getText().toString(), mStreamsToUpload, mHandler, true));
-      mUploadThread.start();
-    }
-  }
-  
-  @Override
-  public void onBackPressed() {
-    
-    if (mParents.size()==0) {
-      super.onBackPressed();
-      return;
-    } else if (mParents.size() == 1) {
-      mParents.pop();
-      mCursor = managedQuery(ProviderTableMeta.CONTENT_URI,
-          null,
-          ProviderTableMeta.FILE_CONTENT_TYPE+"=?",
-          new String[]{"DIR"},
-          null);
-    } else {
-      mParents.pop();
-      mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()),
-          null,
-          ProviderTableMeta.FILE_CONTENT_TYPE+"=?",
-          new String[]{"DIR"},
-          null);
-    }
-    
-    SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout,
-                                   mCursor,
-                                   new String[]{ProviderTableMeta.FILE_NAME},
-                                   new int[]{R.id.textView1});
-    setListAdapter(sca);
-  }
-  
-  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-    if (!mCursor.moveToPosition(position)) {
-      throw new IndexOutOfBoundsException("Incorrect item selected");
-    }
-    String _id = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));
-    mParents.push(_id);
-    
-    mCursor.close();
-    mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, _id),
-                           null,
-                           ProviderTableMeta.FILE_CONTENT_TYPE+"=?",
-                           new String[]{"DIR"},
-                           null);
-    SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout,
-                                                      mCursor,
-                                                      new String[]{ProviderTableMeta.FILE_NAME},
-                                                      new int[]{R.id.textView1});
-    setListAdapter(sca);
-    getListView().invalidate();
-  }
-
-  public void onClick(View v) {
-    switch (v.getId()) {
-      case R.id.uploader_choose_folder:
-        String pathToUpload = null;
-        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");
-        }
-        
-        showDialog(DIALOG_WAITING);
-        mUploadThread = new Thread(new BackgroundUploader(pathToUpload, mStreamsToUpload, mHandler));
-        mUploadThread.start();
-        
-        break;
-      case android.R.id.button1: // dynamic action for create aditional dir
-        showDialog(DIALOG_GET_DIRNAME);
-        break;
-      default:
-        throw new IllegalArgumentException("Wrong element clicked");
-    }
-  }
-
-  public void onUploadComplete(boolean uploadSucc, String message) {
-    dismissDialog(DIALOG_WAITING);
-    Log.i(TAG, "UploadSucc: " + uploadSucc + " message: " + message);
-    if (uploadSucc) {
-      Toast.makeText(this, getResources().getString(R.string.uploader_upload_succeed), Toast.LENGTH_SHORT).show();
-    } else {
-      Toast.makeText(this, getResources().getString(R.string.uploader_upload_failed) + message, Toast.LENGTH_LONG).show();
-    }
-    finish();
-  }
-  
-  @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() {
-    mUsername = mAccount.name.substring(0, mAccount.name.indexOf('@'));
-    mPassword = mAccountManager.getPassword(mAccount);
-    setContentView(R.layout.uploader_layout);
-    mCursor = managedQuery(ProviderMeta.ProviderTableMeta.CONTENT_URI,
-                           null,
-                           ProviderTableMeta.FILE_CONTENT_TYPE+"=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
-                           new String[]{"DIR", mAccount.name},
-                           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);
-    // 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<Parcelable>();
-      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 PartialupdateUpload(String fileLocalPath, String filename, String filepath, String contentType, String contentLength) {
-    ContentValues cv = new ContentValues();
-    cv.put(ProviderTableMeta.FILE_NAME, filename);
-    cv.put(ProviderTableMeta.FILE_PATH, filepath);
-    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, fileLocalPath);
-    cv.put(ProviderTableMeta.FILE_MODIFIED, WebdavUtils.DISPLAY_DATE_FORMAT.format(new java.util.Date()));
-    cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, contentType);
-    cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, contentLength);
-    cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
-    Log.d(TAG, filename+" ++ "+filepath+" ++ " + contentLength + " ++ " + contentType + " ++ " + fileLocalPath);
-    if (!mParents.empty()) {
-      Cursor c = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()),
-                              null,
-                              null,
-                              null,
-                              null);
-      c.moveToFirst();
-      cv.put(ProviderTableMeta.FILE_PARENT, c.getString(c.getColumnIndex(ProviderTableMeta._ID)));
-      c.close();
-    }
-    getContentResolver().insert(ProviderTableMeta.CONTENT_URI_FILE, cv);
-  }
-  
-  class BackgroundUploader implements Runnable {
-    private ArrayList<Parcelable> mUploadStreams;
-    private Handler mHandler;
-    private String mUploadPath;
-    private boolean mCreateDir;
-    
-    public BackgroundUploader(String pathToUpload, ArrayList<Parcelable> streamsToUpload,
-        Handler handler) {
-      mUploadStreams = streamsToUpload;
-      mHandler = handler;
-      mUploadPath = pathToUpload.replace(" ", "%20");
-      mCreateDir = false;
-    }
-
-    public BackgroundUploader(String pathToUpload, ArrayList<Parcelable> streamsToUpload,
-                              Handler handler, boolean createDir) {
-      mUploadStreams = streamsToUpload;
-      mHandler = handler;
-      mUploadPath = pathToUpload.replace(" ", "%20");
-      mCreateDir = createDir;
-    }
-
-    public void run() {
-      boolean any_failed = false;
-      DefaultHttpClient httpClient = new DefaultHttpClient();
-      Uri uri = Uri.parse(mAccountManager.getUserData(mAccount,
-          AccountAuthenticator.KEY_OC_URL));
-      httpClient.getCredentialsProvider().setCredentials(
-          new AuthScope(uri.getHost(), (uri.getPort() == -1) ? 80 : uri
-              .getPort()),
-          new UsernamePasswordCredentials(mUsername, mPassword));
-      BasicHttpContext httpContext = new BasicHttpContext();
-      BasicScheme basicAuth = new BasicScheme();
-      httpContext.setAttribute("preemptive-auth", basicAuth);
-      HttpHost targetHost = new HttpHost(uri.getHost(), (uri.getPort() == -1)
-          ? 80
-          : uri.getPort(), (uri.getScheme() == "https") ? "https" : "http");
-
-      // create last directory in path if nessesary
-      if (mCreateDir) {
-        HttpMkCol method = new HttpMkCol(uri.toString() + mUploadPath + "/");
-        method.setHeader("User-Agent", "Android-ownCloud");
-        try {
-          httpClient.execute(targetHost, method, httpContext);
-          Log.i(TAG, "Creating dir completed");
-        } catch (final Exception e) {
-          e.printStackTrace();
-          mHandler.post(new Runnable() {
-            public void run() {
-              OwnCloudUploader.this.onUploadComplete(false, e.getLocalizedMessage());
-            }
-          });
-          return;
-        }
-      }
-      
-      for (int i = 0; i < mUploadStreams.size(); ++i) {
-        final Cursor c = getContentResolver().query((Uri)mUploadStreams.get(i), null, null, null, null);
-        c.moveToFirst();
-
-        HttpPut method = new HttpPut(uri.toString() + mUploadPath + "/"
-            + c.getString(c.getColumnIndex(Media.DISPLAY_NAME)).replace(" ", "%20"));
-        method.setHeader("Content-type", c.getString(c.getColumnIndex(Media.MIME_TYPE)));
-        method.setHeader("User-Agent", "Android-ownCloud");
-
-        try {
-          FileBody fb = new FileBody(new File(c.getString(c.getColumnIndex(Media.DATA))), c.getString(c.getColumnIndex(Media.MIME_TYPE)));
-          MultipartEntity entity = new MultipartEntity();
-          final FileEntity fileEntity = new FileEntity(new File(c.getString(c.getColumnIndex(Media.DATA))),
-               c.getString(c.getColumnIndex(Media.MIME_TYPE)));
-
-          entity.addPart(c.getString(c.getColumnIndex(Media.DISPLAY_NAME)).replace(" ", "%20"), fb);
-
-          method.setEntity(fileEntity);
-          Log.i(TAG, "executing:" + method.getRequestLine().toString());
-
-          httpClient.execute(targetHost, method, httpContext);
-          mHandler.post(new Runnable() {
-            public void run() {
-              OwnCloudUploader.this.PartialupdateUpload(c.getString(c.getColumnIndex(Media.DATA)),
-                                                        c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
-                                                        mUploadPath + (mUploadPath.equals("/")?"":"/"),
-                                                        fileEntity.getContentType().getValue(),
-                                                        fileEntity.getContentLength()+"");
-            }
-          });
-          Log.i(TAG, "Uploading, done");
-
-        } catch (final Exception e) {
-          any_failed = true;
-          mHandler.post(new Runnable() {
-            public void run() {
-              OwnCloudUploader.this.onUploadComplete(false, c.getString(c.getColumnIndex(Media.DISPLAY_NAME))+ " " + e.getLocalizedMessage());
-            }
-          });
-        }
-      }
-      if (!any_failed) {
-        mHandler.post(new Runnable() {
-          public void run() {
-            OwnCloudUploader.this.onUploadComplete(true, "Success");
-          }
-        });
-      }
-      Bundle bundle = new Bundle();
-      bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
-      //ContentResolver.requestSync(mAccount, AccountAuthenticator.AUTH_TOKEN_TYPE, bundle);
-
-    }
-
-  }
-  
-}
diff --git a/src/eu/alefzero/owncloud/Uploader.java b/src/eu/alefzero/owncloud/Uploader.java
new file mode 100644 (file)
index 0000000..66dec56
--- /dev/null
@@ -0,0 +1,423 @@
+package eu.alefzero.owncloud;
+
+import java.util.ArrayList;
+import java.util.Stack;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ListActivity;
+import android.app.ProgressDialog;
+import android.app.AlertDialog.Builder;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Parcelable;
+import android.provider.MediaStore.Images.Media;
+import android.util.Log;
+import android.view.View;
+import android.view.Window;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.Toast;
+import android.widget.AdapterView.OnItemClickListener;
+import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
+import eu.alefzero.owncloud.db.ProviderMeta;
+import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
+import eu.alefzero.webdav.WebdavUtils;
+
+public class Uploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {
+  private static final String TAG = "ownCloudUploader";
+
+  private Account mAccount;
+  private AccountManager mAccountManager;
+  private String mUsername, mPassword;
+  private Cursor mCursor;
+  private Stack<String> mParents;
+  private Thread mUploadThread;
+  private Handler mHandler;
+  private ArrayList<Parcelable> mStreamsToUpload;
+
+  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<String>();
+    mHandler = new Handler();
+    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);
+        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");
+        }
+        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];
+            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) {
+      showDialog(DIALOG_WAITING);
+      mUploadThread = new Thread(new BackgroundUploader(mPath+mDirname.getText().toString(), mStreamsToUpload, mHandler, true));
+      mUploadThread.start();
+    }
+  }
+  
+  @Override
+  public void onBackPressed() {
+    
+    if (mParents.size()==0) {
+      super.onBackPressed();
+      return;
+    } else if (mParents.size() == 1) {
+      mParents.pop();
+      mCursor = managedQuery(ProviderTableMeta.CONTENT_URI,
+          null,
+          ProviderTableMeta.FILE_CONTENT_TYPE+"=?",
+          new String[]{"DIR"},
+          null);
+    } else {
+      mParents.pop();
+      mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()),
+          null,
+          ProviderTableMeta.FILE_CONTENT_TYPE+"=?",
+          new String[]{"DIR"},
+          null);
+    }
+    
+    SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout,
+                                   mCursor,
+                                   new String[]{ProviderTableMeta.FILE_NAME},
+                                   new int[]{R.id.textView1});
+    setListAdapter(sca);
+  }
+  
+  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+    if (!mCursor.moveToPosition(position)) {
+      throw new IndexOutOfBoundsException("Incorrect item selected");
+    }
+    String _id = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));
+    mParents.push(_id);
+    
+    mCursor.close();
+    mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, _id),
+                           null,
+                           ProviderTableMeta.FILE_CONTENT_TYPE+"=?",
+                           new String[]{"DIR"},
+                           null);
+    SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout,
+                                                      mCursor,
+                                                      new String[]{ProviderTableMeta.FILE_NAME},
+                                                      new int[]{R.id.textView1});
+    setListAdapter(sca);
+    getListView().invalidate();
+  }
+
+  public void onClick(View v) {
+    switch (v.getId()) {
+      case R.id.uploader_choose_folder:
+        String pathToUpload = null;
+        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");
+        }
+        
+        showDialog(DIALOG_WAITING);
+        mUploadThread = new Thread(new BackgroundUploader(pathToUpload, mStreamsToUpload, mHandler));
+        mUploadThread.start();
+        
+        break;
+      case android.R.id.button1: // dynamic action for create aditional dir
+        showDialog(DIALOG_GET_DIRNAME);
+        break;
+      default:
+        throw new IllegalArgumentException("Wrong element clicked");
+    }
+  }
+
+  public void onUploadComplete(boolean uploadSucc, String message) {
+    dismissDialog(DIALOG_WAITING);
+    Log.i(TAG, "UploadSucc: " + uploadSucc + " message: " + message);
+    if (uploadSucc) {
+      Toast.makeText(this, getResources().getString(R.string.uploader_upload_succeed), Toast.LENGTH_SHORT).show();
+    } else {
+      Toast.makeText(this, getResources().getString(R.string.uploader_upload_failed) + message, Toast.LENGTH_LONG).show();
+    }
+    finish();
+  }
+  
+  @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() {
+    mUsername = mAccount.name.substring(0, mAccount.name.indexOf('@'));
+    mPassword = mAccountManager.getPassword(mAccount);
+    setContentView(R.layout.uploader_layout);
+    mCursor = managedQuery(ProviderMeta.ProviderTableMeta.CONTENT_URI,
+                           null,
+                           ProviderTableMeta.FILE_CONTENT_TYPE+"=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+                           new String[]{"DIR", mAccount.name},
+                           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);
+    // 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<Parcelable>();
+      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 PartialupdateUpload(String fileLocalPath, String filename, String filepath, String contentType, String contentLength) {
+    ContentValues cv = new ContentValues();
+    cv.put(ProviderTableMeta.FILE_NAME, filename);
+    cv.put(ProviderTableMeta.FILE_PATH, filepath);
+    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, fileLocalPath);
+    cv.put(ProviderTableMeta.FILE_MODIFIED, WebdavUtils.DISPLAY_DATE_FORMAT.format(new java.util.Date()));
+    cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, contentType);
+    cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, contentLength);
+    cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
+    Log.d(TAG, filename+" ++ "+filepath+" ++ " + contentLength + " ++ " + contentType + " ++ " + fileLocalPath);
+    if (!mParents.empty()) {
+      Cursor c = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()),
+                              null,
+                              null,
+                              null,
+                              null);
+      c.moveToFirst();
+      cv.put(ProviderTableMeta.FILE_PARENT, c.getString(c.getColumnIndex(ProviderTableMeta._ID)));
+      c.close();
+    }
+    getContentResolver().insert(ProviderTableMeta.CONTENT_URI_FILE, cv);
+  }
+  
+  class BackgroundUploader implements Runnable {
+    private ArrayList<Parcelable> mUploadStreams;
+    private Handler mHandler;
+    private String mUploadPath;
+    private boolean mCreateDir;
+    
+    public BackgroundUploader(String pathToUpload, ArrayList<Parcelable> streamsToUpload,
+        Handler handler) {
+      mUploadStreams = streamsToUpload;
+      mHandler = handler;
+      mUploadPath = pathToUpload.replace(" ", "%20");
+      mCreateDir = false;
+    }
+
+    public BackgroundUploader(String pathToUpload, ArrayList<Parcelable> streamsToUpload,
+                              Handler handler, boolean createDir) {
+      mUploadStreams = streamsToUpload;
+      mHandler = handler;
+      mUploadPath = pathToUpload.replace(" ", "%20");
+      mCreateDir = createDir;
+    }
+
+    public void run() {
+      WebdavClient wdc = new WebdavClient(Uri.parse(mAccountManager.getUserData(mAccount,
+          AccountAuthenticator.KEY_OC_URL)));
+      wdc.setCredentials(mUsername, mPassword);
+      wdc.allowUnsignedCertificates();
+
+      // create last directory in path if nessesary
+      if (mCreateDir) {
+        wdc.createDirectory(mUploadPath);
+      }
+      
+      for (int i = 0; i < mUploadStreams.size(); ++i) {
+        final Cursor c = getContentResolver().query((Uri) mUploadStreams.get(i), null, null, null, null);
+        c.moveToFirst();
+        
+        if (!wdc.putFile(c.getString(c.getColumnIndex(Media.DATA)),
+                         mUploadPath+"/"+c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
+                         c.getString(c.getColumnIndex(Media.MIME_TYPE)))) {
+          mHandler.post(new Runnable() {
+            public void run() {
+              Uploader.this.onUploadComplete(false, "Error while uploading file: " + c.getString(c.getColumnIndex(Media.DISPLAY_NAME)));
+            }
+          });
+        }
+      }
+      mHandler.post(new Runnable() {
+        public void run() {
+          Uploader.this.onUploadComplete(true, null);
+        }
+      });
+    }
+
+  }
+  
+}
diff --git a/src/eu/alefzero/owncloud/WebdavClient.java b/src/eu/alefzero/owncloud/WebdavClient.java
new file mode 100644 (file)
index 0000000..9ff1ed9
--- /dev/null
@@ -0,0 +1,146 @@
+package eu.alefzero.owncloud;
+
+import java.io.File;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpVersion;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.params.ConnManagerPNames;
+import org.apache.http.conn.params.ConnPerRouteBean;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.entity.FileEntity;
+import org.apache.http.entity.mime.content.FileBody;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.protocol.BasicHttpContext;
+
+import eu.alefzero.owncloud.authenticator.EasySSLSocketFactory;
+import eu.alefzero.webdav.HttpMkCol;
+
+import android.net.Uri;
+import android.util.Log;
+
+public class WebdavClient {
+  private DefaultHttpClient mHttpClient;
+  private BasicHttpContext mHttpContext;
+  private HttpHost mTargetHost;
+  private SchemeRegistry mSchemeRegistry;
+  private Uri mUri;
+  final private static String TAG = "WebdavClient";
+  
+  WebdavClient(Uri uri) {
+    mUri = uri;
+    mSchemeRegistry = new SchemeRegistry();
+    setupHttpClient();
+  }
+  
+  void setCredentials(String username, String password) {
+    // determine default port for http or https
+    int targetPort = mTargetHost.getPort() == -1 ? 
+                        ( mUri.getScheme().equals("https") ? 443 : 80)
+                        : mUri.getPort();
+
+    mHttpClient.getCredentialsProvider().setCredentials(
+        new AuthScope(mUri.getHost(), targetPort), 
+        new UsernamePasswordCredentials(username, password));
+    BasicScheme basicAuth = new BasicScheme();
+    mHttpContext.setAttribute("preemptive-auth", basicAuth);
+  }
+  
+  void allowUnsignedCertificates() {
+    // https
+    mSchemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
+  }
+  
+  boolean downloadFile(String filepath) {
+    return true;
+  }
+  
+  void getFileList(String dirPath) {
+    
+  }
+  
+  boolean putFile(String localFile,
+                  String remoteTarget,
+                  String contentType) {
+    boolean result = true;
+    HttpPut method = new HttpPut(mUri.toString() + remoteTarget.replace(" ", "%20"));
+    method.setHeader("Content-type", contentType);
+    method.setHeader("Host", mUri.getHost());
+    method.setHeader("User-Agent", "Android-ownCloud");
+
+    try {
+      FileBody fb = new FileBody(new File(localFile, contentType));
+      final FileEntity fileEntity = new FileEntity(new File(localFile), contentType);
+
+      method.setEntity(fileEntity);
+      Log.i(TAG, "executing:" + method.getRequestLine().toString());
+
+      mHttpClient.execute(mTargetHost, method, mHttpContext);
+      /*mHandler.post(new Runnable() {
+      public void run() {
+        Uploader.this.PartialupdateUpload(c.getString(c.getColumnIndex(Media.DATA)),
+                                                  c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
+                                                  mUploadPath + (mUploadPath.equals("/")?"":"/"),
+                                                  fileEntity.getContentType().getValue(),
+                                                  fileEntity.getContentLength()+"");
+      }
+    });
+    Log.i(TAG, "Uploading, done");
+*/
+      Log.i(TAG, "Uploading, done");
+    } catch (final Exception e) {
+      Log.i(TAG, e.getLocalizedMessage());
+      result = false;
+    }
+    
+    return result;
+  }
+  
+  public boolean createDirectory(String path) {
+    HttpMkCol method = new HttpMkCol(mUri.toString() + path + "/");
+    method.setHeader("User-Agent", "Android-ownCloud");
+    
+    try {
+      mHttpClient.execute(mTargetHost, method, mHttpContext);
+      Log.i(TAG, "Creating dir completed");
+    } catch (final Exception e) {
+      e.printStackTrace();
+      return false;
+    }
+    return true;
+  }
+  
+  private void setupHttpClient() {
+    // http scheme
+    mSchemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+    mSchemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
+    
+    HttpParams params = new BasicHttpParams();
+    params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
+    params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
+    params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
+    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+
+    mHttpContext = new BasicHttpContext();
+    ClientConnectionManager cm = new ThreadSafeClientConnManager(params, mSchemeRegistry);
+
+    int port = mUri.getPort() == -1 ? 
+                 mUri.getScheme().equals("https") ? 443 : 80
+               : mUri.getPort();
+    
+    mTargetHost = new HttpHost(mUri.getHost(), port, mUri.getScheme());
+    
+    mHttpClient = new DefaultHttpClient(cm, params);
+  }
+}
index e4396a4..c506886 100644 (file)
@@ -22,17 +22,51 @@ import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.UnknownHostException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
 
 
+import javax.net.SocketFactory;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import javax.security.cert.CertificateException;
+import javax.security.cert.X509Certificate;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+
+import org.apache.http.impl.client.DefaultHttpClient;
+
+import org.apache.commons.httpclient.auth.BasicScheme;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.UsernamePasswordCredentials;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.methods.HttpHead;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.UsernamePasswordCredentials;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.methods.HttpHead;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.conn.params.ConnManagerPNames;
+import org.apache.http.conn.params.ConnPerRouteBean;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.impl.conn.SingleClientConnManager;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.BasicHttpContext;
 
 import org.apache.http.protocol.BasicHttpContext;
 
+
 import android.content.Context;
 import android.os.Handler;
 import android.util.Log;
 import android.content.Context;
 import android.os.Handler;
 import android.util.Log;
@@ -103,10 +137,25 @@ public class AuthUtils {
     sendResult(false, handler, context, "Server error: " + mResultMsg);
     return false;
   }
     sendResult(false, handler, context, "Server error: " + mResultMsg);
     return false;
   }
-
+  
   public static boolean tryGetWebdav(URL url, String username, String pwd,
                                      Handler handler, Context context) {
   public static boolean tryGetWebdav(URL url, String username, String pwd,
                                      Handler handler, Context context) {
-    DefaultHttpClient c = new DefaultHttpClient();
+    SchemeRegistry schemeRegistry = new SchemeRegistry();
+ // http scheme
+ schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+ // https scheme
+ schemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
+
+ HttpParams params = new BasicHttpParams();
+ params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
+ params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
+ params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
+ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+
+ ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
+    
+    DefaultHttpClient c = new DefaultHttpClient(cm, params);
+    
     c.getCredentialsProvider().setCredentials(
         new AuthScope(url.getHost(), (url.getPort() == -1)?80:url.getPort()), 
         new UsernamePasswordCredentials(username, pwd));
     c.getCredentialsProvider().setCredentials(
         new AuthScope(url.getHost(), (url.getPort() == -1)?80:url.getPort()), 
         new UsernamePasswordCredentials(username, pwd));
@@ -117,8 +166,9 @@ public class AuthUtils {
     localcontext.setAttribute("preemptive-auth", basicAuth);
     HttpHost targetHost = new HttpHost(url.getHost(), (url.getPort() == -1)
         ? 80
     localcontext.setAttribute("preemptive-auth", basicAuth);
     HttpHost targetHost = new HttpHost(url.getHost(), (url.getPort() == -1)
         ? 80
-        : url.getPort(), (url.getProtocol() == "https") ? "https" : "http");
+        : url.getPort(), (url.getProtocol().equals("https")) ? "https" : "http");
     HttpHead httpget = new HttpHead(url.toString());
     HttpHead httpget = new HttpHead(url.toString());
+    httpget.setHeader("Host", url.getHost());
     HttpResponse response = null;
     try {
       response = c.execute(targetHost, httpget, localcontext);
     HttpResponse response = null;
     try {
       response = c.execute(targetHost, httpget, localcontext);
@@ -134,6 +184,7 @@ public class AuthUtils {
       return false;
     }
     String status = response.getStatusLine().toString();
       return false;
     }
     String status = response.getStatusLine().toString();
+
     status = status.split(" ")[1];
     Log.i("AuthUtils", "Status returned: " + status);
     if (status.equals("200")) {
     status = status.split(" ")[1];
     Log.i("AuthUtils", "Status returned: " + status);
     if (status.equals("200")) {
diff --git a/src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java b/src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java
new file mode 100644 (file)
index 0000000..f057b8b
--- /dev/null
@@ -0,0 +1,138 @@
+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.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManager;
+
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.conn.scheme.LayeredSocketFactory;
+import org.apache.http.conn.scheme.SocketFactory;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+
+/**
+ * This socket factory will create ssl socket that accepts self signed
+ * certificate
+ * 
+ * @author olamy
+ * @version $Id: EasySSLSocketFactory.java 765355 2009-04-15 20:59:07Z evenisse
+ *          $
+ * @since 1.2.3
+ */
+public class EasySSLSocketFactory implements SocketFactory,
+    LayeredSocketFactory {
+
+  private SSLContext sslcontext = null;
+
+  private static SSLContext createEasySSLContext() throws IOException {
+    try {
+      SSLContext context = SSLContext.getInstance("TLS");
+      context.init(null, new TrustManager[] { new EasyX509TrustManager(
+          null) }, null);
+      return context;
+    } catch (Exception e) {
+      throw new IOException(e.getMessage());
+    }
+  }
+
+  private SSLContext getSSLContext() throws IOException {
+    if (this.sslcontext == null) {
+      this.sslcontext = createEasySSLContext();
+    }
+    return this.sslcontext;
+  }
+
+  /**
+   * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
+   *      java.lang.String, int, java.net.InetAddress, int,
+   *      org.apache.http.params.HttpParams)
+   */
+  public Socket connectSocket(Socket sock, String host, int port,
+      InetAddress localAddress, int localPort, HttpParams params)
+      throws IOException, UnknownHostException, ConnectTimeoutException {
+    int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
+    int soTimeout = HttpConnectionParams.getSoTimeout(params);
+
+    InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
+    SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
+
+    if ((localAddress != null) || (localPort > 0)) {
+      // we need to bind explicitly
+      if (localPort < 0) {
+        localPort = 0; // indicates "any"
+      }
+      InetSocketAddress isa = new InetSocketAddress(localAddress,
+          localPort);
+      sslsock.bind(isa);
+    }
+
+    sslsock.connect(remoteAddress, connTimeout);
+    sslsock.setSoTimeout(soTimeout);
+    return sslsock;
+
+  }
+
+  /**
+   * @see org.apache.http.conn.scheme.SocketFactory#createSocket()
+   */
+  public Socket createSocket() throws IOException {
+    return getSSLContext().getSocketFactory().createSocket();
+  }
+
+  /**
+   * @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
+   */
+  public boolean isSecure(Socket socket) throws IllegalArgumentException {
+    return true;
+  }
+
+  /**
+   * @see org.apache.http.conn.scheme.LayeredSocketFactory#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);
+  }
+
+  // -------------------------------------------------------------------
+  // javadoc in org.apache.http.conn.scheme.SocketFactory says :
+  // Both Object.equals() and Object.hashCode() must be overridden
+  // for the correct operation of some connection managers
+  // -------------------------------------------------------------------
+
+  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
new file mode 100644 (file)
index 0000000..d6323bb
--- /dev/null
@@ -0,0 +1,93 @@
+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/cp2.java b/src/eu/alefzero/owncloud/cp2.java
deleted file mode 100644 (file)
index 9d7ba0d..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-package eu.alefzero.owncloud;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-
-public class cp2 extends ContentProvider {
-
-  @Override
-  public int delete(Uri arg0, String arg1, String[] arg2) {
-    // TODO Auto-generated method stub
-    return 0;
-  }
-
-  @Override
-  public String getType(Uri arg0) {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public Uri insert(Uri arg0, ContentValues arg1) {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public boolean onCreate() {
-    // TODO Auto-generated method stub
-    return false;
-  }
-
-  @Override
-  public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
-      String arg4) {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
-    // TODO Auto-generated method stub
-    return 0;
-  }
-
-}
diff --git a/src/eu/alefzero/owncloud/syncadapter/ContactSyncAdapter.java b/src/eu/alefzero/owncloud/syncadapter/ContactSyncAdapter.java
deleted file mode 100644 (file)
index 61564d5..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-package eu.alefzero.owncloud.syncadapter;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import android.accounts.AccountManager;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.entity.ByteArrayEntity;
-
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.webdav.HttpPropFind;
-
-import android.accounts.Account;
-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 static final String TAG = "ContactSyncAdapter";
-
-    public ContactSyncAdapter(Context context, boolean autoInitialize) {
-        super(context, autoInitialize);
-    }
-
-    @Override
-    public synchronized void onPerformSync(
-            Account account, 
-            Bundle extras, 
-            String authority, 
-            ContentProviderClient provider, 
-            SyncResult syncResult) {
-
-        this.setAccount(account);
-        this.setContentProvider(provider);
-
-        // TODO find all contacts on ownCloud that not synced or the sync date is behind than the last sync date
-        Cursor cursor = getContacts();
-        if (cursor != null && cursor.getCount() > 0) {
-            while (cursor.moveToNext()) {
-                String id = cursor.getString(
-                        cursor.getColumnIndex(ContactsContract.Contacts._ID));
-                String lookup = cursor.getString(
-                        cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
-
-                try {
-                    FileInputStream fis = getContactVcard(lookup);
-                    
-                    HttpPut query = new HttpPut(
-                        getUri() + 
-                        "/addressbooks/"+
-                        getAccount().name.split("@")[0]+
-                        "/default/"+
-                        lookup+
-                        ".vcf"
-                    );
-                    byte[] b = new byte[fis.available()];
-                    fis.read(b);
-                    query.setEntity(new ByteArrayEntity(b));
-                    HttpResponse response = fireRawRequest(query);
-                    if(201 != response.getStatusLine().getStatusCode()) {
-                        syncResult.stats.numIoExceptions++;
-                    }
-                    // TODO make a webdav request based on the stream
-                    // TODO send request to the ownCloud server
-                    // TODO mark the current contact as synced - where to store?
-                    fis.close();
-                } catch (IOException e) {
-                    syncResult.stats.numIoExceptions++;
-                } catch (OperationCanceledException e) {
-                    //TODO maybe to a better break here
-                    return;
-                } catch (AuthenticatorException e) {
-                    syncResult.stats.numAuthExceptions++;
-                }
-            }
-        }
-    }
-
-    protected Uri getUri() {
-        Uri uri = Uri.parse(this.getAccountManager().getUserData(getAccount(), AccountAuthenticator.KEY_CONTACT_URL));
-        return uri;
-    }
-
-   /**
-     * Returns the vCard based on the LookupKey for Contact as Stream 
-     * 
-     * @param lookupKey
-     * @return
-     * @throws IOException
-     */
-    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();
-    }
-
-    /**
-     * Obtains the contact list.
-     *
-     * @return A cursor for for accessing the contact list.
-     */
-    private Cursor getContacts()
-    {
-        // Run query
-        Uri uri = ContactsContract.Contacts.CONTENT_URI;
-        String[] projection = new String[] {
-                ContactsContract.Contacts._ID,
-                ContactsContract.Contacts.LOOKUP_KEY
-        };
-
-        boolean showInvisible = false;
-        String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" + 
-                (showInvisible ? "0" : "1") + "'";
-        String[] selectionArgs = null;
-        String sortOrder = ContactsContract.Contacts._ID + " DESC";
-
-        return getContext().getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
-    }
-
-
-
-}
diff --git a/src/eu/alefzero/owncloud/syncadapter/ContactSyncService.java b/src/eu/alefzero/owncloud/syncadapter/ContactSyncService.java
deleted file mode 100644 (file)
index 2dd7661..0000000
+++ /dev/null
@@ -1,31 +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 concretSyncAdapter = null;
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public void onCreate() {
-        synchronized (syncAdapterLock) {
-            if (concretSyncAdapter == null) {
-                concretSyncAdapter = new ContactSyncAdapter(getApplicationContext(), true);
-            }
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public IBinder onBind(Intent intent) {
-        return concretSyncAdapter.getSyncAdapterBinder();
-    }
-
-}