Browse Source

adjusting design to holo, stability for account setup

Bartek Przybylski 13 năm trước cách đây
mục cha
commit
0aeb425885
81 tập tin đã thay đổi với 2436 bổ sung1022 xóa
  1. 30 9
      AndroidManifest.xml
  2. 2 2
      proguard.cfg
  3. BIN
      res/drawable-hdpi/ic_action_refresh.png
  4. BIN
      res/drawable-hdpi/ic_action_refresh_black.png
  5. BIN
      res/drawable-hdpi/ic_action_search.png
  6. BIN
      res/drawable-hdpi/ic_action_upload.png
  7. BIN
      res/drawable-ldpi/ic_action_refresh.png
  8. BIN
      res/drawable-ldpi/ic_action_refresh_black.png
  9. BIN
      res/drawable-ldpi/ic_action_search.png
  10. BIN
      res/drawable-ldpi/ic_action_upload.png
  11. BIN
      res/drawable-mdpi/ic_action_refresh.png
  12. BIN
      res/drawable-mdpi/ic_action_refresh_black.png
  13. BIN
      res/drawable-mdpi/ic_action_search.png
  14. BIN
      res/drawable-mdpi/ic_action_upload.png
  15. BIN
      res/drawable/common_error.png
  16. 13 0
      res/drawable/connection_secure.xml
  17. BIN
      res/drawable/ic_ok.png
  18. 29 0
      res/drawable/icon_list_selector.xml
  19. 29 0
      res/drawable/list_selector.xml
  20. BIN
      res/drawable/local_file_indicator.png
  21. BIN
      res/drawable/logo_inverted.png
  22. 3 2
      res/drawable/main_header_bg.xml
  23. BIN
      res/drawable/no_network.png
  24. 11 0
      res/drawable/progress_small.xml
  25. BIN
      res/drawable/spinner_inner.png
  26. 1 1
      res/drawable/uploader_list_separator.xml
  27. 176 0
      res/layout-land/account_setup.xml
  28. 31 23
      res/layout-large-land/files.xml
  29. 173 163
      res/layout/account_setup.xml
  30. 32 0
      res/layout/authenticator_getting_started_fragment.xml
  31. 35 0
      res/layout/extensions_available_dialog.xml
  32. 17 0
      res/layout/file_activity_details.xml
  33. 17 0
      res/layout/file_details_empty.xml
  34. 17 0
      res/layout/file_details_fragment.xml
  35. 17 0
      res/layout/file_display_action_list_element.xml
  36. 28 9
      res/layout/files.xml
  37. 17 0
      res/layout/landing_page_fragment.xml
  38. 17 0
      res/layout/landing_page_item.xml
  39. 69 14
      res/layout/list_layout.xml
  40. 17 0
      res/layout/main.xml
  41. 13 0
      res/layout/pick_account_layout.xml
  42. 13 0
      res/layout/selected_account_element.xml
  43. 17 0
      res/layout/uploader_layout.xml
  44. 17 0
      res/layout/uploader_list_item_layout.xml
  45. 6 0
      res/menu/account_picker.xml
  46. 5 3
      res/menu/menu.xml
  47. 6 0
      res/values/colors.xml
  48. 28 9
      res/values/strings.xml
  49. 6 0
      res/values/styles.xml
  50. 31 4
      src/eu/alefzero/owncloud/AccountUtils.java
  51. 1 1
      src/eu/alefzero/owncloud/FileDownloader.java
  52. 0 1
      src/eu/alefzero/owncloud/Uploader.java
  53. 240 195
      src/eu/alefzero/owncloud/authenticator/AccountAuthenticator.java
  54. 5 6
      src/eu/alefzero/owncloud/authenticator/AuthenticationRunnable.java
  55. 162 0
      src/eu/alefzero/owncloud/authenticator/ConnectionCheckerRunnable.java
  56. 206 113
      src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java
  57. 20 0
      src/eu/alefzero/owncloud/authenticator/OnConnectCheckListener.java
  58. 21 11
      src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java
  59. 1 1
      src/eu/alefzero/owncloud/db/ProviderMeta.java
  60. 17 0
      src/eu/alefzero/owncloud/extensions/ExtensionsAvailableActivity.java
  61. 48 0
      src/eu/alefzero/owncloud/extensions/ExtensionsAvailableDialog.java
  62. 116 0
      src/eu/alefzero/owncloud/extensions/ExtensionsListActivity.java
  63. 2 16
      src/eu/alefzero/owncloud/syncadapter/AbstractOwnCloudSyncAdapter.java
  64. 2 1
      src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java
  65. 11 1
      src/eu/alefzero/owncloud/ui/FragmentListView.java
  66. 117 0
      src/eu/alefzero/owncloud/ui/activity/AccountSelectActivity.java
  67. 214 100
      src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java
  68. 93 36
      src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java
  69. 3 6
      src/eu/alefzero/owncloud/ui/adapter/FileListActionListAdapter.java
  70. 19 2
      src/eu/alefzero/owncloud/ui/adapter/FileListListAdapter.java
  71. 7 0
      src/eu/alefzero/owncloud/ui/fragment/AuthenticatorAccountDetailsFragment.java
  72. 7 0
      src/eu/alefzero/owncloud/ui/fragment/AuthenticatorGetStartedFragment.java
  73. 15 1
      src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java
  74. 80 0
      src/eu/alefzero/owncloud/utils/OwnCloudVersion.java
  75. 15 17
      src/eu/alefzero/owncloud/widgets/ActionEditText.java
  76. 53 0
      src/eu/alefzero/webdav/FileRequestEntity.java
  77. 0 36
      src/eu/alefzero/webdav/HttpMkCol.java
  78. 0 49
      src/eu/alefzero/webdav/HttpPropFind.java
  79. 0 43
      src/eu/alefzero/webdav/HttpPropPatch.java
  80. 37 103
      src/eu/alefzero/webdav/WebdavClient.java
  81. 1 44
      src/eu/alefzero/webdav/WebdavUtils.java

+ 30 - 9
AndroidManifest.xml

@@ -1,8 +1,24 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="eu.alefzero.owncloud"
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
+<manifest package="eu.alefzero.owncloud"
     android:versionCode="1"
-    android:versionName="1.0" >
+    android:versionName="1.0" xmlns:android="http://schemas.android.com/apk/res/android">
 
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />
@@ -15,6 +31,7 @@
     <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 
     <uses-sdk
         android:minSdkVersion="8"
@@ -27,11 +44,12 @@
 
     <application
         android:icon="@drawable/icon"
-        android:label="@string/app_name" >
+        android:label="@string/app_name"
+        android:theme="@style/Theme.ownCloud"
+        android:uiOptions="splitActionBarWhenNarrow"> 
         <activity
             android:name=".ui.activity.FileDisplayActivity"
-            android:label="@string/app_name"
-            android:theme="@style/Theme.ownCloud" >
+            android:label="@string/app_name">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 
@@ -69,7 +87,7 @@
 
         <service
             android:name=".authenticator.AccountAuthenticatorService"
-            android:exported="true" >
+            android:exported="true">
             <intent-filter>
                 <action android:name="android.accounts.AccountAuthenticator" />
             </intent-filter>
@@ -102,7 +120,7 @@
         <activity
             android:name=".ui.activity.AuthenticatorActivity"
             android:exported="true"
-            android:theme="@style/Theme.ownCloud" >
+            android:theme="@style/Theme.ownCloud.noActionBar" >
         </activity>
 
         <service android:name=".FileDownloader" >
@@ -125,7 +143,10 @@
         <activity
             android:name=".ui.activity.FileDetailActivity"
             android:theme="@style/Theme.ownCloud" >
-        </activity>
+        </activity>
+        <activity android:name=".extensions.ExtensionsAvailableActivity"></activity>
+        <activity android:name=".extensions.ExtensionsListActivity"></activity>
+        <activity android:name=".ui.activity.AccountSelectActivity" android:uiOptions="none" android:label="@string/prefs_accounts"></activity>
     </application>
 
 </manifest>

+ 2 - 2
proguard.cfg

@@ -18,11 +18,11 @@
     native <methods>;
 }
 
