<activity android:name=".ui.activity.PreferencesNewSessionewSession" >
</activity>
- <activity android:name="com.owncloud.android.ui.preview.PreviewImageActivity" />
+ <activity android:name="com.owncloud.android.ui.preview.PreviewImageActivity" />
<activity android:name="com.owncloud.android.ui.preview.PreviewVideoActivity"
android:label="@string/app_name"
</activity>
<service
- android:name=".authenticator.AccountAuthenticatorService"
+ android:name=".authentication.AccountAuthenticatorService"
android:exported="true">
<intent-filter android:priority="100">
<action android:name="android.accounts.AccountAuthenticator" />
</provider>
<activity
- android:name=".ui.activity.AuthenticatorActivity"
+ android:name=".authentication.AuthenticatorActivity"
android:exported="true"
- android:theme="@style/Theme.ownCloud.noActionBar" >
+ android:theme="@style/Theme.ownCloud.noActionBar"
+ android:launchMode="singleTask">
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:scheme="@string/oauth2_redirect_scheme" />
+ </intent-filter>
<intent-filter>
<action android:name="com.owncloud.android.workaround.accounts.CREATE" />
<category android:name="android.intent.category.DEFAULT" />
<activity android:name=".ui.activity.LogHistoryActivity"/>
- <receiver android:name=".files.InstantUploadBroadcastReceiver">
- <intent-filter>
- <action android:name="com.android.camera.NEW_PICTURE" />
- <data android:mimeType="image/*" />
+ <receiver android:name=".files.InstantUploadBroadcastReceiver">\r
+ <intent-filter>\r
+ <action android:name="com.android.camera.NEW_PICTURE" />\r
+ <data android:mimeType="image/*" />\r
</intent-filter>
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
- </intent-filter>
- </receiver>
- <receiver android:name=".files.BootupBroadcastReceiver">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED"/>
- </intent-filter>
- </receiver>
- <service android:name=".files.services.FileObserverService"/>
- </application>
-
+ </intent-filter>\r
+ </receiver>\r
+ <receiver android:name=".files.BootupBroadcastReceiver">\r
+ <intent-filter>\r
+ <action android:name="android.intent.action.BOOT_COMPLETED"/>\r
+ </intent-filter>\r
+ </receiver>\r
+ <service android:name=".files.services.FileObserverService"/>\r
+ \r
+ </application>\r
+\r
</manifest>
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ownCloud Android client application
-
- Copyright (C) 2012 Bartek Przybylski
- Copyright (C) 2012-2013 ownCloud Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2,
- as published by the Free Software Foundation.
-
- 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/com.owncloud.android"
- 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/owncloud_logo" />
-
- <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:inputType="textNoSuggestions">
- <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:inputType="textNoSuggestions" />
-
- <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"/>
-
- <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:id="@+id/buttons_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:weightSum="1">
-
- <Button
- android:id="@+id/buttonOK"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight=".5"
- android:layout_marginLeft="16dip"
- android:layout_marginRight="16dip"
- android:enabled="false"
- android:onClick="onOkClick"
- android:text="@string/setup_btn_connect"
- android:textColor="@android:color/black" />
-
- </LinearLayout>
-
- <Button
- android:id="@+id/account_register"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/buttons_layout"
- android:layout_centerHorizontal="true"
- android:onClick="onRegisterClick"
- android:paddingTop="10dp"
- android:paddingBottom="10dp"
- android:textColor="#0000FF"
- android:background="@android:color/transparent" />
- <!-- android:text="@string/app_name @string/auth_register" /-->
-
- </RelativeLayout>
-
-</LinearLayout>
+<?xml version="1.0" encoding="utf-8"?>\r
+<!--\r
+ ownCloud Android client application\r
+\r
+ Copyright (C) 2012 Bartek Przybylski\r
+ Copyright (C) 2012-2013 ownCloud Inc.\r
+\r
+ This program is free software: you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License version 2,\r
+ as published by the Free Software Foundation.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+-->\r
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+ xmlns:oc="http://schemas.android.com/apk/res/com.owncloud.android"\r
+ android:layout_width="fill_parent"\r
+ android:layout_height="fill_parent"\r
+ android:focusable="true"\r
+ android:gravity="center|fill"\r
+ android:orientation="vertical" >\r
+\r
+ <FrameLayout\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_gravity="center"\r
+ android:layout_marginLeft="16dip"\r
+ android:layout_marginRight="16dip"\r
+ android:layout_weight="1" >\r
+\r
+ <LinearLayout\r
+ android:layout_width="match_parent"\r
+ android:layout_height="match_parent" >\r
+\r
+ <ImageView\r
+ android:id="@+id/imageView1"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="match_parent"\r
+ android:layout_margin="7dp"\r
+ android:layout_weight="1"\r
+ android:src="@drawable/owncloud_logo" />\r
+\r
+ <LinearLayout\r
+ android:id="@+id/LinearLayout1"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_gravity="center"\r
+ android:layout_weight="1"\r
+ android:orientation="vertical" >\r
+\r
+ <FrameLayout\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_weight="1" >\r
+\r
+ <EditText\r
+ android:id="@+id/hostUrlInput"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:ems="10"\r
+ android:hint="@string/auth_host_url"\r
+ android:inputType="textNoSuggestions">\r
+ <requestFocus />\r
+ </EditText>\r
+\r
+ <ImageView\r
+ android:id="@+id/refreshButton"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:layout_gravity="right|center_vertical"\r
+ android:src="@drawable/ic_action_refresh_black"\r
+ android:onClick="onRefreshClick"\r
+ android:visibility="invisible" />\r
+ </FrameLayout>\r
+\r
+ <LinearLayout\r
+ android:layout_width="match_parent"\r
+ android:layout_height="50dp"\r
+ android:layout_weight="1" >\r
+\r
+ <ImageView\r
+ android:id="@+id/action_indicator"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:layout_marginLeft="5dp"\r
+ android:layout_marginRight="5dp"\r
+ android:src="@android:drawable/stat_notify_sync"\r
+ android:visibility="invisible" />\r
+\r
+ <TextView\r
+ android:id="@+id/status_text"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:text="TextView"\r
+ android:visibility="invisible" />\r
+ </LinearLayout>\r
+\r
+ <CheckBox\r
+ android:id="@+id/oauth_onOff_check"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:checked="false"\r
+ android:onClick="onCheckClick"\r
+ android:text="@string/oauth_check_onoff"\r
+ android:textAppearance="?android:attr/textAppearanceSmall" />\r
+\r
+ <TextView\r
+ android:id="@+id/textView2"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="0dp"\r
+ android:layout_weight="1"\r
+ android:text="@string/auth_login_details"\r
+ android:textAppearance="?android:attr/textAppearanceSmall" />\r
+\r
+ <EditText\r
+ android:id="@+id/oAuthEntryPoint_1"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_weight="1"\r
+ android:ems="10"\r
+ android:enabled="false"\r
+ android:text="@string/oauth2_url_endpoint_auth"\r
+ android:singleLine="true"\r
+ android:visibility="gone" >\r
+ \r
+ <requestFocus />\r
+ </EditText> \r
+ \r
+ <EditText\r
+ android:id="@+id/oAuthEntryPoint_2"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_weight="1"\r
+ android:ems="10"\r
+ android:enabled="false"\r
+ android:text="@string/oauth2_url_endpoint_access"\r
+ android:singleLine="true"\r
+ android:visibility="gone" >\r
+ \r
+ <requestFocus />\r
+ </EditText> \r
+ \r
+ <EditText\r
+ android:id="@+id/account_username"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="0dp"\r
+ android:layout_weight="1"\r
+ android:ems="10"\r
+ android:hint="@string/auth_username"\r
+ android:inputType="textNoSuggestions" />\r
+\r
+ <FrameLayout\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_weight="1" >\r
+\r
+ <EditText\r
+ android:id="@+id/account_password"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:ems="10"\r
+ android:hint="@string/auth_password"\r
+ android:inputType="textPassword"/>\r
+\r
+ <ImageView\r
+ android:id="@+id/viewPasswordButton"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:layout_gravity="right|center_vertical"\r
+ android:src="@android:drawable/ic_menu_view"\r
+ android:onClick="onViewPasswordClick"\r
+ android:visibility="invisible" />\r
+ </FrameLayout>\r
+ \r
+ <TextView\r
+ android:id="@+id/auth_status_text"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_weight="1" \r
+ android:text="@string/text_placeholder"\r
+ android:layout_marginLeft="5dp"\r
+ android:layout_marginRight="5dp"\r
+ android:drawableLeft="@android:drawable/stat_notify_sync"\r
+ android:drawablePadding="5dip"\r
+ android:visibility="invisible" \r
+ />\r
+ \r
+ </LinearLayout>\r
+ \r
+ </LinearLayout>\r
+ </FrameLayout>\r
+\r
+ <RelativeLayout\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_alignParentBottom="true" >\r
+\r
+ <LinearLayout\r
+ android:id="@+id/buttons_layout" \r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:weightSum="1">\r
+\r
+ <Button\r
+ android:id="@+id/buttonOK"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_weight=".5"\r
+ android:layout_marginLeft="16dip"\r
+ android:layout_marginRight="16dip"\r
+ android:enabled="false"\r
+ android:onClick="onOkClick"\r
+ android:text="@string/setup_btn_connect"\r
+ android:textColor="@android:color/black" />\r
+ \r
+ </LinearLayout>\r
+ \r
+ <Button\r
+ android:id="@+id/account_register"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:layout_below="@id/buttons_layout"\r
+ android:layout_centerHorizontal="true"\r
+ android:onClick="onRegisterClick"\r
+ android:paddingTop="10dp"\r
+ android:paddingBottom="10dp"\r
+ android:textColor="#0000FF"\r
+ android:background="@android:color/transparent" />\r
+ <!-- android:text="@string/app_name @string/auth_register" /-->\r
+ \r
+ </RelativeLayout>\r
+\r
+</LinearLayout>\r
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ownCloud Android client application
-
- Copyright (C) 2012 Bartek Przybylski
- Copyright (C) 2012-2013 ownCloud Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2,
- as published by the Free Software Foundation.
-
- 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/>.
--->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical">
-
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:focusable="true"
- android:gravity="center"
- android:orientation="vertical" >
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_gravity="center"
- android:layout_marginBottom="50dip"
- 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: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/owncloud_logo" />
-
- <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:ems="10"
- android:hint="@string/auth_host_url"
- android:inputType="textNoSuggestions" >
- <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:hint="@string/auth_username"
- android:inputType="textNoSuggestions" />
-
- <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:ems="10"
- android:hint="@string/auth_password"
- android:inputType="textPassword"/>
-
- <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">
-
- <LinearLayout
- android:id="@+id/buttons_layout"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:weightSum="1">
-
- <Button
- android:id="@+id/buttonOK"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginLeft="16dip"
- android:layout_marginRight="16dip"
- android:enabled="false"
- android:onClick="onOkClick"
- android:text="@string/setup_btn_connect"
- android:textColor="@android:color/black" />
-
- </LinearLayout>
-
- <Button
- android:id="@+id/account_register"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/buttons_layout"
- android:layout_centerHorizontal="true"
- android:onClick="onRegisterClick"
- android:paddingTop="10dp"
- android:paddingBottom="10dp"
- android:textColor="#0000FF"
- android:background="@android:color/transparent" />
-
- </RelativeLayout>
-
- </LinearLayout>
-
-</ScrollView>
\ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?>\r
+<!--\r
+ ownCloud Android client application\r
+\r
+ Copyright (C) 2012 Bartek Przybylski\r
+ Copyright (C) 2012-2013 ownCloud Inc.\r
+\r
+ This program is free software: you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License version 2,\r
+ as published by the Free Software Foundation.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+-->\r
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"\r
+ android:layout_width="fill_parent"\r
+ android:layout_height="fill_parent"\r
+ android:focusable="true"\r
+ android:gravity="center|fill"\r
+ android:orientation="vertical" >\r
+\r
+ <FrameLayout\r
+ android:layout_width="match_parent"\r
+ android:layout_height="0dip"\r
+ android:layout_gravity="center"\r
+ android:layout_marginBottom="50dip"\r
+ android:layout_marginLeft="16dip"\r
+ android:layout_marginRight="16dip"\r
+ android:layout_weight="1" >\r
+ \r
+ <LinearLayout\r
+ android:id="@+id/LinearLayout1"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_gravity="center"\r
+ android:orientation="vertical" >\r
+ \r
+ <ImageView\r
+ android:id="@+id/imageView1"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_marginBottom="10dp"\r
+ android:layout_weight="1"\r
+ android:src="@drawable/owncloud_logo" />\r
+ \r
+ <FrameLayout\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_weight="1" >\r
+\r
+ <EditText\r
+ android:id="@+id/hostUrlInput"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:ems="10"\r
+ android:hint="@string/auth_host_url"\r
+ android:inputType="textNoSuggestions" >\r
+ <requestFocus />\r
+ </EditText>\r
+\r
+ <ImageView\r
+ android:id="@+id/refreshButton"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:src="@drawable/ic_action_refresh_black"\r
+ android:layout_gravity="right|center_vertical"\r
+ android:visibility="invisible" />\r
+\r
+ </FrameLayout>\r
+\r
+ <LinearLayout\r
+ android:layout_width="match_parent"\r
+ android:layout_height="50dp"\r
+ android:layout_weight="1" >\r
+\r
+ <ImageView\r
+ android:id="@+id/action_indicator"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:layout_marginLeft="5dp"\r
+ android:layout_marginRight="5dp"\r
+ android:src="@android:drawable/stat_notify_sync"\r
+ android:visibility="invisible" />\r
+\r
+ <TextView\r
+ android:id="@+id/status_text"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:text="TextView"\r
+ android:visibility="invisible" />\r
+\r
+ </LinearLayout>\r
+\r
+ <CheckBox\r
+ android:id="@+id/oauth_onOff_check"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:checked="false"\r
+ android:onClick="onCheckClick"\r
+ android:text="@string/oauth_check_onoff"\r
+ android:textAppearance="?android:attr/textAppearanceSmall" />\r
+\r
+ <TextView\r
+ android:id="@+id/textView2"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="0dp"\r
+ android:layout_weight="1"\r
+ android:text="@string/auth_login_details"\r
+ android:textAppearance="?android:attr/textAppearanceSmall" />\r
+\r
+ <EditText\r
+ android:id="@+id/oAuthEntryPoint_1"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_weight="1"\r
+ android:ems="10"\r
+ android:text="@string/oauth2_url_endpoint_auth"\r
+ android:singleLine="true"\r
+ android:visibility="gone" >\r
+\r
+ <requestFocus />\r
+ </EditText> \r
+\r
+ <EditText\r
+ android:id="@+id/oAuthEntryPoint_2"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_weight="1"\r
+ android:ems="10"\r
+ android:text="@string/oauth2_url_endpoint_access"\r
+ android:singleLine="true"\r
+ android:visibility="gone" >\r
+\r
+ <requestFocus />\r
+ </EditText> \r
+\r
+ <EditText\r
+ android:id="@+id/account_username"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="0dp"\r
+ android:layout_weight="1"\r
+ android:ems="10"\r
+ android:hint="@string/auth_username"\r
+ android:inputType="textNoSuggestions" />\r
+\r
+ <FrameLayout\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_weight="1" >\r
+\r
+ <EditText\r
+ android:id="@+id/account_password"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:ems="10"\r
+ android:hint="@string/auth_password"\r
+ android:inputType="textPassword"/>\r
+\r
+ <ImageView\r
+ android:id="@+id/viewPassword"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:layout_gravity="right|center_vertical"\r
+ android:src="@android:drawable/ic_menu_view"\r
+ android:onClick="onViewPasswordClick"\r
+ android:visibility="invisible" />\r
+\r
+ </FrameLayout>\r
+ \r
+ <TextView\r
+ android:id="@+id/auth_status_text"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_weight="1" \r
+ android:text="@string/text_placeholder"\r
+ android:layout_marginLeft="5dp"\r
+ android:layout_marginRight="5dp"\r
+ android:drawableLeft="@android:drawable/stat_notify_sync"\r
+ android:drawablePadding="5dip"\r
+ android:visibility="invisible" \r
+ />\r
+ \r
+ </LinearLayout>\r
+\r
+ </FrameLayout>\r
+\r
+ <RelativeLayout\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content">\r
+\r
+ <LinearLayout\r
+ android:id="@+id/buttons_layout"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:weightSum="1">\r
+\r
+ <Button\r
+ android:id="@+id/buttonOK"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:layout_gravity="center_horizontal"\r
+ android:layout_marginLeft="16dip"\r
+ android:layout_marginRight="16dip"\r
+ android:enabled="false"\r
+ android:onClick="onOkClick"\r
+ android:text="@string/setup_btn_connect"\r
+ android:textColor="@android:color/black" />\r
+\r
+ </LinearLayout>\r
+ \r
+ <Button\r
+ android:id="@+id/account_register"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:layout_below="@id/buttons_layout"\r
+ android:layout_centerHorizontal="true"\r
+ android:onClick="onRegisterClick"\r
+ android:paddingTop="10dp"\r
+ android:paddingBottom="10dp"\r
+ android:textColor="#0000FF"\r
+ android:background="@android:color/transparent" />\r
+ \r
+ <Button\r
+ android:id="@+id/account_register"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:layout_below="@id/buttons_layout"\r
+ android:layout_centerHorizontal="true"\r
+ android:onClick="onRegisterClick"\r
+ android:paddingTop="10dp"\r
+ android:paddingBottom="10dp"\r
+ android:textColor="#0000FF"\r
+ android:background="@android:color/transparent" />\r
+ <!-- android:text="@string/app_name @string/auth_register" /-->\r
+ \r
+ </RelativeLayout>\r
+ \r
+</ScrollView>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Flag to configure OAuth availability in the app.
+ 3 valid values now: on, off, optional
+ -->
+ <string name="oauth2_mode">off</string>
+
+ <!-- constants that must be respected by the authorization server; if changed, the app must be rebuild -->
+ <string name="oauth2_redirect_scheme">owncloud</string>
+ <string name="oauth2_redirect_uri">owncloud://callback</string>
+
+ <!-- values that should be provided by ownCloud server -->
+ <string name="oauth2_url_endpoint_auth">http://owncloud.tuxed.net/oauth/php-oauth/authorize.php</string>
+ <string name="oauth2_url_endpoint_access">http://owncloud.tuxed.net/oauth/php-oauth/token.php</string>
+ <string name="oauth2_scope">owncloud</string>
+ <string name="oauth2_grant_type">authorization_code</string> <!-- the only one supported right now -->
+ <string name="oauth2_response_type">code</string> <!-- depends on oauth2_grant_type -->
+
+ <!-- values that should be agreed between app and authorization server, but can be loaded without rebuilding the app -->
+ <string name="oauth2_client_id">com.owncloud.android</string> <!-- preferable that client decides this -->
+ <string name="oauth2_client_secret"></string> <!-- preferable that client decides this -->
+
+</resources>
<string name="sync_string_contacts">Contacts</string>
<string name="sync_fail_ticker">Synchronization failed</string>
<string name="sync_fail_content">Synchronization of %1$s could not be completed</string>
- <string name="sync_conflicts_in_favourites_ticker">Conflicts found</string>
- <string name="sync_conflicts_in_favourites_content">%1$d kept-in-sync files could not be sync\'ed</string>
+ <string name="sync_fail_content_unauthorized">Invalid credentials for %1$s</string>
+ <string name="sync_conflicts_in_favourites_ticker">Conflicts found</string>
+ <string name="sync_conflicts_in_favourites_content">%1$d kept-in-sync files could not be sync\'ed</string>
<string name="sync_fail_in_favourites_ticker">Kept-in-sync files failed</string>
<string name="sync_fail_in_favourites_content">Contents of %1$d files could not be sync\'ed (%2$d conflicts)</string>
<string name="sync_foreign_files_forgotten_ticker">Some local files were forgotten</string>
<string name="auth_wrong_connection_title">Couldn\'t establish connection</string>
<string name="auth_secure_connection">Secure connection established</string>
<string name="auth_login_details">Login details</string>
- <string name="auth_unauthorized">Invalid login / password</string>
+ <string name="auth_unauthorized">Invalid credentials</string>
+ <string name="auth_oauth_error">Unsuccessful authorization</string>
+ <string name="auth_oauth_error_access_denied">Access denied by authorization server</string>
<string name="auth_not_found">Wrong path given</string>
<string name="auth_internal">Internal server error, code %1$d</string>
+ <string name="auth_wtf_reenter_URL">Unexpected state; please, enter the server URL again</string>
+ <string name="auth_expired_oauth_token_toast">Your authorization expired.\nPlease, authorize again</string>
+ <string name="auth_expired_basic_auth_toast">Your saved credentials are invalid.\nPlease, enter the current credentials</string>
+
<string name="crashlog_message">Application terminated unexpectedly. Would you like to submit a crash report?</string>
<string name="crashlog_send_report">Send report</string>
<string name="crashlog_dont_send_report">Don\'t send report</string>
<string name="wait_a_moment">Wait a moment</string>
<string name="filedisplay_unexpected_bad_get_content">"Unexpected problem ; please select the file from a different app"</string>
<string name="filedisplay_no_file_selected">No file was selected</string>
+
+ <string name="oauth_host_url">oAuth2 URL</string>
+ <string name="oauth_check_onoff">Login with oAuth2.</string>
+ <string name="oauth_login_connection">Connecting to oAuth2 server…</string>
+ <string name="oauth_code_validation_message">Please, open a web browser and go to:\n%1$s.\nValidate this code there:\n%2$s</string>
+ <string name="oauth_connection_url_unavailable">Connection to this URL not available.</string>
+
<string name="ssl_validator_title">Warning</string>
<string name="ssl_validator_header">The identity of the site could not be verified</string>
<string name="ssl_validator_reason_cert_not_trusted">- The server certificate is not trusted</string>
<item name="android:singleLine">true</item>
</style>
+
+ <style name="OAuthDialog" parent="@android:style/Theme.Dialog">
+ <item name="android:windowNoTitle">false</item>
+ </style>
<color name="setup_text_hint">#777777</color>
<color name="setup_text_typed">#000000</color>
\r
package com.owncloud.android;\r
\r
-import com.owncloud.android.authenticator.AccountAuthenticator;\r
+import com.owncloud.android.authentication.AccountAuthenticator;\r
import com.owncloud.android.utils.OwnCloudVersion;\r
\r
import android.accounts.Account;\r
public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php";\r
public static final String WEBDAV_PATH_2_0 = "/files/webdav.php";\r
public static final String WEBDAV_PATH_4_0 = "/remote.php/webdav";\r
+ private static final String ODAV_PATH = "/remote.php/odav";\r
public static final String CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php";\r
public static final String CARDDAV_PATH_4_0 = "/remote/carddav.php";\r
public static final String STATUS_PATH = "/status.php";\r
* @param version version of owncloud\r
* @return webdav path for given OC version, null if OC version unknown\r
*/\r
- public static String getWebdavPath(OwnCloudVersion version) {\r
+ public static String getWebdavPath(OwnCloudVersion version, boolean supportsOAuth) {\r
if (version != null) {\r
+ if (supportsOAuth) {\r
+ return ODAV_PATH;\r
+ }\r
if (version.compareTo(OwnCloudVersion.owncloud_v4) >= 0)\r
return WEBDAV_PATH_4_0;\r
if (version.compareTo(OwnCloudVersion.owncloud_v3) >= 0\r
AccountManager ama = AccountManager.get(context);\r
String baseurl = ama.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL);\r
String strver = ama.getUserData(account, AccountAuthenticator.KEY_OC_VERSION);\r
+ boolean supportsOAuth = (ama.getUserData(account, AccountAuthenticator.KEY_SUPPORTS_OAUTH2) != null);\r
OwnCloudVersion ver = new OwnCloudVersion(strver);\r
- String webdavpath = getWebdavPath(ver);\r
+ String webdavpath = getWebdavPath(ver, supportsOAuth);\r
\r
if (webdavpath == null) return null;\r
return baseurl + webdavpath;\r
import java.util.HashSet;\r
import java.util.Set;\r
\r
-import android.util.Log;\r
-\r
/**\r
* A helper class for some string operations.\r
* \r
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
package com.owncloud.android;
import java.io.File;
import java.util.Stack;
import java.util.Vector;
-import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.authentication.AccountAuthenticator;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileUploader;
-import com.owncloud.android.network.OwnCloudClientUtils;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.MediaStore.Images.Media;
-import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.Toast;
import com.owncloud.android.R;
-import eu.alefzero.webdav.WebdavClient;
/**
* This can be used to upload things to an ownCloud instance.
// in API7 < this constatant is defined in
// Settings.ADD_ACCOUNT_SETTINGS
// and Settings.EXTRA_AUTHORITIES
- Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
- intent.putExtra("authorities", new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
+ Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
+ intent.putExtra("authorities", new String[] { AccountAuthenticator.AUTHORITY });
startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
} else {
// since in API7 there is no direct call for
public void uploadFiles() {
try {
+ /* TODO - mCreateDir can never be true at this moment; we will replace wdc.createDirectory by CreateFolderOperation when that is fixed
WebdavClient wdc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getApplicationContext());
-
// create last directory in path if necessary
if (mCreateDir) {
wdc.createDirectory(mUploadPath);
}
+ */
String[] local = new String[mStreamsToUpload.size()], remote = new String[mStreamsToUpload.size()];
--- /dev/null
+/* ownCloud Android client application
+ * Copyright (C) 2012 Bartek Przybylski
+ * Copyright (C) 2012-2013 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * 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 com.owncloud.android.authentication;
+
+import android.accounts.*;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import com.owncloud.android.Log_OC;
+
+/**
+ * Authenticator for ownCloud accounts.
+ *
+ * Controller class accessed from the system AccountManager, providing integration of ownCloud accounts with the Android system.
+ *
+ * TODO - better separation in operations for OAuth-capable and regular ownCloud accounts.
+ * TODO - review completeness
+ *
+ * @author David A. Velasco
+ */
+public class AccountAuthenticator extends AbstractAccountAuthenticator {
+
+ /**
+ * Is used by android system to assign accounts to authenticators. Should be
+ * used by application and all extensions.
+ */
+ public static final String ACCOUNT_TYPE = "owncloud";
+ public static final String AUTHORITY = "org.owncloud";
+ public static final String AUTH_TOKEN_TYPE = "org.owncloud";
+ public static final String AUTH_TOKEN_TYPE_PASSWORD = "owncloud.password";
+ public static final String AUTH_TOKEN_TYPE_ACCESS_TOKEN = "owncloud.oauth2.access_token";
+ public static final String AUTH_TOKEN_TYPE_REFRESH_TOKEN = "owncloud.oauth2.refresh_token";
+
+ 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 com.owncloud.android.authentication.AuthenticatorActivity.KEY_OC_BASE_URL} and
+ * {@link com.owncloud.android.utils.OwnCloudVersion}
+ *
+ * @deprecated
+ */
+ public static final String KEY_OC_URL = "oc_url";
+ /**
+ * Version should be 3 numbers separated by dot so it can be parsed by
+ * {@link com.owncloud.android.utils.OwnCloudVersion}
+ */
+ public static final String KEY_OC_VERSION = "oc_version";
+ /**
+ * Base url should point to owncloud installation without trailing / ie:
+ * http://server/path or https://owncloud.server
+ */
+ public static final String KEY_OC_BASE_URL = "oc_base_url";
+ /**
+ * Flag signaling if the ownCloud server can be accessed with OAuth2 access tokens.
+ */
+ public static final String KEY_SUPPORTS_OAUTH2 = "oc_supports_oauth2";
+
+ private static final String TAG = AccountAuthenticator.class.getSimpleName();
+
+ 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_OC.i(TAG, "Adding account with type " + accountType
+ + " and auth token " + authTokenType);
+ try {
+ validateAccountType(accountType);
+ } catch (AuthenticatorException e) {
+ Log_OC.e(TAG, "Failed to validate account type " + accountType + ": "
+ + e.getMessage());
+ e.printStackTrace();
+ return e.getFailureBundle();
+ }
+ final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
+ intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
+ intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
+ intent.putExtra(KEY_REQUIRED_FEATURES, requiredFeatures);
+ intent.putExtra(KEY_LOGIN_OPTIONS, options);
+ intent.putExtra(AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_CREATE);
+
+ setIntentFlags(intent);
+
+ final Bundle bundle = new Bundle();
+ bundle.putParcelable(AccountManager.KEY_INTENT, intent);
+ return bundle;
+ }
+
+ /**\r
+ * {@inheritDoc}\r
+ */\r
+ @Override\r
+ public Bundle confirmCredentials(AccountAuthenticatorResponse response,\r
+ Account account, Bundle options) throws NetworkErrorException {\r
+ try {\r
+ validateAccountType(account.type);\r
+ } catch (AuthenticatorException e) {\r
+ Log_OC.e(TAG, "Failed to validate account type " + account.type + ": "\r
+ + e.getMessage());\r
+ e.printStackTrace();\r
+ return e.getFailureBundle();\r
+ }\r
+ Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
+ intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,\r
+ response);\r
+ intent.putExtra(KEY_ACCOUNT, account);\r
+ intent.putExtra(KEY_LOGIN_OPTIONS, options);\r
+\r
+ setIntentFlags(intent);\r
+\r
+ Bundle resultBundle = new Bundle();\r
+ resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);\r
+ return resultBundle;\r
+ }\r
+\r
+ @Override\r
+ public Bundle editProperties(AccountAuthenticatorResponse response,\r
+ String accountType) {\r
+ return null;\r
+ }\r
+\r
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Bundle getAuthToken(AccountAuthenticatorResponse response,
+ Account account, String authTokenType, Bundle options)
+ throws NetworkErrorException {
+ /// validate parameters
+ try {
+ validateAccountType(account.type);
+ validateAuthTokenType(authTokenType);
+ } catch (AuthenticatorException e) {
+ Log_OC.e(TAG, "Failed to validate account type " + account.type + ": "
+ + e.getMessage());
+ e.printStackTrace();
+ return e.getFailureBundle();
+ }
+
+ /// check if required token is stored
+ final AccountManager am = AccountManager.get(mContext);
+ String accessToken;
+ if (authTokenType.equals(AUTH_TOKEN_TYPE_PASSWORD)) {
+ accessToken = am.getPassword(account);
+ } else {
+ accessToken = am.peekAuthToken(account, authTokenType);
+ }
+ if (accessToken != 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, accessToken);
+ return result;
+ }
+
+ /// if not stored, return Intent to access the AuthenticatorActivity and UPDATE the token for the 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.EXTRA_ACCOUNT, account);
+ intent.putExtra(AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_UPDATE_TOKEN);
+
+
+ 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, true);
+ 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_EXCLUDE_FROM_RECENTS);
+ intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
+ }
+
+ private void validateAccountType(String type)
+ throws UnsupportedAccountTypeException {
+ if (!type.equals(ACCOUNT_TYPE)) {
+ throw new UnsupportedAccountTypeException();
+ }
+ }
+
+ private void validateAuthTokenType(String authTokenType)\r
+ throws UnsupportedAuthTokenTypeException {\r
+ if (!authTokenType.equals(AUTH_TOKEN_TYPE) &&\r
+ !authTokenType.equals(AUTH_TOKEN_TYPE_PASSWORD) &&\r
+ !authTokenType.equals(AUTH_TOKEN_TYPE_ACCESS_TOKEN) &&\r
+ !authTokenType.equals(AUTH_TOKEN_TYPE_REFRESH_TOKEN) ) {\r
+ throw new UnsupportedAuthTokenTypeException();\r
+ }\r
+ }\r
+\r
+ public static class AuthenticatorException extends Exception {\r
+ private static final long serialVersionUID = 1L;\r
+ private Bundle mFailureBundle;\r
+\r
+ public AuthenticatorException(int code, String errorMsg) {\r
+ mFailureBundle = new Bundle();\r
+ mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);\r
+ mFailureBundle\r
+ .putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);\r
+ }\r
+\r
+ public Bundle getFailureBundle() {\r
+ return mFailureBundle;\r
+ }\r
+ }\r
+\r
+ public static class UnsupportedAccountTypeException extends\r
+ AuthenticatorException {\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public UnsupportedAccountTypeException() {\r
+ super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
+ "Unsupported account type");\r
+ }\r
+ }\r
+\r
+ public static class UnsupportedAuthTokenTypeException extends\r
+ AuthenticatorException {\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public UnsupportedAuthTokenTypeException() {\r
+ super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
+ "Unsupported auth token type");\r
+ }\r
+ }\r
+\r
+ public static class UnsupportedFeaturesException extends\r
+ AuthenticatorException {\r
+ public static final long serialVersionUID = 1L;\r
+\r
+ public UnsupportedFeaturesException() {\r
+ super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
+ "Unsupported features");\r
+ }\r
+ }\r
+\r
+ public static class AccessDeniedException extends AuthenticatorException {\r
+ public AccessDeniedException(int code, String errorMsg) {\r
+ super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");\r
+ }\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ }\r
+}\r
--- /dev/null
+/* ownCloud Android client application
+ * Copyright (C) 2011 Bartek Przybylski
+ * Copyright (C) 2012-2013 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * 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 com.owncloud.android.authentication;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class AccountAuthenticatorService extends Service {
+
+ private AccountAuthenticator mAuthenticator;
+ static final public String ACCOUNT_TYPE = "owncloud";
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mAuthenticator = new AccountAuthenticator(this);
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mAuthenticator.getIBinder();
+ }
+
+}
--- /dev/null
+/* ownCloud Android client application\r
+ * Copyright (C) 2012 Bartek Przybylski\r
+ * Copyright (C) 2012-2013 ownCloud Inc.\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License version 2,\r
+ * as published by the Free Software Foundation.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package com.owncloud.android.authentication;\r
+\r
+import com.owncloud.android.AccountUtils;\r
+import com.owncloud.android.Log_OC;\r
+import com.owncloud.android.ui.dialog.SslValidatorDialog;\r
+import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener;\r
+import com.owncloud.android.utils.OwnCloudVersion;\r
+import com.owncloud.android.network.OwnCloudClientUtils;\r
+import com.owncloud.android.operations.OwnCloudServerCheckOperation;\r
+import com.owncloud.android.operations.ExistenceCheckOperation;\r
+import com.owncloud.android.operations.OAuth2GetAccessToken;\r
+import com.owncloud.android.operations.OnRemoteOperationListener;\r
+import com.owncloud.android.operations.RemoteOperation;\r
+import com.owncloud.android.operations.RemoteOperationResult;\r
+import com.owncloud.android.operations.RemoteOperationResult.ResultCode;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountAuthenticatorActivity;\r
+import android.accounts.AccountManager;\r
+import android.app.AlertDialog;\r
+import android.app.Dialog;\r
+import android.app.ProgressDialog;\r
+import android.content.ContentResolver;\r
+import android.content.DialogInterface;\r
+import android.content.Intent;\r
+import android.content.SharedPreferences;\r
+import android.net.Uri;\r
+import android.os.Bundle;\r
+import android.os.Handler;\r
+import android.preference.PreferenceManager;\r
+import android.text.InputType;\r
+import android.view.View;\r
+import android.view.View.OnFocusChangeListener;\r
+import android.view.Window;\r
+import android.widget.CheckBox;\r
+import android.widget.EditText;\r
+import android.widget.Button;\r
+import android.widget.ImageView;\r
+import android.widget.TextView;\r
+import android.widget.Toast;\r
+\r
+import com.owncloud.android.R;\r
+\r
+import eu.alefzero.webdav.WebdavClient;\r
+\r
+/**\r
+ * This Activity is used to add an ownCloud account to the App\r
+ * \r
+ * @author Bartek Przybylski\r
+ * @author David A. Velasco\r
+ */\r
+public class AuthenticatorActivity extends AccountAuthenticatorActivity\r
+ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeListener {\r
+\r
+ private static final String TAG = AuthenticatorActivity.class.getSimpleName();\r
+\r
+ public static final String EXTRA_ACCOUNT = "ACCOUNT";\r
+ public static final String EXTRA_USER_NAME = "USER_NAME";\r
+ public static final String EXTRA_HOST_NAME = "HOST_NAME";\r
+ public static final String EXTRA_ACTION = "ACTION";\r
+ \r
+ private static final String KEY_HOST_URL_TEXT = "HOST_URL_TEXT";\r
+ private static final String KEY_OC_VERSION = "OC_VERSION";\r
+ private static final String KEY_ACCOUNT = "ACCOUNT";\r
+ private static final String KEY_STATUS_TEXT = "STATUS_TEXT";\r
+ private static final String KEY_STATUS_ICON = "STATUS_ICON";\r
+ private static final String KEY_STATUS_CORRECT = "STATUS_CORRECT";\r
+ private static final String KEY_IS_SSL_CONN = "IS_SSL_CONN";\r
+ private static final String KEY_OAUTH2_STATUS_TEXT = "OAUTH2_STATUS_TEXT";\r
+ private static final String KEY_OAUTH2_STATUS_ICON = "OAUTH2_STATUS_ICON";\r
+ \r
+ private static final String OAUTH_MODE_ON = "on";\r
+ private static final String OAUTH_MODE_OFF = "off";\r
+ private static final String OAUTH_MODE_OPTIONAL = "optional";\r
+\r
+ private static final int DIALOG_LOGIN_PROGRESS = 0;\r
+ private static final int DIALOG_SSL_VALIDATOR = 1;\r
+ private static final int DIALOG_CERT_NOT_SAVED = 2;\r
+ private static final int DIALOG_OAUTH2_LOGIN_PROGRESS = 3;\r
+\r
+ public static final byte ACTION_CREATE = 0;\r
+ public static final byte ACTION_UPDATE_TOKEN = 1;\r
+\r
+ \r
+ private String mHostBaseUrl;\r
+ private OwnCloudVersion mDiscoveredVersion;\r
+ \r
+ private int mStatusText, mStatusIcon;\r
+ private boolean mStatusCorrect, mIsSslConn;\r
+ private int mOAuth2StatusText, mOAuth2StatusIcon; \r
+ \r
+ private final Handler mHandler = new Handler();\r
+ private Thread mOperationThread;\r
+ private OwnCloudServerCheckOperation mOcServerChkOperation;\r
+ private ExistenceCheckOperation mAuthCheckOperation;\r
+ private RemoteOperationResult mLastSslUntrustedServerResult;\r
+\r
+ private Uri mNewCapturedUriFromOAuth2Redirection;\r
+ \r
+ private AccountManager mAccountMgr;\r
+ private boolean mJustCreated;\r
+ private byte mAction;\r
+ private Account mAccount;\r
+ \r
+ private ImageView mRefreshButton;\r
+ private ImageView mViewPasswordButton;\r
+ private EditText mHostUrlInput;\r
+ private EditText mUsernameInput;\r
+ private EditText mPasswordInput;\r
+ private CheckBox mOAuth2Check;\r
+ private String mOAuthAccessToken;\r
+ private View mOkButton;\r
+ private TextView mAuthStatusLayout;\r
+ \r
+ private TextView mOAuthAuthEndpointText;\r
+ private TextView mOAuthTokenEndpointText;\r
+ \r
+ \r
+ /**\r
+ * {@inheritDoc}\r
+ * \r
+ * IMPORTANT ENTRY POINT 1: activity is shown to the user\r
+ */\r
+ @Override\r
+ protected void onCreate(Bundle savedInstanceState) {\r
+ super.onCreate(savedInstanceState);\r
+ getWindow().requestFeature(Window.FEATURE_NO_TITLE);\r
+ \r
+ /// set view and get references to view elements\r
+ setContentView(R.layout.account_setup);\r
+ mRefreshButton = (ImageView) findViewById(R.id.refreshButton);\r
+ mViewPasswordButton = (ImageView) findViewById(R.id.viewPasswordButton);\r
+ mHostUrlInput = (EditText) findViewById(R.id.hostUrlInput);\r
+ mUsernameInput = (EditText) findViewById(R.id.account_username);\r
+ mPasswordInput = (EditText) findViewById(R.id.account_password);\r
+ mOAuthAuthEndpointText = (TextView)findViewById(R.id.oAuthEntryPoint_1);\r
+ mOAuthTokenEndpointText = (TextView)findViewById(R.id.oAuthEntryPoint_2);\r
+ mOAuth2Check = (CheckBox) findViewById(R.id.oauth_onOff_check);\r
+ mOkButton = findViewById(R.id.buttonOK);\r
+ mAuthStatusLayout = (TextView) findViewById(R.id.auth_status_text); \r
+ \r
+ /// complete label for 'register account' button\r
+ Button b = (Button) findViewById(R.id.account_register);\r
+ if (b != null) {\r
+ b.setText(String.format(getString(R.string.auth_register), getString(R.string.app_name)));\r
+ }\r
+\r
+ /// bind view elements to listeners\r
+ mHostUrlInput.setOnFocusChangeListener(this);\r
+ mPasswordInput.setOnFocusChangeListener(this);\r
+ \r
+ /// initialization\r
+ mAccountMgr = AccountManager.get(this);\r
+ mNewCapturedUriFromOAuth2Redirection = null;\r
+ mAction = getIntent().getByteExtra(EXTRA_ACTION, ACTION_CREATE); \r
+ mAccount = null;\r
+\r
+ if (savedInstanceState == null) {\r
+ /// connection state and info\r
+ mStatusText = mStatusIcon = 0;\r
+ mStatusCorrect = false;\r
+ mIsSslConn = false;\r
+ \r
+ /// retrieve extras from intent\r
+ String tokenType = getIntent().getExtras().getString(AccountAuthenticator.KEY_AUTH_TOKEN_TYPE);\r
+ boolean oAuthRequired = AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN.equals(tokenType) || OAUTH_MODE_ON.equals(getString(R.string.oauth2_mode));\r
+ \r
+ mAccount = getIntent().getExtras().getParcelable(EXTRA_ACCOUNT);\r
+ if (mAccount != null) {\r
+ String ocVersion = mAccountMgr.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION);\r
+ if (ocVersion != null) {\r
+ mDiscoveredVersion = new OwnCloudVersion(ocVersion);\r
+ }\r
+ mHostBaseUrl = mAccountMgr.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);\r
+ mHostUrlInput.setText(mHostBaseUrl);\r
+ String userName = mAccount.name.substring(0, mAccount.name.lastIndexOf('@'));\r
+ mUsernameInput.setText(userName);\r
+ oAuthRequired = (mAccountMgr.getUserData(mAccount, AccountAuthenticator.KEY_SUPPORTS_OAUTH2) != null);\r
+ }\r
+ mOAuth2Check.setChecked(oAuthRequired);\r
+ changeViewByOAuth2Check(oAuthRequired);\r
+ \r
+\r
+ } else {\r
+ loadSavedInstanceState(savedInstanceState);\r
+ }\r
+ \r
+ if (!OAUTH_MODE_OPTIONAL.equals(getString(R.string.oauth2_mode))) {\r
+ mOAuth2Check.setVisibility(View.GONE);\r
+ }\r
+ \r
+ if (mAction == ACTION_UPDATE_TOKEN) {\r
+ /// lock things that should not change\r
+ mHostUrlInput.setEnabled(false);\r
+ mUsernameInput.setEnabled(false);\r
+ mOAuth2Check.setVisibility(View.GONE);\r
+ checkOcServer(); \r
+ }\r
+ \r
+ mPasswordInput.setText(""); // clean password to avoid social hacking (disadvantage: password in removed if the device is turned aside)\r
+ mJustCreated = true;\r
+ }\r
+\r
+\r
+ /**\r
+ * Saves relevant state before {@link #onPause()}\r
+ * \r
+ * Do NOT save {@link #mNewCapturedUriFromOAuth2Redirection}; it keeps a temporal flag, intended to defer the \r
+ * processing of the redirection caught in {@link #onNewIntent(Intent)} until {@link #onResume()} \r
+ * \r
+ * See {@link #loadSavedInstanceState(Bundle)}\r
+ */\r
+ @Override\r
+ protected void onSaveInstanceState(Bundle outState) {\r
+ super.onSaveInstanceState(outState);\r
+ \r
+ /// connection state and info\r
+ outState.putInt(KEY_STATUS_TEXT, mStatusText);\r
+ outState.putInt(KEY_STATUS_ICON, mStatusIcon);\r
+ outState.putBoolean(KEY_STATUS_CORRECT, mStatusCorrect);\r
+ outState.putBoolean(KEY_IS_SSL_CONN, mIsSslConn);\r
+\r
+ /// server data\r
+ if (mDiscoveredVersion != null) \r
+ outState.putString(KEY_OC_VERSION, mDiscoveredVersion.toString());\r
+ outState.putString(KEY_HOST_URL_TEXT, mHostBaseUrl);\r
+ \r
+ /// account data, if updating\r
+ if (mAccount != null)\r
+ outState.putParcelable(KEY_ACCOUNT, mAccount);\r
+ \r
+ // Saving the state of oAuth2 components.\r
+ outState.putInt(KEY_OAUTH2_STATUS_ICON, mOAuth2StatusIcon);\r
+ outState.putInt(KEY_OAUTH2_STATUS_TEXT, mOAuth2StatusText);\r
+ \r
+ }\r
+\r
+\r
+ /**\r
+ * Loads saved state\r
+ * \r
+ * See {@link #onSaveInstanceState(Bundle)}.\r
+ * \r
+ * @param savedInstanceState Saved state, as received in {@link #onCreate(Bundle)}.\r
+ */\r
+ private void loadSavedInstanceState(Bundle savedInstanceState) {\r
+ /// connection state and info\r
+ mStatusCorrect = savedInstanceState.getBoolean(KEY_STATUS_CORRECT);\r
+ mIsSslConn = savedInstanceState.getBoolean(KEY_IS_SSL_CONN);\r
+ mStatusText = savedInstanceState.getInt(KEY_STATUS_TEXT);\r
+ mStatusIcon = savedInstanceState.getInt(KEY_STATUS_ICON);\r
+ updateConnStatus();\r
+ \r
+ /// UI settings depending upon connection\r
+ mOkButton.setEnabled(mStatusCorrect); // TODO really necessary?\r
+ if (!mStatusCorrect)\r
+ mRefreshButton.setVisibility(View.VISIBLE); // seems that setting visibility is necessary\r
+ else\r
+ mRefreshButton.setVisibility(View.INVISIBLE);\r
+ \r
+ /// server data\r
+ String ocVersion = savedInstanceState.getString(KEY_OC_VERSION);\r
+ if (ocVersion != null)\r
+ mDiscoveredVersion = new OwnCloudVersion(ocVersion);\r
+ mHostBaseUrl = savedInstanceState.getString(KEY_HOST_URL_TEXT);\r
+ \r
+ // account data, if updating\r
+ mAccount = savedInstanceState.getParcelable(KEY_ACCOUNT);\r
+ \r
+ // state of oAuth2 components\r
+ mOAuth2StatusIcon = savedInstanceState.getInt(KEY_OAUTH2_STATUS_ICON);\r
+ mOAuth2StatusText = savedInstanceState.getInt(KEY_OAUTH2_STATUS_TEXT);\r
+ // END of getting the state of oAuth2 components.\r
+ }\r
+\r
+ \r
+ /**\r
+ * The redirection triggered by the OAuth authentication server as response to the GET AUTHORIZATION request\r
+ * is caught here.\r
+ * \r
+ * To make this possible, this activity needs to be qualified with android:launchMode = "singleTask" in the\r
+ * AndroidManifest.xml file.\r
+ */\r
+ @Override\r
+ protected void onNewIntent (Intent intent) {\r
+ Log_OC.d(TAG, "onNewIntent()");\r
+ Uri data = intent.getData();\r
+ if (data != null && data.toString().startsWith(getString(R.string.oauth2_redirect_uri))) {\r
+ mNewCapturedUriFromOAuth2Redirection = data;\r
+ }\r
+ }\r
+\r
+ \r
+ /**\r
+ * The redirection triggered by the OAuth authentication server as response to the GET AUTHORIZATION, and \r
+ * deferred in {@link #onNewIntent(Intent)}, is processed here.\r
+ */\r
+ @Override\r
+ protected void onResume() {\r
+ super.onResume();\r
+ // the state of mOAuth2Check is automatically recovered between configuration changes, but not before onCreate() finishes; so keep the next lines here\r
+ changeViewByOAuth2Check(mOAuth2Check.isChecked()); \r
+ if (mAction == ACTION_UPDATE_TOKEN && mJustCreated) {\r
+ if (mOAuth2Check.isChecked())\r
+ Toast.makeText(this, R.string.auth_expired_oauth_token_toast, Toast.LENGTH_LONG).show();\r
+ else\r
+ Toast.makeText(this, R.string.auth_expired_basic_auth_toast, Toast.LENGTH_LONG).show();\r
+ }\r
+ \r
+ if (mNewCapturedUriFromOAuth2Redirection != null) {\r
+ getOAuth2AccessTokenFromCapturedRedirection(); \r
+ }\r
+ \r
+ mJustCreated = false;\r
+ }\r
+ \r
+ \r
+ /**\r
+ * Parses the redirection with the response to the GET AUTHORIZATION request to the \r
+ * oAuth server and requests for the access token (GET ACCESS TOKEN)\r
+ */\r
+ private void getOAuth2AccessTokenFromCapturedRedirection() {\r
+ /// Parse data from OAuth redirection\r
+ String queryParameters = mNewCapturedUriFromOAuth2Redirection.getQuery();\r
+ mNewCapturedUriFromOAuth2Redirection = null;\r
+ \r
+ /// Showing the dialog with instructions for the user.\r
+ showDialog(DIALOG_OAUTH2_LOGIN_PROGRESS);\r
+\r
+ /// GET ACCESS TOKEN to the oAuth server \r
+ RemoteOperation operation = new OAuth2GetAccessToken( getString(R.string.oauth2_client_id), \r
+ getString(R.string.oauth2_redirect_uri), // TODO check - necessary here? \r
+ getString(R.string.oauth2_grant_type),\r
+ queryParameters);\r
+ //WebdavClient client = OwnCloudClientUtils.createOwnCloudClient(Uri.parse(getString(R.string.oauth2_url_endpoint_access)), getApplicationContext());\r
+ WebdavClient client = OwnCloudClientUtils.createOwnCloudClient(Uri.parse(mOAuthTokenEndpointText.getText().toString().trim()), getApplicationContext());\r
+ operation.execute(client, this, mHandler);\r
+ }\r
+ \r
+\r
+ \r
+ /**\r
+ * Handles the change of focus on the text inputs for the server URL and the password\r
+ */\r
+ public void onFocusChange(View view, boolean hasFocus) {\r
+ if (view.getId() == R.id.hostUrlInput) {\r
+ onUrlInputFocusChanged((TextView) view, hasFocus);\r
+ \r
+ } else if (view.getId() == R.id.account_password) {\r
+ onPasswordFocusChanged((TextView) view, hasFocus);\r
+ }\r
+ }\r
+ \r
+\r
+ /**\r
+ * Handles changes in focus on the text input for the server URL.\r
+ * \r
+ * IMPORTANT ENTRY POINT 2: When (!hasFocus), user wrote the server URL and changed to \r
+ * other field. The operation to check the existence of the server in the entered URL is\r
+ * started. \r
+ * \r
+ * When hasFocus: user 'comes back' to write again the server URL.\r
+ * \r
+ * @param hostInput TextView with the URL input field receiving the change of focus.\r
+ * @param hasFocus 'True' if focus is received, 'false' if is lost\r
+ */\r
+ private void onUrlInputFocusChanged(TextView hostInput, boolean hasFocus) {\r
+ if (!hasFocus) {\r
+ checkOcServer();\r
+ \r
+ } else {\r
+ // avoids that the 'connect' button can be clicked if the test was previously passed\r
+ mOkButton.setEnabled(false); \r
+ }\r
+ }\r
+\r
+\r
+ private void checkOcServer() {\r
+ String uri = mHostUrlInput.getText().toString().trim();\r
+ if (uri.length() != 0) {\r
+ mStatusText = R.string.auth_testing_connection;\r
+ mStatusIcon = R.drawable.progress_small;\r
+ updateConnStatus();\r
+ /** TODO cancel previous connection check if the user tries to ammend a wrong URL \r
+ if(mConnChkOperation != null) {\r
+ mConnChkOperation.cancel();\r
+ } */\r
+ mOcServerChkOperation = new OwnCloudServerCheckOperation(uri, this);\r
+ WebdavClient client = OwnCloudClientUtils.createOwnCloudClient(Uri.parse(uri), this);\r
+ mHostBaseUrl = "";\r
+ mDiscoveredVersion = null;\r
+ mOperationThread = mOcServerChkOperation.execute(client, this, mHandler);\r
+ } else {\r
+ mRefreshButton.setVisibility(View.INVISIBLE);\r
+ mStatusText = 0;\r
+ mStatusIcon = 0;\r
+ updateConnStatus();\r
+ }\r
+ }\r
+\r
+\r
+ /**\r
+ * Handles changes in focus on the text input for the password (basic authorization).\r
+ * \r
+ * When (hasFocus), the button to toggle password visibility is shown.\r
+ * \r
+ * When (!hasFocus), the button is made invisible and the password is hidden.\r
+ * \r
+ * @param passwordInput TextView with the password input field receiving the change of focus.\r
+ * @param hasFocus 'True' if focus is received, 'false' if is lost\r
+ */\r
+ private void onPasswordFocusChanged(TextView passwordInput, boolean hasFocus) {\r
+ if (hasFocus) {\r
+ mViewPasswordButton.setVisibility(View.VISIBLE);\r
+ } else {\r
+ int input_type = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;\r
+ passwordInput.setInputType(input_type);\r
+ mViewPasswordButton.setVisibility(View.INVISIBLE);\r
+ }\r
+ }\r
+\r
+\r
+ \r
+ /**\r
+ * Cancels the authenticator activity\r
+ * \r
+ * IMPORTANT ENTRY POINT 3: Never underestimate the importance of cancellation\r
+ * \r
+ * This method is bound in the layout/acceoun_setup.xml resource file.\r
+ * \r
+ * @param view Cancel button\r
+ */\r
+ public void onCancelClick(View view) {\r
+ setResult(RESULT_CANCELED); // TODO review how is this related to AccountAuthenticator (debugging)\r
+ finish();\r
+ }\r
+ \r
+ \r
+ \r
+ /**\r
+ * Checks the credentials of the user in the root of the ownCloud server\r
+ * before creating a new local account.\r
+ * \r
+ * For basic authorization, a check of existence of the root folder is\r
+ * performed.\r
+ * \r
+ * For OAuth, starts the flow to get an access token; the credentials test \r
+ * is postponed until it is available.\r
+ * \r
+ * IMPORTANT ENTRY POINT 4\r
+ * \r
+ * @param view OK button\r
+ */\r
+ public void onOkClick(View view) {\r
+ // this check should be unnecessary\r
+ if (mDiscoveredVersion == null || !mDiscoveredVersion.isVersionValid() || mHostBaseUrl == null || mHostBaseUrl.length() == 0) {\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_wtf_reenter_URL;\r
+ updateConnStatus();\r
+ mOkButton.setEnabled(false);\r
+ Log_OC.wtf(TAG, "The user was allowed to click 'connect' to an unchecked server!!");\r
+ return;\r
+ }\r
+ \r
+ if (mOAuth2Check.isChecked()) {\r
+ startOauthorization();\r
+ \r
+ } else {\r
+ checkBasicAuthorization();\r
+ }\r
+ }\r
+ \r
+ \r
+ /**\r
+ * Tests the credentials entered by the user performing a check of existence on \r
+ * the root folder of the ownCloud server.\r
+ */\r
+ private void checkBasicAuthorization() {\r
+ /// get the path to the root folder through WebDAV from the version server\r
+ String webdav_path = AccountUtils.getWebdavPath(mDiscoveredVersion, false);\r
+ \r
+ /// get basic credentials entered by user\r
+ String username = mUsernameInput.getText().toString();\r
+ String password = mPasswordInput.getText().toString();\r
+ \r
+ /// be gentle with the user\r
+ showDialog(DIALOG_LOGIN_PROGRESS);\r
+ \r
+ /// test credentials accessing the root folder\r
+ mAuthCheckOperation = new ExistenceCheckOperation("", this, false);\r
+ WebdavClient client = OwnCloudClientUtils.createOwnCloudClient(Uri.parse(mHostBaseUrl + webdav_path), this);\r
+ client.setBasicCredentials(username, password);\r
+ mOperationThread = mAuthCheckOperation.execute(client, this, mHandler);\r
+ }\r
+\r
+\r
+ /**\r
+ * Starts the OAuth 'grant type' flow to get an access token, with \r
+ * a GET AUTHORIZATION request to the BUILT-IN authorization server. \r
+ */\r
+ private void startOauthorization() {\r
+ // be gentle with the user\r
+ mStatusIcon = R.drawable.progress_small;\r
+ mStatusText = R.string.oauth_login_connection;\r
+ updateAuthStatus();\r
+ \r
+ // GET AUTHORIZATION request\r
+ //Uri uri = Uri.parse(getString(R.string.oauth2_url_endpoint_auth));\r
+ Uri uri = Uri.parse(mOAuthAuthEndpointText.getText().toString().trim());\r
+ Uri.Builder uriBuilder = uri.buildUpon();\r
+ uriBuilder.appendQueryParameter(OAuth2Constants.KEY_RESPONSE_TYPE, getString(R.string.oauth2_response_type));\r
+ uriBuilder.appendQueryParameter(OAuth2Constants.KEY_REDIRECT_URI, getString(R.string.oauth2_redirect_uri)); \r
+ uriBuilder.appendQueryParameter(OAuth2Constants.KEY_CLIENT_ID, getString(R.string.oauth2_client_id));\r
+ uriBuilder.appendQueryParameter(OAuth2Constants.KEY_SCOPE, getString(R.string.oauth2_scope));\r
+ //uriBuilder.appendQueryParameter(OAuth2Constants.KEY_STATE, whateverwewant);\r
+ uri = uriBuilder.build();\r
+ Log_OC.d(TAG, "Starting browser to view " + uri.toString());\r
+ Intent i = new Intent(Intent.ACTION_VIEW, uri);\r
+ startActivity(i);\r
+ }\r
+\r
+ \r
+ /**\r
+ * Callback method invoked when a RemoteOperation executed by this Activity finishes.\r
+ * \r
+ * Dispatches the operation flow to the right method.\r
+ */\r
+ @Override\r
+ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {\r
+\r
+ if (operation instanceof OwnCloudServerCheckOperation) {\r
+ onOcServerCheckFinish((OwnCloudServerCheckOperation) operation, result);\r
+ \r
+ } else if (operation instanceof OAuth2GetAccessToken) {\r
+ onGetOAuthAccessTokenFinish((OAuth2GetAccessToken)operation, result);\r
+ \r
+ } else if (operation instanceof ExistenceCheckOperation) {\r
+ onAuthorizationCheckFinish((ExistenceCheckOperation)operation, result);\r
+ \r
+ }\r
+ }\r
+ \r
+\r
+ /**\r
+ * Processes the result of the server check performed when the user finishes the enter of the\r
+ * server URL.\r
+ * \r
+ * @param operation Server check performed.\r
+ * @param result Result of the check.\r
+ */\r
+ private void onOcServerCheckFinish(OwnCloudServerCheckOperation operation, RemoteOperationResult result) {\r
+ /// update status icon and text\r
+ updateStatusIconAndText(result);\r
+ updateConnStatus();\r
+\r
+ /// save result state\r
+ mStatusCorrect = result.isSuccess();\r
+ mIsSslConn = (result.getCode() == ResultCode.OK_SSL);\r
+ \r
+ /// very special case (TODO: move to a common place for all the remote operations)\r
+ if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) {\r
+ mLastSslUntrustedServerResult = result;\r
+ showDialog(DIALOG_SSL_VALIDATOR); \r
+ }\r
+ \r
+ /// update the visibility of the 'retry connection' button\r
+ if (!mStatusCorrect)\r
+ mRefreshButton.setVisibility(View.VISIBLE);\r
+ else\r
+ mRefreshButton.setVisibility(View.INVISIBLE);\r
+ \r
+ /// retrieve discovered version and normalize server URL\r
+ mDiscoveredVersion = operation.getDiscoveredVersion();\r
+ mHostBaseUrl = mHostUrlInput.getText().toString().trim();\r
+ if (!mHostBaseUrl.toLowerCase().startsWith("http://") &&\r
+ !mHostBaseUrl.toLowerCase().startsWith("https://")) {\r
+ \r
+ if (mIsSslConn) {\r
+ mHostBaseUrl = "https://" + mHostBaseUrl;\r
+ } else {\r
+ mHostBaseUrl = "http://" + mHostBaseUrl;\r
+ }\r
+ \r
+ }\r
+ if (mHostBaseUrl.endsWith("/"))\r
+ mHostBaseUrl = mHostBaseUrl.substring(0, mHostBaseUrl.length() - 1);\r
+ \r
+ /// allow or not the user try to access the server\r
+ mOkButton.setEnabled(mStatusCorrect);\r
+ }\r
+\r
+\r
+ /**\r
+ * Chooses the right icon and text to show to the user for the received operation result.\r
+ * \r
+ * @param result Result of a remote operation performed in this activity\r
+ */\r
+ private void updateStatusIconAndText(RemoteOperationResult result) {\r
+ mStatusText = mStatusIcon = 0;\r
+\r
+ switch (result.getCode()) {\r
+ case OK_SSL:\r
+ mStatusIcon = android.R.drawable.ic_secure;\r
+ mStatusText = R.string.auth_secure_connection;\r
+ break;\r
+ \r
+ case OK_NO_SSL:\r
+ case OK:\r
+ if (mHostUrlInput.getText().toString().trim().toLowerCase().startsWith("http://") ) {\r
+ mStatusText = R.string.auth_connection_established;\r
+ mStatusIcon = R.drawable.ic_ok;\r
+ } else {\r
+ mStatusText = R.string.auth_nossl_plain_ok_title;\r
+ mStatusIcon = android.R.drawable.ic_partial_secure;\r
+ }\r
+ break;\r
+ \r
+ case SSL_RECOVERABLE_PEER_UNVERIFIED:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_ssl_unverified_server_title;\r
+ break;\r
+ \r
+ case BAD_OC_VERSION:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_bad_oc_version_title;\r
+ break;\r
+ case WRONG_CONNECTION:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_wrong_connection_title;\r
+ break;\r
+ case TIMEOUT:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_timeout_title;\r
+ break;\r
+ case INCORRECT_ADDRESS:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_incorrect_address_title;\r
+ break;\r
+ \r
+ case SSL_ERROR:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_ssl_general_error_title;\r
+ break;\r
+ \r
+ case UNAUTHORIZED:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_unauthorized;\r
+ break;\r
+ case HOST_NOT_AVAILABLE:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_unknown_host_title;\r
+ break;\r
+ case NO_NETWORK_CONNECTION:\r
+ mStatusIcon = R.drawable.no_network;\r
+ mStatusText = R.string.auth_no_net_conn_title;\r
+ break;\r
+ case INSTANCE_NOT_CONFIGURED:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_not_configured_title;\r
+ break;\r
+ case FILE_NOT_FOUND:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_incorrect_path_title;\r
+ break;\r
+ case OAUTH2_ERROR:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_oauth_error;\r
+ break;\r
+ case OAUTH2_ERROR_ACCESS_DENIED:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_oauth_error_access_denied;\r
+ break;\r
+ case UNHANDLED_HTTP_CODE:\r
+ case UNKNOWN_ERROR:\r
+ mStatusIcon = R.drawable.common_error;\r
+ mStatusText = R.string.auth_unknown_error_title;\r
+ break;\r
+ \r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+\r
+ /**\r
+ * Processes the result of the request for and access token send \r
+ * to an OAuth authorization server.\r
+ * \r
+ * @param operation Operation performed requesting the access token.\r
+ * @param result Result of the operation.\r
+ */\r
+ private void onGetOAuthAccessTokenFinish(OAuth2GetAccessToken operation, RemoteOperationResult result) {\r
+ try {\r
+ dismissDialog(DIALOG_OAUTH2_LOGIN_PROGRESS);\r
+ } catch (IllegalArgumentException e) {\r
+ // NOTHING TO DO ; can't find out what situation that leads to the exception in this code, but user logs signal that it happens\r
+ }\r
+\r
+ String webdav_path = AccountUtils.getWebdavPath(mDiscoveredVersion, true);\r
+ if (result.isSuccess() && webdav_path != null) {\r
+ /// be gentle with the user\r
+ showDialog(DIALOG_LOGIN_PROGRESS);\r
+ \r
+ /// time to test the retrieved access token on the ownCloud server\r
+ mOAuthAccessToken = ((OAuth2GetAccessToken)operation).getResultTokenMap().get(OAuth2Constants.KEY_ACCESS_TOKEN);\r
+ Log_OC.d(TAG, "Got ACCESS TOKEN: " + mOAuthAccessToken);\r
+ mAuthCheckOperation = new ExistenceCheckOperation("", this, false);\r
+ WebdavClient client = OwnCloudClientUtils.createOwnCloudClient(Uri.parse(mHostBaseUrl + webdav_path), this);\r
+ client.setBearerCredentials(mOAuthAccessToken);\r
+ mAuthCheckOperation.execute(client, this, mHandler);\r
+ \r
+ } else {\r
+ updateStatusIconAndText(result);\r
+ updateAuthStatus();\r
+ Log_OC.d(TAG, "Access failed: " + result.getLogMessage());\r
+ }\r
+ }\r
+\r
+ \r
+ /**\r
+ * Processes the result of the access check performed to try the user credentials.\r
+ * \r
+ * Creates a new account through the AccountManager.\r
+ * \r
+ * @param operation Access check performed.\r
+ * @param result Result of the operation.\r
+ */\r
+ private void onAuthorizationCheckFinish(ExistenceCheckOperation operation, RemoteOperationResult result) {\r
+ try {\r
+ dismissDialog(DIALOG_LOGIN_PROGRESS);\r
+ } catch (IllegalArgumentException e) {\r
+ // NOTHING TO DO ; can't find out what situation that leads to the exception in this code, but user logs signal that it happens\r
+ }\r
+ \r
+ if (result.isSuccess()) {\r
+ Log_OC.d(TAG, "Successful access - time to save the account");\r
+\r
+ if (mAction == ACTION_CREATE) {\r
+ createAccount();\r
+ \r
+ } else {\r
+ updateToken();\r
+ }\r
+ \r
+ finish();\r
+ \r
+ } else {\r
+ updateStatusIconAndText(result);\r
+ updateAuthStatus();\r
+ Log_OC.d(TAG, "Access failed: " + result.getLogMessage());\r
+ }\r
+ }\r
+\r
+ \r
+ /**\r
+ * Sets the proper response to get that the Account Authenticator that started this activity saves \r
+ * a new authorization token for mAccount.\r
+ */\r
+ private void updateToken() {\r
+ Bundle response = new Bundle();\r
+ response.putString(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);\r
+ response.putString(AccountManager.KEY_ACCOUNT_TYPE, mAccount.type);\r
+ boolean isOAuth = mOAuth2Check.isChecked();\r
+ if (isOAuth) {\r
+ response.putString(AccountManager.KEY_AUTHTOKEN, mOAuthAccessToken);\r
+ // the next line is necessary; by now, notifications are calling directly to the AuthenticatorActivity to update, without AccountManager intervention\r
+ mAccountMgr.setAuthToken(mAccount, AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN, mOAuthAccessToken);\r
+ } else {\r
+ response.putString(AccountManager.KEY_AUTHTOKEN, mPasswordInput.getText().toString());\r
+ mAccountMgr.setPassword(mAccount, mPasswordInput.getText().toString());\r
+ }\r
+ setAccountAuthenticatorResult(response);\r
+ }\r
+\r
+\r
+ /**\r
+ * Creates a new account through the Account Authenticator that started this activity. \r
+ * \r
+ * This makes the account permanent.\r
+ * \r
+ * TODO Decide how to name the OAuth accounts\r
+ */\r
+ private void createAccount() {\r
+ /// create and save new ownCloud account\r
+ boolean isOAuth = mOAuth2Check.isChecked();\r
+ \r
+ Uri uri = Uri.parse(mHostBaseUrl);\r
+ String username = mUsernameInput.getText().toString().trim();\r
+ if (isOAuth) {\r
+ username = "OAuth_user" + (new java.util.Random(System.currentTimeMillis())).nextLong();\r
+ } \r
+ String accountName = username + "@" + uri.getHost();\r
+ if (uri.getPort() >= 0) {\r
+ accountName += ":" + uri.getPort();\r
+ }\r
+ mAccount = new Account(accountName, AccountAuthenticator.ACCOUNT_TYPE);\r
+ if (isOAuth) {\r
+ mAccountMgr.addAccountExplicitly(mAccount, "", null); // with our implementation, the password is never input in the app\r
+ } else {\r
+ mAccountMgr.addAccountExplicitly(mAccount, mPasswordInput.getText().toString(), null);\r
+ }\r
+\r
+ /// add the new account as default in preferences, if there is none already\r
+ Account defaultAccount = AccountUtils.getCurrentOwnCloudAccount(this);\r
+ if (defaultAccount == null) {\r
+ SharedPreferences.Editor editor = PreferenceManager\r
+ .getDefaultSharedPreferences(this).edit();\r
+ editor.putString("select_oc_account", accountName);\r
+ editor.commit();\r
+ }\r
+\r
+ /// prepare result to return to the Authenticator\r
+ // TODO check again what the Authenticator makes with it; probably has the same effect as addAccountExplicitly, but it's not well done\r
+ final Intent intent = new Intent(); \r
+ intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, AccountAuthenticator.ACCOUNT_TYPE);\r
+ intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);\r
+ if (!isOAuth)\r
+ intent.putExtra(AccountManager.KEY_AUTHTOKEN, AccountAuthenticator.ACCOUNT_TYPE); // TODO check this; not sure it's right; maybe\r
+ intent.putExtra(AccountManager.KEY_USERDATA, username);\r
+ if (isOAuth) {\r
+ mAccountMgr.setAuthToken(mAccount, AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN, mOAuthAccessToken);\r
+ }\r
+ /// add user data to the new account; TODO probably can be done in the last parameter addAccountExplicitly, or in KEY_USERDATA\r
+ mAccountMgr.setUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION, mDiscoveredVersion.toString());\r
+ mAccountMgr.setUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL, mHostBaseUrl);\r
+ if (isOAuth)\r
+ mAccountMgr.setUserData(mAccount, AccountAuthenticator.KEY_SUPPORTS_OAUTH2, "TRUE"); // TODO this flag should be unnecessary\r
+ \r
+ setAccountAuthenticatorResult(intent.getExtras());\r
+ setResult(RESULT_OK, intent);\r
+ \r
+ /// immediately request for the synchronization of the new account\r
+ Bundle bundle = new Bundle();\r
+ bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);\r
+ ContentResolver.requestSync(mAccount, AccountAuthenticator.AUTHORITY, bundle);\r
+ }\r
+\r
+\r
+ /**\r
+ * {@inheritDoc}\r
+ * \r
+ * Necessary to update the contents of the SSL Dialog\r
+ * \r
+ * TODO move to some common place for all possible untrusted SSL failures\r
+ */\r
+ @Override\r
+ protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {\r
+ switch (id) {\r
+ case DIALOG_LOGIN_PROGRESS:\r
+ case DIALOG_CERT_NOT_SAVED:\r
+ case DIALOG_OAUTH2_LOGIN_PROGRESS:\r
+ break;\r
+ case DIALOG_SSL_VALIDATOR: {\r
+ ((SslValidatorDialog)dialog).updateResult(mLastSslUntrustedServerResult);\r
+ break;\r
+ }\r
+ default:\r
+ Log_OC.e(TAG, "Incorrect dialog called with id = " + id);\r
+ }\r
+ }\r
+\r
+ \r
+ /**\r
+ * {@inheritDoc}\r
+ */\r
+ @Override\r
+ protected Dialog onCreateDialog(int id) {\r
+ Dialog dialog = null;\r
+ switch (id) {\r
+ case DIALOG_LOGIN_PROGRESS: {\r
+ /// simple progress dialog\r
+ ProgressDialog working_dialog = new ProgressDialog(this);\r
+ working_dialog.setMessage(getResources().getString(R.string.auth_trying_to_login));\r
+ working_dialog.setIndeterminate(true);\r
+ working_dialog.setCancelable(true);\r
+ working_dialog\r
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {\r
+ @Override\r
+ public void onCancel(DialogInterface dialog) {\r
+ /// TODO study if this is enough\r
+ Log_OC.i(TAG, "Login canceled");\r
+ if (mOperationThread != null) {\r
+ mOperationThread.interrupt();\r
+ finish();\r
+ }\r
+ }\r
+ });\r
+ dialog = working_dialog;\r
+ break;\r
+ }\r
+ case DIALOG_OAUTH2_LOGIN_PROGRESS: {\r
+ ProgressDialog working_dialog = new ProgressDialog(this);\r
+ working_dialog.setMessage(String.format("Getting authorization")); \r
+ working_dialog.setIndeterminate(true);\r
+ working_dialog.setCancelable(true);\r
+ working_dialog\r
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {\r
+ @Override\r
+ public void onCancel(DialogInterface dialog) {\r
+ Log_OC.i(TAG, "Login canceled");\r
+ finish();\r
+ }\r
+ });\r
+ dialog = working_dialog;\r
+ break;\r
+ }\r
+ case DIALOG_SSL_VALIDATOR: {\r
+ /// TODO start to use new dialog interface, at least for this (it is a FragmentDialog already)\r
+ dialog = SslValidatorDialog.newInstance(this, mLastSslUntrustedServerResult, this);\r
+ break;\r
+ }\r
+ case DIALOG_CERT_NOT_SAVED: {\r
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);\r
+ builder.setMessage(getResources().getString(R.string.ssl_validator_not_saved));\r
+ builder.setCancelable(false);\r
+ builder.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {\r
+ @Override\r
+ public void onClick(DialogInterface dialog, int which) {\r
+ dialog.dismiss();\r
+ };\r
+ });\r
+ dialog = builder.create();\r
+ break;\r
+ }\r
+ default:\r
+ Log_OC.e(TAG, "Incorrect dialog called with id = " + id);\r
+ }\r
+ return dialog;\r
+ }\r
+\r
+ \r
+ /**\r
+ * Starts and activity to open the 'new account' page in the ownCloud web site\r
+ * \r
+ * @param view 'Account register' button\r
+ */\r
+ public void onRegisterClick(View view) {\r
+ Intent register = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.url_account_register)));\r
+ setResult(RESULT_CANCELED);\r
+ startActivity(register);\r
+ }\r
+\r
+ \r
+ /**\r
+ * Updates the content and visibility state of the icon and text associated\r
+ * to the last check on the ownCloud server.\r
+ */\r
+ private void updateConnStatus() {\r
+ ImageView iv = (ImageView) findViewById(R.id.action_indicator);\r
+ TextView tv = (TextView) findViewById(R.id.status_text);\r
+\r
+ if (mStatusIcon == 0 && mStatusText == 0) {\r
+ iv.setVisibility(View.INVISIBLE);\r
+ tv.setVisibility(View.INVISIBLE);\r
+ } else {\r
+ iv.setImageResource(mStatusIcon);\r
+ tv.setText(mStatusText);\r
+ iv.setVisibility(View.VISIBLE);\r
+ tv.setVisibility(View.VISIBLE);\r
+ }\r
+ }\r
+ \r
+ \r
+ /**\r
+ * Updates the content and visibility state of the icon and text associated\r
+ * to the interactions with the OAuth authorization server.\r
+ */\r
+ private void updateAuthStatus() {\r
+ if (mStatusIcon == 0 && mStatusText == 0) {\r
+ mAuthStatusLayout.setVisibility(View.INVISIBLE);\r
+ } else {\r
+ mAuthStatusLayout.setText(mStatusText);\r
+ mAuthStatusLayout.setCompoundDrawablesWithIntrinsicBounds(mStatusIcon, 0, 0, 0);\r
+ mAuthStatusLayout.setVisibility(View.VISIBLE);\r
+ }\r
+ } \r
+\r
+ \r
+ /**\r
+ * Called when the refresh button in the input field for ownCloud host is clicked.\r
+ * \r
+ * Performs a new check on the URL in the input field.\r
+ * \r
+ * @param view Refresh 'button'\r
+ */\r
+ public void onRefreshClick(View view) {\r
+ onFocusChange(mRefreshButton, false);\r
+ }\r
+ \r
+ \r
+ /**\r
+ * Called when the eye icon in the password field is clicked.\r
+ * \r
+ * Toggles the visibility of the password in the field. \r
+ * \r
+ * @param view 'View password' 'button'\r
+ */\r
+ public void onViewPasswordClick(View view) {\r
+ int selectionStart = mPasswordInput.getSelectionStart();\r
+ int selectionEnd = mPasswordInput.getSelectionEnd();\r
+ int input_type = mPasswordInput.getInputType();\r
+ if ((input_type & InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {\r
+ input_type = InputType.TYPE_CLASS_TEXT\r
+ | InputType.TYPE_TEXT_VARIATION_PASSWORD;\r
+ } else {\r
+ input_type = InputType.TYPE_CLASS_TEXT\r
+ | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;\r
+ }\r
+ mPasswordInput.setInputType(input_type);\r
+ mPasswordInput.setSelection(selectionStart, selectionEnd);\r
+ } \r
+ \r
+ \r
+ /**\r
+ * Called when the checkbox for OAuth authorization is clicked.\r
+ * \r
+ * Hides or shows the input fields for user & password. \r
+ * \r
+ * @param view 'View password' 'button'\r
+ */\r
+ public void onCheckClick(View view) {\r
+ CheckBox oAuth2Check = (CheckBox)view; \r
+ changeViewByOAuth2Check(oAuth2Check.isChecked());\r
+\r
+ }\r
+ \r
+ /**\r
+ * Changes the visibility of input elements depending upon the kind of authorization\r
+ * chosen by the user: basic or OAuth\r
+ * \r
+ * @param checked 'True' when OAuth is selected.\r
+ */\r
+ public void changeViewByOAuth2Check(Boolean checked) {\r
+ \r
+ if (checked) {\r
+ mOAuthAuthEndpointText.setVisibility(View.VISIBLE);\r
+ mOAuthTokenEndpointText.setVisibility(View.VISIBLE);\r
+ mUsernameInput.setVisibility(View.GONE);\r
+ mPasswordInput.setVisibility(View.GONE);\r
+ mViewPasswordButton.setVisibility(View.GONE);\r
+ } else {\r
+ mOAuthAuthEndpointText.setVisibility(View.GONE);\r
+ mOAuthTokenEndpointText.setVisibility(View.GONE);\r
+ mUsernameInput.setVisibility(View.VISIBLE);\r
+ mPasswordInput.setVisibility(View.VISIBLE);\r
+ mViewPasswordButton.setVisibility(View.INVISIBLE);\r
+ } \r
+\r
+ } \r
+ \r
+ /**\r
+ * Called from SslValidatorDialog when a new server certificate was correctly saved.\r
+ */\r
+ public void onSavedCertificate() {\r
+ mOperationThread = mOcServerChkOperation.retry(this, mHandler); \r
+ }\r
+\r
+ /**\r
+ * Called from SslValidatorDialog when a new server certificate could not be saved \r
+ * when the user requested it.\r
+ */\r
+ @Override\r
+ public void onFailedSavingCertificate() {\r
+ showDialog(DIALOG_CERT_NOT_SAVED);\r
+ }\r
+\r
+}\r
--- /dev/null
+/* ownCloud Android client application
+ * Copyright (C) 2012-2013 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * 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 com.owncloud.android.authentication;
+
+/**
+ * Constant values for OAuth 2 protocol.
+ *
+ * Includes required and optional parameter NAMES used in the 'authorization code' grant type.
+ *
+ * @author David A. Velasco
+ */
+
+public class OAuth2Constants {
+
+ /// Parameters to send to the Authorization Endpoint
+ public static final String KEY_RESPONSE_TYPE = "response_type";
+ public static final String KEY_REDIRECT_URI = "redirect_uri";
+ public static final String KEY_CLIENT_ID = "client_id";
+ public static final String KEY_SCOPE = "scope";
+ public static final String KEY_STATE = "state";
+
+ /// Additional parameters to send to the Token Endpoint
+ public static final String KEY_GRANT_TYPE = "grant_type";
+ public static final String KEY_CODE = "code";
+
+ /// Parameters received in an OK response from the Token Endpoint
+ public static final String KEY_ACCESS_TOKEN = "access_token";
+ public static final String KEY_TOKEN_TYPE = "token_type";
+ public static final String KEY_EXPIRES_IN = "expires_in";
+ public static final String KEY_REFRESH_TOKEN = "refresh_token";
+
+ /// Parameters in an ERROR response
+ public static final String KEY_ERROR = "error";
+ public static final String KEY_ERROR_DESCRIPTION = "error_description";
+ public static final String KEY_ERROR_URI = "error_uri";
+ public static final String VALUE_ERROR_ACCESS_DENIED = "access_denied";
+
+}
+++ /dev/null
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- * Copyright (C) 2012-2013 ownCloud Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * 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 com.owncloud.android.authenticator;
-
-import com.owncloud.android.Log_OC;
-import com.owncloud.android.ui.activity.AuthenticatorActivity;
-
-import android.accounts.*;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-
-public class AccountAuthenticator extends AbstractAccountAuthenticator {
- /**
- * Is used by android system to assign accounts to authenticators. Should be
- * used by application and all extensions.
- */
- public static final String ACCOUNT_TYPE = "owncloud";
- public static final String AUTH_TOKEN_TYPE = "org.owncloud";
-
- public static final String KEY_AUTH_TOKEN_TYPE = "authTokenType";
- public static final String KEY_REQUIRED_FEATURES = "requiredFeatures";
- public static final String KEY_LOGIN_OPTIONS = "loginOptions";
- public static final String KEY_ACCOUNT = "account";
- /**
- * Value under this key should handle path to webdav php script. Will be
- * removed and usage should be replaced by combining
- * {@link com.owncloud.android.authenticator.AuthenticatorActivity.KEY_OC_BASE_URL} and
- * {@link com.owncloud.android.utils.OwnCloudVersion}
- *
- * @deprecated
- */
- public static final String KEY_OC_URL = "oc_url";
- /**
- * Version should be 3 numbers separated by dot so it can be parsed by
- * {@link com.owncloud.android.utils.OwnCloudVersion}
- */
- public static final String KEY_OC_VERSION = "oc_version";
- /**
- * Base url should point to owncloud installation without trailing / ie:
- * http://server/path or https://owncloud.server
- */
- public static final String KEY_OC_BASE_URL = "oc_base_url";
-
- private static final String TAG = "AccountAuthenticator";
- private Context mContext;
-
- public AccountAuthenticator(Context context) {
- super(context);
- mContext = context;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Bundle addAccount(AccountAuthenticatorResponse response,
- String accountType, String authTokenType,
- String[] requiredFeatures, Bundle options)
- throws NetworkErrorException {
- Log_OC.i(TAG, "Adding account with type " + accountType
- + " and auth token " + authTokenType);
- try {
- validateAccountType(accountType);
- } catch (AuthenticatorException e) {
- Log_OC.e(TAG, "Failed to validate account type " + accountType + ": "
- + e.getMessage());
- e.printStackTrace();
- return e.getFailureBundle();
- }
- final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
- intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
- response);
- intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
- intent.putExtra(KEY_REQUIRED_FEATURES, requiredFeatures);
- intent.putExtra(KEY_LOGIN_OPTIONS, options);
-
- setIntentFlags(intent);
- final Bundle bundle = new Bundle();
- bundle.putParcelable(AccountManager.KEY_INTENT, intent);
- return bundle;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Bundle confirmCredentials(AccountAuthenticatorResponse response,
- Account account, Bundle options) throws NetworkErrorException {
- try {
- validateAccountType(account.type);
- } catch (AuthenticatorException e) {
- Log_OC.e(TAG, "Failed to validate account type " + account.type + ": "
- + e.getMessage());
- e.printStackTrace();
- return e.getFailureBundle();
- }
- Intent intent = new Intent(mContext, AuthenticatorActivity.class);
- intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
- response);
- intent.putExtra(KEY_ACCOUNT, account);
- intent.putExtra(KEY_LOGIN_OPTIONS, options);
-
- setIntentFlags(intent);
-
- Bundle resultBundle = new Bundle();
- resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);
- return resultBundle;
- }
-
- @Override
- public Bundle editProperties(AccountAuthenticatorResponse response,
- String accountType) {
- return null;
- }
-
- @Override
- public Bundle getAuthToken(AccountAuthenticatorResponse response,
- Account account, String authTokenType, Bundle options)
- throws NetworkErrorException {
- try {
- validateAccountType(account.type);
- validateAuthTokenType(authTokenType);
- } catch (AuthenticatorException e) {
- Log_OC.e(TAG, "Failed to validate account type " + account.type + ": "
- + e.getMessage());
- e.printStackTrace();
- return e.getFailureBundle();
- }
- final AccountManager am = AccountManager.get(mContext);
- final String password = am.getPassword(account);
- if (password != null) {
- final Bundle result = new Bundle();
- result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
- result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
- result.putString(AccountManager.KEY_AUTHTOKEN, password);
- return result;
- }
-
- final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
- intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
- response);
- intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
- intent.putExtra(KEY_LOGIN_OPTIONS, options);
- intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
-
- final Bundle bundle = new Bundle();
- bundle.putParcelable(AccountManager.KEY_INTENT, intent);
- return bundle;
- }
-
- @Override
- public String getAuthTokenLabel(String authTokenType) {
- return null;
- }
-
- @Override
- public Bundle hasFeatures(AccountAuthenticatorResponse response,
- Account account, String[] features) throws NetworkErrorException {
- final Bundle result = new Bundle();
- result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
- return result;
- }
-
- @Override
- public Bundle updateCredentials(AccountAuthenticatorResponse response,
- Account account, String authTokenType, Bundle options)
- throws NetworkErrorException {
- final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
- intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
- response);
- intent.putExtra(KEY_ACCOUNT, account);
- intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
- intent.putExtra(KEY_LOGIN_OPTIONS, options);
- setIntentFlags(intent);
-
- final Bundle bundle = new Bundle();
- bundle.putParcelable(AccountManager.KEY_INTENT, intent);
- return bundle;
- }
-
- @Override
- public Bundle getAccountRemovalAllowed(
- AccountAuthenticatorResponse response, Account account)
- throws NetworkErrorException {
- return super.getAccountRemovalAllowed(response, account);
- }
-
- private void setIntentFlags(Intent intent) {
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
- intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
- intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
- }
-
- private void validateAccountType(String type)
- throws UnsupportedAccountTypeException {
- if (!type.equals(ACCOUNT_TYPE)) {
- throw new UnsupportedAccountTypeException();
- }
- }
-
- private void validateAuthTokenType(String authTokenType)
- throws UnsupportedAuthTokenTypeException {
- if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {
- throw new UnsupportedAuthTokenTypeException();
- }
- }
-
- public static class AuthenticatorException extends Exception {
- private static final long serialVersionUID = 1L;
- private Bundle mFailureBundle;
-
- public AuthenticatorException(int code, String errorMsg) {
- mFailureBundle = new Bundle();
- mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);
- mFailureBundle
- .putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
- }
-
- public Bundle getFailureBundle() {
- return mFailureBundle;
- }
- }
-
- public static class UnsupportedAccountTypeException extends
- AuthenticatorException {
- private static final long serialVersionUID = 1L;
-
- public UnsupportedAccountTypeException() {
- super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
- "Unsupported account type");
- }
- }
-
- public static class UnsupportedAuthTokenTypeException extends
- AuthenticatorException {
- private static final long serialVersionUID = 1L;
-
- public UnsupportedAuthTokenTypeException() {
- super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
- "Unsupported auth token type");
- }
- }
-
- public static class UnsupportedFeaturesException extends
- AuthenticatorException {
- public static final long serialVersionUID = 1L;
-
- public UnsupportedFeaturesException() {
- super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
- "Unsupported features");
- }
- }
-
- public static class AccessDeniedException extends AuthenticatorException {
- public AccessDeniedException(int code, String errorMsg) {
- super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");
- }
-
- private static final long serialVersionUID = 1L;
-
- }
-}
+++ /dev/null
-/* ownCloud Android client application
- * Copyright (C) 2011 Bartek Przybylski
- * Copyright (C) 2012-2013 ownCloud Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * 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 com.owncloud.android.authenticator;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-public class AccountAuthenticatorService extends Service {
-
- private AccountAuthenticator mAuthenticator;
- static final public String ACCOUNT_TYPE = "owncloud";
-
- @Override
- public void onCreate() {
- super.onCreate();
- mAuthenticator = new AccountAuthenticator(this);
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return mAuthenticator.getIBinder();
- }
-
-}
+++ /dev/null
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- * Copyright (C) 2012-2013 ownCloud Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * 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 com.owncloud.android.authenticator;
-
-import java.net.URL;
-
-import org.apache.commons.httpclient.HttpStatus;
-
-import com.owncloud.android.R;
-import com.owncloud.android.network.OwnCloudClientUtils;
-
-import eu.alefzero.webdav.WebdavClient;
-
-import android.content.Context;
-import android.net.Uri;
-import android.os.Handler;
-
-public class AuthenticationRunnable implements Runnable {
-
- private OnAuthenticationResultListener mListener;
- private Handler mHandler;
- private URL mUrl;
- private String mUsername;
- private String mPassword;
- private Context mContext;
-
- public AuthenticationRunnable(URL url, String username, String password, Context context) {
- mListener = null;
- mUrl = url;
- mUsername = username;
- mPassword = password;
- mContext = context;
- }
-
- public void setOnAuthenticationResultListener(
- OnAuthenticationResultListener listener, Handler handler) {
- mListener = listener;
- mHandler = handler;
- }
-
- @Override
- public void run() {
- Uri uri;
- uri = Uri.parse(mUrl.toString());
- WebdavClient wdc = OwnCloudClientUtils.createOwnCloudClient(uri, mUsername, mPassword, mContext);
- int login_result = wdc.tryToLogin();
- switch (login_result) {
- case HttpStatus.SC_OK:
- postResult(true, uri.toString());
- break;
- case HttpStatus.SC_UNAUTHORIZED:
- postResult(false, mContext.getString(R.string.auth_unauthorized));
- break;
- case HttpStatus.SC_NOT_FOUND:
- postResult(false, mContext.getString(R.string.auth_not_found));
- break;
- default:
- postResult(false, String.format(mContext.getString(R.string.auth_internal), login_result));
- }
- }
-
- private void postResult(final boolean success, final String message) {
- if (mHandler != null && mListener != null) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mListener.onAuthenticationResult(success, message);
- }
- });
- }
- }
-}
+++ /dev/null
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- * Copyright (C) 2012-2013 ownCloud Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * 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 com.owncloud.android.authenticator;
-
-public interface OnAuthenticationResultListener {
-
- public void onAuthenticationResult(boolean success, String message);
-
-}
+++ /dev/null
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- * Copyright (C) 2012-2013 ownCloud Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * 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 com.owncloud.android.authenticator;
-
-public interface OnConnectCheckListener {
-
- enum ResultType {
- OK_SSL, OK_NO_SSL, SSL_INIT_ERROR, HOST_NOT_AVAILABLE, TIMEOUT, NO_NETWORK_CONNECTION, INCORRECT_ADDRESS, INSTANCE_NOT_CONFIGURED, FILE_NOT_FOUND, UNKNOWN_ERROR, WRONG_CONNECTION, SSL_UNVERIFIED_SERVER, BAD_OC_VERSION
- }
-
- public void onConnectionCheckResult(ResultType type);
-
-}
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
-import android.util.Log;
public class FileDataStorageManager implements DataStorageManager {
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
/**
* Custom database helper for ownCloud
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.app.ListActivity;
import android.os.Bundle;
import android.os.Handler;
-import android.util.Log;
import android.widget.SimpleAdapter;
public class ExtensionsListActivity extends ListActivity {
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.util.Log;
public class BootupBroadcastReceiver extends BroadcastReceiver {
import java.io.File;
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authentication.AccountAuthenticator;
+import com.owncloud.android.db.DbHandler;
+import com.owncloud.android.files.services.FileUploader;
+
import android.accounts.Account;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.provider.MediaStore.Images.Media;
import android.webkit.MimeTypeMap;
-import com.owncloud.android.AccountUtils;
import com.owncloud.android.Log_OC;
-import com.owncloud.android.authenticator.AccountAuthenticator;
-import com.owncloud.android.db.DbHandler;
-import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.utils.FileStorageUtils;
public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.network.OwnCloudClientUtils;
import com.owncloud.android.operations.RemoteOperationResult;
import com.owncloud.android.operations.SynchronizeFileOperation;
import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.ui.activity.ConflictsResolveActivity;
-import eu.alefzero.webdav.WebdavClient;
import android.accounts.Account;
import android.content.Context;
import android.content.Intent;
import android.os.FileObserver;
-import android.util.Log;
public class OwnCloudFileObserver extends FileObserver {
mPath);
return;
}
- WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(mOCAccount, mContext);
FileDataStorageManager storageManager = new FileDataStorageManager(mOCAccount, mContext.getContentResolver());
OCFile file = storageManager.getFileByLocalPath(mPath); // a fresh object is needed; many things could have occurred to the file since it was registered to observe
// again, assuming that local files are linked to a remote file AT MOST, SOMETHING TO BE DONE;
true,
true,
mContext);
- RemoteOperationResult result = sfo.execute(wc);
+ RemoteOperationResult result = sfo.execute(mOCAccount, mContext);
if (result.getCode() == ResultCode.SYNC_CONFLICT) {
// ISSUE 5: if the user is not running the app (this is a service!), this can be very intrusive; a notification should be preferred
Intent i = new Intent(mContext, ConflictsResolveActivity.class);
package com.owncloud.android.files.services;
import java.io.File;
+import java.io.IOException;
import java.util.AbstractList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import com.owncloud.android.authentication.AuthenticatorActivity;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import eu.alefzero.webdav.OnDatatransferProgressListener;
import com.owncloud.android.network.OwnCloudClientUtils;
import com.owncloud.android.operations.DownloadFileOperation;
import com.owncloud.android.operations.RemoteOperationResult;
+import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.ui.activity.FileDetailActivity;
import com.owncloud.android.ui.fragment.FileDetailFragment;
import com.owncloud.android.ui.preview.PreviewImageActivity;
import com.owncloud.android.ui.preview.PreviewImageFragment;
import android.accounts.Account;
+import android.accounts.AccountsException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
mBinder = new FileDownloaderBinder();
}
-
/**
* Entry point to add one or several files to the queue of downloads.
*
}
-
/**
* Removes a listener interested in the progress of the download for a concrete file.
*
}
}
-
/**
* Core download method: requests a file to download and stores it.
notifyDownloadStart(mCurrentDownload);
- /// prepare client object to send the request to the ownCloud server
- if (mDownloadClient == null || !mLastAccount.equals(mCurrentDownload.getAccount())) {
- mLastAccount = mCurrentDownload.getAccount();
- mStorageManager = new FileDataStorageManager(mLastAccount, getContentResolver());
- mDownloadClient = OwnCloudClientUtils.createOwnCloudClient(mLastAccount, getApplicationContext());
- }
-
- /// perform the download
RemoteOperationResult downloadResult = null;
try {
+ /// prepare client object to send the request to the ownCloud server
+ if (mDownloadClient == null || !mLastAccount.equals(mCurrentDownload.getAccount())) {
+ mLastAccount = mCurrentDownload.getAccount();
+ mStorageManager = new FileDataStorageManager(mLastAccount, getContentResolver());
+ mDownloadClient = OwnCloudClientUtils.createOwnCloudClient(mLastAccount, getApplicationContext());
+ }
+
+ /// perform the download
downloadResult = mCurrentDownload.execute(mDownloadClient);
if (downloadResult.isSuccess()) {
saveDownloadedFile();
}
+ } catch (AccountsException e) {
+ Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
+ downloadResult = new RemoteOperationResult(e);
+ } catch (IOException e) {
+ Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
+ downloadResult = new RemoteOperationResult(e);
+
} finally {
synchronized(mPendingDownloads) {
mPendingDownloads.remove(downloadKey);
int contentId = (downloadResult.isSuccess()) ? R.string.downloader_download_succeeded_content : R.string.downloader_download_failed_content;
Notification finalNotification = new Notification(R.drawable.icon, getString(tickerId), System.currentTimeMillis());
finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;
- Intent showDetailsIntent = null;
- if (downloadResult.isSuccess()) {
- if (PreviewImageFragment.canBePreviewed(download.getFile())) {
- showDetailsIntent = new Intent(this, PreviewImageActivity.class);
- } else {
- showDetailsIntent = new Intent(this, FileDetailActivity.class);
- }
- showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, download.getFile());
- showDetailsIntent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, download.getAccount());
- showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ boolean needsToUpdateCredentials = (downloadResult.getCode() == ResultCode.UNAUTHORIZED);
+ if (needsToUpdateCredentials) {
+ // let the user update credentials with one click
+ Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
+ updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, download.getAccount());
+ updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_UPDATE_TOKEN);
+ updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
+ finalNotification.contentIntent = PendingIntent.getActivity(this, (int)System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT);
+ finalNotification.setLatestEventInfo( getApplicationContext(),
+ getString(tickerId),
+ String.format(getString(contentId), new File(download.getSavePath()).getName()),
+ finalNotification.contentIntent);
+ mDownloadClient = null; // grant that future retries on the same account will get the fresh credentials
} else {
- // TODO put something smart in showDetailsIntent
- showDetailsIntent = new Intent();
+ Intent showDetailsIntent = null;
+ if (downloadResult.isSuccess()) {
+ if (PreviewImageFragment.canBePreviewed(download.getFile())) {
+ showDetailsIntent = new Intent(this, PreviewImageActivity.class);
+ } else {
+ showDetailsIntent = new Intent(this, FileDetailActivity.class);
+ }
+ showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, download.getFile());
+ showDetailsIntent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, download.getAccount());
+ showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+ } else {
+ // TODO put something smart in showDetailsIntent
+ showDetailsIntent = new Intent();
+ }
+ finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int)System.currentTimeMillis(), showDetailsIntent, 0);
+ finalNotification.setLatestEventInfo(getApplicationContext(), getString(tickerId), String.format(getString(contentId), new File(download.getSavePath()).getName()), finalNotification.contentIntent);
}
- finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int)System.currentTimeMillis(), showDetailsIntent, 0);
- finalNotification.setLatestEventInfo(getApplicationContext(), getString(tickerId), String.format(getString(contentId), new File(download.getSavePath()).getName()), finalNotification.contentIntent);
mNotificationManager.notify(tickerId, finalNotification);
}
}
import android.database.Cursor;
import android.os.Binder;
import android.os.IBinder;
-import android.util.Log;
public class FileObserverService extends Service {
+++ /dev/null
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- * Copyright (C) 2012-2013 ownCloud Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * 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 com.owncloud.android.files.services;
-
-import java.io.File;
-
-import com.owncloud.android.AccountUtils;
-import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.network.OwnCloudClientUtils;
-
-import android.accounts.Account;
-import android.content.Context;
-import eu.alefzero.webdav.WebdavClient;
-
-public class FileOperation {
-
- Context mContext;
-
- public FileOperation(Context contex){
- this.mContext = contex;
- }
-
- /**
- * Deletes a file from ownCloud - locally and remote.
- * @param file The file to delete
- * @return True on success, otherwise false
- */
- public boolean delete(OCFile file){
-
- Account account = AccountUtils.getCurrentOwnCloudAccount(mContext);
- WebdavClient client = OwnCloudClientUtils.createOwnCloudClient(account, mContext);
- if(client.deleteFile(file.getRemotePath())){
- File localFile = new File(file.getStoragePath());
- return localFile.delete();
- }
-
- return false;
- }
-
-}
package com.owncloud.android.files.services;
import java.io.File;
+import java.io.IOException;
import java.util.AbstractList;
import java.util.HashMap;
import java.util.Iterator;
import org.apache.jackrabbit.webdav.MultiStatus;
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
+import com.owncloud.android.authentication.AccountAuthenticator;
+import com.owncloud.android.authentication.AuthenticatorActivity;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.operations.ChunkedUploadFileOperation;
+import com.owncloud.android.operations.CreateFolderOperation;
+import com.owncloud.android.operations.RemoteOperation;
+import com.owncloud.android.operations.RemoteOperationResult;
+import com.owncloud.android.operations.UploadFileOperation;
+import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
+import com.owncloud.android.ui.activity.FileDetailActivity;
+import com.owncloud.android.ui.fragment.FileDetailFragment;
+import com.owncloud.android.utils.OwnCloudVersion;
+
+import eu.alefzero.webdav.OnDatatransferProgressListener;
+import eu.alefzero.webdav.WebdavEntry;
+import eu.alefzero.webdav.WebdavUtils;
+
+import com.owncloud.android.network.OwnCloudClientUtils;
+
import android.accounts.Account;
import android.accounts.AccountManager;
+import android.accounts.AccountsException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.os.Process;
import android.webkit.MimeTypeMap;
import android.widget.RemoteViews;
-import android.widget.Toast;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
-import com.owncloud.android.authenticator.AccountAuthenticator;
-import com.owncloud.android.datamodel.FileDataStorageManager;
-import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.db.DbHandler;
-import com.owncloud.android.network.OwnCloudClientUtils;
-import com.owncloud.android.operations.ChunkedUploadFileOperation;
-import com.owncloud.android.operations.RemoteOperationResult;
-import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
-import com.owncloud.android.operations.UploadFileOperation;
import com.owncloud.android.ui.activity.FailedUploadActivity;
-import com.owncloud.android.ui.activity.FileDetailActivity;
import com.owncloud.android.ui.activity.InstantUploadActivity;
-import com.owncloud.android.ui.fragment.FileDetailFragment;
import com.owncloud.android.ui.preview.PreviewImageActivity;
import com.owncloud.android.ui.preview.PreviewImageFragment;
import com.owncloud.android.utils.FileStorageUtils;
-import com.owncloud.android.utils.OwnCloudVersion;
-import eu.alefzero.webdav.OnDatatransferProgressListener;
import eu.alefzero.webdav.WebdavClient;
-import eu.alefzero.webdav.WebdavEntry;
-import eu.alefzero.webdav.WebdavUtils;
public class FileUploader extends Service implements OnDatatransferProgressListener {
notifyUploadStart(mCurrentUpload);
- // / prepare client object to send requests to the ownCloud server
- if (mUploadClient == null || !mLastAccount.equals(mCurrentUpload.getAccount())) {
- mLastAccount = mCurrentUpload.getAccount();
- mStorageManager = new FileDataStorageManager(mLastAccount, getContentResolver());
- mUploadClient = OwnCloudClientUtils.createOwnCloudClient(mLastAccount, getApplicationContext());
- }
-
- // / create remote folder for instant uploads
- if (mCurrentUpload.isRemoteFolderToBeCreated()) {
- mUploadClient.createDirectory(FileStorageUtils.getInstantUploadFilePath(this, ""));
- // ignoring result fail could just mean that it already exists,
- // but local database is not synchronized the upload will be
- // tried anyway
- }
-
- // / perform the upload
RemoteOperationResult uploadResult = null;
+
try {
+ /// prepare client object to send requests to the ownCloud server
+ if (mUploadClient == null || !mLastAccount.equals(mCurrentUpload.getAccount())) {
+ mLastAccount = mCurrentUpload.getAccount();
+ mStorageManager = new FileDataStorageManager(mLastAccount, getContentResolver());
+ mUploadClient = OwnCloudClientUtils.createOwnCloudClient(mLastAccount, getApplicationContext());
+ }
+
+ /// create remote folder for instant uploads
+ if (mCurrentUpload.isRemoteFolderToBeCreated()) {
+ RemoteOperation operation = new CreateFolderOperation( FileStorageUtils.getInstantUploadFilePath(this, ""),
+ mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR).getFileId(), // TODO generalize this : INSTANT_UPLOAD_DIR could not be a child of root
+ mStorageManager);
+ operation.execute(mUploadClient); // ignoring result; fail could just mean that it already exists, but local database is not synchronized; the upload will be tried anyway
+ }
+
+
+ /// perform the upload
uploadResult = mCurrentUpload.execute(mUploadClient);
if (uploadResult.isSuccess()) {
saveUploadedFile();
}
-
+
+ } catch (AccountsException e) {
+ Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
+ uploadResult = new RemoteOperationResult(e);
+
+ } catch (IOException e) {
+ Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
+ uploadResult = new RemoteOperationResult(e);
+
} finally {
synchronized (mPendingUploads) {
mPendingUploads.remove(uploadKey);
Log_OC.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
}
}
-
- // notify result
+
+ /// notify result
+
notifyUploadResult(uploadResult, mCurrentUpload);
sendFinalBroadcast(mCurrentUpload, uploadResult);
Notification finalNotification = new Notification(R.drawable.icon,
getString(R.string.uploader_upload_failed_ticker), System.currentTimeMillis());
finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;
-
+ if (uploadResult.getCode() == ResultCode.UNAUTHORIZED) {
+ // let the user update credentials with one click
+ Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
+ updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, upload.getAccount());
+ updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_UPDATE_TOKEN);
+ updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
+ finalNotification.contentIntent = PendingIntent.getActivity(this, (int)System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT);
+ mUploadClient = null; // grant that future retries on the same account will get the fresh credentials
+ } else {
+ // TODO put something smart in the contentIntent below
+ finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
+ }
+
String content = null;
if (uploadResult.getCode() == ResultCode.LOCAL_STORAGE_FULL
|| uploadResult.getCode() == ResultCode.LOCAL_STORAGE_NOT_COPIED) {
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
-import android.util.Log;
public class LocationServiceLauncherReciever extends BroadcastReceiver {
import android.location.LocationProvider;
import android.os.Bundle;
import android.preference.PreferenceManager;
-import android.util.Log;
import android.widget.Toast;
import com.owncloud.android.Log_OC;
import com.owncloud.android.Log_OC;
-import android.util.Log;
-
/**
* AdvancedSSLProtocolSocketFactory allows to create SSL {@link Socket}s with
* a custom SSLContext and an optional Hostname Verifier.
import com.owncloud.android.Log_OC;
-import android.util.Log;
-
/**
* @author David A. Velasco
*/
--- /dev/null
+/* ownCloud Android client application
+ * Copyright (C) 2012 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * 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 com.owncloud.android.network;
+
+import java.util.Map;
+
+import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.auth.AuthChallengeParser;
+import org.apache.commons.httpclient.auth.AuthScheme;
+import org.apache.commons.httpclient.auth.AuthenticationException;
+import org.apache.commons.httpclient.auth.InvalidCredentialsException;
+import org.apache.commons.httpclient.auth.MalformedChallengeException;
+
+import com.owncloud.android.Log_OC;
+
+/**
+ * Bearer authentication scheme as defined in RFC 6750.
+ *
+ * @author David A. Velasco
+ */
+
+public class BearerAuthScheme implements AuthScheme /*extends RFC2617Scheme*/ {
+
+ private static final String TAG = BearerAuthScheme.class.getSimpleName();
+
+ public static final String AUTH_POLICY = "Bearer";
+
+ /** Whether the bearer authentication process is complete */
+ private boolean mComplete;
+
+ /** Authentication parameter map */
+ private Map mParams = null;
+
+
+ /**
+ * Default constructor for the bearer authentication scheme.
+ */
+ public BearerAuthScheme() {
+ mComplete = false;
+ }
+
+ /**
+ * Constructor for the basic authentication scheme.
+ *
+ * @param challenge Authentication challenge
+ *
+ * @throws MalformedChallengeException Thrown if the authentication challenge is malformed
+ *
+ * @deprecated Use parameterless constructor and {@link AuthScheme#processChallenge(String)} method
+ */
+ public BearerAuthScheme(final String challenge) throws MalformedChallengeException {
+ processChallenge(challenge);
+ mComplete = true;
+ }
+
+ /**
+ * Returns textual designation of the bearer authentication scheme.
+ *
+ * @return "Bearer"
+ */
+ public String getSchemeName() {
+ return "bearer";
+ }
+
+ /**
+ * Processes the Bearer challenge.
+ *
+ * @param challenge The challenge string
+ *
+ * @throws MalformedChallengeException Thrown if the authentication challenge is malformed
+ */
+ public void processChallenge(String challenge) throws MalformedChallengeException {
+ String s = AuthChallengeParser.extractScheme(challenge);
+ if (!s.equalsIgnoreCase(getSchemeName())) {
+ throw new MalformedChallengeException(
+ "Invalid " + getSchemeName() + " challenge: " + challenge);
+ }
+ mParams = AuthChallengeParser.extractParams(challenge);
+ mComplete = true;
+ }
+
+ /**
+ * Tests if the Bearer authentication process has been completed.
+ *
+ * @return 'true' if Bearer authorization has been processed, 'false' otherwise.
+ */
+ public boolean isComplete() {
+ return this.mComplete;
+ }
+
+ /**
+ * Produces bearer authorization string for the given set of
+ * {@link Credentials}.
+ *
+ * @param credentials The set of credentials to be used for authentication
+ * @param method Method name is ignored by the bearer authentication scheme
+ * @param uri URI is ignored by the bearer authentication scheme
+ * @throws InvalidCredentialsException If authentication credentials are not valid or not applicable
+ * for this authentication scheme
+ * @throws AuthenticationException If authorization string cannot be generated due to an authentication failure
+ * @return A bearer authorization string
+ *
+ * @deprecated Use {@link #authenticate(Credentials, HttpMethod)}
+ */
+ public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException {
+ Log_OC.d(TAG, "enter BearerScheme.authenticate(Credentials, String, String)");
+
+ BearerCredentials bearer = null;
+ try {
+ bearer = (BearerCredentials) credentials;
+ } catch (ClassCastException e) {
+ throw new InvalidCredentialsException(
+ "Credentials cannot be used for bearer authentication: "
+ + credentials.getClass().getName());
+ }
+ return BearerAuthScheme.authenticate(bearer);
+ }
+
+
+ /**
+ * Returns 'false'. Bearer authentication scheme is request based.
+ *
+ * @return 'false'.
+ */
+ public boolean isConnectionBased() {
+ return false;
+ }
+
+ /**
+ * Produces bearer authorization string for the given set of {@link Credentials}.
+ *
+ * @param credentials The set of credentials to be used for authentication
+ * @param method The method being authenticated
+ * @throws InvalidCredentialsException If authentication credentials are not valid or not applicable for this authentication
+ * scheme.
+ * @throws AuthenticationException If authorization string cannot be generated due to an authentication failure.
+ *
+ * @return a basic authorization string
+ */
+ public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException {
+ Log_OC.d(TAG, "enter BearerScheme.authenticate(Credentials, HttpMethod)");
+
+ if (method == null) {
+ throw new IllegalArgumentException("Method may not be null");
+ }
+ BearerCredentials bearer = null;
+ try {
+ bearer = (BearerCredentials) credentials;
+ } catch (ClassCastException e) {
+ throw new InvalidCredentialsException(
+ "Credentials cannot be used for bearer authentication: "
+ + credentials.getClass().getName());
+ }
+ return BearerAuthScheme.authenticate(
+ bearer,
+ method.getParams().getCredentialCharset());
+ }
+
+ /**
+ * @deprecated Use {@link #authenticate(BearerCredentials, String)}
+ *
+ * Returns a bearer Authorization header value for the given
+ * {@link BearerCredentials}.
+ *
+ * @param credentials The credentials to encode.
+ *
+ * @return A bearer authorization string
+ */
+ public static String authenticate(BearerCredentials credentials) {
+ return authenticate(credentials, "ISO-8859-1");
+ }
+
+ /**
+ * Returns a bearer Authorization header value for the given
+ * {@link BearerCredentials} and charset.
+ *
+ * @param credentials The credentials to encode.
+ * @param charset The charset to use for encoding the credentials
+ *
+ * @return A bearer authorization string
+ *
+ * @since 3.0
+ */
+ public static String authenticate(BearerCredentials credentials, String charset) {
+ Log_OC.d(TAG, "enter BearerAuthScheme.authenticate(BearerCredentials, String)");
+
+ if (credentials == null) {
+ throw new IllegalArgumentException("Credentials may not be null");
+ }
+ if (charset == null || charset.length() == 0) {
+ throw new IllegalArgumentException("charset may not be null or empty");
+ }
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(credentials.getAccessToken());
+
+ //return "Bearer " + EncodingUtil.getAsciiString(EncodingUtil.getBytes(buffer.toString(), charset));
+ return "Bearer " + buffer.toString();
+ }
+
+ /**
+ * Returns a String identifying the authentication challenge. This is
+ * used, in combination with the host and port to determine if
+ * authorization has already been attempted or not. Schemes which
+ * require multiple requests to complete the authentication should
+ * return a different value for each stage in the request.
+ *
+ * Additionally, the ID should take into account any changes to the
+ * authentication challenge and return a different value when appropriate.
+ * For example when the realm changes in basic authentication it should be
+ * considered a different authentication attempt and a different value should
+ * be returned.
+ *
+ * This method simply returns the realm for the challenge.
+ *
+ * @return String a String identifying the authentication challenge.
+ *
+ * @deprecated no longer used
+ */
+ @Override
+ public String getID() {
+ return getRealm();
+ }
+
+ /**
+ * Returns authentication parameter with the given name, if available.
+ *
+ * @param name The name of the parameter to be returned
+ *
+ * @return The parameter with the given name
+ */
+ @Override
+ public String getParameter(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("Parameter name may not be null");
+ }
+ if (mParams == null) {
+ return null;
+ }
+ return (String) mParams.get(name.toLowerCase());
+ }
+
+ /**
+ * Returns authentication realm. The realm may not be null.
+ *
+ * @return The authentication realm
+ */
+ @Override
+ public String getRealm() {
+ return getParameter("realm");
+ }
+
+}
--- /dev/null
+/* ownCloud Android client application
+ * Copyright (C) 2012 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * 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 com.owncloud.android.network;
+
+import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.util.LangUtils;
+
+/**
+ * Bearer token {@link Credentials}
+ *
+ * @author David A. Velasco
+ */
+public class BearerCredentials implements Credentials {
+
+
+ private String mAccessToken;
+
+
+ /**
+ * The constructor with the bearer token
+ *
+ * @param token The bearer token
+ */
+ public BearerCredentials(String token) {
+ /*if (token == null) {
+ throw new IllegalArgumentException("Bearer token may not be null");
+ }*/
+ mAccessToken = (token == null) ? "" : token;
+ }
+
+
+ /**
+ * Returns the access token
+ *
+ * @return The access token
+ */
+ public String getAccessToken() {
+ return mAccessToken;
+ }
+
+
+ /**
+ * Get this object string.
+ *
+ * @return The access token
+ */
+ public String toString() {
+ return mAccessToken;
+ }
+
+ /**
+ * Does a hash of the access token.
+ *
+ * @return The hash code of the access token
+ */
+ public int hashCode() {
+ int hash = LangUtils.HASH_SEED;
+ hash = LangUtils.hashCode(hash, mAccessToken);
+ return hash;
+ }
+
+ /**
+ * These credentials are assumed equal if accessToken is the same.
+ *
+ * @param o The other object to compare with.
+ *
+ * @return 'True' if the object is equivalent.
+ */
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (this == o) return true;
+ if (this.getClass().equals(o.getClass())) {
+ BearerCredentials that = (BearerCredentials) o;
+ if (LangUtils.equals(mAccessToken, that.mAccessToken)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
+
import org.apache.http.conn.ssl.X509HostnameVerifier;
import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authentication.AccountAuthenticator;
import com.owncloud.android.Log_OC;
import eu.alefzero.webdav.WebdavClient;
import android.accounts.Account;
import android.accounts.AccountManager;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.app.Activity;
import android.content.Context;
import android.net.Uri;
-import android.util.Log;
+import android.os.Bundle;
public class OwnCloudClientUtils {
- final private static String TAG = "OwnCloudClientFactory";
+ final private static String TAG = OwnCloudClientUtils.class.getSimpleName();
/** Default timeout for waiting data from the server */
public static final int DEFAULT_DATA_TIMEOUT = 60000;
/**
* Creates a WebdavClient setup for an ownCloud account
*
- * @param account The ownCloud account
- * @param context The application context
- * @return A WebdavClient object ready to be used
+ * Do not call this method from the main thread.
+ *
+ * @param account The ownCloud account
+ * @param appContext Android application context
+ * @return A WebdavClient object ready to be used
+ * @throws AuthenticatorException If the authenticator failed to get the authorization token for the account.
+ * @throws OperationCanceledException If the authenticator operation was cancelled while getting the authorization token for the account.
+ * @throws IOException If there was some I/O error while getting the authorization token for the account.
*/
- public static WebdavClient createOwnCloudClient (Account account, Context context) {
- Log_OC.d(TAG, "Creating WebdavClient associated to " + account.name);
+ public static WebdavClient createOwnCloudClient (Account account, Context appContext) throws OperationCanceledException, AuthenticatorException, IOException {
+ //Log_OC.d(TAG, "Creating WebdavClient associated to " + account.name);
- Uri uri = Uri.parse(AccountUtils.constructFullURLForAccount(context, account));
- WebdavClient client = createOwnCloudClient(uri, context);
+ Uri uri = Uri.parse(AccountUtils.constructFullURLForAccount(appContext, account));
+ WebdavClient client = createOwnCloudClient(uri, appContext);
+ AccountManager am = AccountManager.get(appContext);
+ if (am.getUserData(account, AccountAuthenticator.KEY_SUPPORTS_OAUTH2) != null) { // TODO avoid a call to getUserData here
+ String accessToken = am.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN, false);
+ client.setBearerCredentials(accessToken); // TODO not assume that the access token is a bearer token
- String username = account.name.substring(0, account.name.lastIndexOf('@'));
- String password = AccountManager.get(context).getPassword(account);
- //String password = am.blockingGetAuthToken(mAccount, AccountAuthenticator.AUTH_TOKEN_TYPE, true);
-
- client.setCredentials(username, password);
+ } else {
+ String username = account.name.substring(0, account.name.lastIndexOf('@'));
+ //String password = am.getPassword(account);
+ String password = am.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_PASSWORD, false);
+ client.setBasicCredentials(username, password);
+ }
return client;
}
- /**
- * Creates a WebdavClient to try a new account before saving it
- *
- * @param uri URL to the ownCloud server
- * @param username User name
- * @param password User password
- * @param context Android context where the WebdavClient is being created.
- * @return A WebdavClient object ready to be used
- */
- public static WebdavClient createOwnCloudClient(Uri uri, String username, String password, Context context) {
- Log_OC.d(TAG, "Creating WebdavClient for " + username + "@" + uri);
-
- WebdavClient client = createOwnCloudClient(uri, context);
-
- client.setCredentials(username, password);
+ public static WebdavClient createOwnCloudClient (Account account, Context appContext, Activity currentActivity) throws OperationCanceledException, AuthenticatorException, IOException {
+ Uri uri = Uri.parse(AccountUtils.constructFullURLForAccount(appContext, account));
+ WebdavClient client = createOwnCloudClient(uri, appContext);
+ AccountManager am = AccountManager.get(appContext);
+ if (am.getUserData(account, AccountAuthenticator.KEY_SUPPORTS_OAUTH2) != null) { // TODO avoid a call to getUserData here
+ AccountManagerFuture<Bundle> future = am.getAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN, null, currentActivity, null, null);
+ Bundle result = future.getResult();
+ String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN);
+ //String accessToken = am.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN, false);
+ if (accessToken == null) throw new AuthenticatorException("WTF!");
+ client.setBearerCredentials(accessToken); // TODO not assume that the access token is a bearer token
+
+ } else {
+ String username = account.name.substring(0, account.name.lastIndexOf('@'));
+ //String password = am.getPassword(account);
+ //String password = am.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_PASSWORD, false);
+ AccountManagerFuture<Bundle> future = am.getAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_PASSWORD, null, currentActivity, null, null);
+ Bundle result = future.getResult();
+ String password = result.getString(AccountManager.KEY_AUTHTOKEN);
+ client.setBasicCredentials(username, password);
+ }
return client;
}
-
/**
* Creates a WebdavClient to access a URL and sets the desired parameters for ownCloud client connections.
*
* @return A WebdavClient object ready to be used
*/
public static WebdavClient createOwnCloudClient(Uri uri, Context context) {
- Log_OC.d(TAG, "Creating WebdavClient for " + uri);
+ //Log_OC.d(TAG, "Creating WebdavClient for " + uri);
//allowSelfsignedCertificates(true);
try {
return mConnManager;
}
+
}
import com.owncloud.android.network.ProgressiveDataTransferer;
import android.accounts.Account;
-import android.util.Log;
import eu.alefzero.webdav.ChunkFromFileChannelRequestEntity;
import eu.alefzero.webdav.WebdavClient;
+++ /dev/null
-/* ownCloud Android client application
- * Copyright (C) 2012-2013 ownCloud Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * 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 com.owncloud.android.operations;
-
-import org.apache.commons.httpclient.HttpStatus;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import com.owncloud.android.AccountUtils;
-import com.owncloud.android.Log_OC;
-import com.owncloud.android.utils.OwnCloudVersion;
-
-import eu.alefzero.webdav.WebdavClient;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.Uri;
-import android.util.Log;
-
-public class ConnectionCheckOperation extends RemoteOperation {
-
- /** Maximum time to wait for a response from the server when the connection is being tested, in MILLISECONDs. */
- public static final int TRY_CONNECTION_TIMEOUT = 5000;
-
- private static final String TAG = ConnectionCheckOperation.class.getSimpleName();
-
- private String mUrl;
- private RemoteOperationResult mLatestResult;
- private Context mContext;
- private OwnCloudVersion mOCVersion;
-
- public ConnectionCheckOperation(String url, Context context) {
- mUrl = url;
- mContext = context;
- mOCVersion = null;
- }
-
- public OwnCloudVersion getDiscoveredVersion() {
- return mOCVersion;
- }
-
- private boolean tryConnection(WebdavClient wc, String urlSt) {
- boolean retval = false;
- GetMethod get = null;
- try {
- get = new GetMethod(urlSt);
- int status = wc.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT);
- String response = get.getResponseBodyAsString();
- if (status == HttpStatus.SC_OK) {
- JSONObject json = new JSONObject(response);
- if (!json.getBoolean("installed")) {
- mLatestResult = new RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
- } else {
- mOCVersion = new OwnCloudVersion(json.getString("version"));
- if (!mOCVersion.isVersionValid()) {
- mLatestResult = new RemoteOperationResult(RemoteOperationResult.ResultCode.BAD_OC_VERSION);
-
- } else {
- mLatestResult = new RemoteOperationResult(urlSt.startsWith("https://") ?
- RemoteOperationResult.ResultCode.OK_SSL :
- RemoteOperationResult.ResultCode.OK_NO_SSL
- );
-
- retval = true;
- }
- }
-
- } else {
- mLatestResult = new RemoteOperationResult(false, status);
- }
-
- } catch (JSONException e) {
- mLatestResult = new RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
-
- } catch (Exception e) {
- mLatestResult = new RemoteOperationResult(e);
-
- } finally {
- if (get != null)
- get.releaseConnection();
- }
-
- if (mLatestResult.isSuccess()) {
- Log_OC.i(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage());
-
- } else if (mLatestResult.getException() != null) {
- Log_OC.e(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage(), mLatestResult.getException());
-
- } else {
- Log_OC.e(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage());
- }
-
- return retval;
- }
-
- private boolean isOnline() {
- ConnectivityManager cm = (ConnectivityManager) mContext
- .getSystemService(Context.CONNECTIVITY_SERVICE);
- return cm != null && cm.getActiveNetworkInfo() != null
- && cm.getActiveNetworkInfo().isConnectedOrConnecting();
- }
-
- @Override
- protected RemoteOperationResult run(WebdavClient client) {
- if (!isOnline()) {
- return new RemoteOperationResult(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION);
- }
- if (mUrl.startsWith("http://") || mUrl.startsWith("https://")) {
- tryConnection(client, mUrl + AccountUtils.STATUS_PATH);
-
- } else {
- client.setBaseUri(Uri.parse("https://" + mUrl + AccountUtils.STATUS_PATH));
- boolean httpsSuccess = tryConnection(client, "https://" + mUrl + AccountUtils.STATUS_PATH);
- if (!httpsSuccess && !mLatestResult.isSslRecoverableException()) {
- Log_OC.d(TAG, "establishing secure connection failed, trying non secure connection");
- client.setBaseUri(Uri.parse("http://" + mUrl + AccountUtils.STATUS_PATH));
- tryConnection(client, "http://" + mUrl + AccountUtils.STATUS_PATH);
- }
- }
- return mLatestResult;
- }
-
-}
--- /dev/null
+/* ownCloud Android client application
+ * Copyright (C) 2012 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * 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 com.owncloud.android.operations;
+
+import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
+
+import com.owncloud.android.Log_OC;
+import com.owncloud.android.datamodel.DataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+
+import eu.alefzero.webdav.WebdavClient;
+import eu.alefzero.webdav.WebdavUtils;
+
+/**
+ * Remote operation performing the creation of a new folder in the ownCloud server.
+ *
+ * @author David A. Velasco
+ */
+public class CreateFolderOperation extends RemoteOperation {
+
+ private static final String TAG = CreateFolderOperation.class.getSimpleName();
+
+ private static final int READ_TIMEOUT = 10000;
+ private static final int CONNECTION_TIMEOUT = 5000;
+
+ protected String mRemotePath;
+ protected long mParentDirId;
+ protected DataStorageManager mStorageManager;
+
+ /**
+ * Constructor
+ *
+ * @param remoetPath Full path to the new directory to create in the remote server.
+ * @param parentDirId Local database id for the parent folder.
+ * @param storageManager Reference to the local database corresponding to the account where the file is contained.
+ */
+ public CreateFolderOperation(String remotePath, long parentDirId, DataStorageManager storageManager) {
+ mRemotePath = remotePath;
+ mParentDirId = parentDirId;
+ mStorageManager = storageManager;
+ }
+
+
+ /**
+ * Performs the remove operation
+ *
+ * @param client Client object to communicate with the remote ownCloud server.
+ */
+ @Override
+ protected RemoteOperationResult run(WebdavClient client) {
+ RemoteOperationResult result = null;
+ MkColMethod mkcol = null;
+ try {
+ mkcol = new MkColMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath));
+ int status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT);
+ if (mkcol.succeeded()) {
+ // Save new directory in local database
+ OCFile newDir = new OCFile(mRemotePath);
+ newDir.setMimetype("DIR");
+ newDir.setParentId(mParentDirId);
+ mStorageManager.saveFile(newDir);
+ }
+
+ result = new RemoteOperationResult(mkcol.succeeded(), status);
+ Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage());
+ client.exhaustResponse(mkcol.getResponseBodyAsStream());
+
+ } catch (Exception e) {
+ result = new RemoteOperationResult(e);
+ Log_OC.e(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage(), e);
+
+ } finally {
+ if (mkcol != null)
+ mkcol.releaseConnection();
+ }
+ return result;
+ }
+
+}
import eu.alefzero.webdav.WebdavClient;
import eu.alefzero.webdav.WebdavUtils;
import android.accounts.Account;
-import android.util.Log;
import android.webkit.MimeTypeMap;
/**
--- /dev/null
+/* ownCloud Android client application
+ * Copyright (C) 2012 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * 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 com.owncloud.android.operations;
+
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.methods.HeadMethod;
+
+import com.owncloud.android.Log_OC;
+
+import eu.alefzero.webdav.WebdavClient;
+import android.content.Context;
+import android.net.ConnectivityManager;
+
+/**
+ * Operation to check the existence or absence of a path in a remote server.
+ *
+ * @author David A. Velasco
+ */
+public class ExistenceCheckOperation extends RemoteOperation {
+
+ /** Maximum time to wait for a response from the server in MILLISECONDs. */
+ public static final int TIMEOUT = 10000;
+
+ private static final String TAG = ExistenceCheckOperation.class.getSimpleName();
+
+ private String mPath;
+ private Context mContext;
+ private boolean mSuccessIfAbsent;
+
+
+ /**
+ * Full constructor. Success of the operation will depend upon the value of successIfAbsent.
+ *
+ * @param path Path to append to the URL owned by the client instance.
+ * @param context Android application context.
+ * @param successIfAbsent When 'true', the operation finishes in success if the path does NOT exist in the remote server (HTTP 404).
+ */
+ public ExistenceCheckOperation(String path, Context context, boolean successIfAbsent) {
+ mPath = (path != null) ? path : "";
+ mContext = context;
+ mSuccessIfAbsent = successIfAbsent;
+ }
+
+
+ @Override
+ protected RemoteOperationResult run(WebdavClient client) {
+ if (!isOnline()) {
+ return new RemoteOperationResult(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION);
+ }
+ RemoteOperationResult result = null;
+ HeadMethod head = null;
+ try {
+ head = new HeadMethod(client.getBaseUri() + mPath);
+ int status = client.executeMethod(head, TIMEOUT, TIMEOUT);
+ client.exhaustResponse(head.getResponseBodyAsStream());
+ boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) || (status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent);
+ result = new RemoteOperationResult(success, status);
+ Log_OC.d(TAG, "Existence check for " + client.getBaseUri() + mPath + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + "finished with HTTP status " + status + (!success?"(FAIL)":""));
+
+ } catch (Exception e) {
+ result = new RemoteOperationResult(e);
+ Log_OC.e(TAG, "Existence check for " + client.getBaseUri() + mPath + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + ": " + result.getLogMessage(), result.getException());
+
+ } finally {
+ if (head != null)
+ head.releaseConnection();
+ }
+ return result;
+ }
+
+ private boolean isOnline() {
+ ConnectivityManager cm = (ConnectivityManager) mContext
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ return cm != null && cm.getActiveNetworkInfo() != null
+ && cm.getActiveNetworkInfo().isConnectedOrConnecting();
+ }
+
+
+}
--- /dev/null
+package com.owncloud.android.operations;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.NameValuePair;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.owncloud.android.Log_OC;
+import com.owncloud.android.authentication.OAuth2Constants;
+import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
+
+import eu.alefzero.webdav.WebdavClient;
+
+public class OAuth2GetAccessToken extends RemoteOperation {
+
+ private static final String TAG = OAuth2GetAccessToken.class.getSimpleName();
+
+ private String mClientId;
+ private String mRedirectUri;
+ private String mGrantType;
+
+ private String mOAuth2AuthorizationResponse;
+ private Map<String, String> mOAuth2ParsedAuthorizationResponse;
+ private Map<String, String> mResultTokenMap;
+
+
+ public OAuth2GetAccessToken(String clientId, String redirectUri, String grantType, String oAuth2AuthorizationResponse) {
+ mClientId = clientId;
+ mRedirectUri = redirectUri;
+ mGrantType = grantType;
+ mOAuth2AuthorizationResponse = oAuth2AuthorizationResponse;
+ mOAuth2ParsedAuthorizationResponse = new HashMap<String, String>();
+ mResultTokenMap = null;
+ }
+
+
+ public Map<String, String> getOauth2AutorizationResponse() {
+ return mOAuth2ParsedAuthorizationResponse;
+ }
+
+ public Map<String, String> getResultTokenMap() {
+ return mResultTokenMap;
+ }
+
+ @Override
+ protected RemoteOperationResult run(WebdavClient client) {
+ RemoteOperationResult result = null;
+ PostMethod postMethod = null;
+
+ try {
+ parseAuthorizationResponse();
+ if (mOAuth2ParsedAuthorizationResponse.keySet().contains(OAuth2Constants.KEY_ERROR)) {
+ if (OAuth2Constants.VALUE_ERROR_ACCESS_DENIED.equals(mOAuth2ParsedAuthorizationResponse.get(OAuth2Constants.KEY_ERROR))) {
+ result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR_ACCESS_DENIED);
+ } else {
+ result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR);
+ }
+ }
+
+ if (result == null) {
+ NameValuePair[] nameValuePairs = new NameValuePair[4];
+ nameValuePairs[0] = new NameValuePair(OAuth2Constants.KEY_GRANT_TYPE, mGrantType);
+ nameValuePairs[1] = new NameValuePair(OAuth2Constants.KEY_CODE, mOAuth2ParsedAuthorizationResponse.get(OAuth2Constants.KEY_CODE));
+ nameValuePairs[2] = new NameValuePair(OAuth2Constants.KEY_REDIRECT_URI, mRedirectUri);
+ nameValuePairs[3] = new NameValuePair(OAuth2Constants.KEY_CLIENT_ID, mClientId);
+ //nameValuePairs[4] = new NameValuePair(OAuth2Constants.KEY_SCOPE, mOAuth2ParsedAuthorizationResponse.get(OAuth2Constants.KEY_SCOPE));
+
+ postMethod = new PostMethod(client.getBaseUri().toString());
+ postMethod.setRequestBody(nameValuePairs);
+ int status = client.executeMethod(postMethod);
+
+ String response = postMethod.getResponseBodyAsString();
+ if (response != null && response.length() > 0) {
+ JSONObject tokenJson = new JSONObject(response);
+ parseAccessTokenResult(tokenJson);
+ if (mResultTokenMap.get(OAuth2Constants.KEY_ERROR) != null || mResultTokenMap.get(OAuth2Constants.KEY_ACCESS_TOKEN) == null) {
+ result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR);
+
+ } else {
+ result = new RemoteOperationResult(true, status);
+ }
+
+ } else {
+ client.exhaustResponse(postMethod.getResponseBodyAsStream());
+ result = new RemoteOperationResult(false, status);
+ }
+ }
+
+ } catch (Exception e) {
+ result = new RemoteOperationResult(e);
+
+ } finally {
+ if (postMethod != null)
+ postMethod.releaseConnection(); // let the connection available for other methods
+
+ if (result.isSuccess()) {
+ Log_OC.i(TAG, "OAuth2 TOKEN REQUEST with auth code " + mOAuth2ParsedAuthorizationResponse.get("code") + " to " + client.getBaseUri() + ": " + result.getLogMessage());
+
+ } else if (result.getException() != null) {
+ Log_OC.e(TAG, "OAuth2 TOKEN REQUEST with auth code " + mOAuth2ParsedAuthorizationResponse.get("code") + " to " + client.getBaseUri() + ": " + result.getLogMessage(), result.getException());
+
+ } else if (result.getCode() == ResultCode.OAUTH2_ERROR) {
+ Log_OC.e(TAG, "OAuth2 TOKEN REQUEST with auth code " + mOAuth2ParsedAuthorizationResponse.get("code") + " to " + client.getBaseUri() + ": " + ((mResultTokenMap != null) ? mResultTokenMap.get(OAuth2Constants.KEY_ERROR) : "NULL"));
+
+ } else {
+ Log_OC.e(TAG, "OAuth2 TOKEN REQUEST with auth code " + mOAuth2ParsedAuthorizationResponse.get("code") + " to " + client.getBaseUri() + ": " + result.getLogMessage());
+ }
+ }
+
+ return result;
+ }
+
+
+ private void parseAuthorizationResponse() {
+ String[] pairs = mOAuth2AuthorizationResponse.split("&");
+ int i = 0;
+ String key = "";
+ String value = "";
+ StringBuilder sb = new StringBuilder();
+ while (pairs.length > i) {
+ int j = 0;
+ String[] part = pairs[i].split("=");
+ while (part.length > j) {
+ String p = part[j];
+ if (j == 0) {
+ key = p;
+ sb.append(key + " = ");
+ } else if (j == 1) {
+ value = p;
+ mOAuth2ParsedAuthorizationResponse.put(key, value);
+ sb.append(value + "\n");
+ }
+
+ Log_OC.v(TAG, "[" + i + "," + j + "] = " + p);
+ j++;
+ }
+ i++;
+ }
+ }
+
+
+ private void parseAccessTokenResult (JSONObject tokenJson) throws JSONException {
+ mResultTokenMap = new HashMap<String, String>();
+
+ if (tokenJson.has(OAuth2Constants.KEY_ACCESS_TOKEN)) {
+ mResultTokenMap.put(OAuth2Constants.KEY_ACCESS_TOKEN, tokenJson.getString(OAuth2Constants.KEY_ACCESS_TOKEN));
+ }
+ if (tokenJson.has(OAuth2Constants.KEY_TOKEN_TYPE)) {
+ mResultTokenMap.put(OAuth2Constants.KEY_TOKEN_TYPE, tokenJson.getString(OAuth2Constants.KEY_TOKEN_TYPE));
+ }
+ if (tokenJson.has(OAuth2Constants.KEY_EXPIRES_IN)) {
+ mResultTokenMap.put(OAuth2Constants.KEY_EXPIRES_IN, tokenJson.getString(OAuth2Constants.KEY_EXPIRES_IN));
+ }
+ if (tokenJson.has(OAuth2Constants.KEY_REFRESH_TOKEN)) {
+ mResultTokenMap.put(OAuth2Constants.KEY_REFRESH_TOKEN, tokenJson.getString(OAuth2Constants.KEY_REFRESH_TOKEN));
+ }
+ if (tokenJson.has(OAuth2Constants.KEY_SCOPE)) {
+ mResultTokenMap.put(OAuth2Constants.KEY_SCOPE, tokenJson.getString(OAuth2Constants.KEY_SCOPE));
+ }
+ if (tokenJson.has(OAuth2Constants.KEY_ERROR)) {
+ mResultTokenMap.put(OAuth2Constants.KEY_ERROR, tokenJson.getString(OAuth2Constants.KEY_ERROR));
+ }
+ if (tokenJson.has(OAuth2Constants.KEY_ERROR_DESCRIPTION)) {
+ mResultTokenMap.put(OAuth2Constants.KEY_ERROR_DESCRIPTION, tokenJson.getString(OAuth2Constants.KEY_ERROR_DESCRIPTION));
+ }
+ if (tokenJson.has(OAuth2Constants.KEY_ERROR_URI)) {
+ mResultTokenMap.put(OAuth2Constants.KEY_ERROR_URI, tokenJson.getString(OAuth2Constants.KEY_ERROR_URI));
+ }
+ }
+
+}
--- /dev/null
+/* ownCloud Android client application
+ * Copyright (C) 2012-2013 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * 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 com.owncloud.android.operations;
+
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.Log_OC;
+import com.owncloud.android.utils.OwnCloudVersion;
+
+import eu.alefzero.webdav.WebdavClient;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Uri;
+
+public class OwnCloudServerCheckOperation extends RemoteOperation {
+
+ /** Maximum time to wait for a response from the server when the connection is being tested, in MILLISECONDs. */
+ public static final int TRY_CONNECTION_TIMEOUT = 5000;
+
+ private static final String TAG = OwnCloudServerCheckOperation.class.getSimpleName();
+
+ private String mUrl;
+ private RemoteOperationResult mLatestResult;
+ private Context mContext;
+ private OwnCloudVersion mOCVersion;
+
+ public OwnCloudServerCheckOperation(String url, Context context) {
+ mUrl = url;
+ mContext = context;
+ mOCVersion = null;
+ }
+
+ public OwnCloudVersion getDiscoveredVersion() {
+ return mOCVersion;
+ }
+
+ private boolean tryConnection(WebdavClient wc, String urlSt) {
+ boolean retval = false;
+ GetMethod get = null;
+ try {
+ get = new GetMethod(urlSt);
+ int status = wc.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT);
+ String response = get.getResponseBodyAsString();
+ if (status == HttpStatus.SC_OK) {
+ JSONObject json = new JSONObject(response);
+ if (!json.getBoolean("installed")) {
+ mLatestResult = new RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
+ } else {
+ mOCVersion = new OwnCloudVersion(json.getString("version"));
+ if (!mOCVersion.isVersionValid()) {
+ mLatestResult = new RemoteOperationResult(RemoteOperationResult.ResultCode.BAD_OC_VERSION);
+
+ } else {
+ mLatestResult = new RemoteOperationResult(urlSt.startsWith("https://") ?
+ RemoteOperationResult.ResultCode.OK_SSL :
+ RemoteOperationResult.ResultCode.OK_NO_SSL
+ );
+
+ retval = true;
+ }
+ }
+
+ } else {
+ mLatestResult = new RemoteOperationResult(false, status);
+ }
+
+ } catch (JSONException e) {
+ mLatestResult = new RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
+
+ } catch (Exception e) {
+ mLatestResult = new RemoteOperationResult(e);
+
+ } finally {
+ if (get != null)
+ get.releaseConnection();
+ }
+
+ if (mLatestResult.isSuccess()) {
+ Log_OC.i(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage());
+
+ } else if (mLatestResult.getException() != null) {
+ Log_OC.e(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage(), mLatestResult.getException());
+
+ } else {
+ Log_OC.e(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage());
+ }
+
+ return retval;
+ }
+
+ private boolean isOnline() {
+ ConnectivityManager cm = (ConnectivityManager) mContext
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ return cm != null && cm.getActiveNetworkInfo() != null
+ && cm.getActiveNetworkInfo().isConnectedOrConnecting();
+ }
+
+ @Override
+ protected RemoteOperationResult run(WebdavClient client) {
+ if (!isOnline()) {
+ return new RemoteOperationResult(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION);
+ }
+ if (mUrl.startsWith("http://") || mUrl.startsWith("https://")) {
+ tryConnection(client, mUrl + AccountUtils.STATUS_PATH);
+
+ } else {
+ client.setBaseUri(Uri.parse("https://" + mUrl + AccountUtils.STATUS_PATH));
+ boolean httpsSuccess = tryConnection(client, "https://" + mUrl + AccountUtils.STATUS_PATH);
+ if (!httpsSuccess && !mLatestResult.isSslRecoverableException()) {
+ Log_OC.d(TAG, "establishing secure connection failed, trying non secure connection");
+ client.setBaseUri(Uri.parse("http://" + mUrl + AccountUtils.STATUS_PATH));
+ tryConnection(client, "http://" + mUrl + AccountUtils.STATUS_PATH);
+ }
+ }
+ return mLatestResult;
+ }
+
+}
*/
package com.owncloud.android.operations;
+import java.io.IOException;
+
+import org.apache.commons.httpclient.Credentials;
+
+import com.owncloud.android.Log_OC;
+import com.owncloud.android.authentication.AccountAuthenticator;
+import com.owncloud.android.network.BearerCredentials;
+import com.owncloud.android.network.OwnCloudClientUtils;
+import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountsException;
+import android.app.Activity;
+import android.content.Context;
import android.os.Handler;
import eu.alefzero.webdav.WebdavClient;
*/
public abstract class RemoteOperation implements Runnable {
- /** Object to interact with the ownCloud server */
+ private static final String TAG = RemoteOperation.class.getSimpleName();
+
+ /** ownCloud account in the remote ownCloud server to operate */
+ private Account mAccount = null;
+
+ /** Android Application context */
+ private Context mContext = null;
+
+ /** Object to interact with the remote server */
private WebdavClient mClient = null;
/** Callback object to notify about the execution of the remote operation */
/** Handler to the thread where mListener methods will be called */
private Handler mListenerHandler = null;
+ /** Activity */
+ private Activity mCallerActivity;
+
/**
* Abstract method to implement the operation in derived classes.
*/
protected abstract RemoteOperationResult run(WebdavClient client);
+
+ /**
+ * Synchronously executes the remote operation on the received ownCloud account.
+ *
+ * Do not call this method from the main thread.
+ *
+ * This method should be used whenever an ownCloud account is available, instead of {@link #execute(WebdavClient)}.
+ *
+ * @param account ownCloud account in remote ownCloud server to reach during the execution of the operation.
+ * @param context Android context for the component calling the method.
+ * @return Result of the operation.
+ */
+ public final RemoteOperationResult execute(Account account, Context context) {
+ if (account == null)
+ throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Account");
+ if (context == null)
+ throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Context");
+ mAccount = account;
+ mContext = context.getApplicationContext();
+ try {
+ mClient = OwnCloudClientUtils.createOwnCloudClient(mAccount, mContext);
+ } catch (Exception e) {
+ Log_OC.e(TAG, "Error while trying to access to " + mAccount.name, e);
+ return new RemoteOperationResult(e);
+ }
+ return run(mClient);
+ }
+
/**
* Synchronously executes the remote operation
*
+ * Do not call this method from the main thread.
+ *
* @param client Client object to reach an ownCloud server during the execution of the operation.
* @return Result of the operation.
*/
}
+ /**
+ * Asynchronously executes the remote operation
+ *
+ * This method should be used whenever an ownCloud account is available, instead of {@link #execute(WebdavClient)}.
+ *
+ * @param account ownCloud account in remote ownCloud server to reach during the execution of the operation.
+ * @param context Android context for the component calling the method.
+ * @param listener Listener to be notified about the execution of the operation.
+ * @param listenerHandler Handler associated to the thread where the methods of the listener objects must be called.
+ * @return Thread were the remote operation is executed.
+ */
+ public final Thread execute(Account account, Context context, OnRemoteOperationListener listener, Handler listenerHandler, Activity callerActivity) {
+ if (account == null)
+ throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Account");
+ if (context == null)
+ throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Context");
+ mAccount = account;
+ mContext = context.getApplicationContext();
+ mCallerActivity = callerActivity;
+ mClient = null; // the client instance will be created from mAccount and mContext in the runnerThread to create below
+
+ if (listener == null) {
+ throw new IllegalArgumentException("Trying to execute a remote operation asynchronously without a listener to notiy the result");
+ }
+ mListener = listener;
+
+ if (listenerHandler == null) {
+ throw new IllegalArgumentException("Trying to execute a remote operation asynchronously without a handler to the listener's thread");
+ }
+ mListenerHandler = listenerHandler;
+
+ Thread runnerThread = new Thread(this);
+ runnerThread.start();
+ return runnerThread;
+ }
+
+
/**
* Asynchronously executes the remote operation
*
* Asynchronous execution of the operation
* started by {@link RemoteOperation#execute(WebdavClient, OnRemoteOperationListener, Handler)},
* and result posting.
+ *
+ * TODO refactor && clean the code; now it's a mess
*/
@Override
public final void run() {
- final RemoteOperationResult result = execute(mClient);
+ RemoteOperationResult result = null;
+ boolean repeat = false;
+ do {
+ try{
+ if (mClient == null) {
+ if (mAccount != null && mContext != null) {
+ if (mCallerActivity != null) {
+ mClient = OwnCloudClientUtils.createOwnCloudClient(mAccount, mContext, mCallerActivity);
+ } else {
+ mClient = OwnCloudClientUtils.createOwnCloudClient(mAccount, mContext);
+ }
+ } else {
+ throw new IllegalStateException("Trying to run a remote operation asynchronously with no client instance or account");
+ }
+ }
+
+ } catch (IOException e) {
+ Log_OC.e(TAG, "Error while trying to access to " + mAccount.name, new AccountsException("I/O exception while trying to authorize the account", e));
+ result = new RemoteOperationResult(e);
+
+ } catch (AccountsException e) {
+ Log_OC.e(TAG, "Error while trying to access to " + mAccount.name, e);
+ result = new RemoteOperationResult(e);
+ }
+ if (result == null)
+ result = run(mClient);
+
+ repeat = false;
+ if (mCallerActivity != null && mAccount != null && mContext != null && !result.isSuccess() && result.getCode() == ResultCode.UNAUTHORIZED) {
+ /// fail due to lack of authorization in an operation performed in foreground
+ AccountManager am = AccountManager.get(mContext);
+ Credentials cred = mClient.getCredentials();
+ if (cred instanceof BearerCredentials) {
+ am.invalidateAuthToken(AccountAuthenticator.ACCOUNT_TYPE, ((BearerCredentials)cred).getAccessToken());
+ } else {
+ am.clearPassword(mAccount);
+ }
+ mClient = null;
+ repeat = true; // when repeated, the creation of a new OwnCloudClient after erasing the saved credentials will trigger the login activity
+ result = null;
+ }
+ } while (repeat);
+
+ final RemoteOperationResult resultToSend = result;
if (mListenerHandler != null && mListener != null) {
mListenerHandler.post(new Runnable() {
@Override
public void run() {
- mListener.onRemoteOperationFinish(RemoteOperation.this, result);
+ mListener.onRemoteOperationFinish(RemoteOperation.this, resultToSend);
}
});
}
}
-
-
+
+
+ /**
+ * Returns the current client instance to access the remote server.
+ *
+ * @return Current client instance to access the remote server.
+ */
+ public final WebdavClient getClient() {
+ return mClient;
+ }
+
}
import org.apache.commons.httpclient.HttpStatus;
import org.apache.jackrabbit.webdav.DavException;
-import android.util.Log;
-
import com.owncloud.android.Log_OC;
import com.owncloud.android.network.CertificateCombinedException;
/** Generated - should be refreshed every time the class changes!! */
private static final long serialVersionUID = -7805531062432602444L;
+
private static final String TAG = "RemoteOperationResult";
-
- public enum ResultCode {
- OK, OK_SSL, OK_NO_SSL, UNHANDLED_HTTP_CODE, UNAUTHORIZED, FILE_NOT_FOUND, INSTANCE_NOT_CONFIGURED, UNKNOWN_ERROR, WRONG_CONNECTION, TIMEOUT, INCORRECT_ADDRESS, HOST_NOT_AVAILABLE, NO_NETWORK_CONNECTION, SSL_ERROR, SSL_RECOVERABLE_PEER_UNVERIFIED, BAD_OC_VERSION, CANCELLED, INVALID_LOCAL_FILE_NAME, INVALID_OVERWRITE, CONFLICT, SYNC_CONFLICT, LOCAL_STORAGE_FULL, LOCAL_STORAGE_NOT_MOVED, LOCAL_STORAGE_NOT_COPIED, QUOTA_EXCEEDED
+
+ public enum ResultCode {
+ OK,
+ OK_SSL,
+ OK_NO_SSL,
+ UNHANDLED_HTTP_CODE,
+ UNAUTHORIZED,
+ FILE_NOT_FOUND,
+ INSTANCE_NOT_CONFIGURED,
+ UNKNOWN_ERROR,
+ WRONG_CONNECTION,
+ TIMEOUT,
+ INCORRECT_ADDRESS,
+ HOST_NOT_AVAILABLE,
+ NO_NETWORK_CONNECTION,
+ SSL_ERROR,
+ SSL_RECOVERABLE_PEER_UNVERIFIED,
+ BAD_OC_VERSION,
+ CANCELLED,
+ INVALID_LOCAL_FILE_NAME,
+ INVALID_OVERWRITE,
+ CONFLICT,
+ OAUTH2_ERROR,
+ SYNC_CONFLICT,
+ LOCAL_STORAGE_FULL,
+ LOCAL_STORAGE_NOT_MOVED,
+ LOCAL_STORAGE_NOT_COPIED,
+ OAUTH2_ERROR_ACCESS_DENIED,
+ QUOTA_EXCEEDED
}
private boolean mSuccess = false;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
-import android.util.Log;
-
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.OCFile;
//import org.apache.jackrabbit.webdav.client.methods.MoveMethod;
import android.accounts.Account;
-import android.util.Log;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.DataStorageManager;
*/
public class RenameFileOperation extends RemoteOperation {
- private static final String TAG = RemoveFileOperation.class.getSimpleName();
+ private static final String TAG = RenameFileOperation.class.getSimpleName();
private static final int RENAME_READ_TIMEOUT = 10000;
private static final int RENAME_CONNECTION_TIMEOUT = 5000;
import android.accounts.Account;
import android.content.Context;
import android.content.Intent;
-import android.util.Log;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.DataStorageManager;
import android.accounts.Account;
import android.content.Context;
-import android.util.Log;
import com.owncloud.android.Log_OC;
import com.owncloud.android.datamodel.DataStorageManager;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
-import android.util.Log;
import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authentication.AccountAuthenticator;
import com.owncloud.android.Log_OC;
-import com.owncloud.android.authenticator.AccountAuthenticator;
import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.utils.OwnCloudVersion;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
-import android.util.Log;
/**
* The ContentProvider for the ownCloud App.
return null;\r
}\r
\r
- protected void initClientForCurrentAccount() throws UnknownHostException {\r
+ protected void initClientForCurrentAccount() throws OperationCanceledException, AuthenticatorException, IOException {\r
if (AccountUtils.constructFullURLForAccount(getContext(), account) == null) {\r
throw new UnknownHostException();\r
}\r
import org.apache.http.entity.ByteArrayEntity;
import com.owncloud.android.AccountUtils;
-import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.authentication.AccountAuthenticator;
import android.accounts.Account;
import android.accounts.AccountManager;
package com.owncloud.android.syncadapter;
import java.io.IOException;
-import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
+import com.owncloud.android.authentication.AuthenticatorActivity;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.ui.activity.ErrorsWhileCopyingHandlerActivity;
import android.accounts.Account;
+import android.accounts.AccountsException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SyncResult;
import android.os.Bundle;
-import android.util.Log;
/**
* SyncAdapter implementation for syncing sample SyncAdapter contacts to the
* platform ContactOperations provider.
*
* @author Bartek Przybylski
+ * @author David A. Velasco
*/
public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
this.setStorageManager(new FileDataStorageManager(account, getContentProvider()));
try {
this.initClientForCurrentAccount();
- } catch (UnknownHostException e) {
- /// the account is unknown for the Synchronization Manager. unreachable for this context; don't try this again
+ } catch (IOException e) {
+ /// the account is unknown for the Synchronization Manager, or unreachable for this context; don't try this again
+ mSyncResult.tooManyRetries = true;
+ notifyFailedSynchronization();
+ return;
+ } catch (AccountsException e) {
+ /// the account is unknown for the Synchronization Manager, or unreachable for this context; don't try this again
mSyncResult.tooManyRetries = true;
notifyFailedSynchronization();
return;
}
}
-
/**
* Called by system SyncManager when a synchronization is required to be cancelled.
mLastFailedResult = result;
}
}
-
/**
private void notifyFailedSynchronization() {
Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_fail_ticker), System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
- // TODO put something smart in the contentIntent below
+ boolean needsToUpdateCredentials = (mLastFailedResult != null && mLastFailedResult.getCode() == ResultCode.UNAUTHORIZED);
+ // TODO put something smart in the contentIntent below for all the possible errors
notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
- notification.setLatestEventInfo(getContext().getApplicationContext(),
- getContext().getString(R.string.sync_fail_ticker),
- String.format(getContext().getString(R.string.sync_fail_content), getAccount().name),
- notification.contentIntent);
+ if (needsToUpdateCredentials) {
+ // let the user update credentials with one click
+ Intent updateAccountCredentials = new Intent(getContext(), AuthenticatorActivity.class);
+ updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, getAccount());
+ updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_UPDATE_TOKEN);
+ updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
+ notification.contentIntent = PendingIntent.getActivity(getContext(), (int)System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT);
+ notification.setLatestEventInfo(getContext().getApplicationContext(),
+ getContext().getString(R.string.sync_fail_ticker),
+ String.format(getContext().getString(R.string.sync_fail_content_unauthorized), getAccount().name),
+ notification.contentIntent);
+ } else {
+ notification.setLatestEventInfo(getContext().getApplicationContext(),
+ getContext().getString(R.string.sync_fail_ticker),
+ String.format(getContext().getString(R.string.sync_fail_content), getAccount().name),
+ notification.contentIntent);
+ }
((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_fail_ticker, notification);
}
((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_conflicts_in_favourites_ticker, notification);
}
}
-
/**
* Notifies the user about local copies of files out of the ownCloud local directory that were 'forgotten' because
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.View;
import android.view.ViewGroup;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authentication.AccountAuthenticator;
import com.owncloud.android.Log_OC;
-import com.owncloud.android.authenticator.AccountAuthenticator;
import com.owncloud.android.R;
/// the account set as default changed since this activity was created
// trigger synchronization
- ContentResolver.cancelSync(null, AccountAuthenticator.AUTH_TOKEN_TYPE);
+ ContentResolver.cancelSync(null, AccountAuthenticator.AUTHORITY);
Bundle bundle = new Bundle();
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
- ContentResolver.requestSync(AccountUtils.getCurrentOwnCloudAccount(this), AccountAuthenticator.AUTH_TOKEN_TYPE, bundle);
+ ContentResolver.requestSync(AccountUtils.getCurrentOwnCloudAccount(this), AccountAuthenticator.AUTHORITY, bundle);
// restart the main activity
Intent i = new Intent(this, FileDisplayActivity.class);
Intent intent = new Intent(
android.provider.Settings.ACTION_ADD_ACCOUNT);
intent.putExtra("authorities",
- new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
+ new String[] { AccountAuthenticator.AUTHORITY });
startActivity(intent);
return true;
}
+++ /dev/null
-/* ownCloud Android client application
- * Copyright (C) 2012 Bartek Przybylski
- * Copyright (C) 2012-2013 ownCloud Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * 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 com.owncloud.android.ui.activity;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import com.owncloud.android.AccountUtils;
-import com.owncloud.android.Log_OC;
-import com.owncloud.android.authenticator.AccountAuthenticator;
-import com.owncloud.android.authenticator.AuthenticationRunnable;
-import com.owncloud.android.authenticator.OnAuthenticationResultListener;
-import com.owncloud.android.authenticator.OnConnectCheckListener;
-import com.owncloud.android.ui.dialog.SslValidatorDialog;
-import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener;
-import com.owncloud.android.network.OwnCloudClientUtils;
-import com.owncloud.android.operations.ConnectionCheckOperation;
-import com.owncloud.android.operations.OnRemoteOperationListener;
-import com.owncloud.android.operations.RemoteOperation;
-import com.owncloud.android.operations.RemoteOperationResult;
-
-import android.accounts.Account;
-import android.accounts.AccountAuthenticatorActivity;
-import android.accounts.AccountManager;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.ContentResolver;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.Uri;
-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.Button;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.TextView;
-import com.owncloud.android.R;
-
-import eu.alefzero.webdav.WebdavClient;
-
-/**
- * This Activity is used to add an ownCloud account to the App
- *
- * @author Bartek Przybylski
- *
- */
-public class AuthenticatorActivity extends AccountAuthenticatorActivity
- implements OnAuthenticationResultListener, OnConnectCheckListener, OnRemoteOperationListener, OnSslValidatorListener,
- OnFocusChangeListener, OnClickListener {
-
- private static final int DIALOG_LOGIN_PROGRESS = 0;
- private static final int DIALOG_SSL_VALIDATOR = 1;
- private static final int DIALOG_CERT_NOT_SAVED = 2;
-
- private static final String TAG = "AuthActivity";
-
- private Thread mAuthThread;
- private AuthenticationRunnable mAuthRunnable;
- //private ConnectionCheckerRunnable mConnChkRunnable = null;
- private ConnectionCheckOperation mConnChkRunnable;
- private final Handler mHandler = new Handler();
- private String mBaseUrl;
-
- private static final String STATUS_TEXT = "STATUS_TEXT";
- private static final String STATUS_ICON = "STATUS_ICON";
- private static final String STATUS_CORRECT = "STATUS_CORRECT";
- private static final String IS_SSL_CONN = "IS_SSL_CONN";
- private int mStatusText, mStatusIcon;
- private boolean mStatusCorrect, mIsSslConn;
- private RemoteOperationResult mLastSslUntrustedServerResult;
-
- public static final String PARAM_USERNAME = "param_Username";
- public static final String PARAM_HOSTNAME = "param_Hostname";
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getWindow().requestFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.account_setup);
- ImageView iv = (ImageView) findViewById(R.id.refreshButton);
- ImageView iv2 = (ImageView) findViewById(R.id.viewPassword);
- TextView tv = (TextView) findViewById(R.id.host_URL);
- TextView tv2 = (TextView) findViewById(R.id.account_password);
-
- if (savedInstanceState != null) {
- mStatusIcon = savedInstanceState.getInt(STATUS_ICON);
- mStatusText = savedInstanceState.getInt(STATUS_TEXT);
- mStatusCorrect = savedInstanceState.getBoolean(STATUS_CORRECT);
- mIsSslConn = savedInstanceState.getBoolean(IS_SSL_CONN);
- setResultIconAndText(mStatusIcon, mStatusText);
- findViewById(R.id.buttonOK).setEnabled(mStatusCorrect);
- if (!mStatusCorrect)
- iv.setVisibility(View.VISIBLE);
- else
- iv.setVisibility(View.INVISIBLE);
-
- } else {
- mStatusText = mStatusIcon = 0;
- mStatusCorrect = false;
- mIsSslConn = false;
- }
- iv.setOnClickListener(this);
- iv2.setOnClickListener(this);
- tv.setOnFocusChangeListener(this);
- tv2.setOnFocusChangeListener(this);
-
- Button b = (Button) findViewById(R.id.account_register);
- if (b != null) {
- b.setText(String.format(getString(R.string.auth_register), getString(R.string.app_name)));
- }
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- outState.putInt(STATUS_ICON, mStatusIcon);
- outState.putInt(STATUS_TEXT, mStatusText);
- outState.putBoolean(STATUS_CORRECT, mStatusCorrect);
- super.onSaveInstanceState(outState);
- }
-
- @Override
- protected Dialog onCreateDialog(int id) {
- Dialog dialog = null;
- switch (id) {
- case DIALOG_LOGIN_PROGRESS: {
- ProgressDialog working_dialog = new ProgressDialog(this);
- working_dialog.setMessage(getResources().getString(
- R.string.auth_trying_to_login));
- working_dialog.setIndeterminate(true);
- working_dialog.setCancelable(true);
- working_dialog
- .setOnCancelListener(new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- Log_OC.i(TAG, "Login canceled");
- if (mAuthThread != null) {
- mAuthThread.interrupt();
- finish();
- }
- }
- });
- dialog = working_dialog;
- break;
- }
- case DIALOG_SSL_VALIDATOR: {
- dialog = SslValidatorDialog.newInstance(this, mLastSslUntrustedServerResult, this);
- break;
- }
- case DIALOG_CERT_NOT_SAVED: {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setMessage(getResources().getString(R.string.ssl_validator_not_saved));
- builder.setCancelable(false);
- builder.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- };
- });
- dialog = builder.create();
- break;
- }
- default:
- Log_OC.e(TAG, "Incorrect dialog called with id = " + id);
- }
- return dialog;
- }
-
- @Override
- protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
- switch (id) {
- case DIALOG_LOGIN_PROGRESS:
- case DIALOG_CERT_NOT_SAVED:
- break;
- case DIALOG_SSL_VALIDATOR: {
- ((SslValidatorDialog)dialog).updateResult(mLastSslUntrustedServerResult);
- break;
- }
- default:
- Log_OC.e(TAG, "Incorrect dialog called with id = " + id);
- }
- }
-
- public void onAuthenticationResult(boolean success, String message) {
- if (success) {
- TextView username_text = (TextView) findViewById(R.id.account_username), password_text = (TextView) findViewById(R.id.account_password);
-
- URL url;
- try {
- url = new URL(message);
- } catch (MalformedURLException e) {
- // should never happen
- Log_OC.e(getClass().getName(), "Malformed URL: " + message);
- return;
- }
-
- String username = username_text.getText().toString().trim();
- String accountName = username + "@" + url.getHost();
- if (url.getPort() >= 0) {
- accountName += ":" + url.getPort();
- }
- Account account = new Account(accountName,
- AccountAuthenticator.ACCOUNT_TYPE);
- AccountManager accManager = AccountManager.get(this);
- accManager.addAccountExplicitly(account, password_text.getText()
- .toString(), null);
-
- // Add this account as default in the preferences, if there is none
- // already
- Account defaultAccount = AccountUtils
- .getCurrentOwnCloudAccount(this);
- if (defaultAccount == null) {
- SharedPreferences.Editor editor = PreferenceManager
- .getDefaultSharedPreferences(this).edit();
- editor.putString("select_oc_account", accountName);
- editor.commit();
- }
-
- final Intent intent = new Intent();
- intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE,
- AccountAuthenticator.ACCOUNT_TYPE);
- intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
- intent.putExtra(AccountManager.KEY_AUTHTOKEN,
- AccountAuthenticator.ACCOUNT_TYPE);
- intent.putExtra(AccountManager.KEY_USERDATA, username);
-
- accManager.setUserData(account,
- AccountAuthenticator.KEY_OC_VERSION, mConnChkRunnable
- .getDiscoveredVersion().toString());
-
- accManager.setUserData(account,
- AccountAuthenticator.KEY_OC_BASE_URL, mBaseUrl);
-
- setAccountAuthenticatorResult(intent.getExtras());
- setResult(RESULT_OK, intent);
- Bundle bundle = new Bundle();
- bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
- //getContentResolver().startSync(ProviderTableMeta.CONTENT_URI,
- // bundle);
- ContentResolver.requestSync(account, "org.owncloud", bundle);
-
- /*
- * if
- * (mConnChkRunnable.getDiscoveredVersion().compareTo(OwnCloudVersion
- * .owncloud_v2) >= 0) { Intent i = new Intent(this,
- * ExtensionsAvailableActivity.class); startActivity(i); }
- */
-
- finish();
- } else {
- try {
- dismissDialog(DIALOG_LOGIN_PROGRESS);
- } catch (IllegalArgumentException e) {
- // NOTHING TO DO ; can't find out what situation that leads to the exception in this code, but user logs signal that it happens
- }
- TextView tv = (TextView) findViewById(R.id.account_username);
- tv.setError(message + " "); // the extra spaces are a workaround for an ugly bug:
- // 1. insert wrong credentials and connect
- // 2. put the focus on the user name field with using hardware controls (don't touch the screen); the error is shown UNDER the field
- // 3. touch the user name field; the software keyboard appears; the error popup is moved OVER the field and SHRINKED in width, losing the last word
- // Seen, at least, in Android 2.x devices
- }
- }
- public void onCancelClick(View view) {
- setResult(RESULT_CANCELED);
- finish();
- }
-
- public void onOkClick(View view) {
- String prefix = "";
- String url = ((TextView) findViewById(R.id.host_URL)).getText()
- .toString().trim();
- if (mIsSslConn) {
- prefix = "https://";
- } else {
- prefix = "http://";
- }
- if (url.toLowerCase().startsWith("http://")
- || url.toLowerCase().startsWith("https://")) {
- prefix = "";
- }
- continueConnection(prefix);
- }
-
- public void onRegisterClick(View view) {
- Intent register = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.url_account_register)));
- setResult(RESULT_CANCELED);
- startActivity(register);
- }
-
- private void continueConnection(String prefix) {
- String url = ((TextView) findViewById(R.id.host_URL)).getText()
- .toString().trim();
- String username = ((TextView) findViewById(R.id.account_username))
- .getText().toString();
- String password = ((TextView) findViewById(R.id.account_password))
- .getText().toString();
- if (url.endsWith("/"))
- url = url.substring(0, url.length() - 1);
-
- URL uri = null;
- String webdav_path = AccountUtils.getWebdavPath(mConnChkRunnable
- .getDiscoveredVersion());
-
- if (webdav_path == null) {
- onAuthenticationResult(false, getString(R.string.auth_bad_oc_version_title));
- return;
- }
-
- try {
- mBaseUrl = prefix + url;
- String url_str = prefix + url + webdav_path;
- uri = new URL(url_str);
- } catch (MalformedURLException e) {
- // should never happen
- onAuthenticationResult(false, getString(R.string.auth_incorrect_address_title));
- return;
- }
-
- showDialog(DIALOG_LOGIN_PROGRESS);
- mAuthRunnable = new AuthenticationRunnable(uri, username, password, this);
- mAuthRunnable.setOnAuthenticationResultListener(this, mHandler);
- mAuthThread = new Thread(mAuthRunnable);
- mAuthThread.start();
- }
-
- @Override
- public void onConnectionCheckResult(ResultType type) {
- mStatusText = mStatusIcon = 0;
- mStatusCorrect = false;
- String t_url = ((TextView) findViewById(R.id.host_URL)).getText()
- .toString().trim().toLowerCase();
-
- switch (type) {
- case OK_SSL:
- mIsSslConn = true;
- mStatusIcon = android.R.drawable.ic_secure;
- mStatusText = R.string.auth_secure_connection;
- mStatusCorrect = true;
- break;
- case OK_NO_SSL:
- mIsSslConn = false;
- mStatusCorrect = true;
- if (t_url.startsWith("http://") ) {
- mStatusText = R.string.auth_connection_established;
- mStatusIcon = R.drawable.ic_ok;
- } else {
- mStatusText = R.string.auth_nossl_plain_ok_title;
- mStatusIcon = android.R.drawable.ic_partial_secure;
- }
- break;
- case BAD_OC_VERSION:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_bad_oc_version_title;
- break;
- case WRONG_CONNECTION:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_wrong_connection_title;
- break;
- case TIMEOUT:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_timeout_title;
- break;
- case INCORRECT_ADDRESS:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_incorrect_address_title;
- break;
- case SSL_UNVERIFIED_SERVER:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_ssl_unverified_server_title;
- break;
- case SSL_INIT_ERROR:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_ssl_general_error_title;
- break;
- case HOST_NOT_AVAILABLE:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_unknown_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_unknown_error_title;
- break;
- case FILE_NOT_FOUND:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_incorrect_path_title;
- break;
- default:
- Log_OC.e(TAG, "Incorrect connection checker result type: " + type);
- }
- setResultIconAndText(mStatusIcon, mStatusText);
- if (!mStatusCorrect)
- findViewById(R.id.refreshButton).setVisibility(View.VISIBLE);
- else
- findViewById(R.id.refreshButton).setVisibility(View.INVISIBLE);
- findViewById(R.id.buttonOK).setEnabled(mStatusCorrect);
- }
-
- @Override
- public void onFocusChange(View view, boolean hasFocus) {
- if (view.getId() == R.id.host_URL) {
- if (!hasFocus) {
- TextView tv = ((TextView) findViewById(R.id.host_URL));
- String uri = tv.getText().toString().trim();
- if (uri.length() != 0) {
- setResultIconAndText(R.drawable.progress_small,
- R.string.auth_testing_connection);
- //mConnChkRunnable = new ConnectionCheckerRunnable(uri, this);
- mConnChkRunnable = new ConnectionCheckOperation(uri, this);
- //mConnChkRunnable.setListener(this, mHandler);
- //mAuthThread = new Thread(mConnChkRunnable);
- //mAuthThread.start();
- WebdavClient client = OwnCloudClientUtils.createOwnCloudClient(Uri.parse(uri), this);
- mAuthThread = mConnChkRunnable.execute(client, this, mHandler);
- } else {
- findViewById(R.id.refreshButton).setVisibility(
- View.INVISIBLE);
- setResultIconAndText(0, 0);
- }
- } else {
- // avoids that the 'connect' button can be clicked if the test was previously passed
- findViewById(R.id.buttonOK).setEnabled(false);
- }
- } else if (view.getId() == R.id.account_password) {
- ImageView iv = (ImageView) findViewById(R.id.viewPassword);
- if (hasFocus) {
- iv.setVisibility(View.VISIBLE);
- } else {
- TextView v = (TextView) findViewById(R.id.account_password);
- int input_type = InputType.TYPE_CLASS_TEXT
- | InputType.TYPE_TEXT_VARIATION_PASSWORD;
- v.setInputType(input_type);
- iv.setVisibility(View.INVISIBLE);
- }
- }
- }
-
- private void setResultIconAndText(int drawable_id, int text_id) {
- ImageView iv = (ImageView) findViewById(R.id.action_indicator);
- TextView tv = (TextView) findViewById(R.id.status_text);
-
- if (drawable_id == 0 && text_id == 0) {
- iv.setVisibility(View.INVISIBLE);
- tv.setVisibility(View.INVISIBLE);
- } else {
- iv.setImageResource(drawable_id);
- tv.setText(text_id);
- iv.setVisibility(View.VISIBLE);
- tv.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.refreshButton) {
- onFocusChange(findViewById(R.id.host_URL), false);
- } else if (v.getId() == R.id.viewPassword) {
- EditText view = (EditText) findViewById(R.id.account_password);
- int selectionStart = view.getSelectionStart();
- int selectionEnd = view.getSelectionEnd();
- int input_type = view.getInputType();
- if ((input_type & InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
- input_type = InputType.TYPE_CLASS_TEXT
- | InputType.TYPE_TEXT_VARIATION_PASSWORD;
- } else {
- input_type = InputType.TYPE_CLASS_TEXT
- | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
- }
- view.setInputType(input_type);
- view.setSelection(selectionStart, selectionEnd);
- }
- }
-
- @Override
- public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
- if (operation.equals(mConnChkRunnable)) {
-
- mStatusText = mStatusIcon = 0;
- mStatusCorrect = false;
- String t_url = ((TextView) findViewById(R.id.host_URL)).getText()
- .toString().trim().toLowerCase();
-
- switch (result.getCode()) {
- case OK_SSL:
- mIsSslConn = true;
- mStatusIcon = android.R.drawable.ic_secure;
- mStatusText = R.string.auth_secure_connection;
- mStatusCorrect = true;
- break;
-
- case OK_NO_SSL:
- case OK:
- mIsSslConn = false;
- mStatusCorrect = true;
- if (t_url.startsWith("http://") ) {
- mStatusText = R.string.auth_connection_established;
- mStatusIcon = R.drawable.ic_ok;
- } else {
- mStatusText = R.string.auth_nossl_plain_ok_title;
- mStatusIcon = android.R.drawable.ic_partial_secure;
- }
- break;
-
-
- case BAD_OC_VERSION:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_bad_oc_version_title;
- break;
- case WRONG_CONNECTION:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_wrong_connection_title;
- break;
- case TIMEOUT:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_timeout_title;
- break;
- case INCORRECT_ADDRESS:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_incorrect_address_title;
- break;
-
- case SSL_RECOVERABLE_PEER_UNVERIFIED:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_ssl_unverified_server_title;
- mLastSslUntrustedServerResult = result;
- showDialog(DIALOG_SSL_VALIDATOR);
- break;
-
- case SSL_ERROR:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_ssl_general_error_title;
- break;
-
- case HOST_NOT_AVAILABLE:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_unknown_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 FILE_NOT_FOUND:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_incorrect_path_title;
- break;
- case UNHANDLED_HTTP_CODE:
- case UNKNOWN_ERROR:
- mStatusIcon = R.drawable.common_error;
- mStatusText = R.string.auth_unknown_error_title;
- break;
- default:
- Log_OC.e(TAG, "Incorrect connection checker result type: " + result.getHttpCode());
- }
- 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 onSavedCertificate() {
- mAuthThread = mConnChkRunnable.retry(this, mHandler);
- }
-
- @Override
- public void onFailedSavingCertificate() {
- showDialog(DIALOG_CERT_NOT_SAVED);
- }
-
-}
import android.os.Handler;
import android.support.v4.app.DialogFragment;
import android.text.method.ScrollingMovementMethod;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
+/* ownCloud Android client application\r
+ * Copyright (C) 2012-2013 ownCloud Inc.\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License version 2,\r
+ * as published by the Free Software Foundation.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
package com.owncloud.android.ui.activity;\r
\r
import android.app.Activity;\r
* \r
* The entry-point for this activity is the 'Failed upload Notification"\r
* \r
- * \r
* @author andomaex / Matthias Baumann\r
- * \r
- * This program is free software: you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation, either version 3 of the License. (at\r
- * your option) any later version.\r
- * \r
- * This program is distributed in the hope that it will be useful, but\r
- * WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more de/\r
*/\r
public class FailedUploadActivity extends Activity {\r
\r
import android.os.IBinder;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
-import android.util.Log;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import android.accounts.Account;
import android.app.AlertDialog;
import android.app.ProgressDialog;
-import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.content.pm.PackageInfo;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
-import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
-import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.owncloud.android.AccountUtils;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
-import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.authentication.AccountAuthenticator;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileObserverService;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
-import com.owncloud.android.network.OwnCloudClientUtils;
+import com.owncloud.android.operations.CreateFolderOperation;
import com.owncloud.android.operations.OnRemoteOperationListener;
import com.owncloud.android.operations.RemoteOperation;
import com.owncloud.android.operations.RemoteOperationResult;
import com.owncloud.android.operations.SynchronizeFileOperation;
import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.syncadapter.FileSyncService;
-import com.owncloud.android.ui.dialog.ChangelogDialog;
import com.owncloud.android.ui.dialog.EditNameDialog;
import com.owncloud.android.ui.dialog.SslValidatorDialog;
import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener;
import com.owncloud.android.ui.preview.PreviewImageFragment;
import com.owncloud.android.ui.preview.PreviewMediaFragment;
-import eu.alefzero.webdav.WebdavClient;
-
/**
* Displays, what files the user has available in his ownCloud.
*
private boolean mBackFromCreatingFirstAccount;
private static final int DIALOG_SETUP_ACCOUNT = 0;
- private static final int DIALOG_CREATE_DIR = 1;
- public static final int DIALOG_SHORT_WAIT = 3;
- private static final int DIALOG_CHOOSE_UPLOAD_SOURCE = 4;
- private static final int DIALOG_SSL_VALIDATOR = 5;
- private static final int DIALOG_CERT_NOT_SAVED = 6;
- private static final String DIALOG_CHANGELOG_TAG = "DIALOG_CHANGELOG";
-
+ public static final int DIALOG_SHORT_WAIT = 1;
+ private static final int DIALOG_CHOOSE_UPLOAD_SOURCE = 2;
+ private static final int DIALOG_SSL_VALIDATOR = 3;
+ private static final int DIALOG_CERT_NOT_SAVED = 4;
private static final int ACTION_SELECT_CONTENT_FROM_APPS = 1;
private static final int ACTION_SELECT_MULTIPLE_FILES = 2;
Log_OC.d(getClass().toString(), "onCreate() start");
super.onCreate(savedInstanceState);
+ mHandler = new Handler();
+
/// Load of parameters from received intent
Account account = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_ACCOUNT);
if (account != null && AccountUtils.setCurrentOwnCloudAccount(this, account.name)) {
setSupportProgressBarIndeterminateVisibility(false); // always AFTER setContentView(...) ; to workaround bug in its implementation
- // show changelog, if needed
- //showChangeLog();
mBackFromCreatingFirstAccount = false;
Log_OC.d(getClass().toString(), "onCreate() end");
/**
- * Shows a dialog with the change log of the current version after each app update
- *
- * TODO make it permanent; by now, only to advice the workaround app for 4.1.x
- */
- private void showChangeLog() {
- if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.JELLY_BEAN) {
- final String KEY_VERSION = "version";
- SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
- int currentVersionNumber = 0;
- int savedVersionNumber = sharedPref.getInt(KEY_VERSION, 0);
- try {
- PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0);
- currentVersionNumber = pi.versionCode;
- } catch (Exception e) {}
-
- if (currentVersionNumber > savedVersionNumber) {
- ChangelogDialog.newInstance(true).show(getSupportFragmentManager(), DIALOG_CHANGELOG_TAG);
- Editor editor = sharedPref.edit();
- editor.putInt(KEY_VERSION, currentVersionNumber);
- editor.commit();
- }
- }
- }
-
-
- /**
* Launches the account creation activity. To use when no ownCloud account is available
*/
private void createFirstAccount() {
Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
- intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
+ intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTHORITY });
startActivity(intent); // the new activity won't be created until this.onStart() and this.onResume() are finished;
}
}
private void startSynchronization() {
- ContentResolver.cancelSync(null, AccountAuthenticator.AUTH_TOKEN_TYPE); // cancel the current synchronizations of any ownCloud account
+ ContentResolver.cancelSync(null, AccountAuthenticator.AUTHORITY); // cancel the current synchronizations of any ownCloud account
Bundle bundle = new Bundle();
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
ContentResolver.requestSync(
AccountUtils.getCurrentOwnCloudAccount(this),
- AccountAuthenticator.AUTH_TOKEN_TYPE, bundle);
+ AccountAuthenticator.AUTHORITY, bundle);
}
outState.putParcelable(FileDetailActivity.KEY_WAITING_TO_PREVIEW, mWaitingToPreview);
Log_OC.d(getClass().toString(), "onSaveInstanceState() end");
}
-
@Override
protected void onResume() {
dialog = builder.create();
break;
}
- case DIALOG_CREATE_DIR: {
- builder = new Builder(this);
- final EditText dirNameInput = new EditText(getBaseContext());
- builder.setView(dirNameInput);
- builder.setTitle(R.string.uploader_info_dirname);
- int typed_color = getResources().getColor(R.color.setup_text_typed);
- dirNameInput.setTextColor(typed_color);
- builder.setPositiveButton(android.R.string.ok,
- new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- String directoryName = dirNameInput.getText().toString();
- if (directoryName.trim().length() == 0) {
- dialog.cancel();
- return;
- }
-
- // Figure out the path where the dir needs to be created
- String path;
- if (mCurrentDir == null) {
- // this is just a patch; we should ensure that mCurrentDir never is null
- if (!mStorageManager.fileExists(OCFile.PATH_SEPARATOR)) {
- OCFile file = new OCFile(OCFile.PATH_SEPARATOR);
- mStorageManager.saveFile(file);
- }
- mCurrentDir = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);
- }
- path = FileDisplayActivity.this.mCurrentDir.getRemotePath();
-
- // Create directory
- path += directoryName + OCFile.PATH_SEPARATOR;
- Thread thread = new Thread(new DirectoryCreator(path, AccountUtils.getCurrentOwnCloudAccount(FileDisplayActivity.this), new Handler()));
- thread.start();
-
- dialog.dismiss();
-
- showDialog(DIALOG_SHORT_WAIT);
- }
- });
- builder.setNegativeButton(R.string.common_cancel,
- new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- });
- dialog = builder.create();
- break;
- }
case DIALOG_SHORT_WAIT: {
ProgressDialog working_dialog = new ProgressDialog(this);
working_dialog.setMessage(getResources().getString(
return !mDirectories.isEmpty();
}
- private class DirectoryCreator implements Runnable {
- private String mTargetPath;
- private Account mAccount;
- private Handler mHandler;
-
- public DirectoryCreator(String targetPath, Account account, Handler handler) {
- mTargetPath = targetPath;
- mAccount = account;
- mHandler = handler;
- }
-
- @Override
- public void run() {
- WebdavClient wdc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getApplicationContext());
- boolean created = wdc.createDirectory(mTargetPath);
- if (created) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- dismissDialog(DIALOG_SHORT_WAIT);
-
- // Save new directory in local database
- OCFile newDir = new OCFile(mTargetPath);
- newDir.setMimetype("DIR");
- newDir.setParentId(mCurrentDir.getFileId());
- mStorageManager.saveFile(newDir);
-
- // Display the new folder right away
- mFileList.listDirectory();
- }
- });
-
- } else {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- dismissDialog(DIALOG_SHORT_WAIT);
- try {
- Toast msg = Toast.makeText(FileDisplayActivity.this, R.string.create_dir_fail_msg, Toast.LENGTH_LONG);
- msg.show();
-
- } catch (NotFoundException e) {
- Log_OC.e(TAG, "Error while trying to show fail message ", e);
- }
- }
- });
- }
- }
-
- }
-
// Custom array adapter to override text colors
private class CustomArrayAdapter<T> extends ArrayAdapter<T> {
} else if (operation instanceof SynchronizeFileOperation) {
onSynchronizeFileOperationFinish((SynchronizeFileOperation)operation, result);
+
+ } else if (operation instanceof CreateFolderOperation) {
+ onCreateFolderOperationFinish((CreateFolderOperation)operation, result);
}
}
}
/**
+ * Updates the view associated to the activity after the finish of an operation trying create a new folder
+ *
+ * @param operation Creation operation performed.
+ * @param result Result of the creation.
+ */
+ private void onCreateFolderOperationFinish(CreateFolderOperation operation, RemoteOperationResult result) {
+ if (result.isSuccess()) {
+ dismissDialog(DIALOG_SHORT_WAIT);
+ mFileList.listDirectory();
+
+ } else {
+ dismissDialog(DIALOG_SHORT_WAIT);
+ try {
+ Toast msg = Toast.makeText(FileDisplayActivity.this, R.string.create_dir_fail_msg, Toast.LENGTH_LONG);
+ msg.show();
+
+ } catch (NotFoundException e) {
+ Log_OC.e(TAG, "Error while trying to show fail message " , e);
+ }
+ }
+ }
+
+
+ /**
* Updates the view associated to the activity after the finish of an operation trying to rename a
* file.
*
//dialog.dismiss();
if (dialog.getResult()) {
String newDirectoryName = dialog.getNewFilename().trim();
- Log.d(TAG, "'create directory' dialog dismissed with new name " + newDirectoryName);
+ Log_OC.d(TAG, "'create directory' dialog dismissed with new name " + newDirectoryName);
if (newDirectoryName.length() > 0) {
String path;
if (mCurrentDir == null) {
// Create directory
path += newDirectoryName + OCFile.PATH_SEPARATOR;
- Thread thread = new Thread(new DirectoryCreator(path, AccountUtils.getCurrentOwnCloudAccount(FileDisplayActivity.this), new Handler()));
- thread.start();
+ RemoteOperation operation = new CreateFolderOperation(path, mCurrentDir.getFileId(), mStorageManager);
+ operation.execute( AccountUtils.getCurrentOwnCloudAccount(FileDisplayActivity.this),
+ FileDisplayActivity.this,
+ FileDisplayActivity.this,
+ mHandler,
+ FileDisplayActivity.this);
showDialog(DIALOG_SHORT_WAIT);
}
}
}
-
+
+
private void requestForDownload() {
Account account = AccountUtils.getCurrentOwnCloudAccount(this);
if (!mDownloaderBinder.isDownloading(account, mWaitingToPreview)) {
* Copyright (C) 2012-2013 ownCloud Inc.
*
* 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.
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
-import android.util.Log;
import android.util.SparseArray;
import android.view.Gravity;
import android.view.View;
* sub-menu underneath the 'Upload' menu-item
*
* @author andomaex / Matthias Baumann
- *
- * 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. (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 de/
*/
public class InstantUploadActivity extends Activity {
@Override
public boolean onLongClick(View v) {
- Log.d(LOG_TAG, message);
+ Log_OC.d(LOG_TAG, message);
Toast toast = Toast.makeText(InstantUploadActivity.this, getString(R.string.failed_upload_retry_text)
+ message, Toast.LENGTH_LONG);
toast.show();
package com.owncloud.android.ui.activity;\r
\r
import com.actionbarsherlock.app.SherlockFragmentActivity;\r
-import com.owncloud.android.authenticator.AccountAuthenticator;\r
+import com.owncloud.android.authentication.AccountAuthenticator;\r
import com.owncloud.android.ui.adapter.LandingScreenAdapter;\r
\r
import android.accounts.Account;\r
dialog.dismiss();\r
switch (which) {\r
case DialogInterface.BUTTON_POSITIVE:\r
- Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");\r
+ Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);\r
intent.putExtra("authorities",\r
- new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
+ new String[] { AccountAuthenticator.AUTHORITY });\r
startActivity(intent);\r
break;\r
case DialogInterface.BUTTON_NEGATIVE:\r
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.DialogFragment;
-import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
-import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
-import android.util.Log;
import com.actionbarsherlock.app.SherlockDialogFragment;
import com.owncloud.android.Log_OC;
import java.io.File;
import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.httpclient.methods.StringRequestEntity;
-import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
-import org.apache.http.HttpStatus;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.utils.URLEncodedUtils;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
-import org.json.JSONObject;
import android.accounts.Account;
-import android.accounts.AccountManager;
-//import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentTransaction;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapFactory.Options;
-import android.graphics.Point;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.FragmentTransaction;
-import android.util.Log;
-import android.view.Display;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.webkit.MimeTypeMap;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-
import com.actionbarsherlock.app.SherlockFragment;
-import com.owncloud.android.AccountUtils;
import com.owncloud.android.DisplayUtils;
import com.owncloud.android.Log_OC;
-import com.owncloud.android.authenticator.AccountAuthenticator;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileObserverService;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
-import com.owncloud.android.network.OwnCloudClientUtils;
import com.owncloud.android.operations.OnRemoteOperationListener;
import com.owncloud.android.operations.RemoteOperation;
import com.owncloud.android.operations.RemoteOperationResult;
import com.owncloud.android.ui.activity.FileDisplayActivity;
import com.owncloud.android.ui.dialog.EditNameDialog;
import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener;
-import com.owncloud.android.utils.OwnCloudVersion;
import com.owncloud.android.R;
import eu.alefzero.webdav.OnDatatransferProgressListener;
-import eu.alefzero.webdav.WebdavClient;
import eu.alefzero.webdav.WebdavUtils;
-
/**
* This Fragment is used to display the details about a file.
*
mProgressListener = null;
}
-
/**
* Creates a details fragment.
*
}
- @Override
- public View getView() {
- return super.getView() == null ? mView : super.getView();
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.fdDownloadBtn: {
- FileDownloaderBinder downloaderBinder = mContainerActivity.getFileDownloaderBinder();
- FileUploaderBinder uploaderBinder = mContainerActivity.getFileUploaderBinder();
- if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, mFile)) {
- downloaderBinder.cancel(mAccount, mFile);
- if (mFile.isDown()) {
- setButtonsForDown();
- } else {
- setButtonsForRemote();
- }
-
- } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, mFile)) {
- uploaderBinder.cancel(mAccount, mFile);
- if (!mFile.fileExists()) {
- // TODO make something better
- if (getActivity() instanceof FileDisplayActivity) {
- // double pane
- FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
- transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null), FTAG); // empty FileDetailFragment
- transaction.commit();
- mContainerActivity.onFileStateChanged();
- } else {
- getActivity().finish();
- }
-
- } else if (mFile.isDown()) {
- setButtonsForDown();
- } else {
- setButtonsForRemote();
- }
-
- } else {
- mLastRemoteOperation = new SynchronizeFileOperation(mFile, null, mStorageManager, mAccount, true, false, getActivity());
- WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getSherlockActivity().getApplicationContext());
- mLastRemoteOperation.execute(wc, this, mHandler);
-
- // update ui
- boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
- getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
-
- }
- break;
- }
+ @Override\r
+ public View getView() {\r
+ return super.getView() == null ? mView : super.getView();\r
+ }\r
+
+ \r
+ @Override\r
+ public void onClick(View v) {\r
+ switch (v.getId()) {\r
+ case R.id.fdDownloadBtn: {\r
+ FileDownloaderBinder downloaderBinder = mContainerActivity.getFileDownloaderBinder();\r
+ FileUploaderBinder uploaderBinder = mContainerActivity.getFileUploaderBinder();\r
+ if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, mFile)) {\r
+ downloaderBinder.cancel(mAccount, mFile);\r
+ if (mFile.isDown()) {\r
+ setButtonsForDown();\r
+ } else {\r
+ setButtonsForRemote();\r
+ }\r
+\r
+ } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, mFile)) {\r
+ uploaderBinder.cancel(mAccount, mFile);\r
+ if (!mFile.fileExists()) {\r
+ // TODO make something better\r
+ if (getActivity() instanceof FileDisplayActivity) {\r
+ // double pane\r
+ FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();\r
+ transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null), FTAG); // empty FileDetailFragment\r
+ transaction.commit();\r
+ mContainerActivity.onFileStateChanged();\r
+ } else {\r
+ getActivity().finish();\r
+ }\r
+ \r
+ } else if (mFile.isDown()) {\r
+ setButtonsForDown();\r
+ } else {\r
+ setButtonsForRemote();\r
+ }\r
+ \r
+ } else {\r
+ mLastRemoteOperation = new SynchronizeFileOperation(mFile, null, mStorageManager, mAccount, true, false, getActivity());\r
+ mLastRemoteOperation.execute(mAccount, getSherlockActivity(), this, mHandler, getSherlockActivity());\r
+ \r
+ // update ui \r
+ boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
+ getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
+ setButtonsForTransferring(); // disable button immediately, although the synchronization does not result in a file transference\r
+ \r
+ }\r
+ break;\r
+ }\r
case R.id.fdKeepInSync: {
CheckBox cb = (CheckBox) getView().findViewById(R.id.fdKeepInSync);
mFile.setKeepInSync(cb.isChecked());
Log_OC.e(TAG, "Incorrect view clicked!");
}
- /* else if (v.getId() == R.id.fdShareBtn) {
- Thread t = new Thread(new ShareRunnable(mFile.getRemotePath()));
- t.start();
- }*/
- }
-
-
+ }\r
+ \r
/**
* Opens mFile.
*/
startActivity(i);
} catch (Throwable t) {
- Log.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mFile.getMimetype());
+ Log_OC.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mFile.getMimetype());
boolean toastIt = true;
String mimeType = "";
try {
}
} catch (IndexOutOfBoundsException e) {
- Log.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);
+ Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);
} catch (ActivityNotFoundException e) {
- Log.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");
+ Log_OC.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");
} catch (Throwable th) {
- Log.e(TAG, "Unexpected problem when opening: " + storagePath, th);
+ Log_OC.e(TAG, "Unexpected problem when opening: " + storagePath, th);
} finally {
if (toastIt) {
}
}
-
@Override
public void onConfirmation(String callerTag) {
if (callerTag.equals(FTAG_CONFIRMATION)) {
mLastRemoteOperation = new RemoveFileOperation( mFile,
true,
mStorageManager);
- WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getSherlockActivity().getApplicationContext());
- mLastRemoteOperation.execute(wc, this, mHandler);
+ mLastRemoteOperation.execute(mAccount, getSherlockActivity(), this, mHandler, getSherlockActivity());
boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
@Override
public void onCancel(String callerTag) {
- Log.d(TAG, "REMOVAL CANCELED");
+ Log_OC.d(TAG, "REMOVAL CANCELED");
}
getView().invalidate();
}
-
/**
* Checks if the fragment is ready to show details of a OCFile
*
}
- // this is a temporary class for sharing purposes, it need to be replaced in transfer service
- @SuppressWarnings("unused")
- private class ShareRunnable implements Runnable {
- private String mPath;
-
- public ShareRunnable(String path) {
- mPath = path;
- }
-
- public void run() {
- AccountManager am = AccountManager.get(getActivity());
- Account account = AccountUtils.getCurrentOwnCloudAccount(getActivity());
- OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION));
- String url = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + AccountUtils.getWebdavPath(ocv);
-
- Log.d("share", "sharing for version " + ocv.toString());
-
- if (ocv.compareTo(new OwnCloudVersion(0x040000)) >= 0) {
- String APPS_PATH = "/apps/files_sharing/";
- String SHARE_PATH = "ajax/share.php";
-
- String SHARED_PATH = "/apps/files_sharing/get.php?token=";
-
- final String WEBDAV_SCRIPT = "webdav.php";
- final String WEBDAV_FILES_LOCATION = "/files/";
-
- WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(account, getActivity().getApplicationContext());
- HttpConnectionManagerParams params = new HttpConnectionManagerParams();
- params.setMaxConnectionsPerHost(wc.getHostConfiguration(), 5);
-
- //wc.getParams().setParameter("http.protocol.single-cookie-header", true);
- //wc.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
-
- PostMethod post = new PostMethod(am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + APPS_PATH + SHARE_PATH);
-
- post.addRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8" );
- post.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));
- List<NameValuePair> formparams = new ArrayList<NameValuePair>();
- Log.d("share", mPath+"");
- formparams.add(new BasicNameValuePair("sources",mPath));
- formparams.add(new BasicNameValuePair("uid_shared_with", "public"));
- formparams.add(new BasicNameValuePair("permissions", "0"));
- post.setRequestEntity(new StringRequestEntity(URLEncodedUtils.format(formparams, HTTP.UTF_8)));
-
- int status;
- try {
- PropFindMethod find = new PropFindMethod(url+"/");
- find.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));
- Log.d("sharer", ""+ url+"/");
-
- for (org.apache.commons.httpclient.Header a : find.getRequestHeaders()) {
- Log.d("sharer-h", a.getName() + ":"+a.getValue());
- }
-
- int status2 = wc.executeMethod(find);
-
- Log.d("sharer", "propstatus "+status2);
-
- GetMethod get = new GetMethod(am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + "/");
- get.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));
-
- status2 = wc.executeMethod(get);
-
- Log.d("sharer", "getstatus "+status2);
- Log.d("sharer", "" + get.getResponseBodyAsString());
-
- for (org.apache.commons.httpclient.Header a : get.getResponseHeaders()) {
- Log.d("sharer", a.getName() + ":"+a.getValue());
- }
-
- status = wc.executeMethod(post);
- for (org.apache.commons.httpclient.Header a : post.getRequestHeaders()) {
- Log.d("sharer-h", a.getName() + ":"+a.getValue());
- }
- for (org.apache.commons.httpclient.Header a : post.getResponseHeaders()) {
- Log.d("sharer", a.getName() + ":"+a.getValue());
- }
- String resp = post.getResponseBodyAsString();
- Log.d("share", ""+post.getURI().toString());
- Log.d("share", "returned status " + status);
- Log.d("share", " " +resp);
-
- if(status != HttpStatus.SC_OK ||resp == null || resp.equals("") || resp.startsWith("false")) {
- return;
- }
-
- JSONObject jsonObject = new JSONObject (resp);
- String jsonStatus = jsonObject.getString("status");
- if(!jsonStatus.equals("success")) throw new Exception("Error while sharing file status != success");
-
- String token = jsonObject.getString("data");
- String uri = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + SHARED_PATH + token;
- Log.d("Actions:shareFile ok", "url: " + uri);
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- } else if (ocv.compareTo(new OwnCloudVersion(0x030000)) >= 0) {
-
- }
- }
- }
-
public void onDismiss(EditNameDialog dialog) {
if (dialog.getResult()) {
String newFilename = dialog.getNewFilename();
- Log.d(TAG, "name edit dialog dismissed with new name " + newFilename);
+ Log_OC.d(TAG, "name edit dialog dismissed with new name " + newFilename);
mLastRemoteOperation = new RenameFileOperation( mFile,
mAccount,
newFilename,
new FileDataStorageManager(mAccount, getActivity().getContentResolver()));
- WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getSherlockActivity().getApplicationContext());
- mLastRemoteOperation.execute(wc, this, mHandler);
+ mLastRemoteOperation.execute(mAccount, getSherlockActivity(), this, mHandler, getSherlockActivity());
boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
}
}
}
-
+
public void listenForTransferProgress() {
if (mProgressListener != null) {
if (mContainerActivity.getFileDownloaderBinder() != null) {
};
-}
\ No newline at end of file
+ /*
+ // this is a temporary class for sharing purposes, it need to be replaced in transfer service
+ @SuppressWarnings("unused")
+ private class ShareRunnable implements Runnable {
+ private String mPath;
+
+ public ShareRunnable(String path) {
+ mPath = path;
+ }
+
+ public void run() {
+ AccountManager am = AccountManager.get(getActivity());
+ Account account = AccountUtils.getCurrentOwnCloudAccount(getActivity());
+ OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION));
+ String url = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + AccountUtils.getWebdavPath(ocv);
+
+ Log_OC.d("share", "sharing for version " + ocv.toString());
+
+ if (ocv.compareTo(new OwnCloudVersion(0x040000)) >= 0) {
+ String APPS_PATH = "/apps/files_sharing/";
+ String SHARE_PATH = "ajax/share.php";
+
+ String SHARED_PATH = "/apps/files_sharing/get.php?token=";
+
+ final String WEBDAV_SCRIPT = "webdav.php";
+ final String WEBDAV_FILES_LOCATION = "/files/";
+
+ WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(account, getActivity().getApplicationContext());
+ HttpConnectionManagerParams params = new HttpConnectionManagerParams();
+ params.setMaxConnectionsPerHost(wc.getHostConfiguration(), 5);
+
+ //wc.getParams().setParameter("http.protocol.single-cookie-header", true);
+ //wc.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
+
+ PostMethod post = new PostMethod(am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + APPS_PATH + SHARE_PATH);
+
+ post.addRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8" );
+ post.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));
+ List<NameValuePair> formparams = new ArrayList<NameValuePair>();
+ Log_OC.d("share", mPath+"");
+ formparams.add(new BasicNameValuePair("sources",mPath));
+ formparams.add(new BasicNameValuePair("uid_shared_with", "public"));
+ formparams.add(new BasicNameValuePair("permissions", "0"));
+ post.setRequestEntity(new StringRequestEntity(URLEncodedUtils.format(formparams, HTTP.UTF_8)));
+
+ int status;
+ try {
+ PropFindMethod find = new PropFindMethod(url+"/");
+ find.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));
+ Log_OC.d("sharer", ""+ url+"/");
+
+ for (org.apache.commons.httpclient.Header a : find.getRequestHeaders()) {
+ Log_OC.d("sharer-h", a.getName() + ":"+a.getValue());
+ }
+
+ int status2 = wc.executeMethod(find);
+
+ Log_OC.d("sharer", "propstatus "+status2);
+
+ GetMethod get = new GetMethod(am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + "/");
+ get.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));
+
+ status2 = wc.executeMethod(get);
+
+ Log_OC.d("sharer", "getstatus "+status2);
+ Log_OC.d("sharer", "" + get.getResponseBodyAsString());
+
+ for (org.apache.commons.httpclient.Header a : get.getResponseHeaders()) {
+ Log_OC.d("sharer", a.getName() + ":"+a.getValue());
+ }
+
+ status = wc.executeMethod(post);
+ for (org.apache.commons.httpclient.Header a : post.getRequestHeaders()) {
+ Log_OC.d("sharer-h", a.getName() + ":"+a.getValue());
+ }
+ for (org.apache.commons.httpclient.Header a : post.getResponseHeaders()) {
+ Log_OC.d("sharer", a.getName() + ":"+a.getValue());
+ }
+ String resp = post.getResponseBodyAsString();
+ Log_OC.d("share", ""+post.getURI().toString());
+ Log_OC.d("share", "returned status " + status);
+ Log_OC.d("share", " " +resp);
+
+ if(status != HttpStatus.SC_OK ||resp == null || resp.equals("") || resp.startsWith("false")) {
+ return;
+ }
+
+ JSONObject jsonObject = new JSONObject (resp);
+ String jsonStatus = jsonObject.getString("status");
+ if(!jsonStatus.equals("success")) throw new Exception("Error while sharing file status != success");
+
+ String token = jsonObject.getString("data");
+ String uri = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + SHARED_PATH + token;
+ Log_OC.d("Actions:shareFile ok", "url: " + uri);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ } else if (ocv.compareTo(new OwnCloudVersion(0x030000)) >= 0) {
+
+ }
+ }
+ }
+ */
+
+}
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
-import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
-import com.owncloud.android.network.OwnCloudClientUtils;
import com.owncloud.android.operations.OnRemoteOperationListener;
import com.owncloud.android.operations.RemoteOperation;
import com.owncloud.android.operations.RemoveFileOperation;
import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener;
import com.owncloud.android.ui.fragment.ConfirmationDialogFragment.ConfirmationDialogFragmentListener;
-import eu.alefzero.webdav.WebdavClient;
import eu.alefzero.webdav.WebdavUtils;
import android.accounts.Account;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
case R.id.action_download_file: {
Account account = AccountUtils.getCurrentOwnCloudAccount(getSherlockActivity());
RemoteOperation operation = new SynchronizeFileOperation(mTargetFile, null, mContainerActivity.getStorageManager(), account, true, false, getSherlockActivity());
- WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(account, getSherlockActivity().getApplicationContext());
- operation.execute(wc, mContainerActivity, mHandler);
+ operation.execute(account, getSherlockActivity(), mContainerActivity, mHandler, getSherlockActivity());
getSherlockActivity().showDialog(FileDisplayActivity.DIALOG_SHORT_WAIT);
return true;
}
AccountUtils.getCurrentOwnCloudAccount(getActivity()),
newFilename,
mContainerActivity.getStorageManager());
- WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(AccountUtils.getCurrentOwnCloudAccount(getSherlockActivity()), getSherlockActivity().getApplicationContext());
- operation.execute(wc, mContainerActivity, mHandler);
+ operation.execute(AccountUtils.getCurrentOwnCloudAccount(getSherlockActivity()), getSherlockActivity(), mContainerActivity, mHandler, getSherlockActivity());
getActivity().showDialog(FileDisplayActivity.DIALOG_SHORT_WAIT);
}
}
RemoteOperation operation = new RemoveFileOperation( mTargetFile,
true,
mContainerActivity.getStorageManager());
- WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(AccountUtils.getCurrentOwnCloudAccount(getSherlockActivity()), getSherlockActivity().getApplicationContext());
- operation.execute(wc, mContainerActivity, mHandler);
+ operation.execute(AccountUtils.getCurrentOwnCloudAccount(getSherlockActivity()), getSherlockActivity(), mContainerActivity, mHandler, getSherlockActivity());
getActivity().showDialog(FileDisplayActivity.DIALOG_SHORT_WAIT);
}
* Copyright (C) 2012-2013 ownCloud Inc.
*
* 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.
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.FragmentStatePagerAdapter;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
import com.owncloud.android.ui.fragment.FileFragment;
+import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
import eu.alefzero.webdav.OnDatatransferProgressListener;
break;
}
default:
- Log.e(TAG, "Incorrect view clicked!");
+ Log_OC.e(TAG, "Incorrect view clicked!");
}
}
*/
package com.owncloud.android.ui.preview;
-import org.apache.commons.httpclient.methods.PostMethod;
-
import android.accounts.Account;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
-import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import com.owncloud.android.ui.fragment.FileFragment;
import com.owncloud.android.AccountUtils;
+import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
/**
mDownloaderBinder = (FileDownloaderBinder) service;
if (mRequestWaitingForBinder) {
mRequestWaitingForBinder = false;
- Log.d(TAG, "Simulating reselection of current page after connection of download binder");
+ Log_OC.d(TAG, "Simulating reselection of current page after connection of download binder");
onPageSelected(mViewPager.getCurrentItem());
}
} else if (component.equals(new ComponentName(PreviewImageActivity.this, FileUploader.class))) {
- Log.d(TAG, "Upload service connected");
+ Log_OC.d(TAG, "Upload service connected");
mUploaderBinder = (FileUploaderBinder) service;
} else {
return;
@Override
public void onServiceDisconnected(ComponentName component) {
if (component.equals(new ComponentName(PreviewImageActivity.this, FileDownloader.class))) {
- Log.d(TAG, "Download service suddenly disconnected");
+ Log_OC.d(TAG, "Download service suddenly disconnected");
mDownloaderBinder = null;
} else if (component.equals(new ComponentName(PreviewImageActivity.this, FileUploader.class))) {
- Log.d(TAG, "Upload service suddenly disconnected");
+ Log_OC.d(TAG, "Upload service suddenly disconnected");
mUploaderBinder = null;
}
}
private void requestForDownload(OCFile file) {
if (mDownloaderBinder == null) {
- Log.d(TAG, "requestForDownload called without binder to download service");
+ Log_OC.d(TAG, "requestForDownload called without binder to download service");
} else if (!mDownloaderBinder.isDownloading(mAccount, file)) {
Intent i = new Intent(this, FileDownloader.class);
mPreviewImagePagerAdapter.notifyDataSetChanged(); // will trigger the creation of new fragments
} else {
- Log.d(TAG, "Download finished, but the fragment is offscreen");
+ Log_OC.d(TAG, "Download finished, but the fragment is offscreen");
}
}
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentStatePagerAdapter;
-import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import com.actionbarsherlock.view.MenuItem;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.network.OwnCloudClientUtils;
import com.owncloud.android.operations.OnRemoteOperationListener;
import com.owncloud.android.operations.RemoteOperation;
import com.owncloud.android.operations.RemoteOperationResult;
import com.owncloud.android.ui.fragment.ConfirmationDialogFragment;
import com.owncloud.android.ui.fragment.FileFragment;
+import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
-import eu.alefzero.webdav.WebdavClient;
import eu.alefzero.webdav.WebdavUtils;
startActivity(i);
} catch (Throwable t) {
- Log.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mFile.getMimetype());
+ Log_OC.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mFile.getMimetype());
boolean toastIt = true;
String mimeType = "";
try {
}
} catch (IndexOutOfBoundsException e) {
- Log.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);
+ Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);
} catch (ActivityNotFoundException e) {
- Log.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");
+ Log_OC.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");
} catch (Throwable th) {
- Log.e(TAG, "Unexpected problem when opening: " + storagePath, th);
+ Log_OC.e(TAG, "Unexpected problem when opening: " + storagePath, th);
} finally {
if (toastIt) {
mLastRemoteOperation = new RemoveFileOperation( mFile, // TODO we need to review the interface with RemoteOperations, and use OCFile IDs instead of OCFile objects as parameters
true,
mStorageManager);
- WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getSherlockActivity().getApplicationContext());
- mLastRemoteOperation.execute(wc, this, mHandler);
+ mLastRemoteOperation.execute(mAccount, getSherlockActivity(), this, mHandler, getSherlockActivity());
getActivity().showDialog(PreviewImageActivity.DIALOG_SHORT_WAIT);
}
// really load the bitmap
options.inJustDecodeBounds = false; // the next decodeFile call will be real
result = BitmapFactory.decodeFile(storagePath, options);
- //Log.d(TAG, "Image loaded - width: " + options.outWidth + ", loaded height: " + options.outHeight);
+ //Log_OC.d(TAG, "Image loaded - width: " + options.outWidth + ", loaded height: " + options.outHeight);
if (result == null) {
mErrorMessageId = R.string.preview_image_error_unknown_format;
- Log.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
+ Log_OC.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
}
} catch (OutOfMemoryError e) {
mErrorMessageId = R.string.preview_image_error_unknown_format;
- Log.e(TAG, "Out of memory occured for file " + storagePath, e);
+ Log_OC.e(TAG, "Out of memory occured for file " + storagePath, e);
} catch (NoSuchFieldError e) {
mErrorMessageId = R.string.common_error_unknown;
- Log.e(TAG, "Error from access to unexisting field despite protection; file " + storagePath, e);
+ Log_OC.e(TAG, "Error from access to unexisting field despite protection; file " + storagePath, e);
} catch (Throwable t) {
mErrorMessageId = R.string.common_error_unknown;
- Log.e(TAG, "Unexpected error loading " + mFile.getStoragePath(), t);
+ Log_OC.e(TAG, "Unexpected error loading " + mFile.getStoragePath(), t);
}
return result;
*/
package com.owncloud.android.ui.preview;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Vector;
import android.accounts.Account;
-import android.os.Bundle;
-import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.util.Log;
-import android.view.View;
import android.view.ViewGroup;
import com.owncloud.android.datamodel.DataStorageManager;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.app.FragmentTransaction;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import com.owncloud.android.media.MediaControlView;
import com.owncloud.android.media.MediaService;
import com.owncloud.android.media.MediaServiceBinder;
-import com.owncloud.android.network.OwnCloudClientUtils;
import com.owncloud.android.operations.OnRemoteOperationListener;
import com.owncloud.android.operations.RemoteOperation;
import com.owncloud.android.operations.RemoteOperationResult;
import com.owncloud.android.ui.fragment.FileDetailFragment;
import com.owncloud.android.ui.fragment.FileFragment;
+import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
-import eu.alefzero.webdav.WebdavClient;
import eu.alefzero.webdav.WebdavUtils;
/**
*/
@Override
public void onPrepared(MediaPlayer vp) {
- Log.e(TAG, "onPrepared");
+ Log_OC.e(TAG, "onPrepared");
mVideoPreview.seekTo(mSavedPlaybackPosition);
if (mAutoplay) {
mVideoPreview.start();
*/
@Override
public void onCompletion(MediaPlayer mp) {
- Log.e(TAG, "completed");
+ Log_OC.e(TAG, "completed");
if (mp != null) {
mVideoPreview.seekTo(0);
// next lines are necessary to work around undesired video loops
super.onStop();
if (mMediaServiceConnection != null) {
- Log.d(TAG, "Unbinding from MediaService ...");
+ Log_OC.d(TAG, "Unbinding from MediaService ...");
if (mMediaServiceBinder != null && mMediaController != null) {
mMediaServiceBinder.unregisterMediaController(mMediaController);
}
private void playAudio() {
if (!mMediaServiceBinder.isPlaying(mFile)) {
- Log.d(TAG, "starting playback of " + mFile.getStoragePath());
+ Log_OC.d(TAG, "starting playback of " + mFile.getStoragePath());
mMediaServiceBinder.start(mAccount, mFile, mAutoplay, mSavedPlaybackPosition);
} else {
private void bindMediaService() {
- Log.d(TAG, "Binding to MediaService...");
+ Log_OC.d(TAG, "Binding to MediaService...");
if (mMediaServiceConnection == null) {
mMediaServiceConnection = new MediaServiceConnection();
}
@Override
public void onServiceConnected(ComponentName component, IBinder service) {
if (component.equals(new ComponentName(getActivity(), MediaService.class))) {
- Log.d(TAG, "Media service connected");
+ Log_OC.d(TAG, "Media service connected");
mMediaServiceBinder = (MediaServiceBinder) service;
if (mMediaServiceBinder != null) {
prepareMediaController();
playAudio(); // do not wait for the touch of nobody to play audio
- Log.d(TAG, "Successfully bound to MediaService, MediaController ready");
+ Log_OC.d(TAG, "Successfully bound to MediaService, MediaController ready");
} else {
- Log.e(TAG, "Unexpected response from MediaService while binding");
+ Log_OC.e(TAG, "Unexpected response from MediaService while binding");
}
}
}
@Override
public void onServiceDisconnected(ComponentName component) {
if (component.equals(new ComponentName(getActivity(), MediaService.class))) {
- Log.e(TAG, "Media service suddenly disconnected");
+ Log_OC.e(TAG, "Media service suddenly disconnected");
if (mMediaController != null) {
mMediaController.setMediaPlayer(null);
} else {
startActivity(i);
} catch (Throwable t) {
- Log.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mFile.getMimetype());
+ Log_OC.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mFile.getMimetype());
boolean toastIt = true;
String mimeType = "";
try {
}
} catch (IndexOutOfBoundsException e) {
- Log.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);
+ Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);
} catch (ActivityNotFoundException e) {
- Log.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");
+ Log_OC.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");
} catch (Throwable th) {
- Log.e(TAG, "Unexpected problem when opening: " + storagePath, th);
+ Log_OC.e(TAG, "Unexpected problem when opening: " + storagePath, th);
} finally {
if (toastIt) {
mLastRemoteOperation = new RemoveFileOperation( mFile, // TODO we need to review the interface with RemoteOperations, and use OCFile IDs instead of OCFile objects as parameters
true,
mStorageManager);
- WebdavClient wc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getSherlockActivity().getApplicationContext());
- mLastRemoteOperation.execute(wc, this, mHandler);
+ mLastRemoteOperation.execute(mAccount, getSherlockActivity(), this, mHandler, getSherlockActivity());
boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Bundle;
-import android.util.Log;
import android.view.MotionEvent;
import android.widget.MediaController;
import android.widget.VideoView;
import com.owncloud.android.AccountUtils;
+import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.media.MediaService;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Log.e(TAG, "ACTIVITY\t\tonCreate");
+ Log_OC.e(TAG, "ACTIVITY\t\tonCreate");
setContentView(R.layout.video_layout);
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- Log.e(TAG, "ACTIVITY\t\tonSaveInstanceState");
+ Log_OC.e(TAG, "ACTIVITY\t\tonSaveInstanceState");
outState.putParcelable(PreviewVideoActivity.EXTRA_FILE, mFile);
outState.putParcelable(PreviewVideoActivity.EXTRA_ACCOUNT, mAccount);
outState.putInt(PreviewVideoActivity.EXTRA_START_POSITION, mVideoPlayer.getCurrentPosition());
@Override
public void onBackPressed() {
- Log.e(TAG, "ACTIVTIY\t\tonBackPressed");
+ Log_OC.e(TAG, "ACTIVTIY\t\tonBackPressed");
Intent i = new Intent();
i.putExtra(EXTRA_AUTOPLAY, mVideoPlayer.isPlaying());
i.putExtra(EXTRA_START_POSITION, mVideoPlayer.getCurrentPosition());
@Override
public void onResume() {
super.onResume();
- Log.e(TAG, "ACTIVTIY\t\tonResume");
+ Log_OC.e(TAG, "ACTIVTIY\t\tonResume");
}
@Override
public void onStart() {
super.onStart();
- Log.e(TAG, "ACTIVTIY\t\tonStart");
+ Log_OC.e(TAG, "ACTIVTIY\t\tonStart");
}
@Override
public void onDestroy() {
super.onDestroy();
- Log.e(TAG, "ACTIVITY\t\tonDestroy");
+ Log_OC.e(TAG, "ACTIVITY\t\tonDestroy");
}
@Override
public void onStop() {
super.onStop();
- Log.e(TAG, "ACTIVTIY\t\tonStop");
+ Log_OC.e(TAG, "ACTIVTIY\t\tonStop");
}
@Override
public void onPause() {
super.onPause();
- Log.e(TAG, "ACTIVTIY\t\tonPause");
+ Log_OC.e(TAG, "ACTIVTIY\t\tonPause");
}
*/
@Override
public void onPrepared(MediaPlayer mp) {
- Log.e(TAG, "ACTIVITY\t\tonPrepare");
+ Log_OC.e(TAG, "ACTIVITY\t\tonPrepare");
mVideoPlayer.seekTo(mSavedPlaybackPosition);
if (mAutoplay) {
mVideoPlayer.start();
*/
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
- Log.e(TAG, "Error in video playback, what = " + what + ", extra = " + extra);
+ Log_OC.e(TAG, "Error in video playback, what = " + what + ", extra = " + extra);
if (mMediaController != null) {
mMediaController.hide();
import android.net.Uri;
import android.os.Environment;
import android.os.StatFs;
-import android.util.Log;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.OCFile;
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
package eu.alefzero.webdav;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthPolicy;
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.params.CoreProtocolPNames;
import org.apache.jackrabbit.webdav.client.methods.DavMethod;
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
-import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
import com.owncloud.android.Log_OC;
+import com.owncloud.android.network.BearerAuthScheme;
+import com.owncloud.android.network.BearerCredentials;
+
import android.net.Uri;
-import android.util.Log;
public class WebdavClient extends HttpClient {
private Uri mUri;
getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
}
- public void setCredentials(String username, String password) {
- getParams().setAuthenticationPreemptive(true);
- getState().setCredentials(AuthScope.ANY,
- getCredentials(username, password));
- }
-
- private Credentials getCredentials(String username, String password) {
- if (mCredentials == null)
- mCredentials = new UsernamePasswordCredentials(username, password);
- return mCredentials;
- }
-
- /**
- * Downloads a file in remoteFilepath to the local targetPath.
- *
- * @param remoteFilepath Path to the file in the remote server, URL DECODED.
- * @param targetFile Local path to save the downloaded file.
- * @return 'True' when the file is successfully downloaded.
- */
- public boolean downloadFile(String remoteFilePath, File targetFile) {
- boolean ret = false;
- GetMethod get = new GetMethod(mUri.toString() + WebdavUtils.encodePath(remoteFilePath));
-
- try {
- int status = executeMethod(get);
- if (status == HttpStatus.SC_OK) {
- targetFile.createNewFile();
- BufferedInputStream bis = new BufferedInputStream(
- get.getResponseBodyAsStream());
- FileOutputStream fos = new FileOutputStream(targetFile);
-
- byte[] bytes = new byte[4096];
- int readResult;
- while ((readResult = bis.read(bytes)) != -1) {
- if (mDataTransferListener != null)
- mDataTransferListener.onTransferProgress(readResult);
- fos.write(bytes, 0, readResult);
- }
- fos.close();
- ret = true;
- } else {
- exhaustResponse(get.getResponseBodyAsStream());
- }
- Log_OC.e(TAG, "Download of " + remoteFilePath + " to " + targetFile + " finished with HTTP status " + status + (!ret?"(FAIL)":""));
-
- } catch (Exception e) {
- logException(e, "dowloading " + remoteFilePath);
-
- } finally {
- if (!ret && targetFile.exists()) {
- targetFile.delete();
- }
- get.releaseConnection(); // let the connection available for other methods
- }
- return ret;
- }
-
- /**
- * Deletes a remote file via webdav
- * @param remoteFilePath Remote file path of the file to delete, in URL DECODED format.
- * @return
- */
- public boolean deleteFile(String remoteFilePath) {
- boolean ret = false;
- DavMethod delete = new DeleteMethod(mUri.toString() + WebdavUtils.encodePath(remoteFilePath));
- try {
- int status = executeMethod(delete);
- ret = (status == HttpStatus.SC_OK || status == HttpStatus.SC_ACCEPTED || status == HttpStatus.SC_NO_CONTENT);
- exhaustResponse(delete.getResponseBodyAsStream());
-
- Log_OC.e(TAG, "DELETE of " + remoteFilePath + " finished with HTTP status " + status + (!ret?"(FAIL)":""));
-
- } catch (Exception e) {
- logException(e, "deleting " + remoteFilePath);
-
- } finally {
- delete.releaseConnection(); // let the connection available for other methods
- }
- return ret;
- }
-
-
- public void setDataTransferProgressListener(OnDatatransferProgressListener listener) {
- mDataTransferListener = listener;
- }
-
- /**
- * Creates or update a file in the remote server with the contents of a local file.
- *
- * @param localFile Path to the local file to upload.
- * @param remoteTarget Remote path to the file to create or update, URL DECODED
- * @param contentType MIME type of the file.
- * @return Status HTTP code returned by the server.
- * @throws IOException When a transport error that could not be recovered occurred while uploading the file to the server.
- * @throws HttpException When a violation of the HTTP protocol occurred.
- */
- public int putFile(String localFile, String remoteTarget, String contentType) throws HttpException, IOException {
- int status = -1;
- PutMethod put = new PutMethod(mUri.toString() + WebdavUtils.encodePath(remoteTarget));
+ public void setBearerCredentials(String accessToken) {
+ AuthPolicy.registerAuthScheme(BearerAuthScheme.AUTH_POLICY, BearerAuthScheme.class);
- try {
- File f = new File(localFile);
- FileRequestEntity entity = new FileRequestEntity(f, contentType);
- entity.addDatatransferProgressListener(mDataTransferListener);
- put.setRequestEntity(entity);
- status = executeMethod(put);
-
- exhaustResponse(put.getResponseBodyAsStream());
-
- } finally {
- put.releaseConnection(); // let the connection available for other methods
- }
- return status;
- }
-
- /**
- * Tries to log in to the current URI, with the current credentials
- *
- * @return A {@link HttpStatus}-Code of the result. SC_OK is good.
- */
- public int tryToLogin() {
- int status = 0;
- HeadMethod head = new HeadMethod(mUri.toString());
- try {
- status = executeMethod(head);
- boolean result = status == HttpStatus.SC_OK;
- Log_OC.d(TAG, "HEAD for " + mUri + " finished with HTTP status " + status + (!result?"(FAIL)":""));
- exhaustResponse(head.getResponseBodyAsStream());
-
- } catch (Exception e) {
- logException(e, "trying to login at " + mUri.toString());
-
- } finally {
- head.releaseConnection();
- }
- return status;
+ List<String> authPrefs = new ArrayList<String>(1);
+ authPrefs.add(BearerAuthScheme.AUTH_POLICY);
+ getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
+
+ mCredentials = new BearerCredentials(accessToken);
+ getState().setCredentials(AuthScope.ANY, mCredentials);
}
- /**
- * Creates a remote directory with the received path.
- *
- * @param path Path of the directory to create, URL DECODED
- * @return 'True' when the directory is successfully created
- */
- public boolean createDirectory(String path) {
- boolean result = false;
- int status = -1;
- MkColMethod mkcol = new MkColMethod(mUri.toString() + WebdavUtils.encodePath(path));
- try {
- Log_OC.d(TAG, "Creating directory " + path);
- status = executeMethod(mkcol);
- Log_OC.d(TAG, "Status returned: " + status);
- result = mkcol.succeeded();
-
- Log_OC.d(TAG, "MKCOL to " + path + " finished with HTTP status " + status + (!result?"(FAIL)":""));
- exhaustResponse(mkcol.getResponseBodyAsStream());
-
- } catch (Exception e) {
- logException(e, "creating directory " + path);
-
- } finally {
- mkcol.releaseConnection(); // let the connection available for other methods
- }
- return result;
+ public void setBasicCredentials(String username, String password) {
+ List<String> authPrefs = new ArrayList<String>(1);
+ authPrefs.add(AuthPolicy.BASIC);
+ getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
+
+ getParams().setAuthenticationPreemptive(true);
+ mCredentials = new UsernamePasswordCredentials(username, password);
+ getState().setCredentials(AuthScope.ANY, mCredentials);
}
-
/**
* Check if a file exists in the OC server
*
+ * TODO replace with ExistenceOperation
+ *
* @return 'true' if the file exists; 'false' it doesn't exist
* @throws Exception When the existence could not be determined
*/
head.releaseConnection(); // let the connection available for other methods
}
}
-
+
/**
* Requests the received method with the received timeout (milliseconds).
*
}
/**
- * Logs an exception triggered in a HTTP request.
- *
- * @param e Caught exception.
- * @param doing Suffix to add at the end of the logged message.
- */
- private void logException(Exception e, String doing) {
- if (e instanceof HttpException) {
- Log_OC.e(TAG, "HTTP violation while " + doing, e);
-
- } else if (e instanceof IOException) {
- Log_OC.e(TAG, "Unrecovered transport exception while " + doing, e);
-
- } else {
- Log_OC.e(TAG, "Unexpected exception while " + doing, e);
- }
- }
-
-
- /**
* Sets the connection and wait-for-data timeouts to be applied by default to the methods performed by this client.
*/
public void setDefaultTimeouts(int defaultDataTimeout, int defaultConnectionTimeout) {
return mUri;
}
+ public final Credentials getCredentials() {\r
+ return mCredentials;\r
+ }\r
+\r
}
import com.owncloud.android.Log_OC;
import android.net.Uri;
-import android.util.Log;
public class WebdavEntry {
private String mName, mPath, mUri, mContentType;