mirror of
				https://github.com/owncloud/android-library.git
				synced 2025-10-31 02:17:41 +00:00 
			
		
		
		
	
						commit
						c99e2fb7b3
					
				
							
								
								
									
										10
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -2,6 +2,9 @@ | ||||
| *.apk | ||||
| *.ap_ | ||||
| 
 | ||||
| .idea/* | ||||
| !.idea/codeStyles/ | ||||
| 
 | ||||
| # files for the dex VM | ||||
| *.dex | ||||
| 
 | ||||
| @ -9,19 +12,14 @@ | ||||
| *.class | ||||
| 
 | ||||
| # generated files | ||||
| bin/ | ||||
| build/ | ||||
| gen/ | ||||
| target/ | ||||
| *.iml | ||||
| 
 | ||||
| # Local configuration files (sdk path, etc) | ||||
| .idea/ | ||||
| .gradle/ | ||||
| local.properties | ||||
| sample_client/local.properties | ||||
| tests/local.properties | ||||
| tests/test_cases/local.properties | ||||
| 
 | ||||
| # Mac .DS_Store files | ||||
| .DS_Store | ||||
| @ -29,5 +27,3 @@ tests/test_cases/local.properties | ||||
| # Proguard README | ||||
| proguard-project.txt | ||||
| sample_client/proguard-project.txt | ||||
| tests/proguard-project.txt | ||||
| tests/test_cases/proguard-project.txt | ||||
							
								
								
									
										412
									
								
								.idea/codeStyles/Project.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										412
									
								
								.idea/codeStyles/Project.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @ -0,0 +1,412 @@ | ||||
| <component name="ProjectCodeStyleConfiguration"> | ||||
|   <code_scheme name="Project" version="173"> | ||||
|     <option name="LINE_SEPARATOR" value="
" /> | ||||
|     <option name="RIGHT_MARGIN" value="150" /> | ||||
|     <AndroidXmlCodeStyleSettings> | ||||
|       <option name="USE_CUSTOM_SETTINGS" value="true" /> | ||||
|     </AndroidXmlCodeStyleSettings> | ||||
|     <JavaCodeStyleSettings> | ||||
|       <option name="FIELD_NAME_PREFIX" value="m" /> | ||||
|       <option name="STATIC_FIELD_NAME_PREFIX" value="s" /> | ||||
|       <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99999" /> | ||||
|       <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99999" /> | ||||
|       <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND"> | ||||
|         <value /> | ||||
|       </option> | ||||
|       <option name="IMPORT_LAYOUT_TABLE"> | ||||
|         <value> | ||||
|           <package name="android" withSubpackages="true" static="false" /> | ||||
|           <emptyLine /> | ||||
|           <package name="" withSubpackages="true" static="false" /> | ||||
|           <emptyLine /> | ||||
|           <package name="javax" withSubpackages="true" static="false" /> | ||||
|           <package name="java" withSubpackages="true" static="false" /> | ||||
|           <emptyLine /> | ||||
|           <package name="" withSubpackages="true" static="true" /> | ||||
|           <emptyLine /> | ||||
|         </value> | ||||
|       </option> | ||||
|     </JavaCodeStyleSettings> | ||||
|     <JetCodeStyleSettings> | ||||
|       <option name="PACKAGES_TO_USE_STAR_IMPORTS"> | ||||
|         <value> | ||||
|           <package name="kotlinx.android.synthetic" withSubpackages="true" static="false" /> | ||||
|         </value> | ||||
|       </option> | ||||
|       <option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" /> | ||||
|       <option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" /> | ||||
|       <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | ||||
|     </JetCodeStyleSettings> | ||||
|     <MarkdownNavigatorCodeStyleSettings> | ||||
|       <option name="RIGHT_MARGIN" value="72" /> | ||||
|     </MarkdownNavigatorCodeStyleSettings> | ||||
|     <Objective-C-extensions> | ||||
|       <file> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" /> | ||||
|       </file> | ||||
|       <class> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" /> | ||||
|         <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" /> | ||||
|       </class> | ||||
|       <extensions> | ||||
|         <pair source="cpp" header="h" fileNamingConvention="NONE" /> | ||||
|         <pair source="c" header="h" fileNamingConvention="NONE" /> | ||||
|       </extensions> | ||||
|     </Objective-C-extensions> | ||||
|     <XML> | ||||
|       <option name="XML_ATTRIBUTE_WRAP" value="0" /> | ||||
|       <option name="XML_KEEP_BLANK_LINES" value="1" /> | ||||
|       <option name="XML_ALIGN_ATTRIBUTES" value="false" /> | ||||
|       <option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" /> | ||||
|       <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" /> | ||||
|     </XML> | ||||
|     <codeStyleSettings language="JAVA"> | ||||
|       <option name="RIGHT_MARGIN" value="150" /> | ||||
|       <option name="KEEP_FIRST_COLUMN_COMMENT" value="false" /> | ||||
|       <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" /> | ||||
|       <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" /> | ||||
|       <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> | ||||
|       <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" /> | ||||
|       <option name="IF_BRACE_FORCE" value="3" /> | ||||
|       <option name="DOWHILE_BRACE_FORCE" value="3" /> | ||||
|       <option name="WHILE_BRACE_FORCE" value="3" /> | ||||
|       <option name="FOR_BRACE_FORCE" value="3" /> | ||||
|       <option name="WRAP_LONG_LINES" value="true" /> | ||||
|       <arrangement> | ||||
|         <rules> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <FIELD>true</FIELD> | ||||
|                   <FINAL>true</FINAL> | ||||
|                   <PUBLIC>true</PUBLIC> | ||||
|                   <STATIC>true</STATIC> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <FIELD>true</FIELD> | ||||
|                   <FINAL>true</FINAL> | ||||
|                   <STATIC>true</STATIC> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <FIELD>true</FIELD> | ||||
|                   <PUBLIC>true</PUBLIC> | ||||
|                   <STATIC>true</STATIC> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <FIELD>true</FIELD> | ||||
|                   <STATIC>true</STATIC> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <INITIALIZER_BLOCK>true</INITIALIZER_BLOCK> | ||||
|                   <STATIC>true</STATIC> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <FIELD>true</FIELD> | ||||
|                   <FINAL>true</FINAL> | ||||
|                   <PUBLIC>true</PUBLIC> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <FIELD>true</FIELD> | ||||
|                   <FINAL>true</FINAL> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <FIELD>true</FIELD> | ||||
|                   <PUBLIC>true</PUBLIC> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <FIELD>true</FIELD> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <INITIALIZER_BLOCK>true</INITIALIZER_BLOCK> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <CONSTRUCTOR>true</CONSTRUCTOR> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <METHOD>true</METHOD> | ||||
|                   <STATIC>true</STATIC> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <METHOD>true</METHOD> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <ENUM>true</ENUM> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <INTERFACE>true</INTERFACE> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <CLASS>true</CLASS> | ||||
|                   <STATIC>true</STATIC> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <CLASS>true</CLASS> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|         </rules> | ||||
|       </arrangement> | ||||
|     </codeStyleSettings> | ||||
|     <codeStyleSettings language="XML"> | ||||
|       <option name="FORCE_REARRANGE_MODE" value="1" /> | ||||
|       <indentOptions> | ||||
|         <option name="CONTINUATION_INDENT_SIZE" value="4" /> | ||||
|       </indentOptions> | ||||
|       <arrangement> | ||||
|         <rules> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>xmlns:android</NAME> | ||||
|                   <XML_NAMESPACE>Namespace:</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>xmlns:.*</NAME> | ||||
|                   <XML_NAMESPACE>Namespace:</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|               <order>BY_NAME</order> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>.*:id</NAME> | ||||
|                   <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>.*:name</NAME> | ||||
|                   <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>name</NAME> | ||||
|                   <XML_NAMESPACE>^$</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>style</NAME> | ||||
|                   <XML_NAMESPACE>^$</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>.*</NAME> | ||||
|                   <XML_NAMESPACE>^$</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|               <order>BY_NAME</order> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>.*:layout_width</NAME> | ||||
|                   <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>.*:layout_height</NAME> | ||||
|                   <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>.*:layout_.*</NAME> | ||||
|                   <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|               <order>BY_NAME</order> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>.*:width</NAME> | ||||
|                   <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|               <order>BY_NAME</order> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>.*:height</NAME> | ||||
|                   <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|               <order>BY_NAME</order> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>.*</NAME> | ||||
|                   <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|               <order>BY_NAME</order> | ||||
|             </rule> | ||||
|           </section> | ||||
|           <section> | ||||
|             <rule> | ||||
|               <match> | ||||
|                 <AND> | ||||
|                   <NAME>.*</NAME> | ||||
|                   <XML_NAMESPACE>.*</XML_NAMESPACE> | ||||
|                 </AND> | ||||
|               </match> | ||||
|               <order>BY_NAME</order> | ||||
|             </rule> | ||||
|           </section> | ||||
|         </rules> | ||||
|       </arrangement> | ||||
|     </codeStyleSettings> | ||||
|     <codeStyleSettings language="kotlin"> | ||||
|       <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | ||||
|       <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" /> | ||||
|       <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> | ||||
|       <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" /> | ||||
|       <option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> | ||||
|       <option name="FIELD_ANNOTATION_WRAP" value="0" /> | ||||
|     </codeStyleSettings> | ||||
|   </code_scheme> | ||||
| </component> | ||||
							
								
								
									
										5
									
								
								.idea/codeStyles/codeStyleConfig.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.idea/codeStyles/codeStyleConfig.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| <component name="ProjectCodeStyleConfiguration"> | ||||
|   <state> | ||||
|     <option name="USE_PER_PROJECT_SETTINGS" value="true" /> | ||||
|   </state> | ||||
| </component> | ||||
| @ -23,10 +23,10 @@ | ||||
| 
 | ||||
|  --> | ||||
| 
 | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     package="com.owncloud.android.lib" | ||||
| <manifest package="com.owncloud.android.lib" | ||||
|     xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:versionCode="1" | ||||
|     android:versionName="1.0" > | ||||
|     android:versionName="1.0"> | ||||
| 
 | ||||
|     <!-- USE_CREDENTIALS, MANAGE_ACCOUNTS and AUTHENTICATE_ACCOUNTS are needed for API < 23. | ||||
|         In API >= 23 the do not exist anymore --> | ||||
|  | ||||
| @ -11,7 +11,7 @@ import java.io.IOException; | ||||
| 
 | ||||
| /** | ||||
|  * Dynamic implementation of {@link OwnCloudClientManager}. | ||||
|  * | ||||
|  * <p> | ||||
|  * Wraps instances of {@link SingleSessionManager} and {@link SimpleFactoryManager} and delegates on one | ||||
|  * or the other depending on the known version of the server corresponding to the {@link OwnCloudAccount} | ||||
|  * | ||||
|  | ||||
| @ -24,14 +24,6 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common; | ||||
| 
 | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory; | ||||
| 
 | ||||
| import android.accounts.Account; | ||||
| import android.accounts.AccountManager; | ||||
| import android.accounts.AuthenticatorException; | ||||
| @ -39,6 +31,13 @@ import android.accounts.OperationCanceledException; | ||||
| import android.content.Context; | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| /** | ||||
|  * OwnCloud Account | ||||
|  * | ||||
| @ -56,10 +55,9 @@ public class OwnCloudAccount { | ||||
| 
 | ||||
|     private Account mSavedAccount; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor for already saved OC accounts. | ||||
|      * | ||||
|      * <p> | ||||
|      * Do not use for anonymous credentials. | ||||
|      */ | ||||
|     public OwnCloudAccount(Account savedAccount, Context context) throws AccountNotFoundException { | ||||
| @ -77,14 +75,13 @@ public class OwnCloudAccount { | ||||
| 
 | ||||
|         AccountManager ama = AccountManager.get(context.getApplicationContext()); | ||||
|         String baseUrl = ama.getUserData(mSavedAccount, AccountUtils.Constants.KEY_OC_BASE_URL); | ||||
|         if (baseUrl == null ) { | ||||
|         if (baseUrl == null) { | ||||
|             throw new AccountNotFoundException(mSavedAccount, "Account not found", null); | ||||
|         } | ||||
|         mBaseUri = Uri.parse(AccountUtils.getBaseUrlForAccount(context, mSavedAccount)); | ||||
|         mDisplayName = ama.getUserData(mSavedAccount, AccountUtils.Constants.KEY_DISPLAY_NAME); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor for non yet saved OC accounts. | ||||
|      * | ||||
| @ -106,7 +103,6 @@ public class OwnCloudAccount { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Method for deferred load of account attributes from AccountManager | ||||
|      * | ||||
|  | ||||
| @ -29,6 +29,7 @@ import android.accounts.AccountManager; | ||||
| import android.accounts.AccountsException; | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory; | ||||
| @ -40,16 +41,14 @@ import com.owncloud.android.lib.common.network.RedirectionPath; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import com.owncloud.android.lib.common.utils.RandomUtils; | ||||
| import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
| import okhttp3.Cookie; | ||||
| import okhttp3.Headers; | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import okhttp3.Cookie; | ||||
| import okhttp3.Headers; | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.http.HttpConstants.OC_X_REQUEST_ID; | ||||
| 
 | ||||
| public class OwnCloudClient extends HttpClient { | ||||
| @ -94,15 +93,6 @@ public class OwnCloudClient extends HttpClient { | ||||
|         clearCookies(); | ||||
|     } | ||||
| 
 | ||||
|     public void setCredentials(OwnCloudCredentials credentials) { | ||||
|         if (credentials != null) { | ||||
|             mCredentials = credentials; | ||||
|             mCredentials.applyTo(this); | ||||
|         } else { | ||||
|             clearCredentials(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void clearCredentials() { | ||||
|         if (!(mCredentials instanceof OwnCloudAnonymousCredentials)) { | ||||
|             mCredentials = OwnCloudCredentialsFactory.getAnonymousCredentials(); | ||||
| @ -114,7 +104,7 @@ public class OwnCloudClient extends HttpClient { | ||||
|         mCredentials.applyTo(this); | ||||
|     } | ||||
| 
 | ||||
|     public int executeHttpMethod (HttpBaseMethod method) throws Exception { | ||||
|     public int executeHttpMethod(HttpBaseMethod method) throws Exception { | ||||
|         boolean repeatWithFreshCredentials; | ||||
|         int repeatCounter = 0; | ||||
|         int status; | ||||
| @ -125,7 +115,7 @@ public class OwnCloudClient extends HttpClient { | ||||
|             status = method.execute(); | ||||
|             checkFirstRedirection(method); | ||||
| 
 | ||||
|             if(mFollowRedirects && !isIdPRedirection()) { | ||||
|             if (mFollowRedirects && !isIdPRedirection()) { | ||||
|                 status = followRedirection(method).getLastStatus(); | ||||
|             } | ||||
| 
 | ||||
| @ -140,12 +130,12 @@ public class OwnCloudClient extends HttpClient { | ||||
| 
 | ||||
|     private void checkFirstRedirection(HttpBaseMethod method) { | ||||
|         final String location = method.getResponseHeader(HttpConstants.LOCATION_HEADER_LOWER); | ||||
|         if(location != null && !location.isEmpty()) { | ||||
|         if (location != null && !location.isEmpty()) { | ||||
|             mRedirectedLocation = location; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private int executeRedirectedHttpMethod (HttpBaseMethod method) throws Exception { | ||||
|     private int executeRedirectedHttpMethod(HttpBaseMethod method) throws Exception { | ||||
|         boolean repeatWithFreshCredentials; | ||||
|         int repeatCounter = 0; | ||||
|         int status; | ||||
| @ -217,7 +207,7 @@ public class OwnCloudClient extends HttpClient { | ||||
|                 try { | ||||
|                     status = executeRedirectedHttpMethod(method); | ||||
|                 } catch (HttpException e) { | ||||
|                     if(e.getMessage().contains(Integer.toString(HttpConstants.HTTP_MOVED_TEMPORARILY))) { | ||||
|                     if (e.getMessage().contains(Integer.toString(HttpConstants.HTTP_MOVED_TEMPORARILY))) { | ||||
|                         status = HttpConstants.HTTP_MOVED_TEMPORARILY; | ||||
|                     } else { | ||||
|                         throw e; | ||||
| @ -242,7 +232,9 @@ public class OwnCloudClient extends HttpClient { | ||||
|     public void exhaustResponse(InputStream responseBodyAsStream) { | ||||
|         if (responseBodyAsStream != null) { | ||||
|             try { | ||||
|                 while (responseBodyAsStream.read(sExhaustBuffer) >= 0) ; | ||||
|                 while (responseBodyAsStream.read(sExhaustBuffer) >= 0) { | ||||
|                     ; | ||||
|                 } | ||||
|                 responseBodyAsStream.close(); | ||||
| 
 | ||||
|             } catch (IOException io) { | ||||
| @ -252,7 +244,7 @@ public class OwnCloudClient extends HttpClient { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public Uri getBaseFilesWebDavUri(){ | ||||
|     public Uri getBaseFilesWebDavUri() { | ||||
|         return Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0); | ||||
|     } | ||||
| 
 | ||||
| @ -274,9 +266,13 @@ public class OwnCloudClient extends HttpClient { | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     public Uri getBaseUri() { | ||||
|         return mBaseUri; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sets the root URI to the ownCloud server. | ||||
|      * | ||||
|      * <p> | ||||
|      * Use with care. | ||||
|      * | ||||
|      * @param uri | ||||
| @ -288,14 +284,19 @@ public class OwnCloudClient extends HttpClient { | ||||
|         mBaseUri = uri; | ||||
|     } | ||||
| 
 | ||||
|     public Uri getBaseUri() { | ||||
|         return mBaseUri; | ||||
|     } | ||||
| 
 | ||||
|     public final OwnCloudCredentials getCredentials() { | ||||
|         return mCredentials; | ||||
|     } | ||||
| 
 | ||||
|     public void setCredentials(OwnCloudCredentials credentials) { | ||||
|         if (credentials != null) { | ||||
|             mCredentials = credentials; | ||||
|             mCredentials.applyTo(this); | ||||
|         } else { | ||||
|             clearCredentials(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void logCookie(Cookie cookie) { | ||||
|         Log_OC.d(TAG, "Cookie name: " + cookie.name()); | ||||
|         Log_OC.d(TAG, "       value: " + cookie.value()); | ||||
| @ -348,27 +349,27 @@ public class OwnCloudClient extends HttpClient { | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     public void setOwnCloudVersion(OwnCloudVersion version) { | ||||
|         mVersion = version; | ||||
|     } | ||||
| 
 | ||||
|     public OwnCloudVersion getOwnCloudVersion() { | ||||
|         return mVersion; | ||||
|     } | ||||
| 
 | ||||
|     public void setAccount(OwnCloudAccount account) { | ||||
|         this.mAccount = account; | ||||
|     public void setOwnCloudVersion(OwnCloudVersion version) { | ||||
|         mVersion = version; | ||||
|     } | ||||
| 
 | ||||
|     public OwnCloudAccount getAccount() { | ||||
|         return mAccount; | ||||
|     } | ||||
| 
 | ||||
|     public void setAccount(OwnCloudAccount account) { | ||||
|         this.mAccount = account; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Checks the status code of an execution and decides if should be repeated with fresh credentials. | ||||
|      * | ||||
|      * <p> | ||||
|      * Invalidates current credentials if the request failed as anauthorized. | ||||
|      * | ||||
|      * <p> | ||||
|      * Refresh current credentials if possible, and marks a retry. | ||||
|      * | ||||
|      * @param status | ||||
| @ -417,7 +418,6 @@ public class OwnCloudClient extends HttpClient { | ||||
|      * of a network request just performed. | ||||
|      * | ||||
|      * @param httpStatusCode Result of the last request ran with the 'credentials' belows. | ||||
| 
 | ||||
|      * @return 'True' if credentials should and might be invalidated, 'false' if shouldn't or | ||||
|      * cannot be invalidated with the given arguments. | ||||
|      */ | ||||
| @ -437,7 +437,7 @@ public class OwnCloudClient extends HttpClient { | ||||
|     /** | ||||
|      * Invalidates credentials stored for the given account in the system  {@link AccountManager} and in | ||||
|      * current {@link OwnCloudClientManagerFactory#getDefaultSingleton()} instance. | ||||
|      * | ||||
|      * <p> | ||||
|      * {@link #shouldInvalidateAccountCredentials(int)} should be called first. | ||||
|      * | ||||
|      * @return 'True' if invalidation was successful, 'false' otherwise. | ||||
| @ -462,6 +462,7 @@ public class OwnCloudClient extends HttpClient { | ||||
| 
 | ||||
|     /** | ||||
|      * Check if the redirection is to an identity provider such as SAML or wayf | ||||
|      * | ||||
|      * @return true if the redirection location includes SAML or wayf, false otherwise | ||||
|      */ | ||||
|     private boolean isIdPRedirection() { | ||||
|  | ||||
| @ -48,7 +48,7 @@ public class OwnCloudClientFactory { | ||||
| 
 | ||||
|     /** | ||||
|      * Creates a OwnCloudClient setup for an ownCloud account | ||||
|      * | ||||
|      * <p> | ||||
|      * Do not call this method from the main thread. | ||||
|      * | ||||
|      * @param account         The ownCloud account | ||||
| @ -62,9 +62,8 @@ public class OwnCloudClientFactory { | ||||
|      * @throws IOException                If there was some I/O error while getting the | ||||
|      *                                    authorization token for the account. | ||||
|      * @throws AccountNotFoundException   If 'account' is unknown for the AccountManager | ||||
|      * | ||||
|      */ | ||||
|     public static OwnCloudClient createOwnCloudClient (Account account, Context appContext, | ||||
|     public static OwnCloudClient createOwnCloudClient(Account account, Context appContext, | ||||
|                                                       Activity currentActivity) | ||||
|             throws OperationCanceledException, AuthenticatorException, IOException, | ||||
|             AccountNotFoundException { | ||||
| @ -89,7 +88,9 @@ public class OwnCloudClientFactory { | ||||
| 
 | ||||
|             Bundle result = future.getResult(); | ||||
|             String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN); | ||||
|             if (accessToken == null) throw new AuthenticatorException("WTF!"); | ||||
|             if (accessToken == null) { | ||||
|                 throw new AuthenticatorException("WTF!"); | ||||
|             } | ||||
|             client.setCredentials( | ||||
|                     OwnCloudCredentialsFactory.newBearerCredentials(username, accessToken) | ||||
|             ); | ||||
| @ -105,12 +106,13 @@ public class OwnCloudClientFactory { | ||||
| 
 | ||||
|             Bundle result = future.getResult(); | ||||
|             String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN); | ||||
|             if (accessToken == null) throw new AuthenticatorException("WTF!"); | ||||
|             if (accessToken == null) { | ||||
|                 throw new AuthenticatorException("WTF!"); | ||||
|             } | ||||
|             client.setCredentials( | ||||
|                     OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken) | ||||
|             ); | ||||
| 
 | ||||
| 
 | ||||
|         } else { | ||||
|             AccountManagerFuture<Bundle> future = am.getAuthToken( | ||||
|                     account, | ||||
|  | ||||
| @ -24,14 +24,14 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import android.accounts.AuthenticatorException; | ||||
| import android.accounts.OperationCanceledException; | ||||
| import android.content.Context; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| /** | ||||
|  * Manager to create and reuse OwnCloudClient instances to access remote OC servers. | ||||
|  * | ||||
|  | ||||
| @ -25,16 +25,8 @@ package com.owncloud.android.lib.common; | ||||
| 
 | ||||
| public class OwnCloudClientManagerFactory { | ||||
| 
 | ||||
|     public static enum Policy { | ||||
|         ALWAYS_NEW_CLIENT, | ||||
|         SINGLE_SESSION_PER_ACCOUNT, | ||||
|         SINGLE_SESSION_PER_ACCOUNT_IF_SERVER_SUPPORTS_SERVER_MONITORING | ||||
|     } | ||||
| 
 | ||||
|     private static Policy sDefaultPolicy = Policy.ALWAYS_NEW_CLIENT; | ||||
| 
 | ||||
|     private static OwnCloudClientManager sDefaultSingleton; | ||||
| 
 | ||||
|     private static String sUserAgent; | ||||
| 
 | ||||
|     public static OwnCloudClientManager newDefaultOwnCloudClientManager() { | ||||
| @ -78,14 +70,14 @@ public class OwnCloudClientManagerFactory { | ||||
|         sDefaultPolicy = policy; | ||||
|     } | ||||
| 
 | ||||
|     public static void setUserAgent(String userAgent) { | ||||
|         sUserAgent = userAgent; | ||||
|     } | ||||
| 
 | ||||
|     public static String getUserAgent() { | ||||
|         return sUserAgent; | ||||
|     } | ||||
| 
 | ||||
|     public static void setUserAgent(String userAgent) { | ||||
|         sUserAgent = userAgent; | ||||
|     } | ||||
| 
 | ||||
|     private static boolean defaultSingletonMustBeUpdated(Policy policy) { | ||||
|         if (sDefaultSingleton == null) { | ||||
|             return false; | ||||
| @ -100,4 +92,10 @@ public class OwnCloudClientManagerFactory { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     public static enum Policy { | ||||
|         ALWAYS_NEW_CLIENT, | ||||
|         SINGLE_SESSION_PER_ACCOUNT, | ||||
|         SINGLE_SESSION_PER_ACCOUNT_IF_SERVER_SUPPORTS_SERVER_MONITORING | ||||
|     } | ||||
| } | ||||
| @ -24,13 +24,11 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common; | ||||
| 
 | ||||
| 
 | ||||
| import android.accounts.AuthenticatorException; | ||||
| import android.accounts.OperationCanceledException; | ||||
| import android.content.Context; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
|  | ||||
| @ -43,7 +43,7 @@ import java.util.concurrent.ConcurrentMap; | ||||
| 
 | ||||
| /** | ||||
|  * Implementation of {@link OwnCloudClientManager} | ||||
|  * | ||||
|  * <p> | ||||
|  * TODO check multithreading safety | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
| @ -62,7 +62,6 @@ public class SingleSessionManager implements OwnCloudClientManager { | ||||
|     private ConcurrentMap<String, OwnCloudClient> mClientsWithUnknownUsername = | ||||
|             new ConcurrentHashMap<>(); | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) throws OperationCanceledException, | ||||
|             AuthenticatorException, IOException { | ||||
| @ -152,7 +151,6 @@ public class SingleSessionManager implements OwnCloudClientManager { | ||||
|         return client; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public OwnCloudClient removeClientFor(OwnCloudAccount account) { | ||||
|         if (Log.isLoggable(TAG, Log.DEBUG)) { | ||||
| @ -187,7 +185,6 @@ public class SingleSessionManager implements OwnCloudClientManager { | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public void saveAllClients(Context context, String accountType) { | ||||
| 
 | ||||
|  | ||||
| @ -39,13 +39,12 @@ import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import com.owncloud.android.lib.resources.files.FileUtils; | ||||
| import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
| import okhttp3.Cookie; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import okhttp3.Cookie; | ||||
| 
 | ||||
| public class AccountUtils { | ||||
| 
 | ||||
|     private static final String TAG = AccountUtils.class.getSimpleName(); | ||||
| @ -91,8 +90,9 @@ public class AccountUtils { | ||||
|         AccountManager ama = AccountManager.get(context.getApplicationContext()); | ||||
|         String baseurl = ama.getUserData(account, Constants.KEY_OC_BASE_URL); | ||||
| 
 | ||||
|         if (baseurl == null) | ||||
|         if (baseurl == null) { | ||||
|             throw new AccountNotFoundException(account, "Account not found", null); | ||||
|         } | ||||
| 
 | ||||
|         return baseurl; | ||||
|     } | ||||
| @ -190,6 +190,7 @@ public class AccountUtils { | ||||
| 
 | ||||
|     /** | ||||
|      * Get the user id corresponding to an OC account. | ||||
|      * | ||||
|      * @param account ownCloud account | ||||
|      * @return user id | ||||
|      */ | ||||
| @ -232,7 +233,7 @@ public class AccountUtils { | ||||
|             String cookiesString = client.getCookiesString(); | ||||
|             if (!"".equals(cookiesString)) { | ||||
|                 ac.setUserData(savedAccount, Constants.KEY_COOKIES, cookiesString); | ||||
|                  Log_OC.d(TAG, "Saving Cookies: "+ cookiesString ); | ||||
|                 Log_OC.d(TAG, "Saving Cookies: " + cookiesString); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @ -260,10 +261,12 @@ public class AccountUtils { | ||||
|             if (cookiesString != null) { | ||||
|                 String[] rawCookies = cookiesString.split(";"); | ||||
|                 List<Cookie> cookieList = new ArrayList<>(rawCookies.length); | ||||
|                 for(String rawCookie : rawCookies) { | ||||
|                 for (String rawCookie : rawCookies) { | ||||
|                     rawCookie = rawCookie.replace(" ", ""); | ||||
|                     final int equalPos = rawCookie.indexOf('='); | ||||
|                     if (equalPos == -1) continue; | ||||
|                     if (equalPos == -1) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     cookieList.add(new Cookie.Builder() | ||||
|                             .name(rawCookie.substring(0, equalPos)) | ||||
|                             .value(rawCookie.substring(equalPos + 1)) | ||||
|  | ||||
| @ -26,7 +26,6 @@ package com.owncloud.android.lib.common.authentication; | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| 
 | ||||
| import okhttp3.Credentials; | ||||
| 
 | ||||
| public class OwnCloudBasicCredentials implements OwnCloudCredentials { | ||||
|  | ||||
| @ -35,7 +35,6 @@ public class BearerCredentials { | ||||
| 
 | ||||
|     private String mAccessToken; | ||||
| 
 | ||||
|      | ||||
|     /** | ||||
|      * The constructor with the bearer token | ||||
|      * | ||||
| @ -48,7 +47,6 @@ public class BearerCredentials { | ||||
|         mAccessToken = (token == null) ? "" : token; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the access token | ||||
|      * | ||||
| @ -58,7 +56,6 @@ public class BearerCredentials { | ||||
|         return mAccessToken; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Get this object string. | ||||
|      * | ||||
| @ -81,12 +78,15 @@ public class BearerCredentials { | ||||
|      * 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 (o == null) { | ||||
|             return false; | ||||
|         } | ||||
|         if (this == o) { | ||||
|             return true; | ||||
|         } | ||||
|         if (this.getClass().equals(o.getClass())) { | ||||
|             BearerCredentials that = (BearerCredentials) o; | ||||
|             if (mAccessToken.equals(that.mAccessToken)) { | ||||
|  | ||||
| @ -28,7 +28,7 @@ package com.owncloud.android.lib.common.authentication.oauth; | ||||
| 
 | ||||
| /** | ||||
|  * Constant values for OAuth 2 protocol. | ||||
|  *  | ||||
|  * <p> | ||||
|  * Includes required and optional parameter NAMES used in the 'authorization code' grant type. | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -29,34 +29,29 @@ package com.owncloud.android.lib.common.authentication.oauth; | ||||
| 
 | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials; | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; | ||||
| import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import okhttp3.MultipartBody; | ||||
| import okhttp3.RequestBody; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import okhttp3.MultipartBody; | ||||
| import okhttp3.RequestBody; | ||||
| 
 | ||||
| 
 | ||||
| public class OAuth2GetAccessTokenOperation extends RemoteOperation<Map<String, String>> { | ||||
| 
 | ||||
|     private final String mAccessTokenEndpointPath; | ||||
|     private final OAuth2ResponseParser mResponseParser; | ||||
|     private String mGrantType; | ||||
|     private String mCode; | ||||
|     private String mClientId; | ||||
|     private String mClientSecret; | ||||
|     private String mRedirectUri; | ||||
|     private final String mAccessTokenEndpointPath; | ||||
| 
 | ||||
|     private final OAuth2ResponseParser mResponseParser; | ||||
| 
 | ||||
| 
 | ||||
|     public OAuth2GetAccessTokenOperation( | ||||
|             String grantType, | ||||
|  | ||||
| @ -35,26 +35,18 @@ public interface OAuth2Provider { | ||||
|      */ | ||||
|     OAuth2RequestBuilder getOperationBuilder(); | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set configuration of the client that will use this {@link OAuth2Provider} | ||||
|      * @param oAuth2ClientConfiguration     Configuration of the client that will use this {@link OAuth2Provider} | ||||
|      */ | ||||
|     void setClientConfiguration(OAuth2ClientConfiguration oAuth2ClientConfiguration); | ||||
| 
 | ||||
|     /** | ||||
|      * Configuration of the client that is using this {@link OAuth2Provider} | ||||
|      * return                   Configuration of the client that is usinng this {@link OAuth2Provider} | ||||
|      */ | ||||
|     OAuth2ClientConfiguration getClientConfiguration(); | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set base URI to authorization server. | ||||
|      * Set configuration of the client that will use this {@link OAuth2Provider} | ||||
|      * | ||||
|      * @param authorizationServerUri        Set base URL to authorization server. | ||||
|      * @param oAuth2ClientConfiguration Configuration of the client that will use this {@link OAuth2Provider} | ||||
|      */ | ||||
|     void setAuthorizationServerUri(String authorizationServerUri); | ||||
|     void setClientConfiguration(OAuth2ClientConfiguration oAuth2ClientConfiguration); | ||||
| 
 | ||||
|     /** | ||||
|      * base URI to authorization server. | ||||
| @ -63,4 +55,11 @@ public interface OAuth2Provider { | ||||
|      */ | ||||
|     String getAuthorizationServerUri(); | ||||
| 
 | ||||
|     /** | ||||
|      * Set base URI to authorization server. | ||||
|      * | ||||
|      * @param authorizationServerUri Set base URL to authorization server. | ||||
|      */ | ||||
|     void setAuthorizationServerUri(String authorizationServerUri); | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -26,7 +26,6 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.authentication.oauth; | ||||
| 
 | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| @ -36,14 +35,7 @@ public class OAuth2ProvidersRegistry { | ||||
| 
 | ||||
|     private OAuth2Provider mDefaultProvider = null; | ||||
| 
 | ||||
|     private OAuth2ProvidersRegistry () { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * See https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom | ||||
|      */ | ||||
|     private static class LazyHolder { | ||||
|         private static final OAuth2ProvidersRegistry INSTANCE = new OAuth2ProvidersRegistry(); | ||||
|     private OAuth2ProvidersRegistry() { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -119,4 +111,11 @@ public class OAuth2ProvidersRegistry { | ||||
|         return toDefault; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * See https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom | ||||
|      */ | ||||
|     private static class LazyHolder { | ||||
|         private static final OAuth2ProvidersRegistry INSTANCE = new OAuth2ProvidersRegistry(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -31,7 +31,6 @@ import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| 
 | ||||
| public class OAuth2QueryParser { | ||||
| 
 | ||||
|     private static final String TAG = OAuth2QueryParser.class.getName(); | ||||
|  | ||||
| @ -3,57 +3,50 @@ | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  * @author Christian Schabesberger | ||||
|  * | ||||
|  * <p> | ||||
|  * Copyright (C) 2018 ownCloud GmbH. | ||||
|  * | ||||
|  * <p> | ||||
|  * 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. | ||||
|  * | ||||
|  * <p> | ||||
|  * 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. | ||||
|  * | ||||
|  * <p> | ||||
|  * 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.lib.common.authentication.oauth; | ||||
| 
 | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials; | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import okhttp3.MultipartBody; | ||||
| import okhttp3.RequestBody; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod; | ||||
| 
 | ||||
| import okhttp3.MultipartBody; | ||||
| import okhttp3.RequestBody; | ||||
| 
 | ||||
| public class OAuth2RefreshAccessTokenOperation extends RemoteOperation<Map<String, String>> { | ||||
| 
 | ||||
|     private static final String TAG = OAuth2RefreshAccessTokenOperation.class.getSimpleName(); | ||||
| 
 | ||||
|     private final String mAccessTokenEndpointPath; | ||||
|     private final OAuth2ResponseParser mResponseParser; | ||||
|     private String mClientId; | ||||
|     private String mClientSecret; | ||||
|     private String mRefreshToken; | ||||
| 
 | ||||
|     private final String mAccessTokenEndpointPath; | ||||
| 
 | ||||
|     private final OAuth2ResponseParser mResponseParser; | ||||
| 
 | ||||
|     public OAuth2RefreshAccessTokenOperation( | ||||
|             String clientId, | ||||
|             String secretId, | ||||
|  | ||||
| @ -30,10 +30,6 @@ import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| 
 | ||||
| public interface OAuth2RequestBuilder { | ||||
| 
 | ||||
|     enum OAuthRequest { | ||||
|         GET_AUTHORIZATION_CODE, CREATE_ACCESS_TOKEN, REFRESH_ACCESS_TOKEN | ||||
|     } | ||||
| 
 | ||||
|     void setRequest(OAuthRequest operation); | ||||
| 
 | ||||
|     void setGrantType(OAuth2GrantType grantType); | ||||
| @ -45,4 +41,8 @@ public interface OAuth2RequestBuilder { | ||||
|     RemoteOperation buildOperation(); | ||||
| 
 | ||||
|     String buildUri(); | ||||
| 
 | ||||
|     enum OAuthRequest { | ||||
|         GET_AUTHORIZATION_CODE, CREATE_ACCESS_TOKEN, REFRESH_ACCESS_TOKEN | ||||
|     } | ||||
| } | ||||
| @ -2,26 +2,24 @@ | ||||
|  * ownCloud Android client application | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
|  * | ||||
|  * <p> | ||||
|  * Copyright (C) 2017 ownCloud GmbH. | ||||
|  * | ||||
|  * <p> | ||||
|  * 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. | ||||
|  * | ||||
|  * <p> | ||||
|  * 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. | ||||
|  * | ||||
|  * <p> | ||||
|  * 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.lib.common.authentication.oauth; | ||||
| 
 | ||||
| 
 | ||||
| import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
|  | ||||
| @ -46,19 +46,14 @@ public class OwnCloudOAuth2Provider implements OAuth2Provider { | ||||
|         return new OwnCloudOAuth2RequestBuilder(this); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setClientConfiguration(OAuth2ClientConfiguration oAuth2ClientConfiguration) { | ||||
|         mClientConfiguration = oAuth2ClientConfiguration; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public OAuth2ClientConfiguration getClientConfiguration() { | ||||
|         return mClientConfiguration; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setAuthorizationServerUri(String authorizationServerUri) { | ||||
|         mAuthorizationServerUrl = authorizationServerUri; | ||||
|     public void setClientConfiguration(OAuth2ClientConfiguration oAuth2ClientConfiguration) { | ||||
|         mClientConfiguration = oAuth2ClientConfiguration; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
| @ -66,6 +61,11 @@ public class OwnCloudOAuth2Provider implements OAuth2Provider { | ||||
|         return mAuthorizationServerUrl; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setAuthorizationServerUri(String authorizationServerUri) { | ||||
|         mAuthorizationServerUrl = authorizationServerUri; | ||||
|     } | ||||
| 
 | ||||
|     public String getAccessTokenEndpointPath() { | ||||
|         return mAccessTokenEndpointPath; | ||||
|     } | ||||
|  | ||||
| @ -75,7 +75,7 @@ public class OwnCloudOAuth2RequestBuilder implements OAuth2RequestBuilder { | ||||
|         } | ||||
|         OAuth2ClientConfiguration clientConfiguration = mOAuth2Provider.getClientConfiguration(); | ||||
| 
 | ||||
|         switch(mRequest) { | ||||
|         switch (mRequest) { | ||||
|             case CREATE_ACCESS_TOKEN: | ||||
|                 return new OAuth2GetAccessTokenOperation( | ||||
|                         mGrantType.getValue(), | ||||
| @ -111,7 +111,7 @@ public class OwnCloudOAuth2RequestBuilder implements OAuth2RequestBuilder { | ||||
|         OAuth2ClientConfiguration clientConfiguration = mOAuth2Provider.getClientConfiguration(); | ||||
|         Uri uri; | ||||
|         Uri.Builder uriBuilder; | ||||
|         switch(mRequest) { | ||||
|         switch (mRequest) { | ||||
|             case GET_AUTHORIZATION_CODE: | ||||
|                 uri = Uri.parse(mOAuth2Provider.getAuthorizationServerUri()); | ||||
|                 uriBuilder = uri.buildUpon(); | ||||
|  | ||||
| @ -32,7 +32,15 @@ import com.owncloud.android.lib.common.http.interceptors.RequestHeaderIntercepto | ||||
| import com.owncloud.android.lib.common.network.AdvancedX509TrustManager; | ||||
| import com.owncloud.android.lib.common.network.NetworkUtils; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import okhttp3.Cookie; | ||||
| import okhttp3.CookieJar; | ||||
| import okhttp3.HttpUrl; | ||||
| import okhttp3.OkHttpClient; | ||||
| import okhttp3.Protocol; | ||||
| 
 | ||||
| import javax.net.ssl.SSLContext; | ||||
| import javax.net.ssl.TrustManager; | ||||
| import javax.net.ssl.X509TrustManager; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| @ -41,18 +49,9 @@ import java.util.List; | ||||
| import java.util.Set; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import javax.net.ssl.SSLContext; | ||||
| import javax.net.ssl.TrustManager; | ||||
| import javax.net.ssl.X509TrustManager; | ||||
| 
 | ||||
| import okhttp3.Cookie; | ||||
| import okhttp3.CookieJar; | ||||
| import okhttp3.HttpUrl; | ||||
| import okhttp3.OkHttpClient; | ||||
| import okhttp3.Protocol; | ||||
| 
 | ||||
| /** | ||||
|  * Client used to perform network operations | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class HttpClient { | ||||
| @ -63,21 +62,13 @@ public class HttpClient { | ||||
|     private static Context sContext; | ||||
|     private static HashMap<String, List<Cookie>> sCookieStore = new HashMap<>(); | ||||
| 
 | ||||
|     public static void setContext(Context context) { | ||||
|         sContext = context; | ||||
|     } | ||||
| 
 | ||||
|     public Context getContext() { | ||||
|         return sContext; | ||||
|     } | ||||
| 
 | ||||
|     public static OkHttpClient getOkHttpClient() { | ||||
|         if (sOkHttpClient == null) { | ||||
|             try { | ||||
|                 final X509TrustManager trustManager = new AdvancedX509TrustManager( | ||||
|                         NetworkUtils.getKnownServersStore(sContext)); | ||||
|                 final SSLContext sslContext = SSLContext.getInstance("TLS"); | ||||
|                 sslContext.init(null, new TrustManager[] {trustManager}, null); | ||||
|                 sslContext.init(null, new TrustManager[]{trustManager}, null); | ||||
| 
 | ||||
|                 // Automatic cookie handling, NOT PERSISTENT | ||||
|                 CookieJar cookieJar = new CookieJar() { | ||||
| @ -130,6 +121,31 @@ public class HttpClient { | ||||
|         return sOkHttpInterceptor; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Add header that will be included for all the requests from now on | ||||
|      * | ||||
|      * @param headerName | ||||
|      * @param headerValue | ||||
|      */ | ||||
|     public static void addHeaderForAllRequests(String headerName, String headerValue) { | ||||
|         getOkHttpInterceptor() | ||||
|                 .addRequestInterceptor( | ||||
|                         new RequestHeaderInterceptor(headerName, headerValue) | ||||
|                 ); | ||||
|     } | ||||
| 
 | ||||
|     public static void deleteHeaderForAllRequests(String headerName) { | ||||
|         getOkHttpInterceptor().deleteRequestHeaderInterceptor(headerName); | ||||
|     } | ||||
| 
 | ||||
|     public Context getContext() { | ||||
|         return sContext; | ||||
|     } | ||||
| 
 | ||||
|     public static void setContext(Context context) { | ||||
|         sContext = context; | ||||
|     } | ||||
| 
 | ||||
|     public void disableAutomaticCookiesHandling() { | ||||
|         OkHttpClient.Builder clientBuilder = getOkHttpClient().newBuilder(); | ||||
|         clientBuilder.cookieJar(new CookieJar() { | ||||
| @ -146,22 +162,6 @@ public class HttpClient { | ||||
|         sOkHttpClient = clientBuilder.build(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Add header that will be included for all the requests from now on | ||||
|      * @param headerName | ||||
|      * @param headerValue | ||||
|      */ | ||||
|     public static void addHeaderForAllRequests(String headerName, String headerValue) { | ||||
|         getOkHttpInterceptor() | ||||
|                 .addRequestInterceptor( | ||||
|                         new RequestHeaderInterceptor(headerName, headerValue) | ||||
|                 ); | ||||
|     } | ||||
| 
 | ||||
|     public static void deleteHeaderForAllRequests(String headerName) { | ||||
|         getOkHttpInterceptor().deleteRequestHeaderInterceptor(headerName); | ||||
|     } | ||||
| 
 | ||||
|     public List<Cookie> getCookiesFromUrl(HttpUrl httpUrl) { | ||||
|         return sCookieStore.get(httpUrl.host()); | ||||
|     } | ||||
|  | ||||
| @ -181,9 +181,13 @@ public class HttpConstants { | ||||
|      *************************************************** TIMEOUTS ********************************************** | ||||
|      ***********************************************************************************************************/ | ||||
| 
 | ||||
|     /** Default timeout for waiting data from the server */ | ||||
|     /** | ||||
|      * Default timeout for waiting data from the server | ||||
|      */ | ||||
|     public static final int DEFAULT_DATA_TIMEOUT = 60000; | ||||
| 
 | ||||
|     /** Default timeout for establishing a connection */ | ||||
|     /** | ||||
|      * Default timeout for establishing a connection | ||||
|      */ | ||||
|     public static final int DEFAULT_CONNECTION_TIMEOUT = 60000; | ||||
| } | ||||
| @ -24,16 +24,17 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.http.interceptors; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Iterator; | ||||
| 
 | ||||
| import okhttp3.Interceptor; | ||||
| import okhttp3.Request; | ||||
| import okhttp3.Response; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Iterator; | ||||
| 
 | ||||
| /** | ||||
|  * Http interceptor to use multiple interceptors in the same {@link okhttp3.OkHttpClient} instance | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class HttpInterceptor implements Interceptor { | ||||
| @ -58,20 +59,12 @@ public class HttpInterceptor implements Interceptor { | ||||
|         return response; | ||||
|     } | ||||
| 
 | ||||
|     public interface RequestInterceptor { | ||||
|         Request intercept(Request request) throws IOException; | ||||
|     } | ||||
| 
 | ||||
|     public interface ResponseInterceptor { | ||||
|         Response intercept(Response response) throws IOException; | ||||
|     } | ||||
| 
 | ||||
|     public HttpInterceptor addRequestInterceptor(RequestInterceptor requestInterceptor) { | ||||
|         mRequestInterceptors.add(requestInterceptor); | ||||
|         return this; | ||||
|     } | ||||
| 
 | ||||
|     public HttpInterceptor addResponseInterceptor (ResponseInterceptor responseInterceptor) { | ||||
|     public HttpInterceptor addResponseInterceptor(ResponseInterceptor responseInterceptor) { | ||||
|         mResponseInterceptors.add(responseInterceptor); | ||||
|         return this; | ||||
|     } | ||||
| @ -106,4 +99,12 @@ public class HttpInterceptor implements Interceptor { | ||||
|     public ArrayList<ResponseInterceptor> getResponseInterceptors() { | ||||
|         return mResponseInterceptors; | ||||
|     } | ||||
| 
 | ||||
|     public interface RequestInterceptor { | ||||
|         Request intercept(Request request) throws IOException; | ||||
|     } | ||||
| 
 | ||||
|     public interface ResponseInterceptor { | ||||
|         Response intercept(Response response) throws IOException; | ||||
|     } | ||||
| } | ||||
| @ -25,12 +25,6 @@ | ||||
| package com.owncloud.android.lib.common.http.methods; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.HttpClient; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import okhttp3.Call; | ||||
| import okhttp3.Headers; | ||||
| import okhttp3.HttpUrl; | ||||
| @ -39,6 +33,11 @@ import okhttp3.Request; | ||||
| import okhttp3.RequestBody; | ||||
| import okhttp3.Response; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| /** | ||||
|  * Wrapper to perform http calls transparently by using: | ||||
|  * - OkHttp for non webdav methods | ||||
| @ -136,6 +135,12 @@ public abstract class HttpBaseMethod { | ||||
| 
 | ||||
|     // Connection parameters | ||||
| 
 | ||||
|     public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) { | ||||
|         mOkHttpClient = mOkHttpClient.newBuilder() | ||||
|                 .retryOnConnectionFailure(retryOnConnectionFailure) | ||||
|                 .build(); | ||||
|     } | ||||
| 
 | ||||
|     public void setReadTimeout(long readTimeout, TimeUnit timeUnit) { | ||||
|         mOkHttpClient = mOkHttpClient.newBuilder() | ||||
|                 .readTimeout(readTimeout, timeUnit) | ||||
| @ -154,12 +159,6 @@ public abstract class HttpBaseMethod { | ||||
|                 .build(); | ||||
|     } | ||||
| 
 | ||||
|     public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) { | ||||
|         mOkHttpClient = mOkHttpClient.newBuilder() | ||||
|                 .retryOnConnectionFailure(retryOnConnectionFailure) | ||||
|                 .build(); | ||||
|     } | ||||
| 
 | ||||
|     // Request | ||||
| 
 | ||||
|     public void addRequestHeader(String name, String value) { | ||||
|  | ||||
| @ -27,13 +27,12 @@ package com.owncloud.android.lib.common.http.methods.nonwebdav; | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| /** | ||||
|  * OkHttp delete calls wrapper | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class DeleteMethod extends HttpMethod{ | ||||
| public class DeleteMethod extends HttpMethod { | ||||
| 
 | ||||
|     public DeleteMethod(URL url) { | ||||
|         super(url); | ||||
|  | ||||
| @ -27,10 +27,9 @@ package com.owncloud.android.lib.common.http.methods.nonwebdav; | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| /** | ||||
|  * OkHttp get calls wrapper | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class GetMethod extends HttpMethod { | ||||
|  | ||||
| @ -29,9 +29,6 @@ import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import okhttp3.Call; | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| /** | ||||
|  * Wrapper to perform OkHttp calls | ||||
|  * | ||||
|  | ||||
| @ -27,15 +27,14 @@ package com.owncloud.android.lib.common.http.methods.nonwebdav; | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| /** | ||||
|  * OkHttp post calls wrapper | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class PostMethod extends HttpMethod { | ||||
| 
 | ||||
|     public PostMethod(URL url){ | ||||
|     public PostMethod(URL url) { | ||||
|         super(url); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -27,11 +27,9 @@ package com.owncloud.android.lib.common.http.methods.nonwebdav; | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import okhttp3.HttpUrl; | ||||
| public class PutMethod extends HttpMethod { | ||||
| 
 | ||||
| public class PutMethod extends HttpMethod{ | ||||
| 
 | ||||
|     public PutMethod(URL url){ | ||||
|     public PutMethod(URL url) { | ||||
|         super(url); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -24,12 +24,13 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.http.methods.webdav; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| 
 | ||||
| /** | ||||
|  * Copy calls wrapper | ||||
|  * | ||||
|  * @author Christian Schabesberger | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
|  | ||||
| @ -24,23 +24,23 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.http.methods.webdav; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Constants; | ||||
| import at.bitfire.dav4android.DavOCResource; | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import at.bitfire.dav4android.exception.RedirectException; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| import okhttp3.HttpUrl; | ||||
| import okhttp3.Protocol; | ||||
| import okhttp3.Response; | ||||
| import okhttp3.ResponseBody; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| /** | ||||
|  * Wrapper to perform WebDAV (dav4android) calls | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public abstract class DavMethod extends HttpBaseMethod { | ||||
| @ -124,6 +124,24 @@ public abstract class DavMethod extends HttpBaseMethod { | ||||
|                 Constants.INSTANCE.getLog()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setUrl(HttpUrl url) { | ||||
|         super.setUrl(url); | ||||
|         mDavResource = new DavOCResource( | ||||
|                 mOkHttpClient, | ||||
|                 HttpUrl.parse(mRequest.url().toString()), | ||||
|                 Constants.INSTANCE.getLog()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean getRetryOnConnectionFailure() { | ||||
|         return false; //TODO: implement me | ||||
|     } | ||||
| 
 | ||||
|     ////////////////////////////// | ||||
|     //         Getter | ||||
|     ////////////////////////////// | ||||
| 
 | ||||
|     @Override | ||||
|     public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) { | ||||
|         super.setRetryOnConnectionFailure(retryOnConnectionFailure); | ||||
| @ -133,24 +151,6 @@ public abstract class DavMethod extends HttpBaseMethod { | ||||
|                 Constants.INSTANCE.getLog()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setUrl(HttpUrl url){ | ||||
|         super.setUrl(url); | ||||
|         mDavResource = new DavOCResource( | ||||
|                 mOkHttpClient, | ||||
|                 HttpUrl.parse(mRequest.url().toString()), | ||||
|                 Constants.INSTANCE.getLog()); | ||||
|     } | ||||
| 
 | ||||
|     ////////////////////////////// | ||||
|     //         Getter | ||||
|     ////////////////////////////// | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean getRetryOnConnectionFailure() { | ||||
|         return false; //TODO: implement me | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean isAborted() { | ||||
|         return mDavResource.isCallAborted(); | ||||
|  | ||||
| @ -24,12 +24,13 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.http.methods.webdav; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| 
 | ||||
| /** | ||||
|  * MkCol calls wrapper | ||||
|  * | ||||
|  * @author Christian Schabesberger | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
|  | ||||
| @ -25,13 +25,13 @@ | ||||
| package com.owncloud.android.lib.common.http.methods.webdav; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| /** | ||||
|  * Move calls wrapper | ||||
|  * | ||||
|  * @author Christian Schabesberger | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
|  | ||||
| @ -24,18 +24,19 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.http.methods.webdav; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Property; | ||||
| import at.bitfire.dav4android.Response; | ||||
| import at.bitfire.dav4android.exception.DavException; | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * Propfind calls wrapper | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class PropfindMethod extends DavMethod { | ||||
| @ -57,7 +58,7 @@ public class PropfindMethod extends DavMethod { | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int onExecute() throws IOException, DavException{ | ||||
|     public int onExecute() throws IOException, DavException { | ||||
|         mDavResource.propfind(mDepth, mPropertiesToRequest, | ||||
|                 (Response response, Response.HrefRelation hrefRelation) -> { | ||||
|                     switch (hrefRelation) { | ||||
|  | ||||
| @ -24,23 +24,25 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.http.methods.webdav; | ||||
| 
 | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| /** | ||||
|  * Put calls wrapper | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class PutMethod extends DavMethod { | ||||
| 
 | ||||
|     public PutMethod(URL url) { | ||||
|         super(url); | ||||
|     }; | ||||
|     } | ||||
| 
 | ||||
|     ; | ||||
| 
 | ||||
|     @Override | ||||
|     public int onExecute() throws IOException, HttpException { | ||||
|  | ||||
| @ -24,6 +24,11 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import javax.net.ssl.TrustManager; | ||||
| import javax.net.ssl.TrustManagerFactory; | ||||
| import javax.net.ssl.X509TrustManager; | ||||
| import java.security.KeyStore; | ||||
| import java.security.KeyStoreException; | ||||
| import java.security.NoSuchAlgorithmException; | ||||
| @ -34,14 +39,6 @@ import java.security.cert.CertificateExpiredException; | ||||
| import java.security.cert.CertificateNotYetValidException; | ||||
| import java.security.cert.X509Certificate; | ||||
| 
 | ||||
| import javax.net.ssl.TrustManager; | ||||
| import javax.net.ssl.TrustManagerFactory; | ||||
| import javax.net.ssl.X509TrustManager; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * @author David A. Velasco | ||||
|  */ | ||||
| @ -63,15 +60,15 @@ public class AdvancedX509TrustManager implements X509TrustManager { | ||||
|         super(); | ||||
|         TrustManagerFactory factory = TrustManagerFactory | ||||
|                 .getInstance(TrustManagerFactory.getDefaultAlgorithm()); | ||||
|         factory.init((KeyStore)null); | ||||
|         factory.init((KeyStore) null); | ||||
|         mStandardTrustManager = findX509TrustManager(factory); | ||||
| 
 | ||||
|         mKnownServersKeyStore = knownServersKeyStore; | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     /** | ||||
|      * Locates the first X509TrustManager provided by a given TrustManagerFactory | ||||
|      * | ||||
|      * @param factory TrustManagerFactory to inspect in the search for a X509TrustManager | ||||
|      * @return The first X509TrustManager found in factory. | ||||
|      * @throws CertStoreException When no X509TrustManager instance was found in factory | ||||
| @ -86,7 +83,6 @@ public class AdvancedX509TrustManager implements X509TrustManager { | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[], | ||||
|      * String authType) | ||||
| @ -95,7 +91,6 @@ public class AdvancedX509TrustManager implements X509TrustManager { | ||||
|         mStandardTrustManager.checkClientTrusted(certificates, authType); | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     /** | ||||
|      * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[], | ||||
|      * String authType) | ||||
| @ -122,19 +117,19 @@ public class AdvancedX509TrustManager implements X509TrustManager { | ||||
|                     cause = cause.getCause(); | ||||
|                 } | ||||
|                 if (cause != null && cause instanceof CertPathValidatorException) { | ||||
|                 	result.setCertPathValidatorException((CertPathValidatorException)cause); | ||||
|                     result.setCertPathValidatorException((CertPathValidatorException) cause); | ||||
|                 } else { | ||||
|                     result.setOtherCertificateException(c); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|         	if (result.isException()) | ||||
|             if (result.isException()) { | ||||
|                 throw result; | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     /** | ||||
|      * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() | ||||
|      */ | ||||
| @ -142,7 +137,6 @@ public class AdvancedX509TrustManager implements X509TrustManager { | ||||
|         return mStandardTrustManager.getAcceptedIssuers(); | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     public boolean isKnownServer(X509Certificate cert) { | ||||
|         try { | ||||
|             return (mKnownServersKeyStore.getCertificateAlias(cert) != null); | ||||
|  | ||||
| @ -24,26 +24,25 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import javax.net.ssl.SSLPeerUnverifiedException; | ||||
| import java.security.cert.CertPathValidatorException; | ||||
| import java.security.cert.CertificateException; | ||||
| import java.security.cert.CertificateExpiredException; | ||||
| import java.security.cert.CertificateNotYetValidException; | ||||
| import java.security.cert.X509Certificate; | ||||
| 
 | ||||
| import javax.net.ssl.SSLPeerUnverifiedException; | ||||
| 
 | ||||
| /** | ||||
|  * Exception joining all the problems that {@link AdvancedX509TrustManager} can find in | ||||
|  * a certificate chain for a server. | ||||
|  *  | ||||
|  * <p> | ||||
|  * This was initially created as an extension of CertificateException, but some | ||||
|  * implementations of the SSL socket layer in existing devices are REPLACING the CertificateException | ||||
|  * instances thrown by {@link javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[], String)} | ||||
|  * with SSLPeerUnverifiedException FORGETTING THE CAUSING EXCEPTION instead of wrapping it. | ||||
|  *  | ||||
|  * <p> | ||||
|  * Due to this, extending RuntimeException is necessary to get that the CertificateCombinedException | ||||
|  * instance reaches {@link AdvancedSslSocketFactory#verifyPeerIdentity}. | ||||
|  *  | ||||
|  * <p> | ||||
|  * BE CAREFUL. As a RuntimeException extensions, Java compilers do not require to handle it | ||||
|  * in client methods. Be sure to use it only when you know exactly where it will go. | ||||
|  * | ||||
| @ -51,7 +50,9 @@ import javax.net.ssl.SSLPeerUnverifiedException; | ||||
|  */ | ||||
| public class CertificateCombinedException extends RuntimeException { | ||||
| 
 | ||||
|     /** Generated - to refresh every time the class changes */ | ||||
|     /** | ||||
|      * Generated - to refresh every time the class changes | ||||
|      */ | ||||
|     private static final long serialVersionUID = -8875782030758554999L; | ||||
| 
 | ||||
|     private X509Certificate mServerCert = null; | ||||
| @ -112,7 +113,7 @@ public class CertificateCombinedException extends RuntimeException { | ||||
|     } | ||||
| 
 | ||||
|     public SSLPeerUnverifiedException getSslPeerUnverifiedException() { | ||||
|         return mSslPeerUnverifiedException ;  | ||||
|         return mSslPeerUnverifiedException; | ||||
|     } | ||||
| 
 | ||||
|     public void setSslPeerUnverifiedException(SSLPeerUnverifiedException s) { | ||||
|  | ||||
| @ -27,6 +27,8 @@ package com.owncloud.android.lib.common.network; | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import okhttp3.MediaType; | ||||
| import okio.BufferedSink; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| @ -34,9 +36,6 @@ import java.nio.ByteBuffer; | ||||
| import java.nio.channels.FileChannel; | ||||
| import java.util.Iterator; | ||||
| 
 | ||||
| import okhttp3.MediaType; | ||||
| import okio.BufferedSink; | ||||
| 
 | ||||
| /** | ||||
|  * A Request body that represents a file chunk and include information about the progress when uploading it | ||||
|  * | ||||
| @ -84,18 +83,19 @@ public class ChunkFromFileRequestBody extends FileRequestBody { | ||||
|         try { | ||||
|             mChannel.position(mOffset); | ||||
|             long size = mFile.length(); | ||||
|             if (size == 0) size = -1; | ||||
|             if (size == 0) { | ||||
|                 size = -1; | ||||
|             } | ||||
|             long maxCount = Math.min(mOffset + mChunkSize, mChannel.size()); | ||||
|             while (mChannel.position() < maxCount) { | ||||
| 
 | ||||
| 
 | ||||
|                 Log_OC.d(TAG, "Sink buffer size: " + sink.buffer().size()); | ||||
| 
 | ||||
|                 readCount = mChannel.read(mBuffer); | ||||
| 
 | ||||
|                 Log_OC.d(TAG, "Read " + readCount + " bytes from file channel to " + mBuffer.toString()); | ||||
| 
 | ||||
|                 sink.buffer().write(mBuffer.array(), 0 ,readCount); | ||||
|                 sink.buffer().write(mBuffer.array(), 0, readCount); | ||||
| 
 | ||||
|                 sink.flush(); | ||||
| 
 | ||||
| @ -118,14 +118,14 @@ public class ChunkFromFileRequestBody extends FileRequestBody { | ||||
|         } catch (Exception exception) { | ||||
| 
 | ||||
|             Log.e(TAG, exception.toString()); | ||||
| //            // any read problem will be handled as if the file is not there | ||||
| //            if (io instanceof FileNotFoundException) { | ||||
| //                throw io; | ||||
| //            } else { | ||||
| //                FileNotFoundException fnf = new FileNotFoundException("Exception reading source file"); | ||||
| //                fnf.initCause(io); | ||||
| //                throw fnf; | ||||
| //            } | ||||
|             //            // any read problem will be handled as if the file is not there | ||||
|             //            if (io instanceof FileNotFoundException) { | ||||
|             //                throw io; | ||||
|             //            } else { | ||||
|             //                FileNotFoundException fnf = new FileNotFoundException("Exception reading source file"); | ||||
|             //                fnf.initCause(io); | ||||
|             //                throw fnf; | ||||
|             //            } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -26,7 +26,11 @@ package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import okhttp3.MediaType; | ||||
| import okhttp3.RequestBody; | ||||
| import okio.BufferedSink; | ||||
| import okio.Okio; | ||||
| import okio.Source; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.util.Collection; | ||||
| @ -34,12 +38,6 @@ import java.util.HashSet; | ||||
| import java.util.Iterator; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| import okhttp3.MediaType; | ||||
| import okhttp3.RequestBody; | ||||
| import okio.BufferedSink; | ||||
| import okio.Okio; | ||||
| import okio.Source; | ||||
| 
 | ||||
| /** | ||||
|  * A Request body that represents a file and include information about the progress when uploading it | ||||
|  * | ||||
|  | ||||
| @ -24,6 +24,11 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import org.apache.http.conn.ssl.X509HostnameVerifier; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.FileOutputStream; | ||||
| @ -35,29 +40,25 @@ import java.security.NoSuchAlgorithmException; | ||||
| import java.security.cert.Certificate; | ||||
| import java.security.cert.CertificateException; | ||||
| 
 | ||||
| 
 | ||||
| import org.apache.http.conn.ssl.X509HostnameVerifier; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| public class NetworkUtils { | ||||
| 
 | ||||
|     final private static String TAG = NetworkUtils.class.getSimpleName(); | ||||
|      | ||||
|     /** Default timeout for waiting data from the server */ | ||||
|     /** | ||||
|      * Default timeout for waiting data from the server | ||||
|      */ | ||||
|     public static final int DEFAULT_DATA_TIMEOUT = 60000; | ||||
|      | ||||
|     /** Default timeout for establishing a connection */ | ||||
|     /** | ||||
|      * Default timeout for establishing a connection | ||||
|      */ | ||||
|     public static final int DEFAULT_CONNECTION_TIMEOUT = 60000; | ||||
|      | ||||
|     /** Standard name for protocol TLS version 1.2 in Java Secure Socket Extension (JSSE) API */ | ||||
|     /** | ||||
|      * Standard name for protocol TLS version 1.2 in Java Secure Socket Extension (JSSE) API | ||||
|      */ | ||||
|     public static final String PROTOCOL_TLSv1_2 = "TLSv1.2"; | ||||
|      | ||||
|     /** Standard name for protocol TLS version 1.0 in JSSE API */ | ||||
|     /** | ||||
|      * Standard name for protocol TLS version 1.0 in JSSE API | ||||
|      */ | ||||
|     public static final String PROTOCOL_TLSv1_0 = "TLSv1"; | ||||
| 
 | ||||
|     final private static String TAG = NetworkUtils.class.getSimpleName(); | ||||
|     private static X509HostnameVerifier mHostnameVerifier = null; | ||||
| 
 | ||||
|     private static String LOCAL_TRUSTSTORE_FILENAME = "knownServers.bks"; | ||||
| @ -68,9 +69,9 @@ public class NetworkUtils { | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the local store of reliable server certificates, explicitly accepted by the user. | ||||
|      *  | ||||
|      * <p> | ||||
|      * Returns a KeyStore instance with empty content if the local store was never created. | ||||
|      *  | ||||
|      * <p> | ||||
|      * Loads the store from the storage environment if needed. | ||||
|      * | ||||
|      * @param context Android context where the operation is being performed. | ||||
| @ -103,7 +104,6 @@ public class NetworkUtils { | ||||
|         return mKnownServersStore; | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     public static void addCertToKnownServersStore(Certificate cert, Context context) | ||||
|             throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { | ||||
| 
 | ||||
|  | ||||
| @ -26,10 +26,9 @@ package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| 
 | ||||
| 
 | ||||
| public interface ProgressiveDataTransferer { | ||||
| 
 | ||||
|     public void addDatatransferProgressListener (OnDatatransferProgressListener listener); | ||||
|     public void addDatatransferProgressListener(OnDatatransferProgressListener listener); | ||||
| 
 | ||||
|     public void addDatatransferProgressListeners(Collection<OnDatatransferProgressListener> listeners); | ||||
| 
 | ||||
|  | ||||
| @ -27,22 +27,19 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Aggregate saving the list of URLs followed in a sequence of redirections during the exceution of a | ||||
|  * {@link RemoteOperation}, and the status codes corresponding to all | ||||
|  * of them. | ||||
|  * | ||||
|  * <p> | ||||
|  * The last status code saved corresponds to the first response not being a redirection, unless the sequence exceeds | ||||
|  * the maximum length of redirections allowed by the {@link com.owncloud.android.lib.common.OwnCloudClient} instance | ||||
|  * that ran the operation. | ||||
|  * | ||||
|  * <p> | ||||
|  * If no redirection was followed, the last (and first) status code contained corresponds to the original URL in the | ||||
|  * request. | ||||
|  */ | ||||
| @ -86,7 +83,6 @@ public class RedirectionPath { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Adds a new status code to the list of status corresponding to followed redirections. | ||||
|      * | ||||
| @ -124,5 +120,4 @@ public class RedirectionPath { | ||||
|         return mLastLocation + 1; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -24,20 +24,18 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import javax.net.ssl.SSLSocket; | ||||
| import java.lang.ref.WeakReference; | ||||
| import java.lang.reflect.InvocationTargetException; | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.concurrent.atomic.AtomicReference; | ||||
| 
 | ||||
| import javax.net.ssl.SSLSocket; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Enables the support of Server Name Indication if existing | ||||
|  * in the underlying network implementation. | ||||
|  *  | ||||
|  * <p> | ||||
|  * Build as a singleton. | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
| @ -53,7 +51,6 @@ public class ServerNameIndicator { | ||||
|     private final WeakReference<Class<?>> mSSLSocketClassRef; | ||||
|     private final WeakReference<Method> mSetHostnameMethodRef; | ||||
| 
 | ||||
| 	 | ||||
|     /** | ||||
|      * Private constructor, class is a singleton. | ||||
|      * | ||||
| @ -65,11 +62,10 @@ public class ServerNameIndicator { | ||||
|         mSetHostnameMethodRef = (setHostnameMethod == null) ? null : new WeakReference<Method>(setHostnameMethod); | ||||
|     } | ||||
| 
 | ||||
| 	 | ||||
|     /** | ||||
|      * Calls the {@code #setHostname(String)} method of the underlying implementation | ||||
|      * of {@link SSLSocket} if exists. | ||||
| 	 *  | ||||
|      * <p> | ||||
|      * Creates and initializes the single instance of the class when needed | ||||
|      * | ||||
|      * @param hostname  The name of the server host of interest. | ||||
| @ -96,7 +92,6 @@ public class ServerNameIndicator { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	 | ||||
|     /** | ||||
|      * Gets the method to invoke trying to minimize the effective | ||||
|      * application of reflection. | ||||
| @ -124,10 +119,9 @@ public class ServerNameIndicator { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Singleton initializer. | ||||
| 	 *  | ||||
|      * <p> | ||||
|      * Uses reflection to extract and 'cache' the method to invoke to indicate the desited host name to the server side. | ||||
|      * | ||||
|      * @param sslSocketClass Underlying class providing the implementation of {@link SSLSocket}. | ||||
|  | ||||
| @ -25,15 +25,15 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| 
 | ||||
| import java.text.ParseException; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | ||||
| import java.util.Locale; | ||||
| 
 | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| 
 | ||||
| public class WebdavUtils { | ||||
|     public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat( | ||||
|             "dd.MM.yyyy hh:mm"); | ||||
| @ -55,7 +55,7 @@ public class WebdavUtils { | ||||
|         for (int i = 0; i < DATETIME_FORMATS.length; ++i) { | ||||
|             try { | ||||
|                 format = DATETIME_FORMATS[i]; | ||||
|             	synchronized(format) { | ||||
|                 synchronized (format) { | ||||
|                     returnDate = format.parse(date); | ||||
|                 } | ||||
|                 return returnDate; | ||||
| @ -68,7 +68,7 @@ public class WebdavUtils { | ||||
| 
 | ||||
|     /** | ||||
|      * Encodes a path according to URI RFC 2396. | ||||
|      *  | ||||
|      * <p> | ||||
|      * If the received path doesn't start with "/", the method adds it. | ||||
|      * | ||||
|      * @param remoteFilePath Path | ||||
| @ -76,13 +76,13 @@ public class WebdavUtils { | ||||
|      */ | ||||
|     public static String encodePath(String remoteFilePath) { | ||||
|         String encodedPath = Uri.encode(remoteFilePath, "/"); | ||||
|         if (!encodedPath.startsWith("/")) | ||||
|         if (!encodedPath.startsWith("/")) { | ||||
|             encodedPath = "/" + encodedPath; | ||||
|         } | ||||
|         return encodedPath; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * | ||||
|      * @param rawEtag | ||||
|      * @return | ||||
|      */ | ||||
| @ -100,7 +100,6 @@ public class WebdavUtils { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * | ||||
|      * @param httpBaseMethod from which to get the etag | ||||
|      * @return etag from response | ||||
|      */ | ||||
|  | ||||
| @ -32,18 +32,17 @@ import java.lang.reflect.Method; | ||||
| import java.net.Socket; | ||||
| import java.util.concurrent.atomic.AtomicReference; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Enforces, if possible, a write timeout for a socket. | ||||
|  * | ||||
|  * <p> | ||||
|  * Built as a singleton. | ||||
|  * | ||||
|  * <p> | ||||
|  * Tries to hit something like this: | ||||
|  * https://android.googlesource.com/platform/external/conscrypt/+/lollipop-release/src/main/java/org/conscrypt/OpenSSLSocketImpl.java#1005 | ||||
|  * | ||||
|  * <p> | ||||
|  * Minimizes the chances of getting stalled in PUT/POST request if the network interface is lost while | ||||
|  * writing the entity into the outwards sockect. | ||||
|  * | ||||
|  * <p> | ||||
|  * It happens. See https://github.com/owncloud/android/issues/1684#issuecomment-295306015 | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
| @ -56,11 +55,9 @@ public class WriteTimeoutEnforcer { | ||||
| 
 | ||||
|     private static final String METHOD_NAME = "setSoWriteTimeout"; | ||||
| 
 | ||||
| 
 | ||||
|     private final WeakReference<Class<?>> mSocketClassRef; | ||||
|     private final WeakReference<Method> mSetSoWriteTimeoutMethodRef; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Private constructor, class is a singleton. | ||||
|      * | ||||
| @ -77,11 +74,10 @@ public class WriteTimeoutEnforcer { | ||||
|         ; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Calls the {@code #setSoWrite(int)} method of the underlying implementation | ||||
|      * of {@link Socket} if exists. | ||||
| 
 | ||||
|      * <p> | ||||
|      * Creates and initializes the single instance of the class when needed | ||||
|      * | ||||
|      * @param writeTimeoutMilliseconds Write timeout to set, in milliseconds. | ||||
| @ -112,7 +108,6 @@ public class WriteTimeoutEnforcer { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the method to invoke trying to minimize the cost of reflection reusing objects cached | ||||
|      * in static members. | ||||
| @ -143,10 +138,9 @@ public class WriteTimeoutEnforcer { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Singleton initializer. | ||||
|      * | ||||
|      * <p> | ||||
|      * Uses reflection to extract and 'cache' the method to invoke to set a write timouet in a socket. | ||||
|      * | ||||
|      * @param socketClass Underlying class providing the implementation of {@link Socket}. | ||||
|  | ||||
| @ -34,6 +34,7 @@ import java.io.InputStream; | ||||
| 
 | ||||
| /** | ||||
|  * Parser for server exceptions | ||||
|  * | ||||
|  * @author davidgonzalez | ||||
|  */ | ||||
| public class ErrorMessageParser { | ||||
| @ -46,6 +47,7 @@ public class ErrorMessageParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Parse exception response | ||||
|      * | ||||
|      * @param is | ||||
|      * @return errorMessage for an exception | ||||
|      * @throws XmlPullParserException | ||||
| @ -74,14 +76,15 @@ public class ErrorMessageParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Parse OCS node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @return reason for exception | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|      */ | ||||
| 	private String readError (XmlPullParser parser) throws XmlPullParserException, IOException { | ||||
|     private String readError(XmlPullParser parser) throws XmlPullParserException, IOException { | ||||
|         String errorMessage = ""; | ||||
| 		parser.require(XmlPullParser.START_TAG,  ns , NODE_ERROR); | ||||
|         parser.require(XmlPullParser.START_TAG, ns, NODE_ERROR); | ||||
|         while (parser.next() != XmlPullParser.END_TAG) { | ||||
|             if (parser.getEventType() != XmlPullParser.START_TAG) { | ||||
|                 continue; | ||||
| @ -99,6 +102,7 @@ public class ErrorMessageParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Skip tags in parser procedure | ||||
|      * | ||||
|      * @param parser | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
| @ -122,6 +126,7 @@ public class ErrorMessageParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Read the text from a node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @return Text of the node | ||||
|      * @throws IOException | ||||
|  | ||||
| @ -35,6 +35,7 @@ import java.io.InputStream; | ||||
| 
 | ||||
| /** | ||||
|  * Parser for Invalid Character server exception | ||||
|  * | ||||
|  * @author masensio | ||||
|  */ | ||||
| public class InvalidCharacterExceptionParser { | ||||
| @ -48,8 +49,10 @@ public class InvalidCharacterExceptionParser { | ||||
|     // Nodes for XML Parser | ||||
|     private static final String NODE_ERROR = "d:error"; | ||||
|     private static final String NODE_EXCEPTION = "s:exception"; | ||||
| 
 | ||||
|     /** | ||||
|      * Parse is as an Invalid Path Exception | ||||
|      * | ||||
|      * @param is | ||||
|      * @return if The exception is an Invalid Char Exception | ||||
|      * @throws XmlPullParserException | ||||
| @ -78,14 +81,15 @@ public class InvalidCharacterExceptionParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Parse OCS node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @return List of ShareRemoteFiles | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|      */ | ||||
| 	private boolean readError (XmlPullParser parser) throws XmlPullParserException, IOException { | ||||
|     private boolean readError(XmlPullParser parser) throws XmlPullParserException, IOException { | ||||
|         String exception = ""; | ||||
| 		parser.require(XmlPullParser.START_TAG,  ns , NODE_ERROR); | ||||
|         parser.require(XmlPullParser.START_TAG, ns, NODE_ERROR); | ||||
|         while (parser.next() != XmlPullParser.END_TAG) { | ||||
|             if (parser.getEventType() != XmlPullParser.START_TAG) { | ||||
|                 continue; | ||||
| @ -105,6 +109,7 @@ public class InvalidCharacterExceptionParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Skip tags in parser procedure | ||||
|      * | ||||
|      * @param parser | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
| @ -128,6 +133,7 @@ public class InvalidCharacterExceptionParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Read the text from a node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @return Text of the node | ||||
|      * @throws IOException | ||||
|  | ||||
| @ -24,7 +24,6 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.operations; | ||||
| 
 | ||||
| 
 | ||||
| public interface OnRemoteOperationListener { | ||||
| 
 | ||||
|     void onRemoteOperationFinish(RemoteOperation caller, RemoteOperationResult result); | ||||
|  | ||||
| @ -12,25 +12,21 @@ import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import okhttp3.OkHttpClient; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import okhttp3.OkHttpClient; | ||||
| 
 | ||||
| public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
| 
 | ||||
|     private static final String TAG = RemoteOperation.class.getSimpleName(); | ||||
| 
 | ||||
|     /** | ||||
|      * OCS API header name | ||||
|      */ | ||||
|     public static final String OCS_API_HEADER = "OCS-APIREQUEST"; | ||||
| 
 | ||||
|     /** | ||||
|      * OCS API header value | ||||
|      */ | ||||
|     public static final String OCS_API_HEADER_VALUE = "true"; | ||||
| 
 | ||||
|     private static final String TAG = RemoteOperation.class.getSimpleName(); | ||||
|     /** | ||||
|      * ownCloud account in the remote ownCloud server to operate | ||||
|      */ | ||||
| @ -61,10 +57,9 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
|      */ | ||||
|     protected Handler mListenerHandler = null; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Asynchronously executes the remote operation | ||||
|      * | ||||
|      * <p> | ||||
|      * This method should be used whenever an ownCloud account is available, | ||||
|      * instead of {@link #execute(OwnCloudClient, OnRemoteOperationListener, Handler))}. | ||||
|      * | ||||
| @ -79,12 +74,14 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
|     public Thread execute(Account account, Context context, | ||||
|                           OnRemoteOperationListener listener, Handler listenerHandler) { | ||||
| 
 | ||||
|         if (account == null) | ||||
|         if (account == null) { | ||||
|             throw new IllegalArgumentException | ||||
|                     ("Trying to execute a remote operation with a NULL Account"); | ||||
|         if (context == null) | ||||
|         } | ||||
|         if (context == null) { | ||||
|             throw new IllegalArgumentException | ||||
|                     ("Trying to execute a remote operation with a NULL Context"); | ||||
|         } | ||||
|         // mAccount and mContext in the runnerThread to create below | ||||
|         mAccount = account; | ||||
|         mContext = context.getApplicationContext(); | ||||
| @ -99,7 +96,6 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
|         return runnerThread; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Asynchronously executes the remote operation | ||||
|      * | ||||
| @ -168,9 +164,9 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
| 
 | ||||
|     /** | ||||
|      * Synchronously executes the remote operation on the received ownCloud account. | ||||
|      * | ||||
|      * <p> | ||||
|      * Do not call this method from the main thread. | ||||
|      * | ||||
|      * <p> | ||||
|      * This method should be used whenever an ownCloud account is available, instead of | ||||
|      * {@link #execute(OwnCloudClient)}. | ||||
|      * | ||||
| @ -180,22 +176,23 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
|      * @return Result of the operation. | ||||
|      */ | ||||
|     public RemoteOperationResult<T> execute(Account account, Context context) { | ||||
|         if (account == null) | ||||
|         if (account == null) { | ||||
|             throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + | ||||
|                     "Account"); | ||||
|         if (context == null) | ||||
|         } | ||||
|         if (context == null) { | ||||
|             throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + | ||||
|                     "Context"); | ||||
|         } | ||||
|         mAccount = account; | ||||
|         mContext = context.getApplicationContext(); | ||||
| 
 | ||||
|         return runOperation(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Synchronously executes the remote operation | ||||
|      * | ||||
|      * <p> | ||||
|      * Do not call this method from the main thread. | ||||
|      * | ||||
|      * @param client Client object to reach an ownCloud server during the execution of | ||||
| @ -203,9 +200,10 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
|      * @return Result of the operation. | ||||
|      */ | ||||
|     public RemoteOperationResult<T> execute(OwnCloudClient client) { | ||||
|         if (client == null) | ||||
|         if (client == null) { | ||||
|             throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + | ||||
|                     "OwnCloudClient"); | ||||
|         } | ||||
|         mClient = client; | ||||
|         if (client.getAccount() != null) { | ||||
|             mAccount = client.getAccount().getSavedAccount(); | ||||
| @ -217,7 +215,7 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
| 
 | ||||
|     /** | ||||
|      * Synchronously executes the remote operation | ||||
|      * | ||||
|      * <p> | ||||
|      * Do not call this method from the main thread. | ||||
|      * | ||||
|      * @param client Client object to reach an ownCloud server during the execution of | ||||
| @ -225,9 +223,10 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
|      * @return Result of the operation. | ||||
|      */ | ||||
|     public RemoteOperationResult<T> execute(OkHttpClient client, Context context) { | ||||
|         if (client == null) | ||||
|         if (client == null) { | ||||
|             throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + | ||||
|                     "OwnCloudClient"); | ||||
|         } | ||||
|         mHttpClient = client; | ||||
|         mContext = context; | ||||
| 
 | ||||
| @ -236,7 +235,7 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
| 
 | ||||
|     /** | ||||
|      * Run operation for asynchronous or synchronous 'onExecute' method. | ||||
|      * | ||||
|      * <p> | ||||
|      * Considers and performs silent refresh of account credentials if possible, and if | ||||
|      * {@link RemoteOperation#setSilentRefreshOfAccountCredentials(boolean)} was called with | ||||
|      * parameter 'true' before the execution. | ||||
|  | ||||
| @ -27,14 +27,18 @@ package com.owncloud.android.lib.common.operations; | ||||
| import android.accounts.Account; | ||||
| import android.accounts.AccountsException; | ||||
| 
 | ||||
| import at.bitfire.dav4android.exception.DavException; | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| import com.owncloud.android.lib.common.network.CertificateCombinedException; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import okhttp3.Headers; | ||||
| import org.json.JSONException; | ||||
| 
 | ||||
| import javax.net.ssl.SSLException; | ||||
| import javax.net.ssl.SSLPeerUnverifiedException; | ||||
| import java.io.ByteArrayInputStream; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| @ -48,13 +52,6 @@ import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import javax.net.ssl.SSLException; | ||||
| import javax.net.ssl.SSLPeerUnverifiedException; | ||||
| 
 | ||||
| import at.bitfire.dav4android.exception.DavException; | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import okhttp3.Headers; | ||||
| 
 | ||||
| public class RemoteOperationResult<T extends Object> | ||||
|         implements Serializable { | ||||
| 
 | ||||
| @ -64,61 +61,6 @@ public class RemoteOperationResult<T extends Object> | ||||
|     private static final long serialVersionUID = 4968939884332372230L; | ||||
| 
 | ||||
|     private static final String TAG = RemoteOperationResult.class.getSimpleName(); | ||||
| 
 | ||||
|     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, | ||||
|         ACCOUNT_NOT_FOUND, | ||||
|         ACCOUNT_EXCEPTION, | ||||
|         ACCOUNT_NOT_NEW, | ||||
|         ACCOUNT_NOT_THE_SAME, | ||||
|         INVALID_CHARACTER_IN_NAME, | ||||
|         SHARE_NOT_FOUND, | ||||
|         LOCAL_STORAGE_NOT_REMOVED, | ||||
|         FORBIDDEN, | ||||
|         SHARE_FORBIDDEN, | ||||
|         SPECIFIC_FORBIDDEN, | ||||
|         OK_REDIRECT_TO_NON_SECURE_CONNECTION, | ||||
|         INVALID_MOVE_INTO_DESCENDANT, | ||||
|         INVALID_COPY_INTO_DESCENDANT, | ||||
|         PARTIAL_MOVE_DONE, | ||||
|         PARTIAL_COPY_DONE, | ||||
|         SHARE_WRONG_PARAMETER, | ||||
|         WRONG_SERVER_RESPONSE, | ||||
|         INVALID_CHARACTER_DETECT_IN_SERVER, | ||||
|         DELAYED_FOR_WIFI, | ||||
|         LOCAL_FILE_NOT_FOUND, | ||||
|         SERVICE_UNAVAILABLE, | ||||
|         SPECIFIC_SERVICE_UNAVAILABLE, | ||||
|         SPECIFIC_UNSUPPORTED_MEDIA_TYPE, | ||||
|         SPECIFIC_METHOD_NOT_ALLOWED | ||||
|     } | ||||
| 
 | ||||
|     private boolean mSuccess = false; | ||||
|     private int mHttpCode = -1; | ||||
|     private String mHttpPhrase = null; | ||||
| @ -128,10 +70,9 @@ public class RemoteOperationResult<T extends Object> | ||||
|     private ArrayList<String> mAuthenticate = new ArrayList<>(); | ||||
|     private String mLastPermanentLocation = null; | ||||
|     private T mData = null; | ||||
| 
 | ||||
|     /** | ||||
|      * Public constructor from result code. | ||||
|      * | ||||
|      * <p> | ||||
|      * To be used when the caller takes the responsibility of interpreting the result of a {@link RemoteOperation} | ||||
|      * | ||||
|      * @param code {@link ResultCode} decided by the caller. | ||||
| @ -146,6 +87,7 @@ public class RemoteOperationResult<T extends Object> | ||||
|     /** | ||||
|      * Create a new RemoteOperationResult based on the result given by a previous one. | ||||
|      * It does not copy the data. | ||||
|      * | ||||
|      * @param prevRemoteOperation | ||||
|      */ | ||||
|     public RemoteOperationResult(RemoteOperationResult prevRemoteOperation) { | ||||
| @ -161,9 +103,9 @@ public class RemoteOperationResult<T extends Object> | ||||
| 
 | ||||
|     /** | ||||
|      * Public constructor from exception. | ||||
|      * | ||||
|      * <p> | ||||
|      * To be used when an exception prevented the end of the {@link RemoteOperation}. | ||||
|      * | ||||
|      * <p> | ||||
|      * Determines a {@link ResultCode} depending on the type of the exception. | ||||
|      * | ||||
|      * @param e Exception that interrupted the {@link RemoteOperation} | ||||
| @ -193,7 +135,7 @@ public class RemoteOperationResult<T extends Object> | ||||
|             mCode = ResultCode.ACCOUNT_EXCEPTION; | ||||
| 
 | ||||
|         } else if (e instanceof SSLException || e instanceof RuntimeException) { | ||||
|             if(e instanceof SSLPeerUnverifiedException) { | ||||
|             if (e instanceof SSLPeerUnverifiedException) { | ||||
|                 mCode = ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED; | ||||
|             } else { | ||||
|                 CertificateCombinedException se = getCertificateCombinedException(e); | ||||
| @ -220,9 +162,9 @@ public class RemoteOperationResult<T extends Object> | ||||
| 
 | ||||
|     /** | ||||
|      * Public constructor from separate elements of an HTTP or DAV response. | ||||
|      * | ||||
|      * <p> | ||||
|      * To be used when the result needs to be interpreted from the response of an HTTP/DAV method. | ||||
|      * | ||||
|      * <p> | ||||
|      * Determines a {@link ResultCode} from the already executed method received as a parameter. Generally, | ||||
|      * will depend on the HTTP code and HTTP response headers received. In some cases will inspect also the | ||||
|      * response body | ||||
| @ -285,39 +227,13 @@ public class RemoteOperationResult<T extends Object> | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parse the error message included in the body response, if any, and set the specific result | ||||
|      * code | ||||
|      * | ||||
|      * @param bodyResponse okHttp response body | ||||
|      * @param resultCode our own custom result code | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     private void parseErrorMessageAndSetCode(String bodyResponse, ResultCode resultCode) { | ||||
| 
 | ||||
|         if (bodyResponse != null && bodyResponse.length() > 0) { | ||||
|             InputStream is = new ByteArrayInputStream(bodyResponse.getBytes()); | ||||
|             ErrorMessageParser xmlParser = new ErrorMessageParser(); | ||||
|             try { | ||||
|                 String errorMessage = xmlParser.parseXMLResponse(is); | ||||
|                 if (errorMessage != "" && errorMessage != null) { | ||||
|                     mCode = resultCode; | ||||
|                     mHttpPhrase = errorMessage; | ||||
|                 } | ||||
|             } catch (Exception e) { | ||||
|                 Log_OC.w(TAG, "Error reading exception from server: " + e.getMessage()); | ||||
|                 // mCode stays as set in this(success, httpCode, headers) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Public constructor from separate elements of an HTTP or DAV response. | ||||
|      * | ||||
|      * <p> | ||||
|      * To be used when the result needs to be interpreted from HTTP response elements that could come from | ||||
|      * different requests (WARNING: black magic, try to avoid). | ||||
|      * | ||||
|      * | ||||
|      * <p> | ||||
|      * <p> | ||||
|      * Determines a {@link ResultCode} depending on the HTTP code and HTTP response headers received. | ||||
|      * | ||||
|      * @param httpCode   HTTP status code returned by an HTTP/DAV method. | ||||
| @ -345,7 +261,7 @@ public class RemoteOperationResult<T extends Object> | ||||
| 
 | ||||
|     /** | ||||
|      * Private constructor for results built interpreting a HTTP or DAV response. | ||||
|      * | ||||
|      * <p> | ||||
|      * Determines a {@link ResultCode} depending of the type of the exception. | ||||
|      * | ||||
|      * @param httpCode   HTTP status code returned by the HTTP/DAV method. | ||||
| @ -389,11 +305,40 @@ public class RemoteOperationResult<T extends Object> | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parse the error message included in the body response, if any, and set the specific result | ||||
|      * code | ||||
|      * | ||||
|      * @param bodyResponse okHttp response body | ||||
|      * @param resultCode   our own custom result code | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     private void parseErrorMessageAndSetCode(String bodyResponse, ResultCode resultCode) { | ||||
| 
 | ||||
|         if (bodyResponse != null && bodyResponse.length() > 0) { | ||||
|             InputStream is = new ByteArrayInputStream(bodyResponse.getBytes()); | ||||
|             ErrorMessageParser xmlParser = new ErrorMessageParser(); | ||||
|             try { | ||||
|                 String errorMessage = xmlParser.parseXMLResponse(is); | ||||
|                 if (errorMessage != "" && errorMessage != null) { | ||||
|                     mCode = resultCode; | ||||
|                     mHttpPhrase = errorMessage; | ||||
|                 } | ||||
|             } catch (Exception e) { | ||||
|                 Log_OC.w(TAG, "Error reading exception from server: " + e.getMessage()); | ||||
|                 // mCode stays as set in this(success, httpCode, headers) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public boolean isSuccess() { | ||||
|         return mSuccess; | ||||
|     } | ||||
| 
 | ||||
|     public void setSuccess(boolean success) { | ||||
|         this.mSuccess = success; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isCancelled() { | ||||
|         return mCode == ResultCode.CANCELLED; | ||||
|     } | ||||
| @ -459,10 +404,11 @@ public class RemoteOperationResult<T extends Object> | ||||
|                 return "Unknown host exception"; | ||||
| 
 | ||||
|             } else if (mException instanceof CertificateCombinedException) { | ||||
|                 if (((CertificateCombinedException) mException).isRecoverable()) | ||||
|                 if (((CertificateCombinedException) mException).isRecoverable()) { | ||||
|                     return "SSL recoverable exception"; | ||||
|                 else | ||||
|                 } else { | ||||
|                     return "SSL exception"; | ||||
|                 } | ||||
| 
 | ||||
|             } else if (mException instanceof SSLException) { | ||||
|                 return "SSL exception"; | ||||
| @ -572,15 +518,65 @@ public class RemoteOperationResult<T extends Object> | ||||
|         mLastPermanentLocation = lastPermanentLocation; | ||||
|     } | ||||
| 
 | ||||
|     public void setSuccess(boolean success) { | ||||
|         this.mSuccess = success; | ||||
|     public T getData() { | ||||
|         return mData; | ||||
|     } | ||||
| 
 | ||||
|     public void setData(T data) { | ||||
|         mData = data; | ||||
|     } | ||||
| 
 | ||||
|     public T getData() { | ||||
|         return mData; | ||||
|     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, | ||||
|         ACCOUNT_NOT_FOUND, | ||||
|         ACCOUNT_EXCEPTION, | ||||
|         ACCOUNT_NOT_NEW, | ||||
|         ACCOUNT_NOT_THE_SAME, | ||||
|         INVALID_CHARACTER_IN_NAME, | ||||
|         SHARE_NOT_FOUND, | ||||
|         LOCAL_STORAGE_NOT_REMOVED, | ||||
|         FORBIDDEN, | ||||
|         SHARE_FORBIDDEN, | ||||
|         SPECIFIC_FORBIDDEN, | ||||
|         OK_REDIRECT_TO_NON_SECURE_CONNECTION, | ||||
|         INVALID_MOVE_INTO_DESCENDANT, | ||||
|         INVALID_COPY_INTO_DESCENDANT, | ||||
|         PARTIAL_MOVE_DONE, | ||||
|         PARTIAL_COPY_DONE, | ||||
|         SHARE_WRONG_PARAMETER, | ||||
|         WRONG_SERVER_RESPONSE, | ||||
|         INVALID_CHARACTER_DETECT_IN_SERVER, | ||||
|         DELAYED_FOR_WIFI, | ||||
|         LOCAL_FILE_NOT_FOUND, | ||||
|         SERVICE_UNAVAILABLE, | ||||
|         SPECIFIC_SERVICE_UNAVAILABLE, | ||||
|         SPECIFIC_UNSUPPORTED_MEDIA_TYPE, | ||||
|         SPECIFIC_METHOD_NOT_ALLOWED | ||||
|     } | ||||
| } | ||||
| @ -39,7 +39,6 @@ public class RandomUtils { | ||||
| 
 | ||||
|     /** | ||||
|      * @param length the number of random chars to be generated | ||||
|      * | ||||
|      * @return String containing random chars | ||||
|      */ | ||||
|     public static String generateRandomString(int length) { | ||||
| @ -59,7 +58,7 @@ public class RandomUtils { | ||||
|      */ | ||||
|     public static int generateRandomInteger(int min, int max) { | ||||
|         Random r = new Random(); | ||||
|         return r.nextInt(max-min) + min; | ||||
|         return r.nextInt(max - min) + min; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -30,9 +30,9 @@ import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.webdav.CopyMethod; | ||||
| import com.owncloud.android.lib.common.network.WebdavUtils; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| @ -41,7 +41,7 @@ import java.util.concurrent.TimeUnit; | ||||
| /** | ||||
|  * Remote operation moving a remote file or folder in the ownCloud server to a different folder | ||||
|  * in the same account. | ||||
|  * | ||||
|  * <p> | ||||
|  * Allows renaming the moving file/folder at the same time. | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
| @ -112,14 +112,13 @@ public class CopyRemoteFileOperation extends RemoteOperation { | ||||
| 
 | ||||
|             final int status = client.executeHttpMethod(copyMethod); | ||||
| 
 | ||||
|             if(status == HttpConstants.HTTP_CREATED || status == HttpConstants.HTTP_NO_CONTENT) { | ||||
|             if (status == HttpConstants.HTTP_CREATED || status == HttpConstants.HTTP_NO_CONTENT) { | ||||
|                 result = new RemoteOperationResult<>(ResultCode.OK); | ||||
|             } else if (status == HttpConstants.HTTP_PRECONDITION_FAILED && !mOverwrite) { | ||||
| 
 | ||||
|                 result = new RemoteOperationResult<>(ResultCode.INVALID_OVERWRITE); | ||||
|                 client.exhaustResponse(copyMethod.getResponseBodyAsStream()); | ||||
| 
 | ||||
| 
 | ||||
|                 /// for other errors that could be explicitly handled, check first: | ||||
|                 /// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4 | ||||
| 
 | ||||
|  | ||||
| @ -24,23 +24,21 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.files; | ||||
| 
 | ||||
| 
 | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.webdav.MkColMethod; | ||||
| import com.owncloud.android.lib.common.network.WebdavUtils; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Remote operation performing the creation of a new folder in the ownCloud server. | ||||
|  * | ||||
| @ -60,6 +58,7 @@ public class CreateRemoteFolderOperation extends RemoteOperation { | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor | ||||
|      * | ||||
|      * @param remotePath     Full path to the new directory to create in the remote server. | ||||
|      * @param createFullPath 'True' means that all the ancestor folders should be created. | ||||
|      */ | ||||
|  | ||||
| @ -56,9 +56,8 @@ public class DownloadRemoteFileOperation extends RemoteOperation { | ||||
|     private static final String TAG = DownloadRemoteFileOperation.class.getSimpleName(); | ||||
|     private static final int FORBIDDEN_ERROR = 403; | ||||
|     private static final int SERVICE_UNAVAILABLE_ERROR = 503; | ||||
| 
 | ||||
|     private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<>(); | ||||
|     private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); | ||||
|     private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<>(); | ||||
|     private long mModificationTimestamp = 0; | ||||
|     private String mEtag = ""; | ||||
|     private GetMethod mGet; | ||||
| @ -94,7 +93,6 @@ public class DownloadRemoteFileOperation extends RemoteOperation { | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private RemoteOperationResult downloadFile(OwnCloudClient client, File targetFile) throws | ||||
|             Exception { | ||||
| 
 | ||||
| @ -177,8 +175,12 @@ public class DownloadRemoteFileOperation extends RemoteOperation { | ||||
|                     ? new RemoteOperationResult<>(RemoteOperationResult.ResultCode.OK) | ||||
|                     : new RemoteOperationResult<>(mGet); | ||||
|         } finally { | ||||
|             if (fos != null) fos.close(); | ||||
|             if (bis != null) bis.close(); | ||||
|             if (fos != null) { | ||||
|                 fos.close(); | ||||
|             } | ||||
|             if (bis != null) { | ||||
|                 bis.close(); | ||||
|             } | ||||
|             if (!savedFile && targetFile.exists()) { | ||||
|                 targetFile.delete(); | ||||
|             } | ||||
|  | ||||
| @ -30,10 +30,9 @@ import java.io.File; | ||||
| 
 | ||||
| public class FileUtils { | ||||
| 
 | ||||
| 	private static final  String TAG = FileUtils.class.getSimpleName(); | ||||
| 
 | ||||
|     public static final String PATH_SEPARATOR = "/"; | ||||
|     public static final String FINAL_CHUNKS_FILE = ".file"; | ||||
|     private static final String TAG = FileUtils.class.getSimpleName(); | ||||
| 
 | ||||
|     public static String getParentPath(String remotePath) { | ||||
|         String parentPath = new File(remotePath).getParent(); | ||||
| @ -44,6 +43,7 @@ public class FileUtils { | ||||
|     /** | ||||
|      * Validate the fileName to detect if contains any forbidden character: / , \ , < , > , | ||||
|      * : , " , | , ? , * | ||||
|      * | ||||
|      * @param fileName | ||||
|      * @param versionSupportsForbiddenChars | ||||
|      * @return | ||||
| @ -52,11 +52,11 @@ public class FileUtils { | ||||
|         boolean result = true; | ||||
| 
 | ||||
|         Log_OC.d(TAG, "fileName =======" + fileName); | ||||
| 		if ( (versionSupportsForbiddenChars && fileName.contains(PATH_SEPARATOR)) || | ||||
| 				(!versionSupportsForbiddenChars && ( fileName.contains(PATH_SEPARATOR) || | ||||
|         if ((versionSupportsForbiddenChars && fileName.contains(PATH_SEPARATOR)) || | ||||
|                 (!versionSupportsForbiddenChars && (fileName.contains(PATH_SEPARATOR) || | ||||
|                         fileName.contains("\\") || fileName.contains("<") || fileName.contains(">") || | ||||
|                         fileName.contains(":") || fileName.contains("\"") || fileName.contains("|") || | ||||
| 				fileName.contains("?") || fileName.contains("*") ) ) ) { | ||||
|                         fileName.contains("?") || fileName.contains("*")))) { | ||||
| 
 | ||||
|             result = false; | ||||
|         } | ||||
| @ -66,6 +66,7 @@ public class FileUtils { | ||||
|     /** | ||||
|      * Validate the path to detect if contains any forbidden character: \ , < , > , : , " , | , | ||||
|      * ? , * | ||||
|      * | ||||
|      * @param path | ||||
|      * @return | ||||
|      */ | ||||
| @ -76,7 +77,7 @@ public class FileUtils { | ||||
|         if (!versionSupportsForbidenChars && | ||||
|                 (path.contains("\\") || path.contains("<") || path.contains(">") || | ||||
|                         path.contains(":") || path.contains("\"") || path.contains("|") || | ||||
| 				path.contains("?") || path.contains("*") ) ){ | ||||
|                         path.contains("?") || path.contains("*"))) { | ||||
|             result = false; | ||||
|         } | ||||
|         return result; | ||||
|  | ||||
| @ -31,9 +31,9 @@ import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.webdav.MoveMethod; | ||||
| import com.owncloud.android.lib.common.network.WebdavUtils; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| @ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit; | ||||
| /** | ||||
|  * Remote operation moving a remote file or folder in the ownCloud server to a different folder | ||||
|  * in the same account. | ||||
|  * | ||||
|  * <p> | ||||
|  * Allows renaming the moving file/folder at the same time. | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
| @ -65,7 +65,7 @@ public class MoveRemoteFileOperation extends RemoteOperation { | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * <p> | ||||
|      * TODO Paths should finish in "/" in the case of folders. ? | ||||
|      * | ||||
|      * @param srcRemotePath    Remote path of the file/folder to move. | ||||
| @ -128,7 +128,7 @@ public class MoveRemoteFileOperation extends RemoteOperation { | ||||
| 
 | ||||
|             final int status = client.executeHttpMethod(move); | ||||
|             /// process response | ||||
|             if(isSuccess(status)) { | ||||
|             if (isSuccess(status)) { | ||||
|                 result = new RemoteOperationResult<>(ResultCode.OK); | ||||
|             } else if (status == HttpConstants.HTTP_PRECONDITION_FAILED && !mOverwrite) { | ||||
| 
 | ||||
|  | ||||
| @ -24,6 +24,7 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.files; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Response; | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| @ -38,8 +39,6 @@ import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import java.net.URL; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Response; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; | ||||
| 
 | ||||
| /** | ||||
| @ -103,7 +102,7 @@ public class ReadRemoteFolderOperation extends RemoteOperation<ArrayList<RemoteF | ||||
|                 result.setData(mFolderAndFiles); | ||||
| 
 | ||||
|             } else { // synchronization failed | ||||
|                 result = new RemoteOperationResult<> (propfindMethod); | ||||
|                 result = new RemoteOperationResult<>(propfindMethod); | ||||
|             } | ||||
| 
 | ||||
|         } catch (Exception e) { | ||||
|  | ||||
| @ -28,10 +28,6 @@ import android.net.Uri; | ||||
| import android.os.Parcel; | ||||
| import android.os.Parcelable; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.math.BigDecimal; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Property; | ||||
| import at.bitfire.dav4android.Response; | ||||
| import at.bitfire.dav4android.property.CreationDate; | ||||
| @ -47,6 +43,10 @@ import at.bitfire.dav4android.property.owncloud.OCPrivatelink; | ||||
| import at.bitfire.dav4android.property.owncloud.OCSize; | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.math.BigDecimal; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.OwnCloudClient.WEBDAV_FILES_PATH_4_0; | ||||
| 
 | ||||
| /** | ||||
| @ -58,11 +58,24 @@ import static com.owncloud.android.lib.common.OwnCloudClient.WEBDAV_FILES_PATH_4 | ||||
| 
 | ||||
| public class RemoteFile implements Parcelable, Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * Parcelable Methods | ||||
|      */ | ||||
|     public static final Parcelable.Creator<RemoteFile> CREATOR = new Parcelable.Creator<RemoteFile>() { | ||||
|         @Override | ||||
|         public RemoteFile createFromParcel(Parcel source) { | ||||
|             return new RemoteFile(source); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public RemoteFile[] newArray(int size) { | ||||
|             return new RemoteFile[size]; | ||||
|         } | ||||
|     }; | ||||
|     /** | ||||
|      * Generated - should be refreshed every time the class changes!! | ||||
|      */ | ||||
|     private static final long serialVersionUID = -8965995357413958539L; | ||||
|      | ||||
|     private String mRemotePath; | ||||
|     private String mMimeType; | ||||
|     private long mLength; | ||||
| @ -76,6 +89,100 @@ public class RemoteFile implements Parcelable, Serializable { | ||||
|     private BigDecimal mQuotaAvailableBytes; | ||||
|     private String mPrivateLink; | ||||
| 
 | ||||
|     public RemoteFile() { | ||||
|         resetData(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create new {@link RemoteFile} with given path. | ||||
|      * <p> | ||||
|      * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'. | ||||
|      * | ||||
|      * @param path The remote path of the file. | ||||
|      */ | ||||
|     public RemoteFile(String path) { | ||||
|         resetData(); | ||||
|         if (path == null || path.length() <= 0 || !path.startsWith(FileUtils.PATH_SEPARATOR)) { | ||||
|             throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path); | ||||
|         } | ||||
|         mRemotePath = path; | ||||
|         mCreationTimestamp = 0; | ||||
|         mLength = 0; | ||||
|         mMimeType = "DIR"; | ||||
|         mQuotaUsedBytes = BigDecimal.ZERO; | ||||
|         mQuotaAvailableBytes = BigDecimal.ZERO; | ||||
|         mPrivateLink = null; | ||||
|     } | ||||
| 
 | ||||
|     public RemoteFile(final Response davResource, String userId) { | ||||
|         this(getRemotePathFromUrl(davResource.getHref(), userId)); | ||||
|         final List<Property> properties = davResource.getProperties(); | ||||
| 
 | ||||
|         for (Property property : properties) { | ||||
|             if (property instanceof CreationDate) { | ||||
|                 this.setCreationTimestamp( | ||||
|                         Long.parseLong(((CreationDate) property).getCreationDate())); | ||||
|             } | ||||
|             if (property instanceof GetContentLength) { | ||||
|                 this.setLength(((GetContentLength) property).getContentLength()); | ||||
|             } | ||||
|             if (property instanceof GetContentType) { | ||||
|                 this.setMimeType(((GetContentType) property).getType()); | ||||
|             } | ||||
|             if (property instanceof GetLastModified) { | ||||
|                 this.setModifiedTimestamp(((GetLastModified) property).getLastModified()); | ||||
|             } | ||||
|             if (property instanceof GetETag) { | ||||
|                 this.setEtag(((GetETag) property).getETag()); | ||||
|             } | ||||
|             if (property instanceof OCPermissions) { | ||||
|                 this.setPermissions(((OCPermissions) property).getPermission()); | ||||
|             } | ||||
|             if (property instanceof OCId) { | ||||
|                 this.setRemoteId(((OCId) property).getId()); | ||||
|             } | ||||
|             if (property instanceof OCSize) { | ||||
|                 this.setSize(((OCSize) property).getSize()); | ||||
|             } | ||||
|             if (property instanceof QuotaUsedBytes) { | ||||
|                 this.setQuotaUsedBytes( | ||||
|                         BigDecimal.valueOf(((QuotaUsedBytes) property).getQuotaUsedBytes())); | ||||
|             } | ||||
|             if (property instanceof QuotaAvailableBytes) { | ||||
|                 this.setQuotaAvailableBytes( | ||||
|                         BigDecimal.valueOf(((QuotaAvailableBytes) property).getQuotaAvailableBytes())); | ||||
|             } | ||||
|             if (property instanceof OCPrivatelink) { | ||||
|                 this.setPrivateLink(((OCPrivatelink) property).getLink()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Reconstruct from parcel | ||||
|      * | ||||
|      * @param source The source parcel | ||||
|      */ | ||||
|     protected RemoteFile(Parcel source) { | ||||
|         readFromParcel(source); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Retrieves a relative path from a remote file url | ||||
|      * <p> | ||||
|      * Example: url:port/remote.php/dav/files/username/Documents/text.txt => /Documents/text.txt | ||||
|      * | ||||
|      * @param url    remote file url | ||||
|      * @param userId file owner | ||||
|      * @return remote relative path of the file | ||||
|      */ | ||||
|     private static String getRemotePathFromUrl(HttpUrl url, String userId) { | ||||
|         final String davFilesPath = WEBDAV_FILES_PATH_4_0 + userId; | ||||
|         final String absoluteDavPath = Uri.decode(url.encodedPath()); | ||||
|         final String pathToOc = absoluteDavPath.split(davFilesPath)[0]; | ||||
|         return absoluteDavPath.replace(pathToOc + davFilesPath, ""); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Getters and Setters | ||||
|      */ | ||||
| @ -168,80 +275,6 @@ public class RemoteFile implements Parcelable, Serializable { | ||||
|         mPrivateLink = privateLink; | ||||
|     } | ||||
| 
 | ||||
|     public RemoteFile() { | ||||
|         resetData(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create new {@link RemoteFile} with given path. | ||||
|      * | ||||
|      * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'. | ||||
|      * | ||||
|      * @param path The remote path of the file. | ||||
|      */ | ||||
|     public RemoteFile(String path) { | ||||
|         resetData(); | ||||
|         if (path == null || path.length() <= 0 || !path.startsWith(FileUtils.PATH_SEPARATOR)) { | ||||
|             throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path); | ||||
|         } | ||||
|         mRemotePath = path; | ||||
|         mCreationTimestamp = 0; | ||||
|         mLength = 0; | ||||
|         mMimeType = "DIR"; | ||||
|         mQuotaUsedBytes = BigDecimal.ZERO; | ||||
|         mQuotaAvailableBytes = BigDecimal.ZERO; | ||||
|         mPrivateLink = null; | ||||
|     } | ||||
| 
 | ||||
|     public RemoteFile(final Response davResource, String userId) { | ||||
|         this(getRemotePathFromUrl(davResource.getHref(), userId)); | ||||
|         final List<Property> properties = davResource.getProperties(); | ||||
| 
 | ||||
|         for(Property property : properties) { | ||||
|             if(property instanceof CreationDate) | ||||
|                 this.setCreationTimestamp( | ||||
|                         Long.parseLong(((CreationDate) property).getCreationDate())); | ||||
|             if(property instanceof GetContentLength) | ||||
|                 this.setLength(((GetContentLength) property).getContentLength()); | ||||
|             if(property instanceof  GetContentType) | ||||
|                 this.setMimeType(((GetContentType) property).getType()); | ||||
|             if(property instanceof GetLastModified) | ||||
|                 this.setModifiedTimestamp(((GetLastModified) property).getLastModified()); | ||||
|             if(property instanceof GetETag) | ||||
|                 this.setEtag(((GetETag) property).getETag()); | ||||
|             if(property instanceof OCPermissions) | ||||
|                 this.setPermissions(((OCPermissions) property).getPermission()); | ||||
|             if(property instanceof OCId) | ||||
|                 this.setRemoteId(((OCId) property).getId()); | ||||
|             if(property instanceof OCSize) | ||||
|                 this.setSize(((OCSize) property).getSize()); | ||||
|             if(property instanceof  QuotaUsedBytes) | ||||
|                 this.setQuotaUsedBytes( | ||||
|                         BigDecimal.valueOf(((QuotaUsedBytes) property).getQuotaUsedBytes())); | ||||
|             if(property instanceof QuotaAvailableBytes) | ||||
|                 this.setQuotaAvailableBytes( | ||||
|                         BigDecimal.valueOf(((QuotaAvailableBytes) property).getQuotaAvailableBytes())); | ||||
|             if(property instanceof OCPrivatelink) | ||||
|                 this.setPrivateLink(((OCPrivatelink) property).getLink()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Retrieves a relative path from a remote file url | ||||
|      * | ||||
|      * Example: url:port/remote.php/dav/files/username/Documents/text.txt => /Documents/text.txt | ||||
|      * | ||||
|      * @param url remote file url | ||||
|      * @param userId file owner | ||||
|      * @return remote relative path of the file | ||||
|      */ | ||||
|     private static String getRemotePathFromUrl(HttpUrl url, String userId) { | ||||
|         final String davFilesPath = WEBDAV_FILES_PATH_4_0 + userId; | ||||
|         final String absoluteDavPath = Uri.decode(url.encodedPath()); | ||||
|         final String pathToOc = absoluteDavPath.split(davFilesPath)[0]; | ||||
|         return absoluteDavPath.replace(pathToOc + davFilesPath, ""); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Used internally. Reset all file properties | ||||
|      */ | ||||
| @ -260,31 +293,6 @@ public class RemoteFile implements Parcelable, Serializable { | ||||
|         mPrivateLink = null; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parcelable Methods | ||||
|      */ | ||||
|     public static final Parcelable.Creator<RemoteFile> CREATOR = new Parcelable.Creator<RemoteFile>() { | ||||
|         @Override | ||||
|         public RemoteFile createFromParcel(Parcel source) { | ||||
|             return new RemoteFile(source); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public RemoteFile[] newArray(int size) { | ||||
|             return new RemoteFile[size]; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Reconstruct from parcel | ||||
|      * | ||||
|      * @param source The source parcel | ||||
|      */ | ||||
|     protected RemoteFile(Parcel source) { | ||||
|         readFromParcel(source); | ||||
|     } | ||||
| 
 | ||||
|     public void readFromParcel(Parcel source) { | ||||
|         mRemotePath = source.readString(); | ||||
|         mMimeType = source.readString(); | ||||
|  | ||||
| @ -24,20 +24,19 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.files; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.webdav.MoveMethod; | ||||
| import com.owncloud.android.lib.common.network.WebdavUtils; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| /** | ||||
|  * Remote operation performing the rename of a remote file or folder in the ownCloud server. | ||||
| @ -92,8 +91,9 @@ public class RenameRemoteFileOperation extends RemoteOperation { | ||||
|         final boolean versionWithForbiddenChars = | ||||
|                 (version != null && version.isVersionWithForbiddenCharacters()); | ||||
| 
 | ||||
|         if(!FileUtils.isValidPath(mNewRemotePath, versionWithForbiddenChars)) | ||||
|         if (!FileUtils.isValidPath(mNewRemotePath, versionWithForbiddenChars)) { | ||||
|             return new RemoteOperationResult<>(ResultCode.INVALID_CHARACTER_IN_NAME); | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             if (mNewName.equals(mOldName)) { | ||||
|  | ||||
| @ -34,6 +34,7 @@ import com.owncloud.android.lib.common.operations.OperationCancelledException; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import okhttp3.MediaType; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.net.URL; | ||||
| @ -41,8 +42,6 @@ import java.util.HashSet; | ||||
| import java.util.Set; | ||||
| import java.util.concurrent.atomic.AtomicBoolean; | ||||
| 
 | ||||
| import okhttp3.MediaType; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; | ||||
| 
 | ||||
| /** | ||||
| @ -56,15 +55,13 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
| public class UploadRemoteFileOperation extends RemoteOperation { | ||||
| 
 | ||||
|     private static final String TAG = UploadRemoteFileOperation.class.getSimpleName(); | ||||
| 
 | ||||
|     protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); | ||||
|     protected String mLocalPath; | ||||
|     protected String mRemotePath; | ||||
|     protected String mMimeType; | ||||
|     protected String mFileLastModifTimestamp; | ||||
|     protected PutMethod mPutMethod = null; | ||||
|     protected String mRequiredEtag = null; | ||||
| 
 | ||||
|     protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); | ||||
|     protected Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>(); | ||||
| 
 | ||||
|     protected FileRequestBody mFileRequestBody = null; | ||||
| @ -154,7 +151,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { | ||||
|         return mDataTransferListeners; | ||||
|     } | ||||
| 
 | ||||
|     public void addDatatransferProgressListener (OnDatatransferProgressListener listener) { | ||||
|     public void addDatatransferProgressListener(OnDatatransferProgressListener listener) { | ||||
|         synchronized (mDataTransferListeners) { | ||||
|             mDataTransferListeners.add(listener); | ||||
|         } | ||||
| @ -175,10 +172,11 @@ public class UploadRemoteFileOperation extends RemoteOperation { | ||||
|     public void cancel() { | ||||
|         synchronized (mCancellationRequested) { | ||||
|             mCancellationRequested.set(true); | ||||
|             if (mPutMethod != null) | ||||
|             if (mPutMethod != null) { | ||||
|                 mPutMethod.abort(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public boolean isSuccess(int status) { | ||||
|         return ((status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_CREATED || | ||||
|  | ||||
| @ -32,6 +32,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import com.owncloud.android.lib.resources.files.FileUtils; | ||||
| import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation; | ||||
| import okhttp3.MediaType; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.RandomAccessFile; | ||||
| @ -39,8 +40,6 @@ import java.net.URL; | ||||
| import java.nio.channels.FileChannel; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import okhttp3.MediaType; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.http.HttpConstants.IF_MATCH_HEADER; | ||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; | ||||
| 
 | ||||
| @ -52,8 +51,8 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
|  */ | ||||
| public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation { | ||||
| 
 | ||||
|     private static final int LAST_CHUNK_TIMEOUT = 900000; //15 mins. | ||||
|     public static final long CHUNK_SIZE = 1024000; | ||||
|     private static final int LAST_CHUNK_TIMEOUT = 900000; //15 mins. | ||||
|     private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName(); | ||||
| 
 | ||||
|     private String mTransferId; | ||||
| @ -127,11 +126,13 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (channel != null) | ||||
|         if (channel != null) { | ||||
|             channel.close(); | ||||
|         } | ||||
| 
 | ||||
|         if (raf != null) | ||||
|         if (raf != null) { | ||||
|             raf.close(); | ||||
|         } | ||||
| 
 | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
| @ -35,6 +35,7 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import okhttp3.FormBody; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.text.DateFormat; | ||||
| @ -42,8 +43,6 @@ import java.text.SimpleDateFormat; | ||||
| import java.util.Calendar; | ||||
| import java.util.Locale; | ||||
| 
 | ||||
| import okhttp3.FormBody; | ||||
| 
 | ||||
| /** | ||||
|  * Creates a new share.  This allows sharing with a user or group or as a link. | ||||
|  * | ||||
| @ -133,7 +132,6 @@ public class CreateRemoteShareOperation extends RemoteOperation { | ||||
|         mGetShareDetails = false;        // defaults to false for backwards compatibility | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set name to create in Share resource. Ignored by servers previous to version 10.0.0 | ||||
|      * | ||||
| @ -154,7 +152,6 @@ public class CreateRemoteShareOperation extends RemoteOperation { | ||||
|         mPassword = password; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set expiration date to create in Share resource. | ||||
|      * | ||||
| @ -165,7 +162,6 @@ public class CreateRemoteShareOperation extends RemoteOperation { | ||||
|         mExpirationDateInMillis = expirationDateInMillis; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set permissions to create in Share resource. | ||||
|      * | ||||
|  | ||||
| @ -50,7 +50,6 @@ public class GetRemoteShareOperation extends RemoteOperation<ShareParserResult> | ||||
| 
 | ||||
|     private long mRemoteId; | ||||
| 
 | ||||
| 
 | ||||
|     public GetRemoteShareOperation(long remoteId) { | ||||
|         mRemoteId = remoteId; | ||||
|     } | ||||
|  | ||||
| @ -36,7 +36,6 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import org.json.JSONArray; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| @ -47,13 +46,13 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
| 
 | ||||
| /** | ||||
|  * Created by masensio on 08/10/2015. | ||||
|  * | ||||
|  * <p> | ||||
|  * Retrieves a list of sharees (possible targets of a share) from the ownCloud server. | ||||
|  * | ||||
|  * <p> | ||||
|  * Currently only handles users and groups. Users in other OC servers (federation) should be added later. | ||||
|  * | ||||
|  * <p> | ||||
|  * Depends on SHAREE API. {@See https://github.com/owncloud/documentation/issues/1626} | ||||
|  * | ||||
|  * <p> | ||||
|  * Syntax: | ||||
|  * Entry point: ocs/v2.php/apps/files_sharing/api/v1/sharees | ||||
|  * HTTP method: GET | ||||
| @ -62,7 +61,7 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
|  * url argument: search - string, optional | ||||
|  * url arguments: perPage - int, optional | ||||
|  * url arguments: page - int, optional | ||||
|  * | ||||
|  * <p> | ||||
|  * Status codes: | ||||
|  * 100 - successful | ||||
|  * | ||||
| @ -72,22 +71,22 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
|  */ | ||||
| public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObject>> { | ||||
| 
 | ||||
|     public static final String NODE_VALUE = "value"; | ||||
|     public static final String PROPERTY_LABEL = "label"; | ||||
|     public static final String PROPERTY_SHARE_TYPE = "shareType"; | ||||
|     public static final String PROPERTY_SHARE_WITH = "shareWith"; | ||||
|     private static final String TAG = GetRemoteShareesOperation.class.getSimpleName(); | ||||
| 
 | ||||
|     // OCS Routes | ||||
|     private static final String OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/sharees";    // from OC 8.2 | ||||
| 
 | ||||
|     // Arguments - names | ||||
|     private static final String PARAM_FORMAT = "format"; | ||||
|     private static final String PARAM_ITEM_TYPE = "itemType"; | ||||
|     private static final String PARAM_SEARCH = "search"; | ||||
|     private static final String PARAM_PAGE = "page";                //  default = 1 | ||||
|     private static final String PARAM_PER_PAGE = "perPage";         //  default = 200 | ||||
| 
 | ||||
|     // Arguments - constant values | ||||
|     private static final String VALUE_FORMAT = "json"; | ||||
|     private static final String VALUE_ITEM_TYPE = "file";         //  to get the server search for users / groups | ||||
| 
 | ||||
|     // JSON Node names | ||||
|     private static final String NODE_OCS = "ocs"; | ||||
|     private static final String NODE_DATA = "data"; | ||||
| @ -95,11 +94,6 @@ public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObj | ||||
|     private static final String NODE_USERS = "users"; | ||||
|     private static final String NODE_GROUPS = "groups"; | ||||
|     private static final String NODE_REMOTES = "remotes"; | ||||
|     public static final String NODE_VALUE = "value"; | ||||
|     public static final String PROPERTY_LABEL = "label"; | ||||
|     public static final String PROPERTY_SHARE_TYPE = "shareType"; | ||||
|     public static final String PROPERTY_SHARE_WITH = "shareWith"; | ||||
| 
 | ||||
|     private String mSearchString; | ||||
|     private int mPage; | ||||
|     private int mPerPage; | ||||
| @ -121,7 +115,7 @@ public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObj | ||||
|     protected RemoteOperationResult<ArrayList<JSONObject>> run(OwnCloudClient client) { | ||||
|         RemoteOperationResult<ArrayList<JSONObject>> result; | ||||
| 
 | ||||
|         try{ | ||||
|         try { | ||||
|             Uri requestUri = client.getBaseUri(); | ||||
|             Uri.Builder uriBuilder = requestUri.buildUpon() | ||||
|                     .appendEncodedPath(OCS_ROUTE) | ||||
| @ -138,7 +132,7 @@ public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObj | ||||
|             int status = client.executeHttpMethod(getMethod); | ||||
|             String response = getMethod.getResponseBodyAsString(); | ||||
| 
 | ||||
|             if(isSuccess(status)) { | ||||
|             if (isSuccess(status)) { | ||||
|                 Log_OC.d(TAG, "Successful response: " + response); | ||||
| 
 | ||||
|                 // Parse the response | ||||
| @ -162,8 +156,8 @@ public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObj | ||||
|                 }; | ||||
| 
 | ||||
|                 ArrayList<JSONObject> data = new ArrayList<>(); // For result data | ||||
|                 for (int i=0; i<6; i++) { | ||||
|                     for(int j=0; j< jsonResults[i].length(); j++){ | ||||
|                 for (int i = 0; i < 6; i++) { | ||||
|                     for (int j = 0; j < jsonResults[i].length(); j++) { | ||||
|                         JSONObject jsonResult = jsonResults[i].getJSONObject(j); | ||||
|                         data.add(jsonResult); | ||||
|                         Log_OC.d(TAG, "*** Added item: " + jsonResult.getString(PROPERTY_LABEL)); | ||||
| @ -173,7 +167,7 @@ public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObj | ||||
|                 result = new RemoteOperationResult<>(OK); | ||||
|                 result.setData(data); | ||||
| 
 | ||||
|                 Log_OC.d(TAG, "*** Get Users or groups completed " ); | ||||
|                 Log_OC.d(TAG, "*** Get Users or groups completed "); | ||||
| 
 | ||||
|             } else { | ||||
|                 result = new RemoteOperationResult<>(getMethod); | ||||
|  | ||||
| @ -24,15 +24,13 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.shares; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.Serializable; | ||||
| 
 | ||||
| import android.os.Parcel; | ||||
| import android.os.Parcelable; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import com.owncloud.android.lib.resources.files.FileUtils; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| 
 | ||||
| /** | ||||
|  * Contains the data of a Share from the Share API | ||||
| @ -42,13 +40,6 @@ import com.owncloud.android.lib.resources.files.FileUtils; | ||||
|  */ | ||||
| public class OCShare implements Parcelable, Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * Generated - should be refreshed every time the class changes!! | ||||
|      */ | ||||
|     private static final long serialVersionUID = 4124975224281327921L; | ||||
| 
 | ||||
|     private static final String TAG = OCShare.class.getSimpleName(); | ||||
| 
 | ||||
|     public static final int DEFAULT_PERMISSION = -1; | ||||
|     public static final int READ_PERMISSION_FLAG = 1; | ||||
|     public static final int UPDATE_PERMISSION_FLAG = 2; | ||||
| @ -78,7 +69,25 @@ public class OCShare implements Parcelable, Serializable { | ||||
|     public static final int FEDERATED_PERMISSIONS_FOR_FOLDER_AFTER_OC9 = | ||||
|             FEDERATED_PERMISSIONS_FOR_FOLDER_UP_TO_OC9 + | ||||
|                     SHARE_PERMISSION_FLAG; | ||||
|     /** | ||||
|      * Parcelable Methods | ||||
|      */ | ||||
|     public static final Parcelable.Creator<OCShare> CREATOR = new Parcelable.Creator<OCShare>() { | ||||
|         @Override | ||||
|         public OCShare createFromParcel(Parcel source) { | ||||
|             return new OCShare(source); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public OCShare[] newArray(int size) { | ||||
|             return new OCShare[size]; | ||||
|         } | ||||
|     }; | ||||
|     /** | ||||
|      * Generated - should be refreshed every time the class changes!! | ||||
|      */ | ||||
|     private static final long serialVersionUID = 4124975224281327921L; | ||||
|     private static final String TAG = OCShare.class.getSimpleName(); | ||||
|     private long mId; | ||||
|     private long mFileSource; | ||||
|     private long mItemSource; | ||||
| @ -110,6 +119,17 @@ public class OCShare implements Parcelable, Serializable { | ||||
|         mPath = path; | ||||
|     } | ||||
| 
 | ||||
|     /// Getters and Setters | ||||
| 
 | ||||
|     /** | ||||
|      * Reconstruct from parcel | ||||
|      * | ||||
|      * @param source The source parcel | ||||
|      */ | ||||
|     protected OCShare(Parcel source) { | ||||
|         readFromParcel(source); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Used internally. Reset all file properties | ||||
|      */ | ||||
| @ -132,8 +152,6 @@ public class OCShare implements Parcelable, Serializable { | ||||
|         mName = ""; | ||||
|     } | ||||
| 
 | ||||
|     /// Getters and Setters | ||||
| 
 | ||||
|     public long getId() { | ||||
|         return mId; | ||||
|     } | ||||
| @ -266,30 +284,6 @@ public class OCShare implements Parcelable, Serializable { | ||||
|         return ShareType.PUBLIC_LINK.equals(mShareType) && mShareWith.length() > 0; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parcelable Methods | ||||
|      */ | ||||
|     public static final Parcelable.Creator<OCShare> CREATOR = new Parcelable.Creator<OCShare>() { | ||||
|         @Override | ||||
|         public OCShare createFromParcel(Parcel source) { | ||||
|             return new OCShare(source); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public OCShare[] newArray(int size) { | ||||
|             return new OCShare[size]; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     /** | ||||
|      * Reconstruct from parcel | ||||
|      * | ||||
|      * @param source The source parcel | ||||
|      */ | ||||
|     protected OCShare(Parcel source) { | ||||
|         readFromParcel(source); | ||||
|     } | ||||
| 
 | ||||
|     public void readFromParcel(Parcel source) { | ||||
|         mId = source.readLong(); | ||||
| 
 | ||||
| @ -314,13 +308,11 @@ public class OCShare implements Parcelable, Serializable { | ||||
|         mName = source.readString(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public int describeContents() { | ||||
|         return this.hashCode(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public void writeToParcel(Parcel dest, int flags) { | ||||
|         dest.writeLong(mId); | ||||
|  | ||||
| @ -25,14 +25,15 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.shares; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Provides method to define a set of share permissions and calculate the appropiate | ||||
|  * int value representing it. | ||||
|  */ | ||||
| public class SharePermissionsBuilder { | ||||
| 
 | ||||
|     /** Set of permissions */ | ||||
|     /** | ||||
|      * Set of permissions | ||||
|      */ | ||||
|     private int mPermissions = OCShare.READ_PERMISSION_FLAG;    // READ is minimum permission | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -32,7 +32,6 @@ import android.net.Uri; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
| 
 | ||||
| import org.xmlpull.v1.XmlPullParserException; | ||||
| 
 | ||||
| import java.io.ByteArrayInputStream; | ||||
| @ -50,7 +49,6 @@ public class ShareToRemoteOperationResultParser { | ||||
|     private OwnCloudVersion mOwnCloudVersion = null; | ||||
|     private Uri mServerBaseUri = null; | ||||
| 
 | ||||
| 
 | ||||
|     public ShareToRemoteOperationResultParser(ShareXMLParser shareXmlParser) { | ||||
|         mShareXmlParser = shareXmlParser; | ||||
|     } | ||||
| @ -112,11 +110,11 @@ public class ShareToRemoteOperationResultParser { | ||||
|                     Log_OC.e(TAG, "Successful status with no share in the response"); | ||||
|                 } | ||||
| 
 | ||||
|             } else if (mShareXmlParser.isWrongParameter()){ | ||||
|             } else if (mShareXmlParser.isWrongParameter()) { | ||||
|                 result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.SHARE_WRONG_PARAMETER); | ||||
|                 result.setData(new ShareParserResult(null, mShareXmlParser.getMessage())); | ||||
| 
 | ||||
|             } else if (mShareXmlParser.isNotFound()){ | ||||
|             } else if (mShareXmlParser.isNotFound()) { | ||||
|                 result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.SHARE_NOT_FOUND); | ||||
|                 result.setData(new ShareParserResult(null, mShareXmlParser.getMessage())); | ||||
| 
 | ||||
|  | ||||
| @ -34,33 +34,25 @@ package com.owncloud.android.lib.resources.shares; | ||||
|  * 5 - Shared by contact | ||||
|  * | ||||
|  * @author masensio | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| public enum ShareType { | ||||
|     NO_SHARED (-1), | ||||
|     USER (0), | ||||
|     GROUP (1), | ||||
|     PUBLIC_LINK (3), | ||||
|     EMAIL (4), | ||||
|     CONTACT (5), | ||||
|     FEDERATED (6); | ||||
|     NO_SHARED(-1), | ||||
|     USER(0), | ||||
|     GROUP(1), | ||||
|     PUBLIC_LINK(3), | ||||
|     EMAIL(4), | ||||
|     CONTACT(5), | ||||
|     FEDERATED(6); | ||||
| 
 | ||||
|     private int value; | ||||
| 
 | ||||
|     private ShareType(int value) | ||||
|     { | ||||
|     private ShareType(int value) { | ||||
|         this.value = value; | ||||
|     } | ||||
| 
 | ||||
|     public int getValue() { | ||||
|         return value; | ||||
|     } | ||||
|      | ||||
|     public static ShareType fromValue(int value) | ||||
|     { | ||||
|         switch (value) | ||||
|         { | ||||
|     public static ShareType fromValue(int value) { | ||||
|         switch (value) { | ||||
|             case -1: | ||||
|                 return NO_SHARED; | ||||
|             case 0: | ||||
| @ -78,4 +70,8 @@ public enum ShareType { | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     public int getValue() { | ||||
|         return value; | ||||
|     } | ||||
| }; | ||||
| @ -31,20 +31,19 @@ import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
|  * | ||||
|  * @author masensio | ||||
|  * @author David González Verdugo | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| public class ShareUtils { | ||||
| 
 | ||||
|     // OCS Route | ||||
| 	public static final String SHARING_API_PATH ="ocs/v2.php/apps/files_sharing/api/v1/shares"; | ||||
|     public static final String SHARING_API_PATH = "ocs/v2.php/apps/files_sharing/api/v1/shares"; | ||||
| 
 | ||||
|     // String to build the link with the token of a share: | ||||
|     public static final String SHARING_LINK_PATH_BEFORE_VERSION_8 = "/public.php?service=files&t="; | ||||
|     public static final String SHARING_LINK_PATH_AFTER_VERSION_8 = "/index.php/s/"; | ||||
| 
 | ||||
|     public static String getSharingLinkPath(OwnCloudVersion version){ | ||||
|         if (version!= null && version.isAfter8Version()){ | ||||
|     public static String getSharingLinkPath(OwnCloudVersion version) { | ||||
|         if (version != null && version.isAfter8Version()) { | ||||
|             return SHARING_LINK_PATH_AFTER_VERSION_8; | ||||
|         } else { | ||||
|             return SHARING_LINK_PATH_BEFORE_VERSION_8; | ||||
|  | ||||
| @ -24,22 +24,23 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.shares; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| import org.xmlpull.v1.XmlPullParser; | ||||
| import org.xmlpull.v1.XmlPullParserException; | ||||
| import org.xmlpull.v1.XmlPullParserFactory; | ||||
| 
 | ||||
| //import android.util.Log; | ||||
| import android.util.Xml; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.network.WebdavUtils; | ||||
| import com.owncloud.android.lib.resources.files.FileUtils; | ||||
| import org.xmlpull.v1.XmlPullParser; | ||||
| import org.xmlpull.v1.XmlPullParserException; | ||||
| import org.xmlpull.v1.XmlPullParserFactory; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| //import android.util.Log; | ||||
| 
 | ||||
| /** | ||||
|  * Parser for Share API Response | ||||
|  * | ||||
|  * @author masensio | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| @ -91,6 +92,11 @@ public class ShareXMLParser { | ||||
|     private int mStatusCode; | ||||
|     private String mMessage; | ||||
| 
 | ||||
|     // Constructor | ||||
|     public ShareXMLParser() { | ||||
|         mStatusCode = -1; | ||||
|     } | ||||
| 
 | ||||
|     // Getters and Setters | ||||
|     public String getStatus() { | ||||
|         return mStatus; | ||||
| @ -116,11 +122,6 @@ public class ShareXMLParser { | ||||
|         this.mMessage = message; | ||||
|     } | ||||
| 
 | ||||
| 	// Constructor | ||||
| 	public ShareXMLParser() { | ||||
| 		mStatusCode = -1; | ||||
| 	} | ||||
| 
 | ||||
|     public boolean isSuccess() { | ||||
|         return mStatusCode == SUCCESS; | ||||
|     } | ||||
| @ -139,6 +140,7 @@ public class ShareXMLParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Parse is as response of Share API | ||||
|      * | ||||
|      * @param is | ||||
|      * @return List of ShareRemoteFiles | ||||
|      * @throws XmlPullParserException | ||||
| @ -165,15 +167,16 @@ public class ShareXMLParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Parse OCS node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @return List of ShareRemoteFiles | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|      */ | ||||
| 	private ArrayList<OCShare> readOCS (XmlPullParser parser) throws XmlPullParserException, | ||||
|     private ArrayList<OCShare> readOCS(XmlPullParser parser) throws XmlPullParserException, | ||||
|             IOException { | ||||
|         ArrayList<OCShare> shares = new ArrayList<>(); | ||||
| 		parser.require(XmlPullParser.START_TAG,  ns , NODE_OCS); | ||||
|         parser.require(XmlPullParser.START_TAG, ns, NODE_OCS); | ||||
|         while (parser.next() != XmlPullParser.END_TAG) { | ||||
|             if (parser.getEventType() != XmlPullParser.START_TAG) { | ||||
|                 continue; | ||||
| @ -194,6 +197,7 @@ public class ShareXMLParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Parse Meta node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
| @ -225,6 +229,7 @@ public class ShareXMLParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Parse Data node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @return | ||||
|      * @throws XmlPullParserException | ||||
| @ -276,9 +281,9 @@ public class ShareXMLParser { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Parse Element node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @return | ||||
|      * @throws XmlPullParserException | ||||
| @ -384,14 +389,15 @@ public class ShareXMLParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Parse a node, to obtain its text. Needs readText method | ||||
|      * | ||||
|      * @param parser | ||||
|      * @param node | ||||
|      * @return Text of the node | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|      */ | ||||
| 	private String readNode (XmlPullParser parser, String node) throws XmlPullParserException, | ||||
| 			IOException{ | ||||
|     private String readNode(XmlPullParser parser, String node) throws XmlPullParserException, | ||||
|             IOException { | ||||
|         parser.require(XmlPullParser.START_TAG, ns, node); | ||||
|         String value = readText(parser); | ||||
|         //Log_OC.d(TAG, "node= " + node + ", value= " + value); | ||||
| @ -401,6 +407,7 @@ public class ShareXMLParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Read the text from a node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @return Text of the node | ||||
|      * @throws IOException | ||||
| @ -417,6 +424,7 @@ public class ShareXMLParser { | ||||
| 
 | ||||
|     /** | ||||
|      * Skip tags in parser procedure | ||||
|      * | ||||
|      * @param parser | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|  | ||||
| @ -33,6 +33,7 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.PutMethod; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import okhttp3.FormBody; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.text.DateFormat; | ||||
| @ -40,11 +41,9 @@ import java.text.SimpleDateFormat; | ||||
| import java.util.Calendar; | ||||
| import java.util.Locale; | ||||
| 
 | ||||
| import okhttp3.FormBody; | ||||
| 
 | ||||
| /** | ||||
|  * Updates parameters of an existing Share resource, known its remote ID. | ||||
|  * | ||||
|  * <p> | ||||
|  * Allow updating several parameters, triggering a request to the server per parameter. | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
| @ -64,7 +63,6 @@ public class UpdateRemoteShareOperation extends RemoteOperation<ShareParserResul | ||||
|     private static final String ENTITY_CONTENT_TYPE = "application/x-www-form-urlencoded"; | ||||
|     private static final String ENTITY_CHARSET = "UTF-8"; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Identifier of the share to update | ||||
|      */ | ||||
| @ -91,7 +89,6 @@ public class UpdateRemoteShareOperation extends RemoteOperation<ShareParserResul | ||||
|     private Boolean mPublicUpload; | ||||
|     private String mName; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor. No update is initialized by default, need to be applied with setters below. | ||||
|      * | ||||
| @ -105,7 +102,6 @@ public class UpdateRemoteShareOperation extends RemoteOperation<ShareParserResul | ||||
|         mPermissions = OCShare.DEFAULT_PERMISSION; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set name to update in Share resource. Ignored by servers previous to version 10.0.0 | ||||
|      * | ||||
| @ -128,7 +124,6 @@ public class UpdateRemoteShareOperation extends RemoteOperation<ShareParserResul | ||||
|         mPassword = password; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set expiration date to update in Share resource. | ||||
|      * | ||||
| @ -141,7 +136,6 @@ public class UpdateRemoteShareOperation extends RemoteOperation<ShareParserResul | ||||
|         mExpirationDateInMillis = expirationDateInMillis; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set permissions to update in Share resource. | ||||
|      * | ||||
|  | ||||
| @ -31,25 +31,18 @@ package com.owncloud.android.lib.resources.status; | ||||
|  * 1 - True | ||||
|  */ | ||||
| public enum CapabilityBooleanType { | ||||
|     UNKNOWN (-1), | ||||
|     FALSE (0), | ||||
|     TRUE (1); | ||||
|     UNKNOWN(-1), | ||||
|     FALSE(0), | ||||
|     TRUE(1); | ||||
| 
 | ||||
|     private int value; | ||||
| 
 | ||||
|     CapabilityBooleanType(int value) | ||||
|     { | ||||
|     CapabilityBooleanType(int value) { | ||||
|         this.value = value; | ||||
|     } | ||||
| 
 | ||||
|     public int getValue() { | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
|     public static CapabilityBooleanType fromValue(int value) | ||||
|     { | ||||
|         switch (value) | ||||
|         { | ||||
|     public static CapabilityBooleanType fromValue(int value) { | ||||
|         switch (value) { | ||||
|             case -1: | ||||
|                 return UNKNOWN; | ||||
|             case 0: | ||||
| @ -60,23 +53,27 @@ public enum CapabilityBooleanType { | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     public static CapabilityBooleanType fromBooleanValue(boolean boolValue){ | ||||
|         if (boolValue){ | ||||
|     public static CapabilityBooleanType fromBooleanValue(boolean boolValue) { | ||||
|         if (boolValue) { | ||||
|             return TRUE; | ||||
|         } else { | ||||
|             return FALSE; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public boolean isUnknown(){ | ||||
|     public int getValue() { | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isUnknown() { | ||||
|         return getValue() == -1; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isFalse(){ | ||||
|     public boolean isFalse() { | ||||
|         return getValue() == 0; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isTrue(){ | ||||
|     public boolean isTrue() { | ||||
|         return getValue() == 1; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -24,7 +24,6 @@ | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.status; | ||||
| 
 | ||||
| import android.net.Uri; | ||||
| @ -35,7 +34,6 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| @ -109,10 +107,8 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation<OCCapability | ||||
|     private static final String PROPERTY_UNDELETE = "undelete"; | ||||
|     private static final String PROPERTY_VERSIONING = "versioning"; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor | ||||
|      * | ||||
|      */ | ||||
|     public GetRemoteCapabilitiesOperation() { | ||||
| 
 | ||||
| @ -135,7 +131,7 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation<OCCapability | ||||
|             int status = client.executeHttpMethod(getMethod); | ||||
| 
 | ||||
|             String response = getMethod.getResponseBodyAsString(); | ||||
|             if(isSuccess(status)) { | ||||
|             if (isSuccess(status)) { | ||||
|                 Log_OC.d(TAG, "Successful response: " + response); | ||||
| 
 | ||||
|                 // Parse the response | ||||
| @ -185,12 +181,12 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation<OCCapability | ||||
|                                 JSONObject respPublic = respFilesSharing.getJSONObject(NODE_PUBLIC); | ||||
|                                 capability.setFilesSharingPublicEnabled(CapabilityBooleanType.fromBooleanValue( | ||||
|                                         respPublic.getBoolean(PROPERTY_ENABLED))); | ||||
|                                 if(respPublic.has(NODE_PASSWORD)) { | ||||
|                                 if (respPublic.has(NODE_PASSWORD)) { | ||||
|                                     capability.setFilesSharingPublicPasswordEnforced( | ||||
|                                             CapabilityBooleanType.fromBooleanValue( | ||||
|                                                     respPublic.getJSONObject(NODE_PASSWORD).getBoolean(PROPERTY_ENFORCED))); | ||||
|                                 } | ||||
|                                 if(respPublic.has(NODE_EXPIRE_DATE)){ | ||||
|                                 if (respPublic.has(NODE_EXPIRE_DATE)) { | ||||
|                                     JSONObject respExpireDate = respPublic.getJSONObject(NODE_EXPIRE_DATE); | ||||
|                                     capability.setFilesSharingPublicExpireDateEnabled( | ||||
|                                             CapabilityBooleanType.fromBooleanValue( | ||||
| @ -205,7 +201,7 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation<OCCapability | ||||
|                                                         respExpireDate.getBoolean(PROPERTY_ENFORCED))); | ||||
|                                     } | ||||
|                                 } | ||||
|                                 if (respPublic.has(PROPERTY_UPLOAD)){ | ||||
|                                 if (respPublic.has(PROPERTY_UPLOAD)) { | ||||
|                                     capability.setFilesSharingPublicUpload(CapabilityBooleanType.fromBooleanValue( | ||||
|                                             respPublic.getBoolean(PROPERTY_UPLOAD))); | ||||
|                                 } | ||||
| @ -237,7 +233,6 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation<OCCapability | ||||
|                             Log_OC.d(TAG, "*** Added " + NODE_FILES_SHARING); | ||||
|                         } | ||||
| 
 | ||||
| 
 | ||||
|                         if (respCapabilities.has(NODE_FILES)) { | ||||
|                             JSONObject respFiles = respCapabilities.getJSONObject(NODE_FILES); | ||||
|                             // Add files | ||||
|  | ||||
| @ -34,13 +34,12 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| import javax.net.ssl.SSLException; | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| import javax.net.ssl.SSLException; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; | ||||
| 
 | ||||
|  | ||||
| @ -101,7 +101,6 @@ public class OCCapability { | ||||
|         mFilesVersioning = CapabilityBooleanType.UNKNOWN; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     // Getters and Setters | ||||
|     public String getAccountName() { | ||||
|         return mAccountName; | ||||
| @ -159,7 +158,6 @@ public class OCCapability { | ||||
|         this.mVersionEdition = versionEdition; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public int getCorePollinterval() { | ||||
|         return mCorePollinterval; | ||||
|     } | ||||
| @ -216,7 +214,6 @@ public class OCCapability { | ||||
|         this.mFilesSharingPublicExpireDateEnforced = filesSharingPublicExpireDateEnforced; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public CapabilityBooleanType getFilesSharingPublicSendMail() { | ||||
|         return mFilesSharingPublicSendMail; | ||||
|     } | ||||
|  | ||||
| @ -139,7 +139,6 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> { | ||||
|         return versionValue; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public boolean isChunkedUploadSupported() { | ||||
|         return (mVersion >= MINIMUN_VERSION_FOR_CHUNKED_UPLOADS); | ||||
|     } | ||||
|  | ||||
| @ -43,6 +43,7 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
| 
 | ||||
| /** | ||||
|  * Gets avatar about the user logged in, if available | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| @ -52,7 +53,9 @@ public class GetRemoteUserAvatarOperation extends RemoteOperation<GetRemoteUserA | ||||
| 
 | ||||
|     private static final String NON_OFFICIAL_AVATAR_PATH = "/index.php/avatar/"; | ||||
| 
 | ||||
|     /** Desired size in pixels of the squared image */ | ||||
|     /** | ||||
|      * Desired size in pixels of the squared image | ||||
|      */ | ||||
|     private int mDimension; | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -30,7 +30,6 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| import java.net.URL; | ||||
|  | ||||
| @ -27,6 +27,9 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.users; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Property; | ||||
| import at.bitfire.dav4android.property.QuotaAvailableBytes; | ||||
| import at.bitfire.dav4android.property.QuotaUsedBytes; | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.webdav.DavUtils; | ||||
| @ -39,10 +42,6 @@ import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import java.net.URL; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Property; | ||||
| import at.bitfire.dav4android.property.QuotaAvailableBytes; | ||||
| import at.bitfire.dav4android.property.QuotaUsedBytes; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.http.methods.webdav.DavConstants.DEPTH_0; | ||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; | ||||
| 
 | ||||
| @ -52,26 +51,7 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
|  */ | ||||
| public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQuotaOperation.RemoteQuota> { | ||||
| 
 | ||||
|     static public class RemoteQuota { | ||||
| 
 | ||||
|         long mFree, mUsed, mTotal; | ||||
|         double mRelative; | ||||
| 
 | ||||
|         public RemoteQuota(long free, long used, long total, double relative) { | ||||
|             mFree = free; | ||||
|             mUsed = used; | ||||
|             mTotal = total; | ||||
|             mRelative = relative; | ||||
|         } | ||||
| 
 | ||||
|         public long getFree() { return mFree; } | ||||
|         public long getUsed() { return mUsed; } | ||||
|         public long getTotal() { return mTotal; } | ||||
|         public double getRelative() { return mRelative; } | ||||
|     } | ||||
| 
 | ||||
|     private static final String TAG = GetRemoteUserQuotaOperation.class.getSimpleName(); | ||||
| 
 | ||||
|     private String mRemotePath; | ||||
| 
 | ||||
|     /** | ||||
| @ -112,7 +92,6 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQu | ||||
|         } catch (Exception e) { | ||||
|             result = new RemoteOperationResult<>(e); | ||||
| 
 | ||||
| 
 | ||||
|         } finally { | ||||
|             if (result.isSuccess()) { | ||||
|                 Log_OC.i(TAG, "Get quota from " + mRemotePath + ": " + result.getLogMessage()); | ||||
| @ -143,12 +122,14 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQu | ||||
|         long quotaAvailable = 0; | ||||
|         long quotaUsed = 0; | ||||
| 
 | ||||
|         for(Property property : properties) { | ||||
|             if(property instanceof QuotaAvailableBytes) | ||||
|         for (Property property : properties) { | ||||
|             if (property instanceof QuotaAvailableBytes) { | ||||
|                 quotaAvailable = ((QuotaAvailableBytes) property).getQuotaAvailableBytes(); | ||||
|             if(property instanceof QuotaUsedBytes) | ||||
|             } | ||||
|             if (property instanceof QuotaUsedBytes) { | ||||
|                 quotaUsed = ((QuotaUsedBytes) property).getQuotaUsedBytes(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // If there's a special case, quota available will contain a negative code | ||||
|         // -1, PENDING: Not computed yet, e.g. external storage mounted but folder sizes need scanning | ||||
| @ -163,8 +144,8 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQu | ||||
|             ); | ||||
|         } else { | ||||
|             long totalQuota = quotaAvailable + quotaUsed; | ||||
|             double relativeQuota = (double)(quotaUsed * 100)/totalQuota; | ||||
|             double roundedRelativeQuota = Math.round(relativeQuota * 100)/100.0d; | ||||
|             double relativeQuota = (double) (quotaUsed * 100) / totalQuota; | ||||
|             double roundedRelativeQuota = Math.round(relativeQuota * 100) / 100.0d; | ||||
| 
 | ||||
|             return new RemoteQuota( | ||||
|                     quotaAvailable, | ||||
| @ -174,4 +155,33 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQu | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     static public class RemoteQuota { | ||||
| 
 | ||||
|         long mFree, mUsed, mTotal; | ||||
|         double mRelative; | ||||
| 
 | ||||
|         public RemoteQuota(long free, long used, long total, double relative) { | ||||
|             mFree = free; | ||||
|             mUsed = used; | ||||
|             mTotal = total; | ||||
|             mRelative = relative; | ||||
|         } | ||||
| 
 | ||||
|         public long getFree() { | ||||
|             return mFree; | ||||
|         } | ||||
| 
 | ||||
|         public long getUsed() { | ||||
|             return mUsed; | ||||
|         } | ||||
| 
 | ||||
|         public long getTotal() { | ||||
|             return mTotal; | ||||
|         } | ||||
| 
 | ||||
|         public double getRelative() { | ||||
|             return mRelative; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -23,12 +23,12 @@ | ||||
| 
 | ||||
|  --> | ||||
| 
 | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|           package="com.owncloud.android.lib.sampleclient" | ||||
| <manifest package="com.owncloud.android.lib.sampleclient" | ||||
|     xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:versionCode="1" | ||||
|     android:versionName="1.0"> | ||||
| 
 | ||||
|     <uses-permission android:name="android.permission.INTERNET"/> | ||||
|     <uses-permission android:name="android.permission.INTERNET" /> | ||||
|     <application | ||||
|         android:icon="@drawable/ic_launcher" | ||||
|         android:label="@string/app_name"> | ||||
| @ -39,8 +39,8 @@ | ||||
|             android:screenOrientation="portrait" | ||||
|             > | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.MAIN"/> | ||||
|                 <category android:name="android.intent.category.LAUNCHER"/> | ||||
|                 <action android:name="android.intent.action.MAIN" /> | ||||
|                 <category android:name="android.intent.category.LAUNCHER" /> | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
|     </application> | ||||
|  | ||||
| @ -38,7 +38,7 @@ public class FilesArrayAdapter extends ArrayAdapter<RemoteFile> { | ||||
|     } | ||||
| 
 | ||||
|     public View getView(int position, View convertView, ViewGroup parent) { | ||||
| 		TextView textView = (TextView)super.getView(position, convertView, parent); | ||||
|         TextView textView = (TextView) super.getView(position, convertView, parent); | ||||
|         textView.setText(getItem(position).getRemotePath()); | ||||
|         return textView; | ||||
|     } | ||||
|  | ||||
| @ -74,7 +74,9 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, | ||||
|     private FilesArrayAdapter mFilesAdapter; | ||||
|     private View mFrame; | ||||
| 
 | ||||
|     /** Called when the activity is first created. */ | ||||
|     /** | ||||
|      * Called when the activity is first created. | ||||
|      */ | ||||
|     @Override | ||||
|     public void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
| @ -95,7 +97,7 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, | ||||
|         ); | ||||
| 
 | ||||
|         mFilesAdapter = new FilesArrayAdapter(this, R.layout.file_in_list); | ||||
|     	((ListView)findViewById(R.id.list_view)).setAdapter(mFilesAdapter); | ||||
|         ((ListView) findViewById(R.id.list_view)).setAdapter(mFilesAdapter); | ||||
| 
 | ||||
|         // TODO move to background thread or task | ||||
|         AssetManager assets = getAssets(); | ||||
| @ -121,7 +123,6 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, | ||||
|         mFrame = findViewById(R.id.frame); | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     @Override | ||||
|     public void onDestroy() { | ||||
|         File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path)); | ||||
| @ -131,7 +132,6 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, | ||||
|         super.onDestroy(); | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     public void onClickHandler(View button) { | ||||
|         switch (button.getId()) { | ||||
|             case R.id.button_refresh: | ||||
| @ -166,7 +166,7 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, | ||||
|         String mimeType = getString(R.string.sample_file_mimetype); | ||||
| 
 | ||||
|         // Get the last modification date of the file from the file system | ||||
| 		Long timeStampLong = fileToUpload.lastModified()/1000; | ||||
|         Long timeStampLong = fileToUpload.lastModified() / 1000; | ||||
|         String timeStamp = timeStampLong.toString(); | ||||
| 
 | ||||
|         UploadRemoteFileOperation uploadOperation = new UploadRemoteFileOperation(fileToUpload.getAbsolutePath(), | ||||
| @ -215,15 +215,15 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, | ||||
|             Log.e(LOG_TAG, result.getLogMessage(), result.getException()); | ||||
| 
 | ||||
|         } else if (operation instanceof ReadRemoteFolderOperation) { | ||||
| 			onSuccessfulRefresh((ReadRemoteFolderOperation)operation, result); | ||||
|             onSuccessfulRefresh((ReadRemoteFolderOperation) operation, result); | ||||
| 
 | ||||
|         } else if (operation instanceof com.owncloud.android.lib.resources.files.UploadRemoteFileOperation) { | ||||
| 			onSuccessfulUpload((com.owncloud.android.lib.resources.files.UploadRemoteFileOperation)operation, result); | ||||
|             onSuccessfulUpload((com.owncloud.android.lib.resources.files.UploadRemoteFileOperation) operation, result); | ||||
| 
 | ||||
| 		} else if (operation instanceof RemoveRemoteFileOperation ) { | ||||
| 			onSuccessfulRemoteDeletion((RemoveRemoteFileOperation)operation, result); | ||||
|         } else if (operation instanceof RemoveRemoteFileOperation) { | ||||
|             onSuccessfulRemoteDeletion((RemoveRemoteFileOperation) operation, result); | ||||
| 
 | ||||
| 		} else if (operation instanceof DownloadRemoteFileOperation ) { | ||||
|         } else if (operation instanceof DownloadRemoteFileOperation) { | ||||
|             onSuccessfulDownload(); | ||||
| 
 | ||||
|         } else { | ||||
| @ -234,7 +234,7 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, | ||||
|     private void onSuccessfulRefresh(ReadRemoteFolderOperation operation, RemoteOperationResult result) { | ||||
|         mFilesAdapter.clear(); | ||||
|         List<RemoteFile> files = new ArrayList<>(); | ||||
|         for(RemoteFile remoteFile: (List<RemoteFile>) result.getData()) { | ||||
|         for (RemoteFile remoteFile : (List<RemoteFile>) result.getData()) { | ||||
|             files.add(remoteFile); | ||||
|         } | ||||
|         if (files != null) { | ||||
|  | ||||
| @ -26,4 +26,4 @@ | ||||
| <TextView xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="wrap_content" | ||||
| /> | ||||
|     /> | ||||
|  | ||||
| @ -33,58 +33,58 @@ | ||||
|         style="@style/ButtonStyle" | ||||
|         android:layout_alignParentLeft="true" | ||||
|         android:layout_alignParentTop="true" | ||||
|         android:text="@string/refresh" | ||||
|         android:onClick="onClickHandler" | ||||
|         android:text="@string/refresh" | ||||
|         /> | ||||
| 
 | ||||
|     <ListView | ||||
|         android:id="@+id/list_view" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
| 		android:layout_below="@+id/button_refresh" | ||||
|         android:layout_above="@+id/button_upload" | ||||
|         android:layout_alignParentLeft="true" | ||||
|         android:layout_alignParentRight="true" | ||||
|         android:layout_below="@+id/button_refresh" | ||||
|         > | ||||
|     </ListView> | ||||
| 
 | ||||
|     <Button | ||||
|         android:id="@+id/button_upload" | ||||
|         style="@style/ButtonStyle" | ||||
|         android:layout_alignParentLeft="true" | ||||
|         android:layout_above="@+id/frame" | ||||
|         android:text="@string/upload" | ||||
|         android:layout_alignParentLeft="true" | ||||
|         android:onClick="onClickHandler" | ||||
|         android:text="@string/upload" | ||||
|         /> | ||||
| 
 | ||||
|     <TextView | ||||
|         android:id="@+id/upload_progress" | ||||
|         style="@style/ProgressStyle" | ||||
|         android:layout_below="@id/list_view" | ||||
|         android:layout_above="@id/frame" | ||||
|         android:layout_toRightOf="@id/button_upload" | ||||
|         android:layout_below="@id/list_view" | ||||
|         android:layout_toLeftOf="@+id/button_delete_remote" | ||||
|         android:layout_toRightOf="@id/button_upload" | ||||
|         android:gravity="center" | ||||
|         android:textSize="14sp" | ||||
|         android:text="0%" | ||||
|         android:textSize="14sp" | ||||
|         /> | ||||
| 
 | ||||
|     <Button | ||||
|         android:id="@id/button_delete_remote" | ||||
|         style="@style/ButtonStyle" | ||||
|         android:layout_alignParentRight="true" | ||||
|         android:layout_above="@id/frame" | ||||
|         android:text="@string/delete_remote_file" | ||||
|         android:layout_alignParentRight="true" | ||||
|         android:onClick="onClickHandler" | ||||
|         android:text="@string/delete_remote_file" | ||||
|         /> | ||||
| 
 | ||||
|     <FrameLayout | ||||
|         android:id="@id/frame" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="@dimen/frame_height" | ||||
|         android:layout_above="@+id/button_download" | ||||
|         android:layout_alignParentLeft="true" | ||||
|         android:layout_alignParentRight="true" | ||||
|         android:layout_above="@+id/button_download" | ||||
|         > | ||||
|     </FrameLayout> | ||||
| 
 | ||||
| @ -93,20 +93,20 @@ | ||||
|         style="@style/ButtonStyle" | ||||
|         android:layout_alignParentBottom="true" | ||||
|         android:layout_alignParentLeft="true" | ||||
|         android:text="@string/download" | ||||
|         android:onClick="onClickHandler" | ||||
|         android:text="@string/download" | ||||
|         /> | ||||
| 
 | ||||
|     <TextView | ||||
|         android:id="@+id/download_progress" | ||||
|         style="@style/ProgressStyle" | ||||
|         android:layout_below="@id/frame" | ||||
|         android:layout_alignParentBottom="true" | ||||
|         android:layout_toRightOf="@id/button_download" | ||||
|         android:layout_below="@id/frame" | ||||
|         android:layout_toLeftOf="@+id/button_delete_local" | ||||
|         android:layout_toRightOf="@id/button_download" | ||||
|         android:gravity="center" | ||||
|         android:textSize="14sp" | ||||
|         android:text="0%" | ||||
|         android:textSize="14sp" | ||||
|         /> | ||||
| 
 | ||||
|     <Button | ||||
| @ -114,8 +114,8 @@ | ||||
|         style="@style/ButtonStyle" | ||||
|         android:layout_alignParentBottom="true" | ||||
|         android:layout_alignParentRight="true" | ||||
|         android:text="@string/delete_local_file" | ||||
|         android:onClick="onClickHandler" | ||||
|         android:text="@string/delete_local_file" | ||||
|         /> | ||||
| 
 | ||||
| </RelativeLayout> | ||||
|  | ||||
| @ -24,11 +24,13 @@ | ||||
|  --> | ||||
| 
 | ||||
| <resources xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
| 
 | ||||
|     <style name="ButtonStyle" parent="@android:style/Widget.Holo.Button"> | ||||
|         <item name="android:layout_width">120dp</item> | ||||
|         <item name="android:layout_height">wrap_content</item> | ||||
|         <item name="android:textSize">12sp</item> | ||||
|     </style> | ||||
| 
 | ||||
|     <style name="ProgressStyle" parent="@android:style/Widget.Holo.TextView"> | ||||
|         <item name="android:layout_width">wrap_content</item> | ||||
|         <item name="android:layout_height">wrap_content</item> | ||||
|  | ||||
| @ -26,5 +26,5 @@ | ||||
|     <string name="server_base_url"></string> | ||||
|     <string name="username"></string> | ||||
|     <string name="password"></string> | ||||
|     <string name ="user_agent">Mozilla/5.0 (Android) ownCloud sample </string> | ||||
|     <string name="user_agent">Mozilla/5.0 (Android) ownCloud sample </string> | ||||
| </resources> | ||||
| @ -24,11 +24,13 @@ | ||||
|  --> | ||||
| 
 | ||||
| <resources xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
| 
 | ||||
|     <style name="ButtonStyle" parent="@android:style/Widget.Button"> | ||||
|         <item name="android:layout_width">120dp</item> | ||||
|         <item name="android:layout_height">wrap_content</item> | ||||
|         <item name="android:textSize">12sp</item> | ||||
|     </style> | ||||
| 
 | ||||
|     <style name="ProgressStyle" parent="@android:style/Widget.TextView"> | ||||
|         <item name="android:layout_width">wrap_content</item> | ||||
|         <item name="android:layout_height">wrap_content</item> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user