--keepclasseswithmembernames class * {
+-keepclasseswithmembers class * {
     public <init>(android.content.Context, android.util.AttributeSet);
 }
 
--keepclasseswithmembernames class * {
+-keepclasseswithmembers class * {
     public <init>(android.content.Context, android.util.AttributeSet, int);
 }
 

BIN
res/drawable-hdpi/ic_action_refresh.png


BIN
res/drawable-hdpi/ic_action_refresh_black.png


BIN
res/drawable-hdpi/ic_action_search.png


BIN
res/drawable-hdpi/ic_action_upload.png


BIN
res/drawable-ldpi/ic_action_refresh.png


BIN
res/drawable-ldpi/ic_action_refresh_black.png


BIN
res/drawable-ldpi/ic_action_search.png


BIN
res/drawable-ldpi/ic_action_upload.png


BIN
res/drawable-mdpi/ic_action_refresh.png


BIN
res/drawable-mdpi/ic_action_refresh_black.png


BIN
res/drawable-mdpi/ic_action_search.png


BIN
res/drawable-mdpi/ic_action_upload.png


BIN
res/drawable/common_error.png


+ 13 - 0
res/drawable/connection_secure.xml

@@ -0,0 +1,13 @@
+<!--?xml version="1.0" encoding="utf-8"? -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+	<gradient android:endColor="#8dc73f" android:centerColor="#d4d4d4"
+		android:startColor="#d4d4d4">
+		<stroke android:width="1dp" color="#8dc73f">
+			<corners android:radius="5dp">
+				<padding android:left="7dp" android:top="7dp" android:right="7dp"
+					android:bottom="7dp">
+				</padding>
+			</corners>
+		</stroke>
+	</gradient>
+</shape>

BIN
res/drawable/ic_ok.png


+ 29 - 0
res/drawable/icon_list_selector.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2010 The Android Open Source Project
+
+     Licensed 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+
+    <item android:drawable="@color/filelist_backgorund" android:state_window_focused="false"/>
+
+    <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
+    <item android:drawable="@android:color/holo_blue_bright" android:state_enabled="false" android:state_focused="true" android:state_pressed="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_enabled="false" android:state_focused="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_focused="true" android:state_pressed="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_focused="false" android:state_pressed="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_focused="true"/>
+
+</selector>

+ 29 - 0
res/drawable/list_selector.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2010 The Android Open Source Project
+
+     Licensed 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+
+    <item android:drawable="@color/filelist_backgorund" android:state_window_focused="false"/>
+
+    <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
+    <item android:drawable="@android:color/holo_blue_bright" android:state_enabled="false" android:state_focused="true" android:state_pressed="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_enabled="false" android:state_focused="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_focused="true" android:state_pressed="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_focused="false" android:state_pressed="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_focused="true"/>
+
+</selector>

BIN
res/drawable/local_file_indicator.png


BIN
res/drawable/logo_inverted.png


+ 3 - 2
res/drawable/main_header_bg.xml

@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <gradient 
-        android:startColor="#1D2D55" 
+    <gradient
+        android:startColor="#1D2D44"
+        android:centerColor="#1D2D55" 
         android:endColor="#1D2D44"
         android:angle="270"
      />

BIN
res/drawable/no_network.png


+ 11 - 0
res/drawable/progress_small.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/spinner_inner"
+    android:pivotX="50%"
+    android:pivotY="50%" 
+    android:fromDegrees="0"
+    android:toDegrees="360"
+    android:interpolator="@android:anim/linear_interpolator"
+    android:duration="1000"
+    android:startOffset="0"/>

BIN
res/drawable/spinner_inner.png


+ 1 - 1
res/drawable/uploader_list_separator.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <shape
   xmlns:android="http://schemas.android.com/apk/res/android">
-    <gradient android:startColor="#fefefe" android:centerColor="#cccccc" android:endColor="#fefefe" android:angle="0"/>
+    <gradient android:startColor="@color/filelist_icon_backgorund" android:endColor="@color/filelist_icon_backgorund" android:angle="0"/>
 </shape>

+ 176 - 0
res/layout-land/account_setup.xml

@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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 <http://www.gnu.org/licenses/>.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:oc="http://schemas.android.com/apk/res/eu.alefzero.owncloud"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:focusable="true"
+    android:gravity="center|fill"
+    android:orientation="vertical" >
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:layout_marginLeft="16dip"
+        android:layout_marginRight="16dip"
+        android:layout_weight="1" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" >
+
+            <ImageView
+                android:id="@+id/imageView1"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_margin="7dp"
+                android:layout_weight="1"
+                android:src="@drawable/logo_inverted" />
+
+            <LinearLayout
+                android:id="@+id/LinearLayout1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:layout_weight="1"
+                android:orientation="vertical" >
+
+                <FrameLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1" >
+
+                    <EditText
+                        android:id="@+id/host_URL"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_weight="1"
+                        android:ems="10"
+                        android:hint="@string/auth_host_url"
+                        android:singleLine="true" >
+
+                        <requestFocus />
+                    </EditText>
+
+                    <ImageView
+                        android:id="@+id/refreshButton"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="right|center_vertical"
+                        android:src="@drawable/ic_action_refresh_black"
+                        android:visibility="invisible" />
+                </FrameLayout>
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="50dp"
+                    android:layout_weight="1" >
+
+                    <ImageView
+                        android:id="@+id/action_indicator"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp"
+                        android:src="@android:drawable/stat_notify_sync"
+                        android:visibility="invisible" />
+
+                    <TextView
+                        android:id="@+id/status_text"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="TextView"
+                        android:visibility="invisible" />
+                </LinearLayout>
+
+                <TextView
+                    android:id="@+id/textView2"
+                    android:layout_width="wrap_content"
+                    android:layout_height="0dp"
+                    android:layout_weight="1"
+                    android:text="@string/auth_login_details"
+                    android:textAppearance="?android:attr/textAppearanceSmall" />
+
+                <EditText
+                    android:id="@+id/account_username"
+                    android:layout_width="match_parent"
+                    android:layout_height="0dp"
+                    android:layout_weight="1"
+                    android:ems="10"
+                    android:hint="@string/auth_username"
+                    android:singleLine="true" />
+
+                <FrameLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1" >
+
+                    <EditText
+                        android:id="@+id/account_password"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_weight="1"
+                        android:ems="10"
+                        android:hint="@string/auth_password"
+                        android:inputType="textPassword"
+                        android:singleLine="true" />
+
+                    <ImageView
+                        android:id="@+id/viewPassword"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="right|center_vertical"
+                        android:src="@android:drawable/ic_menu_view"
+                        android:visibility="invisible" />
+                </FrameLayout>
+            </LinearLayout>
+        </LinearLayout>
+    </FrameLayout>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:weightSum="1" >
+
+            <Button
+                android:id="@+id/buttonCancel"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight=".5"
+                android:text="@string/common_cancel" />
+
+            <Button
+                android:id="@+id/buttonOK"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight=".5"
+                android:enabled="false"
+                android:onClick="onOkClick"
+                android:text="@string/setup_btn_connect"
+                android:textColor="@android:color/black" />
+        </LinearLayout>
+    </RelativeLayout>
+
+</LinearLayout>

+ 31 - 23
res/layout-large-land/files.xml

@@ -1,32 +1,40 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
-    android:background="#F7F7F7"
-    android:orientation="vertical" >
+    android:orientation="horizontal" >
 
     <LinearLayout
-        android:id="@+id/linearLayout1"
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:orientation="horizontal" >
-
-        <LinearLayout
-            android:id="@+id/file_list_container"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content" 
-            android:layout_weight="1">
-        </LinearLayout>
-
-        <fragment
-            android:id="@+id/fileDetail"
-            android:layout_width="0dp"
-            android:layout_height="fill_parent"
-            android:layout_weight="2"
-            class="eu.alefzero.owncloud.ui.fragment.FileDetail" >
-
-            <!-- Preview: layout=@layout/file_details -->
-        </fragment>
+        android:id="@+id/file_list_container"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1" >
     </LinearLayout>
 
+    <fragment
+        android:id="@+id/fileDetail"
+        android:layout_width="0dp"
+        android:layout_height="fill_parent"
+        android:layout_weight="2"
+        class="eu.alefzero.owncloud.ui.fragment.FileDetail" >
+        <!-- Preview: layout=@layout/file_details -->
+    </fragment>
+
 </LinearLayout>

+ 173 - 163
res/layout/account_setup.xml

@@ -1,167 +1,177 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:oc="http://schemas.android.com/apk/res/eu.alefzero.owncloud"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:background="#F7F7F7"
-    android:focusable="true"
-    android:orientation="vertical" >
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ownCloud Android client application
 
-    <LinearLayout
-        android:id="@+id/linearLayout7"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="top"
-        android:background="#1D2D44"
-        android:gravity="center_vertical|top"
-        android:orientation="vertical"
-        android:paddingBottom="2pt"
-        android:paddingTop="2pt" >
+  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.
 
-        <ImageView
-            android:id="@+id/main_header_small"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center|center_vertical|center_horizontal"
-            android:focusable="true"
-            android:src="@drawable/owncloud_logo_small_white" >
-        </ImageView>
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/linearLayout2"
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:layout_gravity="center|center_vertical"
-        android:gravity="center_vertical"
-        android:orientation="vertical" >
-
-        <TableLayout
-            android:id="@+id/tableLayout1"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center_horizontal" >
-
-            <TableRow
-                android:id="@+id/tableRow1"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:gravity="center_horizontal" >
-
-                <TextView
-                    android:id="@+id/textView1"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginBottom="15dip"
-                    android:layout_marginTop="15dip"
-                    android:text="@string/setup_title"
-                    android:textColor="@android:color/black"
-                    android:textSize="7pt"
-                    android:textStyle="bold" >
-                </TextView>
-            </TableRow>
-
-            <TableRow
-                android:id="@+id/tableRow2"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:gravity="center_horizontal"
-                android:weightSum="1.0" >
-


-                <eu.alefzero.owncloud.widgets.ActionEditText
-                    android:id="@+id/host_URL"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_weight="0.75"
-                    android:hint="@string/setup_hint_address"
-                    android:inputType="textUri"
-                    android:textColor="@android:color/black"
-                    android:singleLine="true"
-                    oc:optionOneString="SSL"
-                    oc:optionTwoString="NO SSL"
-                    oc:optionOneColor="#00ff00"
-                    oc:optionTwoColor="#ff0000"
-                    oc:onBadgeClick="sslBadgeClick">
-
-                    <requestFocus>
-                    </requestFocus>
-                </eu.alefzero.owncloud.widgets.ActionEditText>
-            </TableRow>
-
-            <TableRow
-                android:id="@+id/tableRow3"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:gravity="center_horizontal"
-                android:weightSum="1.0" >
-

-                <EditText
-                    android:id="@+id/account_username"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_weight=".75"
-                    android:hint="@string/setup_hint_username"
-                    android:singleLine="true"
-                    android:textColor="@android:color/black" >
-
-                </EditText>
-            </TableRow>
-
-            <TableRow
-                android:id="@+id/tableRow4"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:gravity="center_horizontal"
-                android:weightSum="1.0" >
-

-                <eu.alefzero.owncloud.widgets.ActionEditText
-                    android:id="@+id/account_password"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_weight=".75"
-                    android:hint="@string/setup_hint_password"
-                    android:inputType="textPassword"
-                    android:singleLine="true"
-                    android:textColor="@android:color/black" 
-                    oc:optionOneString="Show"
-                    oc:optionTwoString="Hide"
-                    oc:optionOneColor="#00ff00"
-                    oc:optionTwoColor="#ff0000"
-                    oc:onBadgeClick="passwordBadgeClick">
-
-                </eu.alefzero.owncloud.widgets.ActionEditText>
-            </TableRow>
-        </TableLayout>
-
-        <LinearLayout
-            android:id="@+id/linearLayout1"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center_horizontal"
-            android:orientation="vertical"
-            android:weightSum="1.0" >
-
-            <Button
-                android:id="@+id/buttonOK"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight=".75"
-                android:onClick="onOkClick"
-                android:textColor="@android:color/black"
-                android:text="@string/setup_btn_connect" >
-            </Button>
-<!-- 
-            <Button
-                android:id="@+id/buttonNotUser"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight=".75"
-                android:onClick="onNotUserClick"
-                android:textColor="@android:color/black"
-                android:text="Get started!" >
-            </Button>
--->       
-        </LinearLayout>
-    </LinearLayout>
+  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 <http://www.gnu.org/licenses/>.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:oc="http://schemas.android.com/apk/res/eu.alefzero.owncloud"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:focusable="true"
+    android:gravity="center|fill"
+    android:orientation="vertical" >
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:layout_marginLeft="16dip"
+        android:layout_marginRight="16dip"
+        android:layout_weight="1" >
+
+        <LinearLayout
+            android:id="@+id/LinearLayout1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_weight="1"
+            android:orientation="vertical" >
+
+            <ImageView
+                android:id="@+id/imageView1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginBottom="10dp"
+                android:layout_weight="1"
+                android:src="@drawable/logo_inverted" />
+
+            <FrameLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" >
+
+                <EditText
+                    android:id="@+id/host_URL"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:ems="10"
+                    android:hint="@string/auth_host_url"
+                    android:singleLine="true" >
+
+                    <requestFocus />
+                </EditText>
+
+                <ImageView
+                    android:id="@+id/refreshButton"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:src="@drawable/ic_action_refresh_black"
+                    android:layout_gravity="right|center_vertical"
+                    android:visibility="invisible" />
+
+            </FrameLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="50dp"
+                android:layout_weight="1" >
+
+                <ImageView
+                    android:id="@+id/action_indicator"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="5dp"
+                    android:layout_marginRight="5dp"
+                    android:src="@android:drawable/stat_notify_sync"
+                    android:visibility="invisible" />
+
+                <TextView
+                    android:id="@+id/status_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="TextView"
+                    android:visibility="invisible" />
+
+            </LinearLayout>
+
+            <TextView
+                android:id="@+id/textView2"
+                android:layout_width="wrap_content"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:text="@string/auth_login_details"
+                android:textAppearance="?android:attr/textAppearanceSmall" />
+
+            <EditText
+                android:id="@+id/account_username"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:ems="10"
+                android:singleLine="true"
+                android:hint="@string/auth_username" />
+
+            <FrameLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" >
+
+                <EditText
+                    android:id="@+id/account_password"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:ems="10"
+                    android:hint="@string/auth_password"
+                    android:inputType="textPassword"
+                    android:singleLine="true" />
+
+                <ImageView
+                    android:id="@+id/viewPassword"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="right|center_vertical"
+                    android:src="@android:drawable/ic_menu_view"
+                    android:visibility="invisible" />
+
+            </FrameLayout>
+
+        </LinearLayout>
+
+    </FrameLayout>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:weightSum="1" >
+
+            <Button
+                android:id="@+id/buttonCancel"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight=".5"
+                android:text="@string/common_cancel" />
+
+            <Button
+                android:id="@+id/buttonOK"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight=".5"
+                android:enabled="false"
+                android:onClick="onOkClick"
+                android:text="@string/setup_btn_connect"
+                android:textColor="@android:color/black" />
+
+        </LinearLayout>
+    </RelativeLayout>
+
 </LinearLayout>

+ 32 - 0
res/layout/authenticator_getting_started_fragment.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#F7F7F7"
+    android:focusable="true"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/textView1"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="Large Text"/>
+
+</LinearLayout>

+ 35 - 0
res/layout/extensions_available_dialog.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/extensions_avail"
+    android:layout_width="wrap_content" android:layout_height="wrap_content"
+    android:layout_gravity="center" android:orientation="vertical"  >
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_margin="7dp"
+        android:text="@string/extensions_avail_message" />
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_margin="5dp"
+        android:weightSum="1.0" >
+
+        <Button
+            android:id="@+id/buttonNo"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/common_no"
+            android:layout_weight="0.5"/>
+
+        <Button
+            android:id="@+id/buttonYes"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/common_yes"
+            android:layout_weight="0.5"/>
+
+    </LinearLayout>
+    
+</LinearLayout>

+ 17 - 0
res/layout/file_activity_details.xml

@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"

+ 17 - 0
res/layout/file_details_empty.xml

@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"

+ 17 - 0
res/layout/file_details_fragment.xml

@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"

+ 17 - 0
res/layout/file_display_action_list_element.xml

@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 	android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center_horizontal" android:gravity="center_horizontal">
 	<ImageView android:layout_width="wrap_content"

+ 28 - 9
res/layout/files.xml

@@ -1,14 +1,33 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
-    android:background="#F7F7F7"
-        android:orientation="vertical" >
-       <fragment
-                android:id="@+id/fileList"
-                android:layout_width="fill_parent"
-                android:layout_height="fill_parent"
-                class="eu.alefzero.owncloud.ui.fragment.FileListFragment" >
-                <!-- Preview: layout=@layout/list_layout -->
-            </fragment>
+    android:orientation="vertical" >
+
+    <fragment
+        android:id="@+id/fileList"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        class="eu.alefzero.owncloud.ui.fragment.FileListFragment" >
+
+        <!-- Preview: layout=@layout/list_layout -->
+    </fragment>
+
 </LinearLayout>

+ 17 - 0
res/layout/landing_page_fragment.xml

@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/linearLayout1"
     android:layout_width="fill_parent"

+ 17 - 0
res/layout/landing_page_item.xml

@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent" >

+ 69 - 14
res/layout/list_layout.xml

@@ -1,17 +1,72 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-	android:orientation="horizontal"
-	android:id="@+id/ListItemLayout" android:layout_width="fill_parent"
-	android:background="#F7F7F7" android:layout_height="wrap_content">
-	<ImageView android:layout_width="wrap_content" android:src="@drawable/ic_menu_archive"
-		android:id="@+id/imageView1" android:layout_height="wrap_content"
-		android:layout_marginLeft="15dip" android:focusable="false"
-		android:focusableInTouchMode="false"></ImageView>
-	<TextView android:layout_height="wrap_content"
-		android:textColor="#303030" android:layout_width="wrap_content"
-		android:text="TextView" android:layout_marginLeft="5dip"
-		android:layout_marginBottom="5dip" android:layout_marginRight="30dip"
-		android:id="@+id/Filename" android:focusable="false"
-    android:focusableInTouchMode="false" android:textSize="20dip">
-	</TextView>
+    android:id="@+id/ListItemLayout"
+    android:layout_width="fill_parent"
+    android:background="@drawable/list_selector"
+    android:orientation="horizontal"
+    android:layout_height="56dp">
+
+    <FrameLayout
+        android:layout_width="56dp"
+        android:layout_height="56dp"
+        android:focusable="false"
+        android:focusableInTouchMode="false">
+        
+        <ImageView
+            android:id="@+id/imageView2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/local_file_indicator"/>
+
+        <ImageView
+            android:id="@+id/imageView1"
+            android:layout_width="wrap_content"
+            android:layout_height="48dp"
+            android:layout_gravity="center_vertical"
+            android:layout_margin="4dp"
+            android:src="@drawable/ic_menu_archive" />
+        
+    </FrameLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent" >
+
+        <TextView
+            android:id="@+id/Filename"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="4dp"
+            android:text="TextView"
+            android:textColor="#303030"
+            android:textSize="20dip" />
+
+        <TextView
+            android:id="@+id/Extension"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:text="TextView"
+            android:textColor="#D0D0D0"
+            android:textSize="20dip" />
+    </LinearLayout>
+
 </LinearLayout>

+ 17 - 0
res/layout/main.xml

@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"

+ 13 - 0
res/layout/pick_account_layout.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal" >
+
+    <TextView
+        android:id="@+id/textView1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="TextView" />
+
+</LinearLayout>

+ 13 - 0
res/layout/selected_account_element.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/textView1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="TextView" />
+
+</LinearLayout>

+ 17 - 0
res/layout/uploader_layout.xml

@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 	android:layout_height="wrap_content" android:orientation="vertical"
 	android:layout_width="wrap_content" android:background="#fefefe"

+ 17 - 0
res/layout/uploader_list_item_layout.xml

@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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 <http://www.gnu.org/licenses/>.
+ -->
 <LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"

+ 6 - 0
res/menu/account_picker.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+    <item android:id="@+id/createAccount" android:title="Create Account" android:showAsAction="ifRoom|withText"></item>
+    
+
+</menu>

+ 5 - 3
res/menu/menu.xml

@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <menu
   xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:title="Settings" android:icon="@android:drawable/ic_menu_preferences" android:id="@+id/settingsItem"></item>
-    <item android:id="@+id/createDirectoryItem" android:title="Create Directory" android:icon="@android:drawable/ic_menu_add"></item>
-    <item android:id="@+id/startSync" android:title="Sync account"></item>
+    <item android:id="@+id/startSync" android:title="Sync account" android:showAsAction="ifRoom" android:icon="@drawable/ic_action_refresh"></item><item android:title="Settings" android:icon="@android:drawable/ic_menu_preferences" android:id="@+id/settingsItem" android:showAsAction="never"></item>
+    <item android:id="@+id/createDirectoryItem" android:title="Create Directory" android:icon="@android:drawable/ic_menu_add" android:showAsAction="ifRoom"></item>
+    
+    <item android:id="@+id/search" android:icon="@drawable/ic_action_search" android:showAsAction="ifRoom"></item>
+    <item android:id="@+id/action_upload" android:icon="@drawable/ic_action_upload" android:showAsAction="ifRoom"></item>
 </menu>

+ 6 - 0
res/values/colors.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="filelist_icon_backgorund">#DDDDDD</color>
+    <color name="filelist_backgorund">#F7F7F7</color>
+    
+</resources>

+ 28 - 9
res/values/strings.xml

@@ -17,7 +17,6 @@
     
     <string name="prefs_category_general">General</string>
     <string name="prefs_category_trackmydevice">Device tracking</string>
-    <string name="prefs_sessions">Stored sessions</string>
     <string name="prefs_add_session">Add new session</string>
     <string name="prefs_create_img_thumbnails">Create image thumbnails</string>
     <string name="prefs_select_oc_account">Select an account</string>
@@ -27,13 +26,11 @@
     <string name="prefs_trackmydevice_summary_on">Your ownCloud keeps track of this device</string>
     <string name="prefs_trackmydevice_interval">Update intervall</string>
     <string name="prefs_trackmydevice_interval_summary">Update every %1$s minutes</string>
+    <string name="prefs_accounts">Accounts</string>
     
-    <string name="new_session_id">Session Name</string>
-    <string name="new_session_url">URL</string>
-    <string name="new_session_username">Username</string>
-    <string name="new_session_password">Password</string>
-    <string name="new_session_save">OK</string>
-    <string name="new_session_cancel">Cancel</string>
+    <string name="auth_host_url">ownCloud location</string>
+    <string name="auth_username">Username</string>
+    <string name="auth_password">Password</string>
     <string name="new_session_uri_error">Wrong URL given</string>
     <string name="new_session_session_name_error">Wrong session name</string>
     <string name="sync_string_files">Files</string>
@@ -52,6 +49,8 @@
     <string name="uploader_info_uploading">Uploading</string>
     <string name="uploader_btn_create_dir_text">Create dir for upload</string>
     <string name="filedetails_select_file">Tap on a file to display additional information.</string>
+    <string name="common_yes">Yes</string>
+    <string name="common_no">No</string>
     <string name="common_ok">OK</string>
     <string name="common_cancel">Cancel</string>
     <string name="uploader_info_dirname">Directory name</string>
@@ -73,6 +72,26 @@
     	<item>30</item>
     	<item>60</item>
 	</string-array>
-    <string name="auth_trying_to_login">Trying to login</string>
-    <string name="auth_no_ssl">No SSL</string>
+    <string name="auth_trying_to_login">Trying to login…</string>
+    <string name="auth_no_net_conn_title">No network connection</string>
+    <string name="auth_no_net_conn_message">No network connection have been detected, check your Internet connection and try again.</string>
+    <string name="auth_connect_anyway">Connect anyway</string>
+    <string name="auth_nossl_plain_ok_title">Secure connection unavailable.</string>
+    <string name="auth_nossl_plain_ok_message">Application couldn\'t etablish secure connection to server. Although non secure connection is available. You may continue or cancel.</string>
+    <string name="auth_connection_established">Connection established</string>
+    <string name="auth_testing_connection">Testing connection…</string>
+    <string name="auth_not_configured_title">Malformed ownCloud configuration</string>
+    <string name="auth_not_configured_message">It seems that your ownCloud intance is not correctly configured. Contact your administrator for more details.</string>
+    <string name="auth_unknown_error_title">Unknown error occurred</string>
+    <string name="auth_unknown_error_message">Unknown error occurred. Please contact authors and include logs from your device.</string>
+    <string name="auth_unknow_host_title">Can\'t establish connection</string>
+    <string name="auth_unknow_host_message">Coundn\'t establish connection to host. Please check hostname and server availability and try again.</string>
+    <string name="auth_incorrect_path_title">ownCloud intance not found</string>
+    <string name="auth_incorrect_path_message">Application couldn\'t find ownClound instance at given path. Please check your path and try again.</string>
+    <string name="auth_secure_connection">Secure connection established</string>
+    <string name="auth_unknow_error">Unknown error occured!</string>
+    <string name="auth_login_details">Login details</string>
+    
+    <string name="extensions_avail_title">Extensions available!</string>
+    <string name="extensions_avail_message">Looks like your ownCloud instance is supporting advanced extensions. Would you like to see extensions available for android ?</string>
 </resources>

+ 6 - 0
res/values/styles.xml

@@ -7,6 +7,12 @@
     	<item name="android:actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
     	<item name="actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
 	</style>
+	
+	<style name="Theme.ownCloud.noActionBar" parent="style/Theme.Sherlock.Light.NoActionBar">
+      <item name="android:actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
+      <item name="actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
+  </style>
+	
 
 	<style name="Theme.ownCloud.Widget.ActionBar" parent="style/Widget.Sherlock.Light.ActionBar.Solid.Inverse">
     	<item name="android:background">@drawable/main_header_bg</item>

+ 31 - 4
src/eu/alefzero/owncloud/AccountUtils.java

@@ -1,5 +1,5 @@
 /* ownCloud Android client application
- *   Copyright (C) 2011  Bartek Przybylski
+ *   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
@@ -19,6 +19,7 @@
 package eu.alefzero.owncloud;
 
 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
+import eu.alefzero.owncloud.utils.OwnCloudVersion;
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
@@ -29,15 +30,18 @@ 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/webdav.php";
   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 null, if there is none yet.
+   * @return The current account or first available, if none is available, then null.
    */
-  public static Account getCurrentOwnCloudAccount(Context context){
+  public static Account getCurrentOwnCloudAccount(Context context) {
 	  Account[] ocAccounts = AccountManager.get(context).getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
 	  Account defaultAccount = null;
 	  
@@ -58,4 +62,27 @@ public class AccountUtils {
 	  
 	return defaultAccount;
   }
+  
+  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;
+  }
+
 }

+ 1 - 1
src/eu/alefzero/owncloud/FileDownloader.java

@@ -8,7 +8,6 @@ import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
-import android.content.BroadcastReceiver;
 import android.content.ContentValues;
 import android.content.Intent;
 import android.net.Uri;
@@ -105,6 +104,7 @@ public class FileDownloader extends Service {
     dir.mkdirs();
     File file = new File(dir, mFilePath.replace('/', '.'));
     
+    Log.e(TAG, file.getAbsolutePath() + " " + oc_url.toString());
     wdc.downloadFile(mFilePath, file);
     ContentValues cv = new ContentValues();
     cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getAbsolutePath());

+ 0 - 1
src/eu/alefzero/owncloud/Uploader.java

@@ -436,7 +436,6 @@ public class Uploader extends ListActivity implements OnItemClickListener, andro
         Uri uri = (Uri) mUploadStreams.get(i);
         if (uri.getScheme().equals("content")) {
           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)),

+ 240 - 195
src/eu/alefzero/owncloud/authenticator/AccountAuthenticator.java

@@ -1,3 +1,21 @@
+/* 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
 package eu.alefzero.owncloud.authenticator;
 
 import eu.alefzero.owncloud.ui.activity.AuthenticatorActivity;
@@ -8,225 +26,252 @@ import android.os.Bundle;
 import android.util.Log;
 
 public class AccountAuthenticator extends AbstractAccountAuthenticator {
-    public static final String OPTIONS_USERNAME = "username";
-    public static final String OPTIONS_PASSWORD = "password";
-
-    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";
-    public static final String KEY_OC_URL = "oc_url";
-    public static final String KEY_CONTACT_URL = "oc_contact_url";
-
-    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(getClass().getName(), "Adding account with type " + accountType +
-                " and auth token " + authTokenType);
-        try {
-            validateAccountType(accountType);
-            //validateAuthTokenType(authTokenType);
-            validateRequiredFeatures(requiredFeatures);
-        } catch (AuthenticatorException e) {
-            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);
-        Log.i(getClass().getName(), intent.toString());
-        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) {
-            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) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Bundle getAuthToken(AccountAuthenticatorResponse response,
-                               Account account, String authTokenType, Bundle options)
-            throws NetworkErrorException {
-        Log.i(getClass().getName(), "Getting authToken");
-        try {
-            validateAccountType(account.type);
-            validateAuthTokenType(authTokenType);
-        } catch (AuthenticatorException e) {
-            Log.w(getClass().getName(), "Validating failded in getAuthToken");
-            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;
+  /**
+   * 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();
     }
-
-    @Override
-    public String getAuthTokenLabel(String authTokenType) {
-        return null;
+    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();
     }
-
-    @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;
+    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();
     }
-
-    @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;
+    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;
     }
 
-    @Override
-    public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response,
-                                           Account account) throws NetworkErrorException {
-        return super.getAccountRemovalAllowed(response, account);
+    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 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 validateAuthTokenType(String authTokenType)
+      throws UnsupportedAuthTokenTypeException {
+    if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {
+      throw new UnsupportedAuthTokenTypeException();
     }
+  }
 
-    private void validateAccountType(String type) throws UnsupportedAccountTypeException {
-        if (!type.equals(ACCOUNT_TYPE)) {
-            throw new UnsupportedAccountTypeException();
-        }
-    }
+  public static class AuthenticatorException extends Exception {
+    private static final long serialVersionUID = 1L;
+    private Bundle mFailureBundle;
 
-    private void validateAuthTokenType(String authTokenType) throws UnsupportedAuthTokenTypeException {
-        if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {
-            throw new UnsupportedAuthTokenTypeException();
-        }
+    public AuthenticatorException(int code, String errorMsg) {
+      mFailureBundle = new Bundle();
+      mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);
+      mFailureBundle.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
     }
 
-    private void validateRequiredFeatures(String[] requiredFeatures) throws UnsupportedFeaturesException {
+    public Bundle getFailureBundle() {
+      return mFailureBundle;
     }
+  }
 
-    private void validateCreaditials(String username, String password, String path) throws AccessDeniedException {
+  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 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 static class UnsupportedAuthTokenTypeException
+      extends
+        AuthenticatorException {
+    private static final long serialVersionUID = 1L;
 
-        public Bundle getFailureBundle() {
-            return mFailureBundle;
-        }
+    public UnsupportedAuthTokenTypeException() {
+      super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
+          "Unsupported auth token type");
     }
+  }
 
-    public static class UnsupportedAccountTypeException extends AuthenticatorException {
-        private static final long serialVersionUID = 1L;
+  public static class UnsupportedFeaturesException
+      extends
+        AuthenticatorException {
+    public static final long serialVersionUID = 1L;
 
-        public UnsupportedAccountTypeException() {
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "Unsupported account type");
-        }
+    public UnsupportedFeaturesException() {
+      super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
+          "Unsupported features");
     }
+  }
 
-    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");
     }
 
-    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;
+    private static final long serialVersionUID = 1L;
 
-    }
+  }
 }

+ 5 - 6
src/eu/alefzero/owncloud/authenticator/AuthenticationRunnable.java

@@ -34,9 +34,7 @@ public class AuthenticationRunnable implements Runnable {
   private URL mUrl;
   private String mUsername;
   private String mPassword;
-  
-  private static final String WEBDAV_2_0_PATH = "/files/webdav.php";
-  
+
   public AuthenticationRunnable(URL url, String username, String password) {
     mListener = null;
     mUrl = url;
@@ -51,7 +49,8 @@ public class AuthenticationRunnable implements Runnable {
   
   @Override
   public void run() {
-    Uri uri = Uri.parse(mUrl.toString() + WEBDAV_2_0_PATH);
+    Uri uri;
+    uri = Uri.parse(mUrl.toString());
     WebdavClient client = new WebdavClient(uri);
     client.setCredentials(mUsername, mPassword);
     int login_result = client.tryToLogin(); 
@@ -71,11 +70,11 @@ public class AuthenticationRunnable implements Runnable {
   }
 
   private void postResult(final boolean success, final String message) {
-    if (mHandler != null) {
+    if (mHandler != null && mListener != null) {
       mHandler.post(new Runnable() {
         @Override
         public void run() {
-          AuthenticationRunnable.this.mListener.onAuthenticationResult(success, message);
+          mListener.onAuthenticationResult(success, message);
         }
       });
     }

+ 162 - 0
src/eu/alefzero/owncloud/authenticator/ConnectionCheckerRunnable.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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package eu.alefzero.owncloud.authenticator;
+
+import java.net.ConnectException;
+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 {
+  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 = ResultType.OK;
+      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);
+        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(uri);
+    wc.allowUnsignedCertificates();
+    GetMethod get = new GetMethod(uri.toString());
+    boolean retval = false;
+    try {
+      int status = wc.executeMethod(get);
+      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) {
+        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);
+        }
+      });
+    }
+  }
+  
+}

+ 206 - 113
src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java

@@ -1,138 +1,231 @@
-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
+ * $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
+ *      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
+ * <http://www.apache.org/>.
  *
- * 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.
  */
 
+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.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;
+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;
 
 /**
- * This socket factory will create ssl socket that accepts self signed
- * certificate
+ * <p>
+ * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s 
+ * that accept self-signed certificates. 
+ * </p>
+ * <p>
+ * 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
+ * </p>
+ *
+ * <p>
+ * Example of using custom protocol socket factory for a specific host:
+ *     <pre>
+ *     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);
+ *     </pre>
+ * </p>
+ * <p>
+ * Example of using custom protocol socket factory per default instead of the standard one:
+ *     <pre>
+ *     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);
+ *     </pre>
+ * </p>
+ * 
+ * @author <a href="mailto:oleg -at- ural.ru">Oleg Kalnichevski</a>
  * 
- * @author olamy
- * @version $Id: EasySSLSocketFactory.java 765355 2009-04-15 20:59:07Z evenisse
- *          $
- * @since 1.2.3
+ * <p>
+ * 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.
+ * </p>
  */
-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());
+
+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.
+     * <p>
+     * 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}
+     * </p>
+     *  
+     * @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) {
+            return socketfactory.createSocket(host, port, localAddress, localPort);
+        } else {
+            Socket socket = socketfactory.createSocket();
+            SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
+            SocketAddress remoteaddr = new InetSocketAddress(host, port);
+            socket.bind(localaddr);
+            socket.connect(remoteaddr, timeout);
+            return socket;
+        }
     }
-  }
 
-  private SSLContext getSSLContext() throws IOException {
-    if (this.sslcontext == null) {
-      this.sslcontext = createEasySSLContext();
+    /**
+     * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
+     */
+    public Socket createSocket(String host, int port)
+        throws IOException, UnknownHostException {
+        return getSSLContext().getSocketFactory().createSocket(
+            host,
+            port
+        );
     }
-    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);
+
+    /**
+     * @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
+        );
     }
 
-    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();
-  }
+    public boolean equals(Object obj) {
+        return ((obj != null) && obj.getClass().equals(EasySSLSocketFactory.class));
+    }
+
+    public int hashCode() {
+        return EasySSLSocketFactory.class.hashCode();
+    }
 
 }

+ 20 - 0
src/eu/alefzero/owncloud/authenticator/OnConnectCheckListener.java

@@ -0,0 +1,20 @@
+package eu.alefzero.owncloud.authenticator;
+
+public interface OnConnectCheckListener {
+  
+  enum ResultType {
+    OK,
+    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);
+  
+}

+ 21 - 11
src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java

@@ -173,13 +173,21 @@ public class FileDataStorageManager implements DataStorageManager {
       
       if (getContentProvider() != null) {
         try {
-          c = getContentProvider().query(req_uri, null, null, null, null);
+          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, null, null, null);
+        c = getContentResolver().query(req_uri,
+                                       null,
+                                       ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+                                       new String[]{mAccount.name},
+                                       null);
       }
 
       if (c.moveToFirst()) {
@@ -201,22 +209,24 @@ public class FileDataStorageManager implements DataStorageManager {
     if (getContentResolver() != null) {
       c = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
                                     null,
-                                    cmp_key + "=?",
-                                    new String[] {value},
+                                    cmp_key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+                                    new String[] {value, mAccount.name},
                                     null);
     } else {
       try {
         c = getContentProvider().query(ProviderTableMeta.CONTENT_URI,
                                       null,
-                                      cmp_key + "=?",
-                                      new String[] {value},
+                                      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;
       }
     }
-    return c.moveToFirst();
+    boolean retval = c.moveToFirst();
+    c.close();
+    return retval;
   }
   
   private Cursor getCursorForValue(String key, String value) {
@@ -224,15 +234,15 @@ public class FileDataStorageManager implements DataStorageManager {
     if (getContentResolver() != null) {
       c = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
                                      null,
-                                     key + "=?",
-                                     new String[] {value},
+                                     key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+                                     new String[] {value, mAccount.name},
                                      null);
     } else {
       try {
         c = getContentProvider().query(ProviderTableMeta.CONTENT_URI,
                                        null,
-                                       key + "=?",
-                                       new String[]{value},
+                                       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());

+ 1 - 1
src/eu/alefzero/owncloud/db/ProviderMeta.java

@@ -58,7 +58,7 @@ public class ProviderMeta {
     public static final String FILE_PATH = "path";
     public static final String FILE_ACCOUNT_OWNER = "file_owner";
     
-    public static final String DEFAULT_SORT_ORDER = FILE_NAME + " asc";
+    public static final String DEFAULT_SORT_ORDER = FILE_NAME + " collate nocase asc";
 
   }
 }

+ 17 - 0
src/eu/alefzero/owncloud/extensions/ExtensionsAvailableActivity.java

@@ -0,0 +1,17 @@
+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");
+  }
+}

+ 48 - 0
src/eu/alefzero/owncloud/extensions/ExtensionsAvailableDialog.java

@@ -0,0 +1,48 @@
+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());
+    }
+  }
+
+}

+ 116 - 0
src/eu/alefzero/owncloud/extensions/ExtensionsListActivity.java

@@ -0,0 +1,116 @@
+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<HashMap<String, String>> ll = new LinkedList<HashMap<String,String>>();  
+    for (int i = 0; i < a.length(); ++i) {
+      try {
+        ExtensionApplicationEntry ela = new ExtensionApplicationEntry(((JSONObject)a.get(i)));
+        HashMap<String, String> ss = new HashMap<String, String>();
+        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; }
+  }
+}

+ 2 - 16
src/eu/alefzero/owncloud/syncadapter/AbstractOwnCloudSyncAdapter.java

@@ -22,7 +22,6 @@ import java.io.IOException;
 import java.net.UnknownHostException;
 import java.util.Date;
 
-import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.ClientProtocolException;
@@ -39,7 +38,6 @@ import android.content.Context;
 import android.net.Uri;
 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
 import eu.alefzero.owncloud.datamodel.DataStorageManager;
-import eu.alefzero.webdav.HttpPropFind;
 import eu.alefzero.webdav.WebdavClient;
 
 /**
@@ -49,8 +47,7 @@ import eu.alefzero.webdav.WebdavClient;
  * @author sassman
  * 
  */
-public abstract class AbstractOwnCloudSyncAdapter extends
-		AbstractThreadedSyncAdapter {
+public abstract class AbstractOwnCloudSyncAdapter extends AbstractThreadedSyncAdapter {
 
 	private AccountManager accountManager;
 	private Account account;
@@ -58,9 +55,7 @@ public abstract class AbstractOwnCloudSyncAdapter extends
 	private Date lastUpdated;
 	private DataStorageManager mStoreManager;
 
-	private HttpHost mHost;
 	private WebdavClient mClient = null;
-	private static String TAG = "AbstractOwnCloudSyncAdapter";
 
 	public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize) {
 		super(context, autoInitialize);
@@ -131,15 +126,6 @@ public abstract class AbstractOwnCloudSyncAdapter extends
 		};
 	}
 
-	protected HttpPropFind getPropFindQuery()
-			throws OperationCanceledException, AuthenticatorException,
-			IOException {
-		HttpPropFind query = new HttpPropFind(getUri().toString());
-		query.setHeader("Content-type", "text/xml");
-		query.setHeader("User-Agent", "Android-ownCloud");
-		return query;
-	}
-
 	protected HttpResponse fireRawRequest(HttpRequest query)
 			throws ClientProtocolException, OperationCanceledException,
 			AuthenticatorException, IOException {
@@ -171,7 +157,7 @@ public abstract class AbstractOwnCloudSyncAdapter extends
 			mClient = new WebdavClient(uri);
 			mClient.setCredentials(username, password);
 			mClient.allowUnsignedCertificates();
-			mHost = mClient.getTargetHost();
+			//mHost = mClient.getTargetHost();
 		}
 
 		return mClient;

+ 2 - 1
src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java

@@ -31,7 +31,6 @@ import android.content.ContentProviderClient;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SyncResult;
-import android.content.IntentSender.SendIntentException;
 import android.os.Bundle;
 import android.util.Log;
 import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
@@ -62,6 +61,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
 			this.setContentProvider(provider);
 			this.setStorageManager(new FileDataStorageManager(account, getContentProvider()));
 
+			Log.d("ASD", "syncing owncloud account " + account.name);
+			
 			Intent i = new Intent(FileSyncService.SYNC_MESSAGE);
 			i.putExtra(FileSyncService.IN_PROGRESS, true);
 			i.putExtra(FileSyncService.ACCOUNT_NAME, account.name);

+ 11 - 1
src/eu/alefzero/owncloud/ui/FragmentListView.java

@@ -7,17 +7,21 @@ 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 {
+public class FragmentListView extends SherlockFragment
+                              implements OnItemClickListener,
+                                         OnItemLongClickListener {
   ListView mList;
   
   @Override
   public void onCreate(Bundle savedInstanceState) {
     mList = new ListView(getActivity());
     mList.setOnItemClickListener(this);
+    mList.setOnItemLongClickListener(this);
     super.onCreate(savedInstanceState);
   }
   
@@ -38,6 +42,12 @@ public class FragmentListView extends SherlockFragment implements OnItemClickLis
   }
   
   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;
+  }
+  
   
   
 }

+ 117 - 0
src/eu/alefzero/owncloud/ui/activity/AccountSelectActivity.java

@@ -0,0 +1,117 @@
+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.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+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 {
+
+  @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();
+
+    AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
+    Account accounts[] = am.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
+    LinkedList< HashMap<String, String>> ll = new LinkedList<HashMap<String,String>>();
+    for (Account a : accounts) {
+      HashMap<String, String> h = new HashMap<String, String>();
+      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}));
+  }
+  
+  @Override
+  public boolean onCreateOptionsMenu(Menu menu) {
+    MenuInflater inflater = getSherlock().getMenuInflater();
+    inflater.inflate(eu.alefzero.owncloud.R.menu.account_picker, menu);
+    return true;
+  }
+  
+  @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);
+    Intent i = new Intent(this, FileDisplayActivity.class);
+    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;
+  }
+  
+  private class AccountCheckedSimpleAdepter extends SimpleAdapter {
+    private Account mCurrentAccount;
+    private List<? extends Map<String, ?>> mPrivateData;
+    
+    public AccountCheckedSimpleAdepter(Context context,
+                                       List<? extends Map<String, ?>> 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;
+  } 
+    
+    
+  }
+}
+

+ 214 - 100
src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java

@@ -1,5 +1,5 @@
 /* ownCloud Android client application
- *   Copyright (C) 2011  Bartek Przybylski
+ *   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
@@ -30,22 +30,27 @@ import android.content.ContentResolver;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.SharedPreferences;
-import android.graphics.Color;
 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 android.widget.Toast;
 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
@@ -53,37 +58,70 @@ import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
  * @author Bartek Przybylski
  * 
  */
-public class AuthenticatorActivity extends AccountAuthenticatorActivity implements OnAuthenticationResultListener {
+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 boolean mUseSSLConnection;
+  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";
 
-  public AuthenticatorActivity() {
-    mUseSSLConnection = true;
-  }
-
   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     getWindow().requestFeature(Window.FEATURE_NO_TITLE);
     setContentView(R.layout.account_setup);
-    if (getIntent().hasExtra(PARAM_USERNAME)) {
-      String username = getIntent().getStringExtra(PARAM_HOSTNAME);
-      TextView host_text, user_text;
-      host_text = (TextView) findViewById(R.id.host_URL);
-      user_text = (TextView) findViewById(R.id.account_username);
-      host_text.setText(host_text.getText()
-          + username.substring(username.lastIndexOf('@')));
-      user_text.setText(user_text.getText()
-          + username.substring(0, username.lastIndexOf('@') - 1));
+    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
@@ -92,20 +130,20 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity implemen
     switch (id) {
       case DIALOG_LOGIN_PROGRESS : {
         ProgressDialog working_dialog = new ProgressDialog(this);
-        dialog = working_dialog;
         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(getClass().getName(), "Login canceled");
+            Log.i(TAG, "Login canceled");
             if (mAuthThread != null) {
               mAuthThread.interrupt();
               finish();
             }
           }
         });
+        dialog = working_dialog;
         break;
       }
       default :
@@ -146,21 +184,20 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity implemen
       }
 
       final Intent intent = new Intent();
-      intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE,
-          AccountAuthenticator.ACCOUNT_TYPE);
+      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);
-      accManager.setUserData(account, AccountAuthenticator.KEY_OC_URL,
-          url.toString());
-
-      // TODO prepare this URL using a central service
+      intent.putExtra(AccountManager.KEY_AUTHTOKEN, AccountAuthenticator.ACCOUNT_TYPE);
       intent.putExtra(AccountManager.KEY_USERDATA, username);
-      accManager.setUserData(
-          account,
-          AccountAuthenticator.KEY_CONTACT_URL,
-          url.toString().replace(AccountUtils.WEBDAV_PATH_2_0,
-              AccountUtils.CARDDAV_PATH_2_0));
+
+      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);
@@ -168,96 +205,173 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity implemen
       bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
       getContentResolver().startSync(ProviderTableMeta.CONTENT_URI, bundle);
 
-      dismissDialog(0);
+      /*if (mConnChkRunnable.getDiscoveredVersion().compareTo(OwnCloudVersion.owncloud_v2) >= 0) {
+        Intent i = new Intent(this, ExtensionsAvailableActivity.class);
+        startActivity(i);
+      }*/
+
       finish();
     } else {
-      Toast.makeText(this, message, Toast.LENGTH_LONG).show();
-      dismissDialog(0);
+      dismissDialog(DIALOG_LOGIN_PROGRESS);
+      TextView tv = (TextView) findViewById(R.id.account_username);
+      tv.setError(message);
     }
   }
 
   public void onOkClick(View view) {
-    TextView url_text = (TextView) findViewById(R.id.host_URL);
-    TextView username_text = (TextView) findViewById(R.id.account_username);
-    TextView password_text = (TextView) findViewById(R.id.account_password);
-    Log.i(getClass().getName(), "OK clicked");
-    boolean hasErrors = false;
-
-    URL uri = null;
-    if (url_text.getText().toString().trim().length() == 0) {
-      url_text.setTextColor(Color.RED);
-      hasErrors = true;
+    String prefix = "";
+    String url = ((TextView) findViewById(R.id.host_URL)).getText().toString();
+    if (mIsSslConn) {
+      prefix = "https://";
     } else {
-      url_text.setTextColor(android.R.color.black);
+      prefix = "http://";
     }
-    try {
-      String url_str = url_text.getText().toString();
-      if (!url_str.startsWith("http://") && !url_str.startsWith("https://")) {
-        if (mUseSSLConnection)
-          url_str = "https://" + url_str;
-        else
-          url_str = "http://" + url_str;
-      }
-      uri = new URL(url_str);
-    } catch (MalformedURLException e) {
-      url_text.setTextColor(Color.RED);
-      e.printStackTrace();
-      hasErrors = true;
-    }
-
-    if (username_text.getText().toString().contains(" ")
-        || username_text.getText().toString().trim().length() == 0) {
-      username_text.setTextColor(Color.RED);
-      hasErrors = true;
-    } else {
-      username_text.setTextColor(android.R.color.black);
-    }
-
-    if (password_text.getText().toString().trim().length() == 0) {
-      password_text.setTextColor(Color.RED);
-      hasErrors = true;
-    } else {
-      password_text.setTextColor(android.R.color.black);
-    }
-    if (hasErrors) {
-      return;
+    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);
 
-    int new_port = uri.getPort();
-    if (new_port == -1) {
-      if (mUseSSLConnection)
-        new_port = 443;
-      else
-        new_port = 80;
-    }
+    URL uri = null;
+    String webdav_path = AccountUtils.getWebdavPath(mConnChkRunnable.getDiscoveredVersion());
 
     try {
-      uri = new URL(uri.getProtocol(), uri.getHost(), new_port, uri.getPath());
+      mBaseUrl = prefix + url;
+      String url_str = prefix + url + webdav_path;
+      uri = new URL(url_str);
     } catch (MalformedURLException e) {
-      e.printStackTrace(); // should not happend
+      // should not happend
+      e.printStackTrace();
     }
 
     showDialog(DIALOG_LOGIN_PROGRESS);
-    mAuthRunnable = new AuthenticationRunnable(
-        uri,
-        username_text.getText().toString(),
-        password_text.getText().toString());
+    mAuthRunnable = new AuthenticationRunnable(uri, username, password);
     mAuthRunnable.setOnAuthenticationResultListener(this, mHandler);
-    Log.e(TAG, uri.toString());
     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();
 
-  public void sslBadgeClick(View view, String val) {
-    mUseSSLConnection = ((TextView) view).getText().equals("SSL");
+    switch (type) {
+      case OK:
+        // ugly as hell
+        if (t_url.startsWith("http://") || t_url.startsWith("https://")) {
+          mIsSslConn = t_url.startsWith("http://") ? false : true;
+          mStatusIcon = R.drawable.ic_ok;
+          mStatusText = R.string.auth_connection_established;
+          mStatusCorrect = true;
+        } else {
+          mIsSslConn = true;
+          mStatusIcon = android.R.drawable.ic_secure;
+          mStatusText =  R.string.auth_secure_connection;
+          mStatusCorrect = true;          
+        }
+        break;
+      case OK_NO_SSL:
+        mStatusIcon = android.R.drawable.ic_secure;
+        mStatusText = R.string.auth_nossl_plain_ok_title;
+        mStatusCorrect = true;
+        mIsSslConn = false;
+        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);
   }
 
-  public void passwordBadgeClick(View view, String val) {
-    int input_type = InputType.TYPE_CLASS_TEXT;
-    input_type |= val.equals("Hide")
-                  ? InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
-                  : InputType.TYPE_TEXT_VARIATION_PASSWORD;
+  @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);
+          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);
+    }
+  }
 
-    ((TextView) view).setInputType(input_type);
+  @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);
+    }
   }
 }

+ 93 - 36
src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java

@@ -25,14 +25,15 @@ import android.app.AlertDialog.Builder;
 import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
 import android.content.DialogInterface.OnClickListener;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
+import android.provider.MediaStore;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -54,8 +55,6 @@ 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.db.ProviderMeta.ProviderTableMeta;
-import eu.alefzero.owncloud.syncadapter.FileSyncAdapter;
 import eu.alefzero.owncloud.syncadapter.FileSyncService;
 import eu.alefzero.owncloud.ui.fragment.FileListFragment;
 import eu.alefzero.webdav.WebdavClient;
@@ -76,6 +75,9 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
 	
 	private static final int DIALOG_SETUP_ACCOUNT = 0;
 	private static final int DIALOG_CREATE_DIR = 1;
+	
+	private static final int REQUEST_ACCOUNT_SETUP = 0;
+	private static final int ACTION_SELECT_FILE = 1;
 
 	public void pushPath(String path) {
 		mDirectories.insert(path, 0);
@@ -96,8 +98,8 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
       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);
+      builder.setPositiveButton(android.R.string.ok, this);
+      builder.setNegativeButton(android.R.string.cancel, this);
       dialog = builder.create();
       break;
     case DIALOG_CREATE_DIR:
@@ -107,12 +109,13 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
       final Account a = AccountUtils.getCurrentOwnCloudAccount(this);
       builder.setView(dirName);
       builder.setTitle(R.string.uploader_info_dirname);
-      dirName.setTextColor(R.color.setup_text_typed);
+      int typed_color = getResources().getColor(R.color.setup_text_typed);
+      dirName.setTextColor(typed_color);
 
-      builder.setPositiveButton(R.string.common_ok, new OnClickListener() {
+      builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {
           String s = dirName.getText().toString();
-          if (s.trim().isEmpty()) {
+          if (s.trim().length() == 0) {
             dialog.cancel();
             return;
           }
@@ -140,6 +143,8 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
               dialog.cancel();
             }
           });
+      dialog = builder.create();
+      break;
     }
     default: 
       dialog = null;
@@ -151,27 +156,19 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
+
 		if(!accountsAreSetup()){
       showDialog(DIALOG_SETUP_ACCOUNT);
       return;
     }
-
-		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);  
-
-		mDirectories = new CustomArrayAdapter<String>(this,
-				R.layout.sherlock_spinner_dropdown_item);
-		mDirectories.add("/");
-		setContentView(R.layout.files);
-		mStorageManager = new FileDataStorageManager(AccountUtils.getCurrentOwnCloudAccount(this), getContentResolver());
-		ActionBar action_bar = getSupportActionBar();
-		action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
-		action_bar.setDisplayShowTitleEnabled(false);
-		action_bar.setListNavigationCallbacks(mDirectories, this);
-		action_bar.setDisplayHomeAsUpEnabled(true);
+		
+		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+    setProgressBarIndeterminateVisibility(false);
 	}
 
 	@Override
 	public boolean onOptionsItemSelected(MenuItem item) {
+	  boolean retval = true;
 		switch (item.getItemId()) {
 		case R.id.settingsItem: {
 			Intent i = new Intent(this, Preferences.class);
@@ -190,13 +187,23 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
 		      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, "Upload file from..."), ACTION_SELECT_FILE);
+		  break;
+		}
+		  
 		case android.R.id.home: {
-			onBackPressed();
+		  Intent i = new Intent(this, AccountSelectActivity.class);
+		  startActivity(i);
+		  finish();
 			break;
 		}
-			
+			default:
+			  retval = false;
 		}
-		return true;
+		return retval;
 	}
 	
 	@Override
@@ -225,15 +232,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
 	      showDialog(DIALOG_SETUP_ACCOUNT);
 	    }
 	  }
-	 
-	 @Override
-	  protected void onStart() {
-	    super.onStart();
-	    // Check, if there are ownCloud accounts
-	    if(!accountsAreSetup()){
-	      showDialog(DIALOG_SETUP_ACCOUNT);
-	    }
-	 }
+
 	    
 	 @Override
 	protected void onResume() {
@@ -242,16 +241,74 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
       showDialog(DIALOG_SETUP_ACCOUNT);
       return;
     }
+	  
 	   IntentFilter f = new IntentFilter(FileSyncService.SYNC_MESSAGE);
 	   b = new  BR();
 	   registerReceiver(b, f);
-	   setProgressBarIndeterminateVisibility(false);
+	   if (getSupportFragmentManager().findFragmentById(R.id.fileList) == null)
+	     setContentView(R.layout.files);
+	   
+	   mDirectories = new CustomArrayAdapter<String>(this,
+	        R.layout.sherlock_spinner_dropdown_item);
+	    mDirectories.add("/");
+	    
+	    mStorageManager = new FileDataStorageManager(AccountUtils.getCurrentOwnCloudAccount(this), getContentResolver());
+	    ActionBar action_bar = getSupportActionBar();
+	    action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
+	    action_bar.setDisplayShowTitleEnabled(false);
+	    action_bar.setListNavigationCallbacks(mDirectories, this);
+	    action_bar.setDisplayHomeAsUpEnabled(true);
 	}
 	    
+	 public void onActivityResult(int requestCode, int resultCode, Intent data) {
+     if (resultCode == RESULT_OK) {
+         if (requestCode == ACTION_SELECT_FILE) {
+             Uri selectedImageUri = data.getData();
+
+             String filemanagerstring = selectedImageUri.getPath();
+
+             String selectedImagePath = getPath(selectedImageUri);
+
+             //DEBUG PURPOSE - you can delete this if you want
+             if(selectedImagePath!=null)
+                 System.out.println(selectedImagePath);
+             else System.out.println("selectedImagePath is null");
+             if(filemanagerstring!=null)
+                 System.out.println(filemanagerstring);
+             else System.out.println("filemanagerstring is null");
+
+             //NOW WE HAVE OUR WANTED STRING
+             if(selectedImagePath!=null)
+                 System.out.println("selectedImagePath is the right one for you!");
+             else
+                 System.out.println("filemanagerstring is the right one for you!");
+         }
+     }
+	 }
+	 
+     public String getPath(Uri uri) {
+       String[] projection = { MediaStore.Images.Media.DATA };
+       Cursor cursor = managedQuery(uri, projection, null, null, null);
+       if(cursor!=null)
+       {
+           //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
+           //THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
+           int column_index = cursor
+           .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
+           cursor.moveToFirst();
+           return cursor.getString(column_index);
+       }
+       else return null;
+   }
+     
 	 @Override
 	protected void onPause() {
 	  super.onPause();
-	  unregisterReceiver(b);
+	  if (b != null) {
+	    unregisterReceiver(b);
+	    b = null;
+	  }
+	  
 	}
 	 
 	@Override
@@ -322,7 +379,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
 
 		
 	}
-
+	
 	 public void onClick(DialogInterface dialog, int which) {
 	    // In any case - we won't need it anymore
 	    dialog.dismiss();

+ 3 - 6
src/eu/alefzero/owncloud/ui/adapter/FileListActionListAdapter.java

@@ -21,9 +21,6 @@ package eu.alefzero.owncloud.ui.adapter;
 import java.io.File;
 
 import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.R.drawable;
-import eu.alefzero.owncloud.R.id;
-import eu.alefzero.owncloud.R.layout;
 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
 import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
 import android.accounts.Account;
@@ -45,10 +42,10 @@ public class FileListActionListAdapter implements ListAdapter {
 
   private Context mContext;
   private Account mAccount;
-  private String mFilename, mFileType, mFilePath, mFileStoragePath, mItemId;
+  private String mFilename, mFileType, mFilePath, mFileStoragePath;
   
   private final int ITEM_DOWNLOAD = 0;
-  private final int ITEM_SHARE = 1;
+  //private final int ITEM_SHARE = 1;
   
   public FileListActionListAdapter(Cursor c, Context co, Account account) {
     mContext = co;
@@ -56,7 +53,7 @@ public class FileListActionListAdapter implements ListAdapter {
     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));
+    //mItemId = c.getString(c.getColumnIndex(ProviderTableMeta._ID));
     mAccount = account;
   }
   

+ 19 - 2
src/eu/alefzero/owncloud/ui/adapter/FileListListAdapter.java

@@ -96,11 +96,28 @@ public class FileListListAdapter implements ListAdapter {
     if (mFiles.size() > position) {
       OCFile file = mFiles.get(position);
       TextView fileName = (TextView) view.findViewById(R.id.Filename);
-      fileName.setText(DisplayUtils.HtmlDecode(file.getFileName()));
+      TextView ext_text = (TextView) view.findViewById(R.id.Extension);
+      String name = file.getFileName();
+      String ext = file.getFileName();
+      if (name.lastIndexOf('.') != -1) {
+        name = name.substring(0, name.lastIndexOf('.'));
+        ext = ext.substring(ext.lastIndexOf('.'));
+      } else {
+        ext = "";
+      }
+      
+      fileName.setText(DisplayUtils.HtmlDecode(name));
+      ext_text.setText(ext);
+      ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);
       if (!file.getMimetype().equals("DIR")) {
-        ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);
         fileIcon.setImageResource(R.drawable.file);
+      } else {
+        fileIcon.setImageResource(R.drawable.ic_menu_archive);
       }
+      ImageView down = (ImageView) view.findViewById(R.id.imageView2);
+      if (file.getStoragePath() != null) down.setVisibility(View.VISIBLE);
+      else down.setVisibility(View.INVISIBLE);
+      
     }
 
     return view;

+ 7 - 0
src/eu/alefzero/owncloud/ui/fragment/AuthenticatorAccountDetailsFragment.java

@@ -0,0 +1,7 @@
+package eu.alefzero.owncloud.ui.fragment;
+
+import com.actionbarsherlock.app.SherlockFragment;
+
+public class AuthenticatorAccountDetailsFragment extends SherlockFragment {
+
+}

+ 7 - 0
src/eu/alefzero/owncloud/ui/fragment/AuthenticatorGetStartedFragment.java

@@ -0,0 +1,7 @@
+package eu.alefzero.owncloud.ui.fragment;
+
+import com.actionbarsherlock.app.SherlockFragment;
+
+public class AuthenticatorGetStartedFragment extends SherlockFragment {
+
+}

+ 15 - 1
src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java

@@ -21,6 +21,8 @@ import java.util.Stack;
 import java.util.Vector;
 
 import android.accounts.Account;
+import android.content.ClipData;
+import android.content.ClipDescription;
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.Log;
@@ -57,6 +59,9 @@ public class FileListFragment extends FragmentListView {
     super.onCreate(savedInstanceState);
 
     mAccount = AccountUtils.getCurrentOwnCloudAccount(getActivity());
+    getListView().setDivider(getResources().getDrawable(R.drawable.uploader_list_separator));
+    getListView().setDividerHeight(1);
+    
     populateFileList();
   }
   
@@ -89,7 +94,16 @@ public class FileListFragment extends FragmentListView {
       startActivity(i);
     }
   }
-
+  
+  @Override
+  public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
+    ClipData.Item item = new ClipData.Item("ASD");
+    ClipDescription cd = new ClipDescription("ASD", new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN});
+    ClipData dragData = new ClipData(cd, item);
+    arg1.startDrag(dragData, new View.DragShadowBuilder(arg0.getChildAt(arg2)), null, 0);
+    return true;
+  }
+  
   /**
    * Call this, when the user presses the up button
    */

+ 80 - 0
src/eu/alefzero/owncloud/utils/OwnCloudVersion.java

@@ -0,0 +1,80 @@
+/* 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package eu.alefzero.owncloud.utils;
+
+public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
+  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;
+    }
+  }
+}

+ 15 - 17
src/eu/alefzero/owncloud/widgets/ActionEditText.java

@@ -5,20 +5,14 @@ import java.lang.reflect.Method;
 
 import eu.alefzero.owncloud.R;
 import android.content.Context;
-import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
-import android.text.InputType;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.MotionEvent;
-import android.view.View;
-import android.widget.CheckBox;
 import android.widget.EditText;
-import android.widget.TextView;
 
 public class ActionEditText extends EditText {
   private String s;
@@ -26,6 +20,7 @@ public class ActionEditText extends EditText {
   private int optionOneColor; 
   private String optionTwoString;
   private int optionTwoColor;
+  private Rect mTextBounds, mButtonRect;
   
   private String badgeClickCallback;
   private Rect btn_rect;
@@ -34,39 +29,41 @@ public class ActionEditText extends EditText {
     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);
-    Rect r = new Rect();
     
     Paint p = getPaint();
-    Rect text_bounds = new Rect();
     
-    p.getTextBounds(s, 0, s.length(), text_bounds);
+    p.getTextBounds(s, 0, s.length(), mTextBounds);
     
-    getDrawingRect(r);
-    r.top += 10;
-    r.bottom -= 10;
-    r.left = (int)(getWidth() - text_bounds.width() - 18);
-    r.right = getWidth() - 10;
-    btn_rect = r;
+    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(r, p);
+    canvas.drawRect(mButtonRect, p);
     p.setColor(Color.GRAY);
     
-    canvas.drawText(s, r.left + 3, r.bottom - (text_bounds.height()/2), p);
+    canvas.drawText(s, mButtonRect.left + 3, mButtonRect.bottom - (mTextBounds.height()/2), p);
     
     invalidate();
   }
@@ -81,6 +78,7 @@ public class ActionEditText extends EditText {
         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;

+ 53 - 0
src/eu/alefzero/webdav/FileRequestEntity.java

@@ -0,0 +1,53 @@
+package eu.alefzero.webdav;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.httpclient.methods.RequestEntity;
+
+/**
+ * A RequestEntity that represents a File.
+ *
+ */
+public class FileRequestEntity implements RequestEntity {
+
+  final File file;
+  final String contentType;
+
+  public FileRequestEntity(final File file, final String contentType) {
+    super();
+    if (file == null) {
+      throw new IllegalArgumentException("File may not be null");
+    }
+    this.file = file;
+    this.contentType = contentType;
+  }
+  public long getContentLength() {
+    return this.file.length();
+  }
+
+  public String getContentType() {
+    return this.contentType;
+  }
+
+  public boolean isRepeatable() {
+    return true;
+  }
+
+  public void writeRequest(final OutputStream out) throws IOException {
+    byte[] tmp = new byte[4096];
+    int i = 0;
+    InputStream instream = new FileInputStream(this.file);
+    try {
+      while ((i = instream.read(tmp)) >= 0) {
+        out.write(tmp, 0, i);
+      }
+    } finally {
+      instream.close();
+    }
+  }
+
+}

+ 0 - 36
src/eu/alefzero/webdav/HttpMkCol.java

@@ -1,36 +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 <http://www.gnu.org/licenses/>.
- *
- */
-package eu.alefzero.webdav;
-
-import java.net.URI;
-
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
-
-public class HttpMkCol extends HttpEntityEnclosingRequestBase {
-
-  public final static String METHOD_NAME = "MKCOL";
-  
-  public HttpMkCol(final String uri) {
-    setURI(URI.create(uri));
-  }
-
-  @Override
-  public String getMethod() {
-    return METHOD_NAME;
-  }
-}

+ 0 - 49
src/eu/alefzero/webdav/HttpPropFind.java

@@ -1,49 +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 <http://www.gnu.org/licenses/>.
- *
- */
-package eu.alefzero.webdav;
-
-import java.net.URI;
-
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
-import org.apache.http.protocol.HTTP;
-
-public class HttpPropFind extends HttpEntityEnclosingRequestBase {
-
-  public final static String METHOD_NAME = "PROPFIND";
-  
-  public HttpPropFind(final URI uri) {
-    super();
-    setURI(uri);
-  }
-
-  public HttpPropFind(final String uri) {
-    this.setDepth("1");
-    setURI(URI.create(uri));
-    this.setHeader(HTTP.CONTENT_TYPE, "text/xml" + HTTP.CHARSET_PARAM + HTTP.UTF_8.toLowerCase());
-  }
-  
-  @Override
-  public String getMethod() {
-    return METHOD_NAME;
-  }
-  
-  public void setDepth(String depth) {
-    this.setHeader("Depth", depth);
-  }
-  
-}

+ 0 - 43
src/eu/alefzero/webdav/HttpPropPatch.java

@@ -1,43 +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 <http://www.gnu.org/licenses/>.
- *
- */
-package eu.alefzero.webdav;
-
-import java.net.URI;
-
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
-
-public class HttpPropPatch extends HttpEntityEnclosingRequestBase {
-
-  public static final String METHOD_NAME = "PROPPATCH";
-  
-  public HttpPropPatch(URI uri) {
-    super();
-    setURI(uri);
-  }
-  
-  public HttpPropPatch(final String uri) {
-    super();
-    setURI(URI.create(uri));
-  }
-  
-  @Override
-  public String getMethod() {
-    return METHOD_NAME;
-  }
-  
-}

+ 37 - 103
src/eu/alefzero/webdav/WebdavClient.java

@@ -21,70 +21,37 @@ import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.net.URLDecoder;
 
 import org.apache.commons.httpclient.Credentials;
 import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpMethod;
 import org.apache.commons.httpclient.UsernamePasswordCredentials;
 import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.methods.HeadMethod;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.HttpVersion;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpHead;
-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.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 org.apache.commons.httpclient.methods.PutMethod;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.apache.commons.httpclient.protocol.Protocol;
+import org.apache.http.HttpStatus;
+import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
 
 import eu.alefzero.owncloud.authenticator.EasySSLSocketFactory;
-import eu.alefzero.webdav.HttpMkCol;
 
-import android.net.Uri;
+import android.net.Uri;
 import android.util.Log;
 
 public class WebdavClient extends HttpClient {
-  private DefaultHttpClient mHttpClient;
-  private BasicHttpContext mHttpContext;
-  private HttpHost mTargetHost;
-  private SchemeRegistry mSchemeRegistry;
   private Uri mUri;
   private Credentials mCredentials;
-  final private static String TAG = "WebdavClient";
-  
-  public DefaultHttpClient getHttpClient() {
-    return mHttpClient;
-  }
-  public HttpHost getTargetHost() {
-    return mTargetHost;
-  }
+  final private static String TAG = "WebdavClient";
+  private static final String USER_AGENT = "Android-ownCloud";
   
   public WebdavClient(Uri uri) {
-    mUri = uri;
-    mSchemeRegistry = new SchemeRegistry();
-    setupHttpClient();
+    mUri = uri;
+    getParams().setParameter(HttpMethodParams.USER_AGENT, USER_AGENT);
   }
   
-  public 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();
-
+  public void setCredentials(String username, String password) {
     getParams().setAuthenticationPreemptive(true);
     getState().setCredentials(AuthScope.ANY, getCredentials(username, password));
   }
@@ -94,22 +61,27 @@ public class WebdavClient extends HttpClient {
       mCredentials = new UsernamePasswordCredentials(username, password); 
     return mCredentials;
   }
+
   public void allowUnsignedCertificates() {
-    // https
-    mSchemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
+    // https
+    Protocol.registerProtocol("https", new Protocol("https", new EasySSLSocketFactory(), 443));
   }
   
   public boolean downloadFile(String filepath, File targetPath) {
-    HttpGet get = new HttpGet(mUri.toString() + filepath.replace(" ", "%20"));
-    get.setHeader("Host", mUri.getHost());
-    get.setHeader("User-Agent", "Android-ownCloud");
+    //HttpGet get = new HttpGet(mUri.toString() + filepath.replace(" ", "%20"));
+   
+    Log.e("ASD", mUri.toString() + URLDecoder.decode(filepath) + "");
+    GetMethod get = new GetMethod(mUri.toString() + URLDecoder.decode(filepath));
+    
+//    get.setHeader("Host", mUri.getHost());
+//    get.setHeader("User-Agent", "Android-ownCloud");
     
     try {
-      HttpResponse response = mHttpClient.execute(mTargetHost, get, mHttpContext);
-      if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+      int status = executeMethod(get);
+      if (status != HttpStatus.SC_OK) {
         return false;
       }
-      BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent());
+      BufferedInputStream bis = new BufferedInputStream(get.getResponseBodyAsStream());
       FileOutputStream fos = new FileOutputStream(targetPath);
       
       byte[] bytes = new byte[512];
@@ -127,29 +99,14 @@ public class WebdavClient extends HttpClient {
                   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 {
-      final FileEntity fileEntity = new FileEntity(new File(localFile), contentType);
-
-      method.setEntity(fileEntity);
-      Log.i(TAG, "executing:" + method.getRequestLine().toString());
+      FileRequestEntity entity = new FileRequestEntity(new File(localFile), contentType);
+      PutMethod put = new PutMethod(mUri.toString() + remoteTarget.substring(1));
+      put.setRequestEntity(entity);
+      int status = executeMethod(put);
+      Log.d(TAG, "PUT method return with status "+status);
 
-      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.getMessage());
@@ -169,13 +126,13 @@ public class WebdavClient extends HttpClient {
     }
     return r;
   }
-  
+
   public boolean createDirectory(String path) {
-    HttpMkCol method = new HttpMkCol(mUri.toString() + path + "/");
-    method.setHeader("User-Agent", "Android-ownCloud");
-    
-    try {
-      mHttpClient.execute(mTargetHost, method, mHttpContext);
+    try {
+      MkColMethod mkcol = new MkColMethod(mUri.toString() + "/" + path + "/");
+      int status = executeMethod(mkcol);
+      Log.d(TAG, "Status returned " + status);
+      Log.d(TAG, "uri: " + mkcol.getURI().toString());
       Log.i(TAG, "Creating dir completed");
     } catch (final Exception e) {
       e.printStackTrace();
@@ -183,27 +140,4 @@ public class WebdavClient extends HttpClient {
     }
     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);
-  }
 }

+ 1 - 44
src/eu/alefzero/webdav/WebdavUtils.java

@@ -1,5 +1,5 @@
 /* ownCloud Android client application
- *   Copyright (C) 2011  Bartek Przybylski
+ *   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
@@ -18,45 +18,12 @@
 
 package eu.alefzero.webdav;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Locale;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import android.util.Log;
-
 public class WebdavUtils {
-  
-  public static final String RESPONSE = "response";
-  public static final String HREF = "href";
-  public static final String IS_HIDDEN = "ishidden";
-  public static final String RESOURCE_TYPE = "resourcetype";
-  public static final String CONTENT_TYPE = "getcontenttype";
-  public static final String CONTENT_LENGTH = "getcontentlength";
-  public static final String LAST_MODIFIED = "getlastmodified";
-  public static final String LAST_ACCESS = "lastaccessed";
-  public static final String CREATE_DATE = "creationdate";
-  
-  public static final String PROPSTAT = "propstat";
-  public static final String STATUS = "status";
-  public static final String PROP = "prop";
-
-  private static final String DAV_NAMESPACE_PREFIX = "DAV:";
-  
   public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy hh:mm");
   private static final SimpleDateFormat DATETIME_FORMATS[] = {
       new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US),
@@ -86,14 +53,4 @@ public class WebdavUtils {
     }
     return null;
   }
-  
-  private static String determineDAVPrefix(Element e) {
-    for (int i = 0; i < e.getAttributes().getLength(); ++i) {
-      String attrName = e.getAttributes().item(i).getNodeName();
-      if (e.getAttribute(attrName).equals(DAV_NAMESPACE_PREFIX)) {
-        return attrName.substring(attrName.lastIndexOf(':')+1) + ":";
-      }
-    }
-    return null;
-  }
 }