Преглед на файлове

Merge branch 'master' of https://github.com/nextcloud/android into integration-with-master

# Conflicts:
#	src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java
#	src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java
#	src/main/res/values-en-rGB/strings.xml
AndyScherzinger преди 8 години
родител
ревизия
de825e2238
променени са 100 файла, в които са добавени 2211 реда и са изтрити 2081 реда
  1. 5 5
      .drone.yml
  2. 1 0
      .gitignore
  3. 2 2
      .tx/config
  4. 10 0
      CHANGELOG.md
  5. 6 6
      CONTRIBUTING.md
  6. 99 0
      ICONS.txt
  7. 1 1
      README.md
  8. 12 3
      SETUP.md
  9. 2 2
      androidTest/java/com/owncloud/android/datamodel/OCFileUnitTest.java
  10. 1 1
      automationTest/src/test/java/com/owncloud/android/test/ui/models/FileListView.java
  11. 104 77
      build.gradle
  12. 74 0
      drawable_resources/alphabetical_asc.svg
  13. 69 0
      drawable_resources/alphabetical_desc.svg
  14. 1 0
      drawable_resources/arrow-right.svg
  15. 1 0
      drawable_resources/calendar.svg
  16. 119 0
      drawable_resources/get_it_as_apk.svg
  17. 58 0
      drawable_resources/ic_activity.svg
  18. 58 0
      drawable_resources/ic_activity_light_grey.svg
  19. 56 0
      drawable_resources/ic_list_empty_error.svg
  20. 62 0
      drawable_resources/ic_list_empty_home.svg
  21. 58 0
      drawable_resources/ic_list_empty_image.svg
  22. 62 0
      drawable_resources/ic_list_empty_recent.svg
  23. 56 0
      drawable_resources/ic_list_empty_shared.svg
  24. 58 0
      drawable_resources/ic_list_empty_video.svg
  25. 58 0
      drawable_resources/ic_search_light_blue.svg
  26. 58 0
      drawable_resources/ic_search_light_grey.svg
  27. 57 0
      drawable_resources/ic_star_light_grey.svg
  28. 1 0
      drawable_resources/ic_twitter.svg
  29. 1 0
      drawable_resources/ic_web.svg
  30. 64 0
      drawable_resources/modification_asc.svg
  31. 63 0
      drawable_resources/modification_desc.svg
  32. 77 0
      drawable_resources/size_asc.svg
  33. 76 0
      drawable_resources/size_desc.svg
  34. 2 2
      gradle/wrapper/gradle-wrapper.properties
  35. BIN
      res/drawable/ic_synced.png
  36. 0 316
      res/values-da/strings.xml
  37. 0 425
      res/values-es-rMX/strings.xml
  38. 5 0
      res/xml/backup_config.xml
  39. 0 93
      src/com/owncloud/android/services/SyncedFolderJobService.java
  40. 0 78
      src/com/owncloud/android/services/observer/SyncedFolderObserver.java
  41. 0 84
      src/com/owncloud/android/services/observer/SyncedFolderObserverService.java
  42. 0 27
      src/com/owncloud/android/ui/fragment/AuthenticatorAccountDetailsFragment.java
  43. 0 27
      src/com/owncloud/android/ui/fragment/AuthenticatorGetStartedFragment.java
  44. 0 525
      src/com/owncloud/android/ui/fragment/ExtendedListFragment.java
  45. 0 109
      src/com/owncloud/android/utils/RecursiveFileObserver.java
  46. 35 0
      src/generic/google-services.json
  47. 14 8
      src/main/AndroidManifest.xml
  48. 0 0
      src/main/java/com/afollestad/sectionedrecyclerview/SectionedRecyclerViewAdapter.java
  49. 98 42
      src/main/java/com/owncloud/android/MainApp.java
  50. 0 0
      src/main/java/com/owncloud/android/authentication/AccountAuthenticator.java
  51. 0 0
      src/main/java/com/owncloud/android/authentication/AccountAuthenticatorActivity.java
  52. 0 0
      src/main/java/com/owncloud/android/authentication/AccountAuthenticatorService.java
  53. 8 9
      src/main/java/com/owncloud/android/authentication/AccountUtils.java
  54. 331 169
      src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java
  55. 0 0
      src/main/java/com/owncloud/android/authentication/AuthenticatorAsyncTask.java
  56. 0 0
      src/main/java/com/owncloud/android/authentication/LoginUrlInfo.java
  57. 0 0
      src/main/java/com/owncloud/android/authentication/OAuth2Constants.java
  58. 0 0
      src/main/java/com/owncloud/android/authentication/PassCodeManager.java
  59. 0 0
      src/main/java/com/owncloud/android/authentication/SsoWebViewClient.java
  60. 9 5
      src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java
  61. 0 0
      src/main/java/com/owncloud/android/datamodel/MediaFolder.java
  62. 1 2
      src/main/java/com/owncloud/android/datamodel/MediaProvider.java
  63. 24 12
      src/main/java/com/owncloud/android/datamodel/OCFile.java
  64. 4 1
      src/main/java/com/owncloud/android/datamodel/SyncedFolder.java
  65. 8 0
      src/main/java/com/owncloud/android/datamodel/SyncedFolderDisplayItem.java
  66. 94 12
      src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java
  67. 0 0
      src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java
  68. 28 21
      src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java
  69. 0 0
      src/main/java/com/owncloud/android/datastorage/DataStorageProvider.java
  70. 0 0
      src/main/java/com/owncloud/android/datastorage/StoragePoint.java
  71. 0 0
      src/main/java/com/owncloud/android/datastorage/UniqueStorageList.java
  72. 0 0
      src/main/java/com/owncloud/android/datastorage/providers/AbstractCommandLineStoragePoint.java
  73. 0 0
      src/main/java/com/owncloud/android/datastorage/providers/AbstractStoragePointProvider.java
  74. 0 0
      src/main/java/com/owncloud/android/datastorage/providers/EnvironmentStoragePointProvider.java
  75. 0 0
      src/main/java/com/owncloud/android/datastorage/providers/HardcodedStoragePointProvider.java
  76. 0 0
      src/main/java/com/owncloud/android/datastorage/providers/IStoragePointProvider.java
  77. 0 0
      src/main/java/com/owncloud/android/datastorage/providers/MountCommandStoragePointProvider.java
  78. 0 0
      src/main/java/com/owncloud/android/datastorage/providers/SystemDefaultStoragePointProvider.java
  79. 0 0
      src/main/java/com/owncloud/android/datastorage/providers/VDCStoragePointProvider.java
  80. 0 0
      src/main/java/com/owncloud/android/db/OCUpload.java
  81. 46 2
      src/main/java/com/owncloud/android/db/PreferenceManager.java
  82. 2 1
      src/main/java/com/owncloud/android/db/ProviderMeta.java
  83. 0 0
      src/main/java/com/owncloud/android/db/UploadResult.java
  84. 0 0
      src/main/java/com/owncloud/android/features/FeatureList.java
  85. 3 3
      src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java
  86. 43 10
      src/main/java/com/owncloud/android/files/FileMenuFilter.java
  87. 1 1
      src/main/java/com/owncloud/android/files/InstantUploadBroadcastReceiver.java
  88. 0 0
      src/main/java/com/owncloud/android/files/services/ConnectivityActionReceiver.java
  89. 11 0
      src/main/java/com/owncloud/android/files/services/FileDownloader.java
  90. 14 0
      src/main/java/com/owncloud/android/files/services/FileUploader.java
  91. 0 0
      src/main/java/com/owncloud/android/files/services/IndexedForest.java
  92. 0 0
      src/main/java/com/owncloud/android/media/MediaControlView.java
  93. 0 0
      src/main/java/com/owncloud/android/media/MediaService.java
  94. 0 0
      src/main/java/com/owncloud/android/media/MediaServiceBinder.java
  95. 0 0
      src/main/java/com/owncloud/android/operations/CheckCurrentCredentialsOperation.java
  96. 0 0
      src/main/java/com/owncloud/android/operations/CopyFileOperation.java
  97. 0 0
      src/main/java/com/owncloud/android/operations/CreateFolderOperation.java
  98. 0 0
      src/main/java/com/owncloud/android/operations/CreateShareViaLinkOperation.java
  99. 0 0
      src/main/java/com/owncloud/android/operations/CreateShareWithShareeOperation.java
  100. 0 0
      src/main/java/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java

+ 5 - 5
.drone.yml

@@ -1,19 +1,19 @@
 pipeline:
   test:
-    image: nextcloudci/android:android-7
+    image: nextcloudci/android:android-15
     commands:
       - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI -c 20M
       - emulator -avd test -no-window &
       - ./wait_for_emulator.sh
       # build app and assemble APK, in debug mode
       - ./gradlew assembleDebug
-      # run all the local unit tests of app module
-      - ./gradlew :testDebug
       # run all the instrumented tests of app module - DISABLED until we get an stable setup for Espresso in Travis
       # - ./gradlew connectedDebugAndroidTest --info
       # install app, then assemble and install instrumented tests of app module
-      - ./gradlew :installDebug
-      - ./gradlew :installDebugAndroidTest
+      - ./gradlew :installGenericDebug
+      - ./gradlew :installModifiedDebug
+      - ./gradlew :installGenericDebugAndroidTest
+      - ./gradlew :installModifiedDebugAndroidTest
       # run sample instrumented unit test
       # TODO fails because test runner is not available
       #- adb shell am instrument -w -e debug false -e class com.owncloud.android.datamodel.OCFileUnitTest com.owncloud.android.test/android.support.test.runner.AndroidJUnitRunner

+ 1 - 0
.gitignore

@@ -33,3 +33,4 @@ tests/proguard-project.txt
 *.iml
 build
 /gradle.properties
+

Файловите разлики са ограничени, защото са твърде много
+ 2 - 2
.tx/config


+ 10 - 0
CHANGELOG.md

@@ -1,3 +1,13 @@
+## 1.4.2 (March 14, 2017)
+- Auto Upload for newly taken photos/images (Android 6+)
+- Auto Upload improvements and fixes
+- Filtering improvements
+- Fix for Android permissions (removed read phone state permission)
+- Fix re-upload of files
+- Avoid toggling favourite for all selected files
+- Link to providers list in the setup screen
+- further bugfixes and improvements
+
 ## 1.4.1 (January 27, 2017)
 - Share URLs to Nextcloud
 - Improve performance of Auto Upload view

+ 6 - 6
CONTRIBUTING.md

@@ -128,9 +128,9 @@ _stable beta_ releases done via the Beta program of the Google Play store and f-
 Whenever a PR is reviewed/approved we put it on master.
 Before releasing a new stable version there is at least one release candidate. It is based on the current master and during this phase the master is feature freezed. After ~2 weeks with no error a stable version will be releaded, which is identically to the latest release candidate. 
 
-### Development Beta
+### Nightly
 Done as a standalone app that can be installed in parallel to the stable app.
-Any PR which is labelled "ready for beta" will be automatically included in the beta app. This label should only set by the main developers. 
+Any PR which is labelled "ready for nightly" will be automatically included in the nightly app. This label should only set by the main developers. 
 Same applies for the android-library. This repository also has a branch called beta which includes all upcoming features. The beta branch on this repository must always use the android-library beta branch.
 
 ## Version Name and number
@@ -151,8 +151,8 @@ Examples for different versions:
 
 beware, that beta releases for an upcoming version will always use the minor and hotfix version of the release they are targeting. So to make sure the version code of the upcoming stable release will always be higher stable releases set the 2 beta digits to '99' as seen above in the examples.
 
-### Development Beta
-For development beta the version name is in format YYYYMMDD. It is mainly as a reference for reporting bugs and is not related to stable/release candidates as it is an independent app.
+### Nightly
+For nightly the version name is in format YYYYMMDD. It is mainly as a reference for reporting bugs and is not related to stable/release candidates as it is an independent app.
 
 ## Release cycle
 * for each release we choose several PRs that will be included in the next release. Currently there are many open PRs from ownCloud, but after merging them, the intention is to choose the PRs that are ready (reviewed, tested) to get them merged very soon.
@@ -180,7 +180,7 @@ Release Candidate releases are based on the git [master](https://github.com/next
 2. Create a [release/tag](https://github.com/nextcloud/android/releases) in git. Tag name following the naming schema: ```rc-Mayor.Minor.Hotfix-betaIncrement``` (e.g. rc-1.2.0-12) naming the version number following the [semantic versioning schema](http://semver.org/)
 
 
-###Development Beta Release
-Beta releases are based on the git [beta](https://github.com/nextcloud/android/tree/beta) and are done independently from stable releases and integrate open PRs that might not be production ready or heavily tested but being put out there for people willing to test new features and provide valuable feedback on new features to be incorporated before a feature gets released in the stable app.
+### Nightly Release
+Nightly releases are based on the git [beta](https://github.com/nextcloud/android/tree/beta) and are done independently from stable releases and integrate open PRs that might not be production ready or heavily tested but being put out there for people willing to test new features and provide valuable feedback on new features to be incorporated before a feature gets released in the stable app.
 
 The deployment/build is done once a day automatically. If code has changed a new apk will be published on https://github.com/nextcloud/android/tree/beta/apks and it will also be available on f-droid.

+ 99 - 0
ICONS.txt

@@ -0,0 +1,99 @@
+Standard Google Material Design icons
+Copyright (c) 2014, Google (http://www.google.com/design/)
+uses the license at https://github.com/google/material-design-icons/blob/master/LICENSE
+
+Twitter icon graphic
+Copyright (c) 2014, Austin Andrews (http://materialdesignicons.com/),
+with Reserved Font Name Material Design Icons.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.

+ 1 - 1
README.md

@@ -29,7 +29,7 @@ if you want to join the Github organization just let us know and we’ll add you
 Make sure you read [SETUP.md](https://github.com/nextcloud/android/blob/master/SETUP.md) and [CONTRIBUTING.md](https://github.com/nextcloud/android/blob/master/CONTRIBUTING.md) when you start working on this project. Basically: Fork this repository and contribute back using pull requests to the master branch.
 Easy starting points are also reviewing [pull requests](https://github.com/nextcloud/android/pulls) and working on [starter issue](https://github.com/nextcloud/android/issues?q=is%3Aopen+is%3Aissue+label%3A%22starter+issue%22).
 
-**Beta version** [beta version](https://github.com/nextcloud/android/raw/beta/apks/latest.apk)
+**Nightly version** [nightly version](https://download.nextcloud.com/android/nightly/latest.apk)
 
 **License:** [GPLv2](https://github.com/nextcloud/android/blob/master/LICENSE.txt)
 

+ 12 - 3
SETUP.md

@@ -28,7 +28,7 @@ For other software dependencies check the details in the section corresponding t
 
 You will need [git][1] to access to the different versions of the Nextcloud's source code. The source code is hosted in Github and may be read by anybody without needing a Github account. You will need a Github account if you want to contribute to the development of the app with your own code.
 
-Next steps will assume you have a Github account and that you will get the code from your own fork. 
+Next steps will assume you have a Github account and that you will get the code from your own fork.
 
 * In a web browser, go to https://github.com/nextcloud/android, and click the 'Fork' button near the top right corner.
 * Open a terminal and go on with the next steps in it.
@@ -63,11 +63,20 @@ To set up the project in Android Studio follow the next steps:
 * Run the 'clean' and 'build' tasks using the Gradle wrapper provided
     - Windows: ```gradlew.bat clean build```
     - Mac OS/Linux: ```./gradlew clean build```
-	
+
 The first time the Gradle wrapper is called, the correct Gradle version will be downloaded automatically. An Internet connection is needed for it works.
-	
+
 The generated APK file is saved in android/build/outputs/apk as android-debug.apk
 
+### 4. App flavours
+
+The app is currently equipped to be built with two flavours:
+* generic - the regular build, released as a Nextcloud Android app on the Play store
+* custom - a customized build, to be used by people who need features we can't or
+  won't include into the traditional build (like Firebase Analytics)
+
+When building the *generic*, you will *not* get the dependencies imposed by the *custom*
+build.
 
 [0]: https://github.com/nextcloud/android/blob/master/CONTRIBUTING.md
 [1]: https://git-scm.com/

+ 2 - 2
androidTest/java/com/owncloud/android/datamodel/OCFileUnitTest.java

@@ -85,7 +85,7 @@ public class OCFileUnitTest {
         mFile.setModificationTimestampAtLastSyncForData(MODIFICATION_TIMESTAMP_AT_LAST_SYNC_FOR_DATA);
         mFile.setLastSyncDateForProperties(LAST_SYNC_DATE_FOR_PROPERTIES);
         mFile.setLastSyncDateForData(LAST_SYNC_DATE_FOR_DATA);
-        mFile.setFavorite(true);
+        mFile.setAvailableOffline(true);
         mFile.setEtag(ETAG);
         mFile.setShareViaLink(true);
         mFile.setShareWithSharee(true);
@@ -120,7 +120,7 @@ public class OCFileUnitTest {
         );
         assertThat(fileReadFromParcel.getLastSyncDateForProperties(), is(LAST_SYNC_DATE_FOR_PROPERTIES));
         assertThat(fileReadFromParcel.getLastSyncDateForData(), is(LAST_SYNC_DATE_FOR_DATA));
-        assertThat(fileReadFromParcel.isFavorite(), is(true));
+        assertThat(fileReadFromParcel.setAvailableOffline(), is(true));
         assertThat(fileReadFromParcel.getEtag(), is(ETAG));
         assertThat(fileReadFromParcel.isSharedViaLink(), is(true));
         assertThat(fileReadFromParcel.isSharedWithSharee(), is(true));

+ 1 - 1
automationTest/src/test/java/com/owncloud/android/test/ui/models/FileListView.java

@@ -89,7 +89,7 @@ public class FileListView {
 	private static String localFileIndicator = 
 			"com.owncloud.android:id/localFileIndicator";
 	private static String favoriteFileIndicator = 
-			"com.owncloud.android:id/favoriteIcon";
+			"com.owncloud.android:id/keptOfflineIcon";
 	private static String sharedElementIndicator = 
 			"com.owncloud.android:id/sharedIcon";
 	

+ 104 - 77
build.gradle

@@ -8,9 +8,13 @@
 buildscript {
     repositories {
         jcenter()
+        maven {
+            url 'https://oss.sonatype.org/content/repositories/snapshots/'
+        }
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.2.3'
+        classpath 'com.android.tools.build:gradle:2.3.0'
+        classpath 'com.google.gms:google-services:3.0.0'
     }
 }
 
@@ -19,8 +23,13 @@ apply plugin: 'checkstyle'
 apply plugin: 'pmd'
 apply plugin: 'findbugs'
 
+configurations.all {
+    // check for updates every build
+    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
+}
+
 ext {
-    supportLibraryVersion = '24.2.1'
+    supportLibraryVersion = '25.0.0'
 
     travisBuild = System.getenv("TRAVIS") == "true"
 
@@ -28,6 +37,11 @@ ext {
     preDexEnabled = "true".equals(System.getProperty("pre-dex", "true"))
 }
 
+configurations.all {
+    // Check for updates every build
+    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
+}
+
 repositories {
     jcenter()
     maven { url "https://jitpack.io" }
@@ -37,51 +51,6 @@ repositories {
     }
 }
 
-dependencies {
-    /// dependencies for app building
-    compile name: 'touch-image-view'
-
-    compile 'com.github.nextcloud:android-library:1.0.11'
-    compile "com.android.support:support-v4:${supportLibraryVersion}"
-    compile "com.android.support:design:${supportLibraryVersion}"
-    compile 'com.jakewharton:disklrucache:2.0.2'
-    compile "com.android.support:appcompat-v7:${supportLibraryVersion}"
-    compile 'com.getbase:floatingactionbutton:1.10.1'
-    compile 'com.google.code.findbugs:annotations:2.0.1'
-
-
-    /// dependencies for local unit tests
-    testCompile 'junit:junit:4.12'
-    testCompile 'org.mockito:mockito-core:1.10.19'
-
-    /// dependencies for instrumented tests
-    // JUnit4 Rules
-    androidTestCompile 'com.android.support.test:rules:0.5'
-
-    // Android JUnit Runner
-    androidTestCompile 'com.android.support.test:runner:0.5'
-
-    // Android Annotation Support
-    androidTestCompile "com.android.support:support-annotations:${supportLibraryVersion}"
-
-    // Espresso core
-    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
-
-    // UIAutomator - for cross-app UI tests, and to grant screen is turned on in Espresso tests
-    androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
-    // fix conflict in dependencies; see http://g.co/androidstudio/app-test-app-conflict for details
-    androidTestCompile "com.android.support:support-annotations:${supportLibraryVersion}"
-
-
-}
-
-tasks.withType(Test) {
-    /// increased logging for tests
-    testLogging {
-        events "passed", "skipped", "failed"
-    }
-}
-
 android {
     lintOptions {
         abortOnError true
@@ -89,8 +58,13 @@ android {
         htmlReport true
         htmlOutput file("$project.buildDir/reports/lint/lint.html")
     }
-    compileSdkVersion 24
-    buildToolsVersion "24.0.2"
+
+    dexOptions {
+        javaMaxHeapSize "4g"
+    }
+
+    compileSdkVersion 25
+    buildToolsVersion '25.0.0'
 
     defaultConfig {
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
@@ -100,40 +74,34 @@ android {
         testInstrumentationRunnerArgument "TEST_PASSWORD", "\"$System.env.OCTEST_APP_PASSWORD\""
         testInstrumentationRunnerArgument "TEST_SERVER_URL", "\"$System.env.OCTEST_SERVER_BASE_URL\""
 
-        applicationId "com.nextcloud.client"
-    }
+        multiDexEnabled true
 
-    // adapt structure from Eclipse to Gradle/Android Studio expectations;
-    // see http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Configuring-the-Structure
-    sourceSets {
-        main {
-            manifest.srcFile 'AndroidManifest.xml'
-            java.srcDirs = ['src']
-            resources.srcDirs = ['src']
-            aidl.srcDirs = ['src']
-            renderscript.srcDirs = ['src']
-            res.srcDirs = ['res']
-            assets.srcDirs = ['assets']
-        }
+        // adapt structure from Eclipse to Gradle/Android Studio expectations;
+        // see http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Configuring-the-Structure
 
+        productFlavors {
+            generic {
+                applicationId 'com.nextcloud.client'
+            }
+
+            modified {
+                // structure is:
+                // domain tld
+                // domain name
+                // .client
+                applicationId 'com.custom.client'
+            }
+        }
 
-        // move whole local unit tests structure as a whole from src/test/* to test/*
-        test.setRoot('test')
+        configurations {
+            modifiedCompile
+        }
+    }
 
-        // move whole instrumented tests structure as a whole from src/androidTest/* to androidTest/*
-        androidTest.setRoot('androidTest')
 
+    // adapt structure from Eclipse to Gradle/Android Studio expectations;
+    // see http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Configuring-the-Structure
 
-        // Move the build types to build-types/<type>
-        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
-        // This moves them out of them default location under src/<type>/... which would
-        // conflict with src/ being used by the main source set.
-        // Adding new build types or product flavors should be accompanied
-        // by a similar customization.
-        debug.setRoot('build-types/debug')
-        release.setRoot('build-types/release')
-    }
-	
     dexOptions {
         // Skip pre-dexing when running on Travis CI or when disabled via -Dpre-dex=false.
         preDexLibraries = preDexEnabled && !travisBuild
@@ -151,6 +119,7 @@ android {
     packagingOptions {
         exclude 'META-INF/LICENSE.txt'
     }
+
     task checkstyle(type: Checkstyle) {
         configFile = file("${rootProject.projectDir}/checkstyle.xml")
         configProperties.checkstyleSuppressionsPath = file("${project.rootDir}/config/quality/checkstyle/suppressions.xml").absolutePath
@@ -203,3 +172,61 @@ android {
     check.dependsOn 'checkstyle', 'findbugs', 'pmd', 'lint'
 
 }
+
+dependencies {
+    /// dependencies for app building
+    compile name: 'touch-image-view'
+    compile 'com.android.support:multidex:1.0.1'
+
+    compile 'com.github.nextcloud:android-library:1.0.14'
+    compile "com.android.support:support-v4:${supportLibraryVersion}"
+    compile "com.android.support:design:${supportLibraryVersion}"
+    compile 'com.jakewharton:disklrucache:2.0.2'
+    compile "com.android.support:appcompat-v7:${supportLibraryVersion}"
+    compile "com.android.support:cardview-v7:${supportLibraryVersion}"
+    compile 'com.getbase:floatingactionbutton:1.10.1'
+    compile 'com.google.code.findbugs:annotations:2.0.1'
+    compile group: 'commons-io', name: 'commons-io', version: '2.4'
+    compile 'com.google.android.gms:play-services:10.2.0'
+    compile 'com.github.evernote:android-job:v1.1.8'
+    compile 'com.jakewharton:butterknife:8.4.0'
+    annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
+    compile 'org.greenrobot:eventbus:3.0.0'
+
+    compile 'org.parceler:parceler-api:1.1.6'
+    annotationProcessor 'org.parceler:parceler:1.1.6'
+
+    compile 'com.github.bumptech.glide:glide:3.7.0'
+    compile 'com.caverock:androidsvg:1.2.1'
+    /// dependencies for local unit tests
+    testCompile 'junit:junit:4.12'
+    testCompile 'org.mockito:mockito-core:1.10.19'
+
+    /// dependencies for instrumented tests
+    // JUnit4 Rules
+    androidTestCompile 'com.android.support.test:rules:0.5'
+
+    // Android JUnit Runner
+    androidTestCompile 'com.android.support.test:runner:0.5'
+
+    // Android Annotation Support
+    androidTestCompile "com.android.support:support-annotations:${supportLibraryVersion}"
+
+    // Espresso core
+    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
+
+    // UIAutomator - for cross-app UI tests, and to grant screen is turned on in Espresso tests
+    //androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
+    // fix conflict in dependencies; see http://g.co/androidstudio/app-test-app-conflict for details
+    //androidTestCompile "com.android.support:support-annotations:${supportLibraryVersion}"
+
+}
+
+tasks.withType(Test) {
+    /// increased logging for tests
+    testLogging {
+        events "passed", "skipped", "failed"
+    }
+}
+
+apply plugin: 'com.google.gms.google-services'

+ 74 - 0
drawable_resources/alphabetical_asc.svg

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="25.6"
+   height="25.6"
+   viewBox="0 0 24 24"
+   id="svg2"
+   inkscape:version="0.92.0 r15299"
+   sodipodi:docname="alphabetical_asc.svg"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\newSortingLayout\res\drawable-xxxhdpi\ic_alphabetical_asc.png"
+   inkscape:export-xdpi="360"
+   inkscape:export-ydpi="360">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="27.81"
+     inkscape:cx="5.6317334"
+     inkscape:cy="12"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <g
+     id="g4174"
+     transform="matrix(0.92801764,0,0,0.92801764,3.1474097,-0.40986228)"
+     style="fill:#757575;fill-opacity:1">
+    <path
+       inkscape:connector-curvature="0"
+       id="path4"
+       d="m 4.9604453,12.687998 v 1.805869 h 4.0659743 v 0.05724 L 4.535752,20.951046 v 1.190987 H 11.86263 V 20.326932 H 7.4088934 v -0.07571 L 11.796157,13.954685 V 12.687992 H 4.9604453 Z"
+       style="fill:#757575;fill-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path4-2"
+       d="M 6.9569297,2.3102604 4.0357798,11.764298 h 2.2416409 l 0.679509,-2.5536989 h 2.7328076 l 0.7367497,2.5536989 h 2.326579 L 9.7931408,2.3102604 Z m 1.314702,1.539974 h 0.027698 L 8.5356806,4.7587082 8.781264,5.6764144 9.3776808,7.6798582 H 7.2689873 L 7.8358603,5.6948791 8.0629788,4.7679408 Z"
+       style="fill:#757575;fill-opacity:1" />
+  </g>
+  <path
+     inkscape:connector-curvature="0"
+     d="m 19.12569,12.771205 -1.428741,-0.0014 -0.0086,6.184289 -1.53692,-1.544835 -1.015429,1.013386 3.263957,3.275355 3.275354,-3.263958 -1.013385,-1.015428 -1.544836,1.53692 z"
+     id="path4-3"
+     sodipodi:nodetypes="cccccccccc"
+     style="fill:#757575;fill-opacity:1" />
+</svg>

+ 69 - 0
drawable_resources/alphabetical_desc.svg

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="25.6"
+   height="25.6"
+   viewBox="0 0 24 24"
+   id="svg2"
+   inkscape:version="0.92.0 r15299"
+   sodipodi:docname="alphabetical_desc.svg"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\newSortingLayout\res\drawable-xxxhdpi\ic_alphabetical_desc.png"
+   inkscape:export-xdpi="360"
+   inkscape:export-ydpi="360">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="27.81"
+     inkscape:cx="-2.5868955"
+     inkscape:cy="12"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <path
+     style="fill:#757575;fill-opacity:1"
+     d="m 7.7507904,1.734489 v 1.675878 h 3.7732956 v 0.05312 L 7.3566676,9.402743 V 10.508 H 14.15614 V 8.823554 H 10.022993 V 8.753294 L 14.094451,2.909997 V 1.734483 H 7.7507904 Z"
+     id="path4"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#757575;fill-opacity:1"
+     d="M 9.6035632,11.364486 6.8926845,20.138 H 8.9729668 L 9.6035632,17.768122 H 12.139657 L 12.823374,20.138 h 2.159106 l -2.746863,-8.773514 z m 1.2200668,1.429123 h 0.0257 l 0.219338,0.84308 0.227906,0.851647 0.553485,1.859232 H 9.8931541 l 0.5260679,-1.842096 0.21077,-0.860215 0.193634,-0.851648 z"
+     id="path4-2"
+     inkscape:connector-curvature="0" />
+  <path
+     inkscape:connector-curvature="0"
+     d="m 19.12569,12.771205 -1.428741,-0.0014 -0.0086,6.184289 -1.53692,-1.544835 -1.015429,1.013386 3.263957,3.275355 3.275354,-3.263958 -1.013385,-1.015428 -1.544836,1.53692 z"
+     id="path4-3"
+     sodipodi:nodetypes="cccccccccc"
+     style="fill:#757575;fill-opacity:1" />
+</svg>

+ 1 - 0
drawable_resources/arrow-right.svg

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z" /></svg>

+ 1 - 0
drawable_resources/calendar.svg

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M19,19H5V8H19M16,1V3H8V1H6V3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3H18V1M17,12H12V17H17V12Z" /></svg>

+ 119 - 0
drawable_resources/get_it_as_apk.svg

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+    xmlns:dc="http://purl.org/dc/elements/1.1/"
+    xmlns:cc="http://creativecommons.org/ns#"
+    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+    xmlns="http://www.w3.org/2000/svg"
+    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+    id="svg2"
+    version="1.1"
+    inkscape:version="0.91 r13725"
+    width="646"
+    height="250"
+    viewBox="0 0 646 250"
+    sodipodi:docname="get it as apk.svg"
+    inkscape:export-filename="/home/tobi/Daten/projekt/nextcloud/graphic/get it as apk.png"
+    inkscape:export-xdpi="90"
+    inkscape:export-ydpi="90">
+  <metadata
+     id="metadata8">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs6" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1600"
+     inkscape:window-height="835"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="0.70710678"
+     inkscape:cx="-365.55383"
+     inkscape:cy="112.63522"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer2"
+     showguides="true"
+     inkscape:guide-bbox="true">
+    <sodipodi:guide
+       position="195.16147,-94.752308"
+       orientation="0,1"
+       id="guide4794" />
+    <sodipodi:guide
+       position="159.80613,-198.697"
+       orientation="0,1"
+       id="guide4796" />
+  </sodipodi:namedview>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="apk"
+     style="display:inline">
+    <rect
+       style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;stroke:#a6a6a6;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
+       id="rect4142"
+       width="558.33984"
+       height="163.47433"
+       x="44.59919"
+       y="43.897827"
+       ry="20.533007" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.70548439px;line-height:125%;font-family:Helvetica;-inkscape-font-specification:Helvetica;text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="222.50375"
+       y="90.160751"
+       id="text4163"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4165"
+         x="222.50375"
+         y="90.160751"
+         style="font-size:32.55822754px;fill:#ffffff">GET IT AS</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:35.25382233px;line-height:125%;font-family:Helvetica;-inkscape-font-specification:Helvetica;text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="223.56383"
+       y="176.70526"
+       id="text4167"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4169"
+         x="223.56383"
+         y="176.70526"
+         style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:88.134552px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Semi-Bold'">APK-File</tspan></text>
+    <g
+       style="fill:#000000"
+       id="g4784"
+       transform="matrix(1.0640299,0,0,1.0640299,-61.475209,-106.93774)">
+      <path
+         id="path4774"
+         d="m 126.7489,161.76071 110.43377,0 0,110.43377 -110.43377,0 z"
+         inkscape:connector-curvature="0"
+         style="fill:none" />
+      <path
+         id="path4776"
+         d="m 154.35734,244.58604 c 0,2.53077 2.07064,4.60141 4.60141,4.60141 l 4.6014,0 0,16.10493 c 0,3.81916 3.08294,6.9021 6.90212,6.9021 3.81916,0 6.9021,-3.08294 6.9021,-6.9021 l 0,-16.10493 9.20283,0 0,16.10493 c 0,3.81916 3.08294,6.9021 6.9021,6.9021 3.81917,0 6.90212,-3.08294 6.90212,-6.9021 l 0,-16.10493 4.60139,0 c 2.53078,0 4.60141,-2.07064 4.60141,-4.60141 l 0,-46.01408 -55.21688,0 0,46.01408 z m -11.50351,-46.01408 c -3.81918,0 -6.90212,3.08295 -6.90212,6.90212 l 0,32.20986 c 0,3.81915 3.08294,6.9021 6.90212,6.9021 3.81916,0 6.9021,-3.08295 6.9021,-6.9021 l 0,-32.20986 c 0,-3.81917 -3.08294,-6.90212 -6.9021,-6.90212 z m 78.22391,0 c -3.81916,0 -6.9021,3.08295 -6.9021,6.90212 l 0,32.20986 c 0,3.81915 3.08294,6.9021 6.9021,6.9021 3.81917,0 6.90212,-3.08295 6.90212,-6.9021 l 0,-32.20986 c 0,-3.81917 -3.08295,-6.90212 -6.90212,-6.90212 z m -22.86899,-26.87221 5.98182,-5.98182 c 0.9203,-0.92028 0.9203,-2.34672 0,-3.26701 -0.92027,-0.92028 -2.34671,-0.92028 -3.26699,0 l -6.81008,6.81009 c -3.63512,-1.84057 -7.77637,-2.89888 -12.14772,-2.89888 -4.41735,0 -8.55862,1.05831 -12.23974,2.89888 l -6.8561,-6.81009 c -0.92027,-0.92028 -2.34671,-0.92028 -3.267,0 -0.92028,0.92029 -0.92028,2.34673 0,3.26701 l 6.02785,6.02783 c -6.81009,5.01554 -11.27345,13.06801 -11.27345,22.22481 l 55.21688,0 c 0,-9.1568 -4.46335,-17.25529 -11.36547,-22.27082 z m -25.44578,13.06799 -4.60141,0 0,-4.60139 4.60141,0 0,4.60139 z m 23.00703,0 -4.60141,0 0,-4.60139 4.60141,0 0,4.60139 z"
+         inkscape:connector-curvature="0"
+         style="fill:#ffffff" />
+    </g>
+  </g>
+</svg>

+ 58 - 0
drawable_resources/ic_activity.svg

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="32"
+   width="32"
+   version="1.0"
+   viewBox="0 0 32 32"
+   id="svg4"
+   sodipodi:docname="ic_activity.svg"
+   inkscape:version="0.92.1 r15371"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\activities\src\main\res\drawable-mdpi\ic_activity.png"
+   inkscape:export-xdpi="72"
+   inkscape:export-ydpi="72">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="7.375"
+     inkscape:cx="16"
+     inkscape:cy="16"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg4" />
+  <path
+     d="M 16,1.9491526 6,18.810169 H 17 L 16,30.050847 26,13.189831 H 15 Z"
+     id="path2"
+     style="fill:#757575;fill-opacity:1;stroke-width:0.96784461"
+     inkscape:connector-curvature="0" />
+</svg>

+ 58 - 0
drawable_resources/ic_activity_light_grey.svg

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="32"
+   width="32"
+   version="1.0"
+   viewBox="0 0 32 32"
+   id="svg4"
+   sodipodi:docname="ic_activity_light_grey.svg"
+   inkscape:version="0.92.1 r15371"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\activities\src\main\res\drawable-mdpi\ic_activity_light_grey.png"
+   inkscape:export-xdpi="216"
+   inkscape:export-ydpi="216">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="7.375"
+     inkscape:cx="-20.40678"
+     inkscape:cy="16"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg4" />
+  <path
+     d="M 16,1.9491526 6,18.810169 H 17 L 16,30.050847 26,13.189831 H 15 Z"
+     id="path2"
+     style="fill:#000000;fill-opacity:1;stroke-width:0.96784461;opacity:0.5"
+     inkscape:connector-curvature="0" />
+</svg>

+ 56 - 0
drawable_resources/ic_list_empty_error.svg

@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="16"
+   width="16"
+   version="1.1"
+   id="svg4"
+   sodipodi:docname="ic_list_empty_error.svg"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\favourites\src\main\res\drawable-mdpi\ic_list_empty_error.png"
+   inkscape:export-xdpi="432"
+   inkscape:export-ydpi="432"
+   inkscape:version="0.92.1 r15371">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="14.75"
+     inkscape:cx="8"
+     inkscape:cy="8"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg4" />
+  <path
+     d="M5.516 2L2 5.516v4.968L5.516 14h4.968L14 10.484V5.516L10.484 2H5.516zM7 4h2v5H7V4zm0 6h2v2H7v-2z"
+     id="path2"
+     style="fill:#000000;fill-opacity:1;opacity:0.5" />
+</svg>

+ 62 - 0
drawable_resources/ic_list_empty_home.svg

@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="16"
+   width="16"
+   version="1"
+   id="svg6"
+   sodipodi:docname="ic_list_empty_home.svg"
+   inkscape:version="0.92.1 r15371"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\favourites\src\main\res\drawable-xxxhdpi\ic_home.png"
+   inkscape:export-xdpi="576"
+   inkscape:export-ydpi="576">
+  <metadata
+     id="metadata12">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs10" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview8"
+     showgrid="false"
+     inkscape:zoom="14.75"
+     inkscape:cx="8"
+     inkscape:cy="8"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg6" />
+  <path
+     color="#000"
+     fill="none"
+     d="M-62.897-32.993h163.31v97.986h-163.31z"
+     id="path2" />
+  <path
+     d="M 8,1.4367797 0.46588938,8.9426374 H 3.2911808 V 14.59322 H 12.708819 V 8.9426374 h 2.825292 L 12.708819,6.089093 V 2.3502906 H 9.8835281 v 1.0171049 z"
+     id="path4"
+     inkscape:connector-curvature="0"
+     style="opacity:1;fill-rule:evenodd;stroke-width:0.94176388;fill:#757575;fill-opacity:1" />
+</svg>

+ 58 - 0
drawable_resources/ic_list_empty_image.svg

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="16"
+   width="16"
+   version="1"
+   id="svg4"
+   sodipodi:docname="ic_list_empty_image.svg"
+   inkscape:version="0.92.1 r15371"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\favourites\src\main\res\drawable-mdpi\ic_list_empty_image.png"
+   inkscape:export-xdpi="432"
+   inkscape:export-ydpi="432">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="14.75"
+     inkscape:cx="8"
+     inkscape:cy="8"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg4" />
+  <path
+     style="block-progression:tb;text-transform:none;text-indent:0;fill:#000000;fill-opacity:1;opacity:0.5"
+     d="M1.344 2A.445.445 0 0 0 1 2.438v11.124c0 .23.212.44.438.44h13.125a.457.457 0 0 0 .437-.44V2.61c0-.337-.264-.61-.515-.61zM2 3h12v5l-1-1-3 4-3-3-4 4H2zm2.5 1a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3z"
+     fill="#969696"
+     color="#000"
+     id="path2" />
+</svg>

+ 62 - 0
drawable_resources/ic_list_empty_recent.svg

@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="16"
+   width="16"
+   version="1"
+   id="svg6"
+   sodipodi:docname="ic_list_empty_recent.svg"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\favourites\src\main\res\drawable-mdpi\ic_recent.png"
+   inkscape:export-xdpi="144"
+   inkscape:export-ydpi="144"
+   inkscape:version="0.92.1 r15371">
+  <metadata
+     id="metadata12">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs10" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview8"
+     showgrid="false"
+     inkscape:zoom="14.75"
+     inkscape:cx="8"
+     inkscape:cy="8"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg6" />
+  <path
+     color="#000"
+     fill="none"
+     d="M-62.897-32.993h163.31v97.986h-163.31z"
+     id="path2" />
+  <path
+     style="color:#000000;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;isolation:auto;mix-blend-mode:normal;stroke-width:0.93220341;fill:#757575;fill-opacity:1;opacity:1"
+     d="M 8,0.54237288 C 3.8927119,0.54237288 0.54237288,3.8927119 0.54237288,8 c 0,4.107288 3.35033902,7.457627 7.45762712,7.457627 4.107288,0 7.457627,-3.350339 7.457627,-7.457627 C 15.457627,3.8927119 12.107288,0.54237288 8,0.54237288 Z M 8,2.4067797 c 3.100508,0 5.59322,2.4927118 5.59322,5.5932203 0,3.100508 -2.492712,5.59322 -5.59322,5.59322 C 4.8994915,13.59322 2.4067797,11.100508 2.4067797,8 2.4067797,4.8994915 4.8994915,2.4067797 8,2.4067797 Z M 7.5898305,3.2755932 A 0.57516949,0.57516949 0 0 0 7.0258475,3.8470339 L 6.2316102,7.9860169 V 8 C 6.0610169,8.7038136 6.5457627,8.9322034 7.0864407,9.260339 h 0.00466 L 9.8858475,10.73322 C 10.494576,11.201186 11.197458,10.289492 10.588729,9.819661 L 8.9322034,8.009322 V 8 L 8.1771186,3.8516949 A 0.57516949,0.57516949 0 0 0 7.5898305,3.2755932 Z"
+     id="path4"
+     inkscape:connector-curvature="0" />
+</svg>

+ 56 - 0
drawable_resources/ic_list_empty_shared.svg

@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="16"
+   width="16"
+   version="1.1"
+   id="svg4"
+   sodipodi:docname="ic_list_empty_shared.svg"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\favourites\src\main\res\drawable-mdpi\ic_shared.png"
+   inkscape:export-xdpi="144"
+   inkscape:export-ydpi="144"
+   inkscape:version="0.92.1 r15371">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="14.75"
+     inkscape:cx="-10.20339"
+     inkscape:cy="8"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg4" />
+  <path
+     d="M12.228 1a2.457 2.457 0 0 0-2.46 2.454c0 .075.01.15.016.224L5.05 6.092a2.445 2.445 0 0 0-1.596-.586A2.453 2.453 0 0 0 1 7.96a2.453 2.453 0 0 0 2.454 2.455 2.45 2.45 0 0 0 1.46-.477l4.865 2.474c-.004.044-.01.09-.01.134a2.457 2.457 0 1 0 .804-1.818l-4.696-2.4c.02-.123.035-.25.035-.378 0-.072-.01-.144-.015-.214l4.74-2.414A2.457 2.457 0 1 0 12.228.99z"
+     id="path2"
+     style="fill:#757575;fill-opacity:1;opacity:1" />
+</svg>

+ 58 - 0
drawable_resources/ic_list_empty_video.svg

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="16"
+   width="16"
+   version="1"
+   id="svg4"
+   sodipodi:docname="ic_list_empty_video.svg"
+   inkscape:version="0.92.1 r15371"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\favourites\src\main\res\drawable-mdpi\ic_list_empty_video.png"
+   inkscape:export-xdpi="432"
+   inkscape:export-ydpi="432">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="14.75"
+     inkscape:cx="8"
+     inkscape:cy="8"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg4" />
+  <path
+     style="block-progression:tb;text-transform:none;text-indent:0;fill:#000000;fill-opacity:1;opacity:0.5"
+     d="M1.344 2A.445.445 0 0 0 1 2.438v11.124c0 .23.212.44.438.44h13.124a.457.457 0 0 0 .438-.44V2.61c0-.336-.265-.61-.516-.61zM2 3h12v10H2zm3 2v6l6-3z"
+     fill="#969696"
+     color="#000"
+     id="path2" />
+</svg>

+ 58 - 0
drawable_resources/ic_search_light_blue.svg

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="24"
+   height="24"
+   viewBox="0 0 24 24"
+   id="svg4"
+   sodipodi:docname="ic_search_light_blue.svg"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\filtering-improvements\res\drawable-xxxhdpi\ic_search_light_blue.png"
+   inkscape:export-xdpi="1152"
+   inkscape:export-ydpi="1152"
+   inkscape:version="0.92.0 r15299">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="9.8333333"
+     inkscape:cx="12"
+     inkscape:cy="12"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg4" />
+  <path
+     d="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z"
+     id="path2"
+     style="fill:#99cde9;fill-opacity:1" />
+</svg>

+ 58 - 0
drawable_resources/ic_search_light_grey.svg

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="24"
+   height="24"
+   viewBox="0 0 24 24"
+   id="svg4"
+   sodipodi:docname="ic_search_light_grey.svg"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\new-filtering-magic\res\drawable-xxxhdpi\ic_search_light_grey.png"
+   inkscape:export-xdpi="1152"
+   inkscape:export-ydpi="1152"
+   inkscape:version="0.92.0 r15299">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="9.8333333"
+     inkscape:cx="-15.305085"
+     inkscape:cy="12"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg4" />
+  <path
+     d="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z"
+     id="path2"
+     style="fill:#000000;fill-opacity:1;opacity:0.5" />
+</svg>

+ 57 - 0
drawable_resources/ic_star_light_grey.svg

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="24"
+   height="24"
+   viewBox="0 0 24 24"
+   id="svg4"
+   sodipodi:docname="ic_star_light_grey.svg"
+   inkscape:version="0.92.1 r15371"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\favourites\src\main\res\drawable-xxxhdpi\ic_star_light_grey.png"
+   inkscape:export-xdpi="1152"
+   inkscape:export-ydpi="1152">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="9.8333333"
+     inkscape:cx="12"
+     inkscape:cy="12"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg4" />
+  <path
+     d="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z"
+     id="path2"
+     style="fill:#000000;fill-opacity:1;opacity:0.5" />
+</svg>

+ 1 - 0
drawable_resources/ic_twitter.svg

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M22.46,6C21.69,6.35 20.86,6.58 20,6.69C20.88,6.16 21.56,5.32 21.88,4.31C21.05,4.81 20.13,5.16 19.16,5.36C18.37,4.5 17.26,4 16,4C13.65,4 11.73,5.92 11.73,8.29C11.73,8.63 11.77,8.96 11.84,9.27C8.28,9.09 5.11,7.38 3,4.79C2.63,5.42 2.42,6.16 2.42,6.94C2.42,8.43 3.17,9.75 4.33,10.5C3.62,10.5 2.96,10.3 2.38,10C2.38,10 2.38,10 2.38,10.03C2.38,12.11 3.86,13.85 5.82,14.24C5.46,14.34 5.08,14.39 4.69,14.39C4.42,14.39 4.15,14.36 3.89,14.31C4.43,16 6,17.26 7.89,17.29C6.43,18.45 4.58,19.13 2.56,19.13C2.22,19.13 1.88,19.11 1.54,19.07C3.44,20.29 5.7,21 8.12,21C16,21 20.33,14.46 20.33,8.79C20.33,8.6 20.33,8.42 20.32,8.23C21.16,7.63 21.88,6.87 22.46,6Z" /></svg>

+ 1 - 0
drawable_resources/ic_web.svg

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M16.36,14C16.44,13.34 16.5,12.68 16.5,12C16.5,11.32 16.44,10.66 16.36,10H19.74C19.9,10.64 20,11.31 20,12C20,12.69 19.9,13.36 19.74,14M14.59,19.56C15.19,18.45 15.65,17.25 15.97,16H18.92C17.96,17.65 16.43,18.93 14.59,19.56M14.34,14H9.66C9.56,13.34 9.5,12.68 9.5,12C9.5,11.32 9.56,10.65 9.66,10H14.34C14.43,10.65 14.5,11.32 14.5,12C14.5,12.68 14.43,13.34 14.34,14M12,19.96C11.17,18.76 10.5,17.43 10.09,16H13.91C13.5,17.43 12.83,18.76 12,19.96M8,8H5.08C6.03,6.34 7.57,5.06 9.4,4.44C8.8,5.55 8.35,6.75 8,8M5.08,16H8C8.35,17.25 8.8,18.45 9.4,19.56C7.57,18.93 6.03,17.65 5.08,16M4.26,14C4.1,13.36 4,12.69 4,12C4,11.31 4.1,10.64 4.26,10H7.64C7.56,10.66 7.5,11.32 7.5,12C7.5,12.68 7.56,13.34 7.64,14M12,4.03C12.83,5.23 13.5,6.57 13.91,8H10.09C10.5,6.57 11.17,5.23 12,4.03M18.92,8H15.97C15.65,6.75 15.19,5.55 14.59,4.44C16.43,5.07 17.96,6.34 18.92,8M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" /></svg>

+ 64 - 0
drawable_resources/modification_asc.svg

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="25.6"
+   height="25.6"
+   viewBox="0 0 24 24"
+   id="svg2"
+   inkscape:version="0.92.0 r15299"
+   sodipodi:docname="modified_asc.svg"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\newSortingLayout\res\drawable-xxxhdpi\ic_modification_asc.png"
+   inkscape:export-xdpi="360"
+   inkscape:export-ydpi="360">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="22.63"
+     inkscape:cx="15.581769"
+     inkscape:cy="6.7845462"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <path
+     style="fill:#757575;fill-opacity:1;stroke-width:1.06666672"
+     d="M 11.589844 2.1328125 A 9.4570668 9.4570668 0 0 0 2.1328125 11.589844 C 2.1328125 16.79123 6.3600875 21.048828 11.589844 21.048828 A 9.4570668 9.4570668 0 0 0 13.015625 20.921875 L 13.015625 19.017578 A 7.5656534 7.5656534 0 0 1 11.589844 19.15625 A 7.5656534 7.5656534 0 0 1 4.0253906 11.589844 A 7.5656534 7.5656534 0 0 1 11.589844 4.0253906 A 7.5656534 7.5656534 0 0 1 18.978516 10 L 20.902344 10 A 9.4570668 9.4570668 0 0 0 11.589844 2.1328125 z M 10.644531 6.8632812 L 10.644531 12.535156 L 13.015625 13.957031 L 13.015625 12.392578 L 12.0625 11.826172 L 12.0625 6.8632812 L 10.644531 6.8632812 z "
+     transform="scale(0.93749999)"
+     id="path4" />
+  <path
+     inkscape:connector-curvature="0"
+     d="m 13.720313,16.930993 h 5.580275 v -1.736354 h -5.580275 m 0,-4.340882 v 1.736354 h 8.370413 v -1.736354 m -8.370413,10.418118 h 2.790138 v -1.736351 h -2.790138 z"
+     id="path4-8"
+     style="fill:#757575;fill-opacity:1;stroke-width:1.16980636" />
+</svg>

+ 63 - 0
drawable_resources/modification_desc.svg

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="25.6"
+   height="25.6"
+   viewBox="0 0 24 24"
+   id="svg2"
+   inkscape:version="0.92.0 r15299"
+   sodipodi:docname="modified_desc.svg"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\newSortingLayout\res\drawable-xxxhdpi\ic_modified_desc.png"
+   inkscape:export-xdpi="360"
+   inkscape:export-ydpi="360">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="22.63"
+     inkscape:cx="15.581769"
+     inkscape:cy="6.7845462"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <path
+     style="fill:#757575;fill-opacity:1;stroke-width:1.06666672"
+     d="M 11.589844 2.1328125 A 9.4570668 9.4570668 0 0 0 2.1328125 11.589844 C 2.1328125 16.79123 6.3600875 21.048828 11.589844 21.048828 A 9.4570668 9.4570668 0 0 0 13.015625 20.921875 L 13.015625 19.017578 A 7.5656534 7.5656534 0 0 1 11.589844 19.15625 A 7.5656534 7.5656534 0 0 1 4.0253906 11.589844 A 7.5656534 7.5656534 0 0 1 11.589844 4.0253906 A 7.5656534 7.5656534 0 0 1 18.978516 10 L 20.902344 10 A 9.4570668 9.4570668 0 0 0 11.589844 2.1328125 z M 10.644531 6.8632812 L 10.644531 12.535156 L 13.015625 13.957031 L 13.015625 12.392578 L 12.0625 11.826172 L 12.0625 6.8632812 L 10.644531 6.8632812 z "
+     transform="scale(0.93749999)"
+     id="path4" />
+  <path
+     inkscape:connector-curvature="0"
+     d="m 13.720313,15.194639 h 5.580275 v 1.736354 h -5.580275 m 0,4.340882 v -1.736354 h 8.370413 v 1.736354 M 13.720313,10.853757 h 2.790138 v 1.736351 h -2.790138 z"
+     id="path4-8"
+     style="fill:#757575;fill-opacity:1;stroke-width:1.16980636" />
+</svg>

+ 77 - 0
drawable_resources/size_asc.svg

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="25.6"
+   height="25.6"
+   viewBox="0 0 24 24"
+   id="svg2"
+   inkscape:version="0.92.0 r15299"
+   sodipodi:docname="size_asc.svg"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\newSortingLayout\res\drawable-xxxhdpi\ic_size_asc.png"
+   inkscape:export-xdpi="360"
+   inkscape:export-ydpi="360">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="22.627418"
+     inkscape:cx="15.398362"
+     inkscape:cy="7.3901816"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer3"
+     inkscape:label="Layer 3" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="Layer 2"
+     style="display:inline" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer1"
+     inkscape:label="Layer 1" />
+  <path
+     inkscape:connector-curvature="0"
+     d="m 13.720501,15.194819 h 5.580275 v 1.736354 h -5.580275 m 0,4.340882 v -1.736354 h 8.370414 v 1.736354 M 13.720501,10.853937 h 2.790138 v 1.736351 h -2.790138 z"
+     id="path4-8"
+     style="fill:#757575;fill-opacity:1;stroke-width:1.16980636" />
+  <path
+     style="fill:#757575;fill-opacity:1;stroke-width:1.06666672"
+     d="M 10.412109 1.8046875 A 9.4570668 9.4570668 0 0 0 0.95507812 11.259766 A 9.4570668 9.4570668 0 0 0 10.412109 20.71875 A 9.4570668 9.4570668 0 0 0 13.015625 20.337891 L 13.015625 18.351562 A 7.5656534 7.5656534 0 0 1 10.412109 18.826172 A 7.5656534 7.5656534 0 0 1 2.8457031 11.259766 A 7.5656534 7.5656534 0 0 1 10.412109 3.6953125 A 7.5656534 7.5656534 0 0 1 17.869141 10 L 19.773438 10 A 9.4570668 9.4570668 0 0 0 10.412109 1.8046875 z M 10.412109 5.5878906 L 10.412109 11.259766 L 6.4023438 15.269531 C 8.191236 17.058424 10.881148 17.400168 13.015625 16.296875 L 13.015625 10 L 15.941406 10 C 15.711784 8.9928477 15.206905 8.0355871 14.419922 7.2519531 C 13.313445 6.1360192 11.859041 5.5878906 10.412109 5.5878906 z "
+     transform="scale(0.93749999)"
+     id="path4-88" />
+</svg>

+ 76 - 0
drawable_resources/size_desc.svg

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="25.6"
+   height="25.6"
+   viewBox="0 0 24 24"
+   id="svg2"
+   inkscape:version="0.92.0 r15299"
+   sodipodi:docname="size_desc.svg"
+   inkscape:export-filename="C:\DEV\src\Android\Nextcloud\newSortingLayout\res\drawable-xxxhdpi\ic_size_desc.png"
+   inkscape:export-xdpi="360"
+   inkscape:export-ydpi="360">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1005"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="22.63"
+     inkscape:cx="11.152894"
+     inkscape:cy="8.874615"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer3"
+     inkscape:label="Layer 3" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="Layer 2"
+     style="display:inline" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer1"
+     inkscape:label="Layer 1" />
+  <path
+     style="fill:#757575;fill-opacity:1;stroke-width:1.06666672"
+     d="M 10.412109 1.8046875 A 9.4570668 9.4570668 0 0 0 0.95507812 11.259766 A 9.4570668 9.4570668 0 0 0 10.412109 20.71875 A 9.4570668 9.4570668 0 0 0 13.015625 20.337891 L 13.015625 18.351562 A 7.5656534 7.5656534 0 0 1 10.412109 18.826172 A 7.5656534 7.5656534 0 0 1 2.8457031 11.259766 A 7.5656534 7.5656534 0 0 1 10.412109 3.6953125 A 7.5656534 7.5656534 0 0 1 17.869141 10 L 19.773438 10 A 9.4570668 9.4570668 0 0 0 10.412109 1.8046875 z M 10.412109 5.5878906 L 10.412109 11.259766 L 6.4023438 15.269531 C 8.191236 17.058424 10.881148 17.400168 13.015625 16.296875 L 13.015625 10 L 15.941406 10 C 15.711784 8.9928477 15.206905 8.0355871 14.419922 7.2519531 C 13.313445 6.1360192 11.859041 5.5878906 10.412109 5.5878906 z "
+     transform="scale(0.93749999)"
+     id="path4-88" />
+  <path
+     inkscape:connector-curvature="0"
+     d="m 13.720312,16.930993 h 5.580275 v -1.736354 h -5.580275 m 0,-4.340882 v 1.736354 h 8.370413 v -1.736354 m -8.370413,10.418118 h 2.790138 v -1.736351 h -2.790138 z"
+     id="path4-8"
+     style="fill:#757575;fill-opacity:1;stroke-width:1.16980636" />
+</svg>

+ 2 - 2
gradle/wrapper/gradle-wrapper.properties

@@ -1,6 +1,6 @@
-#Tue Aug 16 10:44:46 CEST 2016
+#Wed Mar 15 00:10:20 CET 2017
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip

BIN
res/drawable/ic_synced.png


+ 0 - 316
res/values-da/strings.xml

@@ -1,316 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-  <string name="about_version">version %1$s</string>
-  <string name="actionbar_sync">Genindlæs konto</string>
-  <string name="actionbar_upload">Upload</string>
-  <string name="actionbar_upload_from_apps">Indhold fra andre apps</string>
-  <string name="actionbar_upload_files">Filer</string>
-  <string name="actionbar_open_with">Åben med</string>
-  <string name="actionbar_mkdir">Ny mappe</string>
-  <string name="actionbar_settings">Indstillinger</string>
-  <string name="actionbar_see_details">Detaljer</string>
-  <string name="actionbar_send_file">Send</string>
-  <string name="actionbar_sort">Sortér</string>
-  <string name="actionbar_sort_title">Sortér efter</string>
-  <string-array name="actionbar_sortby">
-    <item>A-Å</item>
-    <item>Nyeste - ældste</item>
-  </string-array>
-  <!--TODO re-enable when server-side folder size calculation is available   
-    	<item>Biggest - Smallest</item>-->
-  <!--TODO re-enable when "Accounts" is available in Navigation Drawer-->
-  <!--<string name="drawer_item_accounts">Accounts</string>-->
-  <string name="drawer_item_all_files">Alle filer</string>
-  <!--TODO re-enable when "On Device" is available
-    <string name="drawer_item_on_device">On device</string>-->
-  <string name="drawer_item_settings">Indstillinger</string>
-  <string name="drawer_item_uploads_list">Uploade filer</string>
-  <string name="drawer_close">Luk</string>
-  <string name="drawer_open">Åbn</string>
-  <string name="prefs_category_general">Generel</string>
-  <string name="prefs_category_more">Mere</string>
-  <string name="prefs_accounts">Konti</string>
-  <string name="prefs_manage_accounts">Administrer konti</string>
-  <string name="prefs_passcode">Passcode-lås</string>
-  <string name="prefs_instant_upload">Upload billeder straks</string>
-  <string name="prefs_instant_upload_summary">Upload straks billeder taget med kameraet</string>
-  <string name="prefs_instant_video_upload">Upload videoer straks</string>
-  <string name="prefs_instant_video_upload_summary">Upload straks videor optaget med kameraet</string>
-  <string name="prefs_log_title">Slå logning til</string>
-  <string name="prefs_log_summary">Dette bruges til at logregistrere problemer</string>
-  <string name="prefs_log_title_history">Logningshistorik</string>
-  <string name="prefs_log_summary_history">Dette viser de optagne logger</string>
-  <string name="prefs_log_delete_history_button">Slet historik</string>
-  <string name="prefs_help">Hjælp</string>
-  <string name="prefs_recommend">Anbefal til en ven</string>
-  <string name="prefs_feedback">Feedback</string>
-  <string name="prefs_imprint">Aftryk</string>
-  <string name="prefs_remember_last_share_location">Husk delt placering</string>
-  <string name="prefs_remember_last_upload_location_summary">Husk seneste delte placering for overførsel</string>
-  <string name="recommend_subject">Prøv %1$s på din smartphone!</string>
-  <string name="recommend_text">Jeg ønsker at invitere dig til at bruge %1$s på din smartphone!\nHent den her: %2$s</string>
-  <string name="auth_host_url">Serveradresse https://…</string>
-  <string name="auth_username">Brugernavn</string>
-  <string name="auth_password">Kodeord</string>
-  <string name="auth_register">Ny med %1$s</string>
-  <string name="sync_string_files">Filer</string>
-  <string name="setup_btn_connect">Tilslut</string>
-  <string name="uploader_btn_upload_text">Upload</string>
-  <string name="uploader_wrn_no_account_title">Ingen konto fundet</string>
-  <string name="uploader_wrn_no_account_setup_btn_text">Opsætning</string>
-  <string name="uploader_wrn_no_account_quit_btn_text">Afslut</string>
-  <string name="file_list_seconds_ago">sekunder siden</string>
-  <string name="file_list_empty">Her er tomt. Upload noget!</string>
-  <string name="file_list_loading">Indlæser...</string>
-  <string name="local_file_list_empty">Der er ingen filer i denne mappe.</string>
-  <string name="file_list_folder">mappe</string>
-  <string name="file_list_folders">mapper</string>
-  <string name="file_list_file">fil</string>
-  <string name="file_list_files">fil</string>
-  <string name="filedetails_select_file">Tryk på en fil for at vise yderligere information.</string>
-  <string name="filedetails_size">Størelse:</string>
-  <string name="filedetails_type">Type:</string>
-  <string name="filedetails_created">Oprettet:</string>
-  <string name="filedetails_modified">Ændret:</string>
-  <string name="filedetails_download">Hent</string>
-  <string name="filedetails_renamed_in_upload_msg">Filen blev omdøbt til %1$s under upload</string>
-  <string name="action_share">Del</string>
-  <string name="common_yes">Ja</string>
-  <string name="common_no">Nej</string>
-  <string name="common_ok">OK</string>
-  <string name="common_cancel">Annuller</string>
-  <string name="common_back">Tilbage</string>
-  <string name="common_error">Fejl</string>
-  <string name="common_loading">Indlæser...</string>
-  <string name="common_unknown">ukendt</string>
-  <string name="common_error_unknown">Ukendt fejl</string>
-  <string name="about_title">Om</string>
-  <string name="change_password">Skift kodeord</string>
-  <string name="create_account">Opret konto</string>
-  <string name="upload_chooser_title">Upload fra ...</string>
-  <string name="uploader_info_dirname">Mappenavn</string>
-  <string name="uploader_upload_in_progress_ticker">Uploader ...</string>
-  <string name="uploader_upload_in_progress_content">%1$d%% Uploader %2$s</string>
-  <string name="uploader_upload_succeeded_ticker">Upload færdig</string>
-  <string name="uploader_upload_failed_ticker">Upload fejlede</string>
-  <string name="uploader_upload_failed_content_single">Upload af %1$s kunne ikke gennemføres</string>
-  <string name="uploads_view_title">Uploade filer</string>
-  <string name="uploads_view_group_current_uploads">Nuværende</string>
-  <string name="uploads_view_group_finished_uploads">Sendt</string>
-  <string name="uploads_view_upload_status_succeeded">Fuldført</string>
-  <string name="uploads_view_upload_status_failed_credentials_error">Godkendelsesfejl</string>
-  <string name="uploads_view_upload_status_failed_folder_error">Mappefejl</string>
-  <string name="uploads_view_upload_status_failed_file_error">Filfejl</string>
-  <string name="uploads_view_upload_status_failed_permission_error">Manglende rettigheder</string>
-  <string name="uploads_view_upload_status_unknown_fail">Ukendt fejl</string>
-  <string name="uploads_view_later_waiting_to_upload">Venter med upload</string>
-  <string name="downloader_download_in_progress_ticker">Downloader ...</string>
-  <string name="downloader_download_in_progress_content">%1$d%% Downloader %2$s</string>
-  <string name="downloader_download_succeeded_ticker">Download fuldført</string>
-  <string name="downloader_download_failed_ticker">Download fejlede</string>
-  <string name="downloader_download_failed_content">Download af %1$s kunne ikke fuldføres</string>
-  <string name="downloader_not_downloaded_yet">Endnu ikke downloadet</string>
-  <string name="common_choose_account">Vælg konto</string>
-  <string name="sync_fail_content_unauthorized">Ugyldig adgangskode for %1$s</string>
-  <string name="sync_conflicts_in_favourites_ticker">Konflikter fundet</string>
-  <string name="sync_conflicts_in_favourites_content">%1$d hold-synkroniseret filer kunne ikke synkroniseres</string>
-  <string name="sync_fail_in_favourites_ticker">Hold-synkroniseret filer mislykkedes</string>
-  <string name="sync_fail_in_favourites_content">Indholdet af %1$d filer ikke kunne synkroniseres (%2$d konflikter)</string>
-  <string name="sync_foreign_files_forgotten_ticker">Visse lokale filer blev glemt</string>
-  <string name="sync_foreign_files_forgotten_content">%1$d filer ud af %2$s mappe kunne ikke kopieres ind i</string>
-  <string name="sync_foreign_files_forgotten_explanation">Fra version 1.3.16 bliver filer uploadet fra denne enhed kopieret til mappen %1$s for at forhindre datatab når en enkelt fil synkroniseres med flere konti.\n\nPå grund af denne ændring er alle filer som var uploadet i tidligere versioner af denne app kopieret til mappen %2$s. Imidlertid forhindrede en fejl færdiggørelsen af denne operation under konto-synkronisering. Du kan enten lade filen (el. filerne) være som de er og fjerne linket til %3$s eller flytte filen (el. filerne) til mappen %1$s og beholde linket til %4$s.\n\nHerunder er en liste med den lokale fil(er), og den fjerne mappe(r) i %5$s, som de var knyttet til.</string>
-  <string name="sync_current_folder_was_removed">Mappen %1$s eksistere ikke længere</string>
-  <string name="foreign_files_move">Flyt alle</string>
-  <string name="foreign_files_success">Alle filer blev flyttet</string>
-  <string name="foreign_files_fail">Visse filer kunne ikke flyttes</string>
-  <string name="foreign_files_local_text">Lokal: %1$s</string>
-  <string name="foreign_files_remote_text">Fjernplacering: %1$s</string>
-  <string name="pass_code_configure_your_pass_code">Angiv din passcode</string>
-  <string name="pass_code_configure_your_pass_code_explanation">Denne passcode vil blive forespurgt hver gang app\'en startes</string>
-  <string name="pass_code_remove_your_pass_code">Fjern din passcode</string>
-  <string name="pass_code_mismatch">Passcode\'erne er ikke ens</string>
-  <string name="pass_code_wrong">Ukorrekt passcode</string>
-  <string name="pass_code_removed">Passcode blev fjernet</string>
-  <string name="pass_code_stored">Passcode blev gendannet</string>
-  <string name="media_notif_ticker">%1$s musikafspiller</string>
-  <string name="media_state_playing">%1$s (afspiller)</string>
-  <string name="media_state_loading">%1$s (indlæser)</string>
-  <string name="media_event_done">%1$s afspilning færdig</string>
-  <string name="media_err_nothing_to_play">Mediefil ikke fundet</string>
-  <string name="media_err_no_account">Ingen konto angivet</string>
-  <string name="media_err_not_in_owncloud">Fil er ikke en gyldig konto</string>
-  <string name="media_err_unsupported">Ikke-understøttet medie codec</string>
-  <string name="media_err_io">Mediefilen kunne ikke læses</string>
-  <string name="media_err_malformed">Mediefilen er ikke korrekt \"encoded\"</string>
-  <string name="media_err_timeout">Tiden udløb under forsøg på at afspille</string>
-  <string name="media_err_invalid_progressive_playback">Mediefilen kan ikke streames</string>
-  <string name="media_err_unknown">Mediefil kan ikke afspilles med tilgængelige medieafspiller</string>
-  <string name="media_err_security_ex">Sikkerhedsfejl ved forsøg på afspilning af </string>
-  <string name="media_err_io_ex">Inputfejl ved forsøg på afspilning af %1$s</string>
-  <string name="media_err_unexpected">Uventet fejl ved forsøg på afspilning af %1$s</string>
-  <string name="media_rewind_description">Tilbagespolingsknap</string>
-  <string name="media_play_pause_description">Afspil eller pause knap</string>
-  <string name="media_forward_description">Hurtigt fremad-knap</string>
-  <string name="auth_no_net_conn_title">Ingen netværksforbindelse</string>
-  <string name="auth_nossl_plain_ok_title">Sikker forbindelse ikke tilgængelig.</string>
-  <string name="auth_connection_established">Forbindelse oprettet</string>
-  <string name="auth_testing_connection">Tester forbindelsen</string>
-  <string name="auth_not_configured_title">Misdannet server konfiguration</string>
-  <string name="auth_account_not_new">En konto for den samme bruger og server eksisterer allerede på enheden</string>
-  <string name="auth_account_not_the_same">Den indtastede bruger passer ikke til brugeren for denne konto</string>
-  <string name="auth_unknown_error_title">Ukendt fejl opstod!</string>
-  <string name="auth_unknown_host_title">Kunne ikke finde værten</string>
-  <string name="auth_incorrect_path_title">Server instans blev ikke fundet</string>
-  <string name="auth_timeout_title">Serveren var for længe om at svare</string>
-  <string name="auth_ssl_general_error_title">SSL-initialiseringen fejlede</string>
-  <string name="auth_ssl_unverified_server_title">Kunne ikke bekræfte SSl-serverens identitet</string>
-  <string name="auth_bad_oc_version_title">Ikke genkendt serverversion</string>
-  <string name="auth_wrong_connection_title">Kunne ikke oprette forbindelse</string>
-  <string name="auth_secure_connection">Sikker forbindelse oprettet</string>
-  <string name="auth_unauthorized">Forkert brugernavn eller kodeord</string>
-  <string name="auth_oauth_error">Mislykket godkendelse</string>
-  <string name="auth_oauth_error_access_denied">Adgang afvist af autorisationsserver</string>
-  <string name="auth_expired_oauth_token_toast">Din godkendelse udløb. Gentag godkendelse</string>
-  <string name="auth_expired_saml_sso_token_toast">Din session udløb. Forbind venligst igen</string>
-  <string name="auth_unsupported_auth_method">Serveren understøtter ikke denne godkendelsesmetode</string>
-  <string name="auth_unsupported_multiaccount">%1$s understøtter ikke flere konti</string>
-  <string name="auth_fail_get_user_name">Din server retunere ikke et korrekt bruger-id. Kontakt venligst din administrator</string>
-  <string name="auth_account_does_not_exist">Kontoen findes endnu ikke på enheden</string>
-  <string name="common_rename">Omdøb</string>
-  <string name="common_remove">Fjern</string>
-  <string name="confirmation_remove_alert">Er du sikker på at du vil fjerne %1$s ?</string>
-  <string name="confirmation_remove_folder_alert">Ønsker du virkelig at slette %1$s og dets indhold?</string>
-  <string name="confirmation_remove_local">Kun lokal</string>
-  <string name="remove_success_msg">Vellykket fjernelse</string>
-  <string name="remove_fail_msg">Fjernelse kunne ikke fuldføres</string>
-  <string name="rename_dialog_title">Indtast et nyt navn</string>
-  <string name="rename_local_fail_msg">Lokal kopi kunne ikke omdøbes; prøv et andet nyt navn</string>
-  <string name="rename_server_fail_msg">Omdøbning kunne ikke gennemføres</string>
-  <string name="sync_file_fail_msg">Ekstern fil kunne ikke kontrolleres</string>
-  <string name="sync_file_nothing_to_do_msg">Filindholdet allerede synkroniseret</string>
-  <string name="create_dir_fail_msg">Kunne ikke oprette mappe</string>
-  <string name="filename_forbidden_characters">Ugyldige tegn: / \\ &lt; &gt; : \" | ? *</string>
-  <string name="filename_forbidden_charaters_from_server">Filnavnet indeholder mindst ét ugyldigt tegn</string>
-  <string name="filename_empty">Filnavnet kan ikke stå tomt.</string>
-  <string name="wait_a_moment">Vent et øjeblik</string>
-  <string name="filedisplay_unexpected_bad_get_content">Uventet problem; prøv venligst en anden applikation til at vælge filen</string>
-  <string name="filedisplay_no_file_selected">Ingen fil blev valgt</string>
-  <string name="activity_chooser_title">Send link til ...</string>
-  <string name="wait_for_tmp_copy_from_private_storage">Kopierer fil fra privat lager.</string>
-  <string name="oauth_check_onoff">Log på med oAuth2</string>
-  <string name="oauth_login_connection">Forbinder til oAuth2-server...</string>
-  <string name="ssl_validator_header">Sidens identitet kunne ikke verificeres</string>
-  <string name="ssl_validator_reason_cert_not_trusted">- Serverens certifikat er ikke troværdigt</string>
-  <string name="ssl_validator_reason_cert_expired">- Serverens certifikat er udløbet</string>
-  <string name="ssl_validator_reason_cert_not_yet_valid">- Serverens certifikat er for ung</string>
-  <string name="ssl_validator_reason_hostname_not_verified">- URL adressen stemmer ikke overens med værtsnavnet i certifikatet</string>
-  <string name="ssl_validator_question">Stoler du på certifikatet alligevel?</string>
-  <string name="ssl_validator_not_saved">Certifikatet kunne ikke gemmes</string>
-  <string name="ssl_validator_btn_details_see">Detaljer</string>
-  <string name="ssl_validator_btn_details_hide">Gem</string>
-  <string name="ssl_validator_label_subject">Udstedt til:</string>
-  <string name="ssl_validator_label_issuer">Udstedt af:</string>
-  <string name="ssl_validator_label_CN">Almindeligt navn:</string>
-  <string name="ssl_validator_label_O">Organisation:</string>
-  <string name="ssl_validator_label_OU">Organisatorisk enhed:</string>
-  <string name="ssl_validator_label_C">Land:</string>
-  <string name="ssl_validator_label_ST">Stat:</string>
-  <string name="ssl_validator_label_L">Sted:</string>
-  <string name="ssl_validator_label_validity">Gyldighed:</string>
-  <string name="ssl_validator_label_validity_from">Fra:</string>
-  <string name="ssl_validator_label_validity_to">Til:</string>
-  <string name="ssl_validator_label_signature">Signatur:</string>
-  <string name="ssl_validator_label_signature_algorithm">Algoritme:</string>
-  <string name="ssl_validator_null_cert">Certifikatet kunne ikke vises.</string>
-  <string name="ssl_validator_no_info_about_error">- Ingen information om fejlen</string>
-  <string name="placeholder_sentence">Dette er en pladsholder</string>
-  <string name="placeholder_filename">pladsholder.txt</string>
-  <string name="placeholder_filetype">PNG Billede</string>
-  <string name="placeholder_filesize">389 KB</string>
-  <string name="placeholder_timestamp">2012/05/18 12:23 PM</string>
-  <string name="placeholder_media_time">12:23:45</string>
-  <string name="instant_upload_path">/Øjeblikkelig upload</string>
-  <string name="conflict_title">Filkonflikt</string>
-  <string name="conflict_message">Hvilke filer ønsker du at beholde? Hvis du vælger begge versioner, så vil den lokale fil få et tal tilføjet til sit navn.</string>
-  <string name="conflict_keep_both">Behold begge</string>
-  <string name="conflict_use_local_version">lokal version</string>
-  <string name="conflict_use_server_version">serverversion</string>
-  <string name="preview_image_description">Forhåndsvisning af billede</string>
-  <string name="preview_image_error_unknown_format">Dette billede kan ikke vises</string>
-  <string name="error__upload__local_file_not_copied">%1$s kunne ikke kopieres til %2$s lokale mappe</string>
-  <string name="share_link_no_support_share_api">Beklager, deling er ikke slået til på din server. Kontakt venligst din
-⇥⇥administrator.</string>
-  <string name="share_link_file_no_exist">Kan ikke dele. Tjek venligst om filen findes.</string>
-  <string name="share_link_file_error">Der opstod en fejl ved deling af denne fil eller mappe</string>
-  <string name="unshare_link_file_no_exist">Kan ikke fjerne deling. Tjek venligst om filen findes.</string>
-  <string name="unshare_link_file_error">Der opstod en fejl ved stopning af deling af denne mappe.</string>
-  <string name="share_link_password_title">Angiv et kodeord</string>
-  <string name="share_link_empty_password">Du skal angive et kodeord</string>
-  <string name="activity_chooser_send_file_title">Send</string>
-  <string name="copy_link">Kopiér link</string>
-  <string name="clipboard_text_copied">Kopieret til udklipsholder</string>
-  <string name="error_cant_bind_to_operations_service">Kritisk fejl: kan ikke udføre handlingerne</string>
-  <string name="network_error_socket_exception">Der opstod en fejl under tilslutningen til serveren.</string>
-  <string name="network_error_socket_timeout_exception">Der opstod en fejl mens vi ventede på serveren, handlingen kunne ikke gennemføres</string>
-  <string name="network_error_connect_timeout_exception">Der opstod en fejl mens vi ventede på serveren, handlingen kunne ikke gennemføres</string>
-  <string name="network_host_not_available">Handlingen kunne ikke gennemføres, serveren er utilgængelig</string>
-  <string name="empty"></string>
-  <string name="forbidden_permissions">Du har ikke rettigheden %s</string>
-  <string name="forbidden_permissions_rename">til at omdøbe denne fil</string>
-  <string name="forbidden_permissions_delete">til at slette denne fil</string>
-  <string name="share_link_forbidden_permissions">til at dele denne fil</string>
-  <string name="unshare_link_forbidden_permissions">til at stoppe deling af denne fil</string>
-  <string name="forbidden_permissions_create">til at oprette filen</string>
-  <string name="uploader_upload_forbidden_permissions">til at overføre til denne mappe</string>
-  <string name="downloader_download_file_not_found">Filen er ikke længere tilgængelig på serveren</string>
-  <string name="prefs_category_accounts">Konti</string>
-  <string name="prefs_add_account">Tilføj konto</string>
-  <string name="auth_redirect_non_secure_connection_title">Sikker forbindelse videredirigeres gennem en usikker rute.</string>
-  <string name="actionbar_logger">Logge</string>
-  <string name="log_send_mail_subject">%1$s Android-app - logge</string>
-  <string name="saml_authentication_required_text">Godkendelse påkrævet</string>
-  <string name="saml_authentication_wrong_pass">Forkert kodeord</string>
-  <string name="actionbar_move">Flyt</string>
-  <string name="file_list_empty_moving">Der er intet her. Du kan tilføje en mappe!</string>
-  <string name="folder_picker_choose_button_text">Vælg</string>
-  <string name="move_file_not_found">Kan ikke flytte. Tjek venligst om filen findes</string>
-  <string name="move_file_invalid_into_descendent">Det er ikke muligt at flytte en mappe til en undermappe</string>
-  <string name="move_file_invalid_overwrite">Filen findes allerede i destinationsmappen</string>
-  <string name="move_file_error">Der opstod en fejl under forsøg på at flytte denne mappe eller fil</string>
-  <string name="forbidden_permissions_move">til at flytte denne fil</string>
-  <string name="copy_file_not_found">Kunne ikke kopiere. Tjek venligst om filerne findes</string>
-  <string name="copy_file_invalid_into_descendent">Det er ikke muligt at kopiere en mappe til én af dens undermapper</string>
-  <string name="copy_file_invalid_overwrite">Filen findes allerede i destinationsmappen</string>
-  <string name="copy_file_error">Der opstod en fejl under forsøg på at kopiere denne fil eller mappe</string>
-  <string name="forbidden_permissions_copy">til at kopiere denne fil</string>
-  <string name="prefs_category_details">Detaljer</string>
-  <string name="shared_subject_header">delt</string>
-  <string name="with_you_subject_header">med dig</string>
-  <string name="subject_user_shared_with_you">%1$s delte \"%2$s\" med dig</string>
-  <string name="subject_shared_with_you">\"%1$s\" er blevet delt med dig</string>
-  <string name="auth_refresh_button">Genopfrisk forbindelsen</string>
-  <string name="auth_host_address">Serveradresse</string>
-  <string name="common_error_out_memory">Ikke tilstrækkelig hukommelse</string>
-  <string name="username">Brugernavn</string>
-  <string name="file_list__footer__folder">1 mappe</string>
-  <string name="file_list__footer__folders">%1$d mapper</string>
-  <string name="file_list__footer__file">1 fil</string>
-  <string name="file_list__footer__file_and_folder">1 fil, 1 mappe</string>
-  <string name="file_list__footer__file_and_folders">1 fil, %1$d mapper</string>
-  <string name="file_list__footer__files">%1$d filer</string>
-  <string name="file_list__footer__files_and_folder">%1$d filer, 1 mape</string>
-  <string name="file_list__footer__files_and_folders">%1$d filer, %2$d mapper</string>
-  <string name="share_dialog_title">Deling</string>
-  <string name="share_via_link_section_title">Del link</string>
-  <string name="share_via_link_expiration_date_label">Vælg udløbsdato</string>
-  <string name="share_via_link_password_label">Beskyt med adgangskode</string>
-  <string name="share_via_link_password_title">Sikret</string>
-  <string name="share_via_link_edit_permission_label">Tillad redigering</string>
-  <string name="share_search">Søg</string>
-  <string name="share_privilege_can_share">kan dele</string>
-  <string name="share_privilege_can_edit">kan redigere</string>
-  <string name="share_privilege_can_edit_create">opret</string>
-  <string name="share_privilege_can_edit_change">tilpas</string>
-  <string name="share_privilege_can_edit_delete">slet</string>
-  <string name="edit_share_unshare">Stop deling</string>
-</resources>

+ 0 - 425
res/values-es-rMX/strings.xml

@@ -1,425 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="about_android">%1$s Android app</string>
-    <string name="about_version">versión %1$s</string>
-    <string name="actionbar_sync">Actualizar cuenta</string>
-    <string name="actionbar_upload">Subir archivo</string>
-    <string name="actionbar_upload_from_apps">Contenido de otras aplicaciones</string>
-    <string name="actionbar_upload_files">Archivos</string>
-    <string name="actionbar_open_with">Abrir con</string>
-    <string name="actionbar_mkdir">Nueva carpeta</string>
-    <string name="actionbar_settings">Ajustes</string>
-    <string name="actionbar_see_details">Detalles</string>
-    <string name="actionbar_send_file">Enviar</string>
-    <string name="actionbar_sort">Filtrar</string>
-    <string name="actionbar_sort_title">Filtrar por</string>
-    <string name="menu_item_sort_by_name">A - Z</string>
-    <string name="menu_item_sort_by_date">Más reciente - Más antiguo</string>
-    <string name="menu_item_sort_by_size">Más grande - Más pequeño</string>
-    <string name="drawer_item_all_files">Todos los archivos</string>
-    <string name="drawer_item_on_device">En su dispositivo</string>
-    <string name="drawer_item_settings">Ajustes</string>
-    <string name="drawer_item_uploads_list">Subidas</string>
-    <string name="drawer_quota">%1$s de %2$s usados</string>
-	<string name="drawer_close">Cerrar</string>
-    <string name="drawer_open">Abrir</string>
-    <string name="prefs_category_general">General</string>
-    <string name="prefs_category_more">Más</string>
-    <string name="prefs_accounts">Cuentas</string>
-    <string name="prefs_manage_accounts">Administrar cuentas</string>
-    <string name="prefs_passcode">Código de seguridad</string>
-    <string name="prefs_show_hidden_files">Mostrar archivos escondidos</string>
-    <string name="prefs_instant_upload">Subida instantánea de imágenes</string>
-    <string name="prefs_instant_upload_summary">Subida instantánea de fotografías tomadas por la cámara</string>
-    <string name="prefs_instant_video_upload">Subida instantánea de video</string>
-    <string name="prefs_instant_video_upload_summary">Subida instantánea de videos grabados por la cámara</string>
-    <string name="prefs_log_title">Activar registro</string>
-    <string name="prefs_log_summary">Esto es usado para registrar problemas</string>
-    <string name="prefs_log_title_history">Historial de registro</string>
-    <string name="prefs_log_summary_history">Esto muestra los registros grabados</string>
-    <string name="prefs_log_delete_history_button">Borrar historial</string>
-    <string name="prefs_calendar_contacts">Sincronizar calendario  &amp; contactos</string>
-    <string name="prefs_calendar_contacts_summary">Configure DAVdroid (v1.3.0+) para la cuenta actual</string>
-    <string name="prefs_calendar_contacts_address_resolve_error">La dirección del servidor para la cuenta no se pudo resolver para DAVdroid</string>
-    <string name="prefs_calendar_contacts_no_store_error">No se encuentran instaladas las aplicaciones Google Play o F-Droid</string>
-    <string name="prefs_calendar_contacts_sync_setup_successful">La configuración de Calendario &amp; contactos se sincronizaron exitosamente</string>
-    <string name="prefs_help">Ayuda</string>
-    <string name="prefs_recommend">Recomendar a un amigo</string>
-    <string name="prefs_feedback">Mensajes de retroalimentación</string>
-    <string name="prefs_imprint">Imprint</string>
-    <string name="prefs_remember_last_share_location">Recordar la ubicación compartida</string>
-    <string name="prefs_remember_last_upload_location_summary">Recordar la última ubicación de subida</string>
-
-	<string name="recommend_subject">Prueba  %1$s en tu smarthphone!</string>
-	<string name="recommend_text">¡Quisiera invitarlo a usar %1$s en su smartphone!\\nDescargue aquí: %2$s</string>
-
-    <string name="auth_check_server">Probar servidor</string>
-    <string name="auth_host_url">Dirección del servidor https://…</string>
-    <string name="auth_username">Nombre de usuario</string>
-    <string name="auth_password">Contraseña</string>
-    <string name="sync_string_files">Archivos</string>
-    <string name="setup_btn_connect">Conectar</string>
-    <string name="uploader_btn_upload_text">Subir</string>
-    <string name="uploader_top_message">Elegir carpeta de subida</string>
-    <string name="uploader_wrn_no_account_title">No se encontraron cuentas</string>
-    <string name="uploader_wrn_no_account_text">No hay %1$s cuentas en su dispositivo. Por favor configure una cuenta primero.</string>
-    <string name="uploader_wrn_no_account_setup_btn_text">Configuración</string>
-    <string name="uploader_wrn_no_account_quit_btn_text">Salir</string>
-    <string name="uploader_error_title_no_file_to_upload">No hay archivo para subir</string>
-    <string name="uploader_error_message_received_piece_of_text">%1$s no puede subir una pieza de texto como un archivo.</string>
-    <string name="uploader_error_message_no_file_to_upload">La información recibida no incluye un archivo válido.</string>
-    <string name="uploader_error_title_file_cannot_be_uploaded">El archivo no puede ser subido</string>
-    <string name="uploader_error_message_read_permission_not_granted">%1$s no tiene permitido leer el archivo recibido</string>
-    <string name="uploader_error_message_source_file_not_found">El archivo a subir no fue encontrado en esta localización. Por favor revise si existe el archivo.</string>
-    <string name="uploader_error_message_source_file_not_copied">Un error ocurrió mientras se copiaba el archivo a una carpeta temporal. Por favor intente enviarlo de nuevo.</string>
-    <string name="uploader_upload_files_behaviour">Opción de subida:</string>
-    <string name="uploader_upload_files_behaviour_move_to_nextcloud_folder">Mover archivo a carpeta de Nextcloud</string>
-    <string name="uploader_upload_files_behaviour_only_upload">Mantener archivo en carpeta de origen</string>
-    <string name="uploader_upload_files_behaviour_upload_and_delete_from_source">Borrar archivo de la carpeta de origen</string>
-    <string name="file_list_seconds_ago">hace segundos</string>
-    <string name="file_list_loading">Cargando&#8230;</string>
-    <string name="file_list_no_app_for_file_type">¡No hay aplicación para este tipo de archivo!</string>
-    <string name="local_file_list_empty">No hay archivos en esta carpeta</string>
-    <string name="file_list_folder">carpeta</string>
-    <string name="file_list_folders">carpetas</string>
-    <string name="file_list_file">archivo</string>
-    <string name="file_list_files">archivos</string>
-    <string name="filedetails_select_file">Pulsa sobre un archivo para mostrar información adicional.</string>
-    <string name="filedetails_size">Tamaño:</string>
-    <string name="filedetails_type">Tipo:</string>
-    <string name="filedetails_created">Creado:</string>
-    <string name="filedetails_modified">Modificado:</string>
-    <string name="filedetails_download">Descargar</string>
-    <string name="filedetails_sync_file">Sincronizar</string>
-    <string name="filedetails_renamed_in_upload_msg">El archivo fue renombrado como %1$s durante la subida</string>
-    <string name="list_layout">Vista de lista</string>
-    <string name="action_share">Compartir</string>
-    <string name="common_yes">Sí</string>
-    <string name="common_no">No</string>
-    <string name="common_ok">Aceptar</string>
-    <string name="common_remove_upload">Eliminar subida</string>
-    <string name="common_retry_upload">Reintentar subida</string>
-    <string name="common_cancel_sync">Cancelar sincronización</string>
-    <string name="common_cancel">Cancelar</string>
-    <string name="common_back">Atrás</string>
-    <string name="common_save">Guardar</string>
-    <string name="common_save_exit">Guardar &amp; salir</string>
-    <string name="common_error">Error</string>
-    <string name="common_loading">Cargando ...</string>
-    <string name="common_unknown">desconocido</string>
-    <string name="common_error_unknown">Error desconocido</string>
-    <string name="common_pending">Pendiente</string>
-    <string name="about_title">Acerca de</string>
-    <string name="change_password">Cambiar contraseña</string>
-    <string name="delete_account">Eliminar cuenta</string>
-    <string name="delete_account_warning">Eliminar cuenta %s?\\n\\nEl borrado no se puede deshacer.</string>
-    <string name="create_account">Crear cuenta</string>
-    <string name="upload_chooser_title">Subir</string>
-    <string name="uploader_info_dirname">Nombre de la carpeta</string>
-    <string name="uploader_upload_in_progress_ticker">Subiendo...</string>
-    <string name="uploader_upload_in_progress_content">%1$d%% Subiendo %2$s</string>
-    <string name="uploader_upload_succeeded_ticker">Subido con éxito</string>
-    <string name="uploader_upload_succeeded_content_single">%1$s subidos</string>
-    <string name="uploader_upload_failed_ticker">Error en la subida</string>
-    <string name="uploader_upload_failed_content_single">La subida de %1$s no se pudo completar</string>
-    <string name="uploader_upload_failed_credentials_error">Subida fallida, necesita iniciar sesión de nuevo</string>
-    <string name="uploads_view_title">Subidas</string>
-    <string name="uploads_view_group_current_uploads">Actual</string>
-    <string name="uploads_view_group_failed_uploads">Falló (toque para reintentar)</string>
-    <string name="uploads_view_group_finished_uploads">Subido</string>
-    <string name="uploads_view_upload_status_succeeded">Completado</string>
-    <string name="uploads_view_upload_status_cancelled">Cancelado</string>
-    <string name="uploads_view_upload_status_paused">Pausado</string>
-    <string name="uploads_view_upload_status_failed_connection_error">Error de conexión</string>
-    <string name="uploads_view_upload_status_failed_retry">La subida se reintentará en breve</string>
-    <string name="uploads_view_upload_status_failed_credentials_error">Error de credenciales</string>
-    <string name="uploads_view_upload_status_failed_folder_error">Error de carpeta</string>
-    <string name="uploads_view_upload_status_failed_file_error">Error de archivo</string>
-    <string name="uploads_view_upload_status_failed_localfile_error">Archivo local no encontrado</string>
-    <string name="uploads_view_upload_status_failed_permission_error">Error de permisos</string>
-    <string name="uploads_view_upload_status_conflict">Conflicto</string>
-    <string name="uploads_view_upload_status_service_interrupted">La aplicación a terminado</string>
-    <string name="uploads_view_upload_status_unknown_fail">Error desconocido</string>
-    <string name="uploads_view_upload_status_waiting_for_wifi">Esperando conexión Wi-Fi</string>
-    <string name="uploads_view_later_waiting_to_upload">Esperando para subir</string>
-    <string name="downloader_download_in_progress_ticker">Descargando ...</string>
-    <string name="downloader_download_in_progress_content">%1$s Descargada de %2$s</string>
-    <string name="downloader_download_succeeded_ticker">Descarga completa</string>
-    <string name="downloader_download_succeeded_content">%1$s descargado</string>
-    <string name="downloader_download_failed_ticker">Falló la descarga</string>
-    <string name="downloader_download_failed_content">La descarga de %1$s no se pudo completar</string>
-    <string name="downloader_not_downloaded_yet">No descargado</string>
-    <string name="downloader_download_failed_credentials_error">Descarga fallida, necesita iniciar sesión de nuevo</string>
-    <string name="common_choose_account">Elige una cuenta</string>
-    <string name="sync_fail_ticker">Sincronización fallida</string>
-    <string name="sync_fail_ticker_unauthorized">Sincronización fallida, necesita iniciar sesión de nuevo</string>
-    <string name="sync_fail_content">Sincronización de %1$s no pudo ser completada</string>
-    <string name="sync_fail_content_unauthorized">Contraseña no válida para %1$s</string>
-    <string name="sync_conflicts_in_favourites_ticker">Se encontraron conflictos</string>
-    <string name="sync_conflicts_in_favourites_content">Falló la sincronización de contenidos de %1$d archivos</string>
-    <string name="sync_fail_in_favourites_ticker">Fallos en la sincronización de contenidos</string>
-    <string name="sync_fail_in_favourites_content">Los contenidos de %1$d archivos no fueron sincronizados (%2$d conflictos)</string>
-    <string name="sync_foreign_files_forgotten_ticker">Algunos archivos locales se han perdido</string>
-    <string name="sync_foreign_files_forgotten_content">%1$d archivos de las %2$s carpetas no pudieron ser copiadas</string>
-    <string name="sync_foreign_files_forgotten_explanation">A partir de la versión 1.3.16, los archivos subidos desde este dispositivo son copiados a la carpeta local %1$s para prevenir pérdidas cuando un archivo es sincronizado en múltiples cuentas.\\n\\nDebido a este cambio, todos los archivos subidos en versiones previas de esta aplicación eran copiadas en la carpeta %2$s. Sin embargo, un error prevenía completar esta operación durante la sincronización de la cuenta. Puede elegir dejar los archivos como tal y remover el enlace a %3$s, o mover el archivo dentro de la carpeta %1$s y mantener el enlace a %4$s.\\n\\nEnlistados debajo están los archivos locales, y los archivos remotos en %5$s donde fueron enlazados.</string>
-    <string name="sync_current_folder_was_removed">La carpeta local %1$s no existe.</string>
-    <string name="foreign_files_move">Mover todo</string>
-    <string name="foreign_files_success">Todos los archivos fueron movidos</string>
-    <string name="foreign_files_fail">Algunos archivos no han podido ser movidos</string>
-    <string name="foreign_files_local_text">Local: %1$s</string>
-    <string name="foreign_files_remote_text">Remoto: %1$s</string>
-    <string name="upload_query_move_foreign_files">No hay suficiente espacio para copiar los archivos seleccionados en la carpeta %1$s. ¿Le gustaría moverlos en su lugar?</string>
-    <string name="pass_code_enter_pass_code">Por favor entre su código de seguridad</string>
-    
-    <string name="pass_code_configure_your_pass_code">Ingrese su código de seguridad</string>
-    <string name="pass_code_configure_your_pass_code_explanation">El código de seguridad será solicitado en cada ocasión que inicie la aplicación</string>
-    <string name="pass_code_reenter_your_pass_code">Por favor reingrese el código de seguridad</string>
-    <string name="pass_code_remove_your_pass_code">Eliminar su código de seguridad</string>
-    <string name="pass_code_mismatch">Los códigos de seguridad no son iguales</string>
-    <string name="pass_code_wrong">Código de seguridad incorrecto</string>
-    <string name="pass_code_removed">Código de seguridad eliminado</string>
-    <string name="pass_code_stored">Código de seguridad almacenado</string>
-    
-    <string name="media_notif_ticker">Reproductor de música %1$s</string>
-    <string name="media_state_playing">%1$s (reproduciendo)</string>
-    <string name="media_state_loading">%1$s (cargando)</string>
-    <string name="media_event_done">%1$s reproducción finalizada</string>
-    <string name="media_err_nothing_to_play">No se encuentra archivo de medio</string>
-    <string name="media_err_no_account">No se ha proporcionado cuenta</string>
-    <string name="media_err_not_in_owncloud">El archivo no esta en una cuenta valida </string>
-    <string name="media_err_unsupported">Codec No Soportado</string>
-    <string name="media_err_io">El archivo de medios no pudo ser leído </string>
-    <string name="media_err_malformed">Archivo no codificado correctamente</string>
-    <string name="media_err_timeout">Tiempo de espera agotado en el intento de reproducción</string>
-    <string name="media_err_invalid_progressive_playback">Archivo de medio no puede ser transmitido</string>
-    <string name="media_err_unknown">El archivo de medios no se puede reproducir con el reproductor de medios por defecto </string>
-    <string name="media_err_security_ex">Error de seguridad al intentar reproducir %1$s</string>
-    <string name="media_err_io_ex">Error de entrada al intentar reproducir %1$s</string>
-    <string name="media_err_unexpected">Error inesperado intentando reproducir %1$s</string>
-    <string name="media_rewind_description">Botón Rebobinado</string>
-    <string name="media_play_pause_description">Botón de reproducción o pausa </string>
-    <string name="media_forward_description">Botón avance rápido</string>
-
-	<string name="auth_getting_authorization">Obteniendo autorización &#8230;</string>
-	<string name="auth_trying_to_login">Intentando iniciar en sesión &#8230;</string>
-	<string name="auth_no_net_conn_title">Sin conexión de red</string>
-	<string name="auth_nossl_plain_ok_title">Conexión segura no disponible.</string>
-	<string name="auth_connection_established">Conexión establecida</string>
-	<string name="auth_testing_connection">Probando conexión</string>
-	<string name="auth_not_configured_title">Configuración de servidor en formato incorrecto</string>
-	<string name="auth_account_not_new">Una cuenta para el mismo usuario y servidor ya existen en el dispositivo</string>
-	<string name="auth_account_not_the_same">El usuario introducido no concuerda con el usuario de esta cuenta</string>
-	<string name="auth_unknown_error_title">Ocurrió un error desconocido</string>
-	<string name="auth_unknown_host_title">No se pudo encontrar la dirección</string>
-	<string name="auth_incorrect_path_title">Instancia de servidor no encontrada</string>
-	<string name="auth_timeout_title">El servidor ha tardado demasiado en responder</string>
-	<string name="auth_incorrect_address_title">Formato erróneo de la dirección del servidor</string>
-	<string name="auth_ssl_general_error_title">Falló la inicialización SSL</string>
-	<string name="auth_ssl_unverified_server_title">No fue posible verificar la identidad del servidor SLL</string>
-	<string name="auth_bad_oc_version_title">No se reconoce  la versión del servidor </string>
-	<string name="auth_wrong_connection_title">No se ha podido establecer la conexión</string>
-	<string name="auth_secure_connection">Conexión segura establecida</string>
-	<string name="auth_unauthorized">Nombre de usuario o contraseña incorrecta</string>
-	<string name="auth_oauth_error">Autorización no satisfactoria</string>
-	<string name="auth_oauth_error_access_denied">Acceso denegado por servidor de autorización</string>
-	<string name="auth_wtf_reenter_URL">Estado inesperado; por favor ingrese la dirección del servidor de nuevo</string>
-	<string name="auth_expired_oauth_token_toast">Su autorización ha expirado. Por favor, autorice de nuevo</string>
-	<string name="auth_expired_basic_auth_toast">Por favor ingrese la contraseña actual</string>
-	<string name="auth_expired_saml_sso_token_toast">Su sesión ha expirado. Favor de conectarse de nuevo</string>
-	<string name="auth_connecting_auth_server">Conectando al servidor de autenticación ...</string>
-	<string name="auth_unsupported_auth_method">El servidor no soporta este método de autenticación</string>
-	<string name="auth_unsupported_multiaccount">%1$s no soporta cuentas múltiples</string>
-	<string name="auth_fail_get_user_name">Su servidor no esta regresando un id de usuario correcto, por favor contacte un administrador
-	</string>
-	<string name="auth_can_not_auth_against_server">No se puede autenticar a este servidor</string>
-    <string name="auth_account_does_not_exist">La cuenta no existe aun en el dispositivo</string>
-    
-    <string name="favorite">Fijar como disponible localmente</string>
-    <string name="unfavorite">Remover como disponible localmente</string>
-    <string name="common_rename">Renombrar</string>
-    <string name="common_remove">Borrar</string>
-    <string name="confirmation_remove_file_alert">¿Realmente desea eliminar %1$s?</string>
-    <string name="confirmation_remove_folder_alert">¿Realmente desea eliminar %1$s y sus contenidos?</string>
-    <string name="confirmation_remove_local">Sólo local</string>
-    <string name="remove_success_msg">Borrado correctamente</string>
-    <string name="remove_fail_msg">El borrado no pudo ser completado</string>
-    <string name="rename_dialog_title">Introduzca un nombre nuevo</string>
-    <string name="rename_local_fail_msg">No se pudo cambiar el nombre de la copia local, trata con un nombre differente</string>
-    <string name="rename_server_fail_msg">No se pudo cambiar el nombre</string>
-    <string name="sync_file_fail_msg">No pudo comprobarse el archivo remoto</string>
-    <string name="sync_file_nothing_to_do_msg">Ya está sincronizado</string>
-    <string name="create_dir_fail_msg">La carpeta no pudo ser creada</string>
-    <string name="filename_forbidden_characters">Carácteres ilegales: / \\ &lt; &gt; : \" | ? *</string>
-    <string name="filename_forbidden_charaters_from_server">El nombre del archivo contiene al menos un carácter inválido.</string>
-    <string name="filename_empty">El nombre del archivo no puede estar vacío</string>
-    <string name="wait_a_moment">Espere un momento</string>
-    <string name="wait_checking_credentials">Revisando credenciales almacenadas</string>
-    <string name="filedisplay_unexpected_bad_get_content">Problema inesperado; por favor seleccione el archivo de una diferente aplicación</string>
-    <string name="filedisplay_no_file_selected">No fué seleccionado ningún archivo</string>
-    <string name="activity_chooser_title">Enviar enlace a &#8230;</string>
-    <string name="wait_for_tmp_copy_from_private_storage">Copiar archivo desde un alojamiento privado</string>
-    
-    <string name="oauth_check_onoff">Ingresar con oAuth2</string> 
-    <string name="oauth_login_connection">Conectando al servidor oAuth2...</string>    
-        
-    <string name="ssl_validator_header">La identidad del sitio no puede ser verificada</string>
-    <string name="ssl_validator_reason_cert_not_trusted">- El certificado del servidor no es de confianza</string>
-    <string name="ssl_validator_reason_cert_expired">- El certificado del servidor expiró</string>
-    <string name="ssl_validator_reason_cert_not_yet_valid">- El certificado del servidor es demasiado reciente</string>
-    <string name="ssl_validator_reason_hostname_not_verified">- La URL no coincide con el nombre de dominio del certificado</string>
-    <string name="ssl_validator_question">¿Confías de todas formas en este certificado?</string>
-    <string name="ssl_validator_not_saved">El certificado no pudo ser guardado</string>
-    <string name="ssl_validator_btn_details_see">Detalles</string>
-    <string name="ssl_validator_btn_details_hide">Ocultar</string>
-    <string name="ssl_validator_label_subject">Emitido para:</string>
-    <string name="ssl_validator_label_issuer">Emitido por:</string>
-    <string name="ssl_validator_label_CN">Nombre común:</string>
-    <string name="ssl_validator_label_O">Organización:</string>
-    <string name="ssl_validator_label_OU">Unidad organizativa</string>
-    <string name="ssl_validator_label_C">Pais:</string>
-    <string name="ssl_validator_label_ST">Estado:</string>
-    <string name="ssl_validator_label_L">Ubicación:</string>
-    <string name="ssl_validator_label_validity">Validez:</string>
-    <string name="ssl_validator_label_validity_from">De:</string>
-    <string name="ssl_validator_label_validity_to">A:</string>
-    <string name="ssl_validator_label_signature">Firma:</string>
-    <string name="ssl_validator_label_signature_algorithm">Algoritmo:</string>
-    <string name="digest_algorithm_not_available">El algoritmo de análisis no está disponible en su teléfono</string>
-    <string name="ssl_validator_label_certificate_fingerprint">Huella digital:</string>
-    <string name="certificate_load_problem">Hay un problema cargando el certificado.</string>
-    <string name="ssl_validator_null_cert">El certificado no pudo ser mostrado.</string>
-    <string name="ssl_validator_no_info_about_error">- No hay información acerca del error</string>
-
-    <string name="placeholder_sentence">Esto es un marcador de posición</string>
-    <string name="placeholder_filename">marcadordeposición.txt</string>
-    <string name="placeholder_filetype">Imagen PNG</string>
-    <string name="placeholder_filesize">389 KB</string>
-    <string name="placeholder_timestamp">2012/05/18 12:23 PM</string>
-    <string name="placeholder_media_time">12:23:45</string>
-
-    <string name="instant_upload_on_wifi">Subir imágenes a través de wifi únicamente</string>
-    <string name="instant_video_upload_on_wifi">Subir videos a través de wifi únicamente</string>
-    <string name="instant_video_upload_on_charging">Subir al cargar batería únicamente</string>
-    <string name="instant_upload_on_charging">Subir al cargar batería únicamente</string>
-    <string name="instant_upload_path">/SubidasInstantáneas</string>
-    <string name="conflict_title">Conflicto de archivo</string>
-    <string name="conflict_message">¿Que archivos desea mantener? Si selecciona ambas versiones, el archivo local tendrá un numero agregado a su nombre.</string>
-    <string name="conflict_keep_both">Mantener ambas</string>
-    <string name="conflict_use_local_version">versión local</string>
-    <string name="conflict_use_server_version">versión de servidor</string>
-    
-    <string name="preview_image_description">Previsualización de imagen</string>
-    <string name="preview_image_error_unknown_format">Esta imagen no puede ser mostrada</string>
-
-    <string name="error__upload__local_file_not_copied">%1$s no pudo ser copiada a la carpeta local %2$s </string>
-    <string name="prefs_instant_upload_path_title">Carpeta de subida instantánea</string>
-    <string name="prefs_folder_sync_local_path_title">Carpeta local</string>
-    <string name="prefs_folder_sync_remote_path_title">Carpeta remota</string>
-    <string name="prefs_instant_upload_path_use_subfolders_title">Use subdirectorios</string>
-    <string name="prefs_instant_upload_path_use_subfolders_summary">Almacenar en subdirectorios basados en año y mes</string>
-
-	<string name="share_link_no_support_share_api">Lo sentimos, compartir no esta habilitado en su servidor. Por favor contacte a su 
-		administrador.</string>
-	<string name="share_link_file_no_exist">Incapaz de compartir. Por favor revise si existe el archivo</string>
-	<string name="share_link_file_error">Ocurrió un error mientras se trataba de compartir este archivo o carpeta</string>
-	<string name="unshare_link_file_no_exist">Incapaz de dejar de compartir. Por favor revise si existe el archivo</string>
-	<string name="unshare_link_file_error">Ocurrió un error al tratar de dejar de compartir este archivo o carpeta</string>
-    <string name="update_link_file_no_exist">Incapaz de actualizar. Por favor revise si existe el archivo</string>
-    <string name="update_link_file_error">Ocurrió un error mientras se intentaba actualizar el recurso compartido</string>
-    <string name="share_link_password_title">Ingrese una contraseña</string>
-    <string name="share_link_empty_password">Debe ingresar una contraseña</string>
-
-    <string name="activity_chooser_send_file_title">Enviar</string>
-
-    <string name="copy_link">Copiar enlace</string>
-    <string name="clipboard_text_copied">Copiado al portapapeles</string>
-    <string name="clipboard_no_text_to_copy">No se recibió texto para copiar a este portapapeles</string>
-    <string name="clipboard_uxexpected_error">Error inesperado al copiar a portapapeles</string>
-    <string name="clipboard_label">Texto copiado de %1$s</string>
-
-    <string name="error_cant_bind_to_operations_service">Error crítico: no se pueden realizar las operaciones</string>
-
-    <string name="network_error_socket_exception">Ocurrió un error mientras se conectaba con el servidor</string>
-    <string name="network_error_socket_timeout_exception">Ocurrió un error mientras se esperaba por el servidor; la operación no pudo ser completada</string>
-    <string name="network_error_connect_timeout_exception">Ocurrió un error mientras se esperaba por el servidor; la operación no pudo ser completada</string>
-    <string name="network_host_not_available">La operación no pudo ser completada; el servidor no esta disponible</string>
-    <string name="forbidden_permissions">No tiene los permisos %s</string>
-    <string name="forbidden_permissions_rename">para renombrar este archivo</string>
-    <string name="forbidden_permissions_delete">para borrar este archivo</string>
-    <string name="share_link_forbidden_permissions">para compartir este archivo</string>
-    <string name="unshare_link_forbidden_permissions">para dejar de compartir este archivo</string>
-    <string name="update_link_forbidden_permissions">para actualizar este recurso compartido</string>
-    <string name="forbidden_permissions_create">para crear este archivo</string>
-    <string name="uploader_upload_forbidden_permissions">para subir esta carpeta</string>
-    <string name="downloader_download_file_not_found">El archivo ya no esta disponible en el servidor</string>
-
-    <string name="file_migration_dialog_title">Actualizando ruta de almacenamiento</string>
-    <string name="file_migration_finish_button">Terminar</string>
-    <string name="file_migration_preparing">Preparando para la migración&#8230;</string>
-    <string name="file_migration_checking_destination">Revisar destino&#8230;</string>
-    <string name="file_migration_saving_accounts_configuration">Guardando la configuración de las cuentas&#8230;</string>
-    <string name="file_migration_waiting_for_unfinished_sync">Esperando por sincronizaciones incompletas&#8230;</string>
-    <string name="file_migration_migrating">Moviendo información&#8230;</string>
-    <string name="file_migration_updating_index">Actualizando índice&#8230;</string>
-    <string name="file_migration_cleaning">Limpiando&#8230;</string>
-    <string name="file_migration_restoring_accounts_configuration">Restaurando configuración de cuentas&#8230;</string>
-    <string name="file_migration_ok_finished">Completado</string>
-    <string name="file_migration_failed_not_enough_space">ERROR: No hay suficiente espacio</string>
-    <string name="file_migration_failed_not_writable">ERROR: El archivo no se puede escribir</string>
-    <string name="file_migration_failed_not_readable">ERROR: El archivo no se puede leer</string>
-    <string name="file_migration_failed_dir_already_exists">ERROR: El directorio de Nextcloud ya existe</string>
-    <string name="file_migration_failed_while_coping">ERROR: Durante la migración</string>
-    <string name="file_migration_failed_while_updating_index">ERROR: Durante la actualización del índice</string>
-
-    <string name="file_migration_directory_already_exists">La carpeta de la información ya existe, ¿que hacer?</string>
-    <string name="file_migration_override_data_folder">Sobrescribir</string>
-    <string name="file_migration_use_data_folder">Usar el existente</string>
-
-    <string name="prefs_category_accounts">Cuentas</string>
-    <string name="prefs_add_account">Agregar cuenta</string>
-    <string name="drawer_manage_accounts">Administrar cuentas</string>
-    <string name="auth_redirect_non_secure_connection_title">La conexión segura esta redirigiendo a una ruta insegura</string>
-
-	<string name="actionbar_logger">Registros</string>
-	<string name="log_send_history_button">Enviar historial</string>
-	<string name="log_send_no_mail_app">No hay aplicación para mandar registros encontrados. Por favor instale una aplicación de correo</string>
-	<string name="log_send_mail_subject">Aplicación de registros %1$s Android</string>
-	<string name="log_progress_dialog_text">Cargando información &#8230;</string>
-
-	<string name="saml_authentication_required_text">Autenticación requerida</string>
-	<string name="saml_authentication_wrong_pass">Contraseña incorrecta</string>
-	<string name="actionbar_move">Mover</string>
-    <string name="actionbar_copy">Copiar</string>
-	<string name="file_list_empty_moving">No hay nada aquí. ¡Puede agregar una carpeta!</string>
-	<string name="folder_picker_choose_button_text">Seleccionar</string>
-
-    <string name="move_file_not_found">Incapaz de mover. Por favor revise si existe el archivo</string>
-    <string name="move_file_invalid_into_descendent">No es posible mover una carpeta dentro de un subdirectorio</string>
-    <string name="move_file_invalid_overwrite">El archivo ya existe en la carpeta de destino</string>
-    <string name="move_file_error">Ocurrió un error mientras se intentaba mover este archivo o carpeta</string>
-    <string name="forbidden_permissions_move">mover este archivo</string>
-
-
-    <string name="copy_file_not_found">Incapaz de copiar. Por favor revise si existe el archivo</string>
-    <string name="copy_file_invalid_into_descendent">No es posible copiar una carpeta dentro de un subdirectorio</string>
-    <string name="copy_file_invalid_overwrite">El archivo ya existe en la carpeta de destino</string>
-    <string name="copy_file_error">Ocurrió un error mientras se intentaba copiar este archivo o carpeta</string>
-    <string name="forbidden_permissions_copy">copiar este archivo</string>
-
-    <string name="prefs_category_instant_uploading">Subidas instantáneas</string>
-    <string name="prefs_category_details">Detalles</string>
-
-	<string name="prefs_instant_video_upload_path_title">Carpeta de subida instantánea de video</string>
-    <string name="auth_host_address">Dirección del servidor</string>
-    <string name="share_dialog_title">Compartiendo</string>
-    <string name="share_via_link_section_title">Enlace compartido</string>
-    <string name="share_via_link_expiration_date_label">Establecer fecha de caducidad</string>
-    <string name="share_via_link_password_label">Protección con contraseña</string>
-    <string name="share_search">Buscar</string>
-
-    <string name="share_privilege_can_share">puede compartir</string>
-    <string name="share_privilege_can_edit">puede editar</string>
-    <string name="share_privilege_can_edit_create">crear</string>
-    <string name="share_privilege_can_edit_delete">eliminar</string>
-    <string name="whats_new_skip">Saltar</string>
-</resources>

+ 5 - 0
res/xml/backup_config.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<full-backup-content>
+    <exclude domain="sharedpref" path="evernote_jobs.xml" />
+    <exclude domain="database" path="evernote_jobs.db" />
+</full-backup-content>

+ 0 - 93
src/com/owncloud/android/services/SyncedFolderJobService.java

@@ -1,93 +0,0 @@
-/**
- *   Nextcloud Android client application
- *
- *   @author Tobias Kaminsky
- *   Copyright (C) 2016 Tobias Kaminsky
- *   Copyright (C) 2016 Nextcloud
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- *   License as published by the Free Software Foundation; either
- *   version 3 of the License, or any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- *   You should have received a copy of the GNU Affero General Public
- *   License along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package com.owncloud.android.services;
-
-import android.accounts.Account;
-import android.annotation.TargetApi;
-import android.app.job.JobParameters;
-import android.app.job.JobService;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Build;
-import android.os.PersistableBundle;
-
-import com.owncloud.android.MainApp;
-import com.owncloud.android.authentication.AccountUtils;
-import com.owncloud.android.files.services.FileUploader;
-import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.operations.UploadFileOperation;
-import com.owncloud.android.utils.FileStorageUtils;
-import com.owncloud.android.utils.MimeTypeUtil;
-
-import java.io.File;
-
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
-public class SyncedFolderJobService extends JobService {
-    private static final String TAG = "SyncedFolderJobService";
-
-    public static final String LOCAL_PATH = "filePath";
-    public static final String REMOTE_PATH = "remotePath";
-    public static final String ACCOUNT = "account";
-    public static final String UPLOAD_BEHAVIOUR = "uploadBehaviour";
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        return START_REDELIVER_INTENT;
-    }
-
-    @Override
-    public boolean onStartJob(JobParameters params) {
-        Context context = MainApp.getAppContext();
-        PersistableBundle bundle = params.getExtras();
-        String filePath = bundle.getString(LOCAL_PATH);
-        String remotePath = bundle.getString(REMOTE_PATH);
-        Account account = AccountUtils.getOwnCloudAccountByName(context, bundle.getString(ACCOUNT));
-        Integer uploadBehaviour = bundle.getInt(UPLOAD_BEHAVIOUR);
-
-        Log_OC.d(TAG, "startJob: " + params.getJobId() + ", filePath: " + filePath);
-
-        File file = new File(filePath);
-
-        // File can be deleted between job generation and job execution. If file does not exist, just ignore it
-        if (file.exists()) {
-            String mimeType = MimeTypeUtil.getBestMimeTypeByFilename(file.getAbsolutePath());
-
-            FileUploader.UploadRequester requester = new FileUploader.UploadRequester();
-            requester.uploadNewFile(
-                    context,
-                    account,
-                    filePath,
-                    remotePath,
-                    uploadBehaviour,
-                    mimeType,
-                    true,           // create parent folder if not existent
-                    UploadFileOperation.CREATED_AS_INSTANT_PICTURE
-            );
-        }
-        return false;
-    }
-
-    @Override
-    public boolean onStopJob(JobParameters params) {
-        return false;
-    }
-}

+ 0 - 78
src/com/owncloud/android/services/observer/SyncedFolderObserver.java

@@ -1,78 +0,0 @@
-package com.owncloud.android.services.observer;
-
-import android.annotation.TargetApi;
-import android.app.job.JobInfo;
-import android.app.job.JobScheduler;
-import android.content.ComponentName;
-import android.content.Context;
-import android.os.Build;
-import android.os.FileObserver;
-import android.os.PersistableBundle;
-import android.util.Log;
-
-import com.owncloud.android.MainApp;
-import com.owncloud.android.datamodel.SyncedFolder;
-import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.services.SyncedFolderJobService;
-import com.owncloud.android.utils.FileStorageUtils;
-import com.owncloud.android.utils.RecursiveFileObserver;
-
-import java.io.File;
-import java.util.Date;
-
-class SyncedFolderObserver extends RecursiveFileObserver {
-
-    private Context context;
-
-    public static final String TAG = "SyncedFolderObserver";
-    private SyncedFolder syncedFolder;
-
-
-    public SyncedFolderObserver(SyncedFolder syncedFolder) {
-        super(syncedFolder.getLocalPath(), FileObserver.CREATE + FileObserver.MOVED_TO);
-
-        context = MainApp.getAppContext();
-        this.syncedFolder = syncedFolder;
-        Log_OC.d("SyncedFolderObserver", "Started watching: " + syncedFolder.getLocalPath());
-    }
-
-
-    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-    @Override
-    public void onEvent(int event, String path) {
-        Log.d(TAG, "Event: " + event + " Path: " + path);
-
-        File temp = new File(path);
-
-        // do not upload "null"-files, test if file exists and is a real file
-        if (!temp.getName().equalsIgnoreCase("null") && temp.isFile() && !temp.getName().endsWith(".tmp")) {
-            PersistableBundle bundle = new PersistableBundle();
-            // TODO extract
-            bundle.putString(SyncedFolderJobService.LOCAL_PATH, path);
-            bundle.putString(SyncedFolderJobService.REMOTE_PATH, FileStorageUtils.getInstantUploadFilePath(
-                                                                 syncedFolder.getRemotePath(), temp.getName(),
-                                                                 new Date().getTime(),
-                                                                 syncedFolder.getSubfolderByDate()));
-            bundle.putString(SyncedFolderJobService.ACCOUNT, syncedFolder.getAccount());
-            bundle.putInt(SyncedFolderJobService.UPLOAD_BEHAVIOUR, syncedFolder.getUploadAction());
-
-            JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
-
-            Long date = new Date().getTime();
-            JobInfo job = new JobInfo.Builder(
-                    date.intValue(),
-                    new ComponentName(context, SyncedFolderJobService.class))
-                    .setRequiresCharging(syncedFolder.getChargingOnly())
-                    .setMinimumLatency(10000)
-                    .setRequiredNetworkType(syncedFolder.getWifiOnly() ? JobInfo.NETWORK_TYPE_UNMETERED : JobInfo.NETWORK_TYPE_ANY)
-                    .setExtras(bundle)
-                    .setPersisted(true)
-                    .build();
-
-            Integer result = js.schedule(job);
-            if (result <= 0) {
-                Log_OC.d(TAG, "Job failed to start: " + result);
-            }
-        }
-    }
-}

+ 0 - 84
src/com/owncloud/android/services/observer/SyncedFolderObserverService.java

@@ -1,84 +0,0 @@
-package com.owncloud.android.services.observer;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Binder;
-import android.os.IBinder;
-
-import com.owncloud.android.MainApp;
-import com.owncloud.android.datamodel.SyncedFolder;
-import com.owncloud.android.datamodel.SyncedFolderProvider;
-import com.owncloud.android.lib.common.utils.Log_OC;
-
-import java.util.HashMap;
-
-public class SyncedFolderObserverService extends Service {
-    private static final String TAG = "SyncedFolderObserverService";
-    private SyncedFolderProvider mProvider;
-    private HashMap<String, SyncedFolderObserver> syncedFolderMap = new HashMap<>();
-    private final IBinder mBinder = new SyncedFolderObserverBinder();
-
-    @Override
-    public void onCreate() {
-        mProvider = new SyncedFolderProvider(MainApp.getAppContext().getContentResolver());
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        Log_OC.d(TAG, "start");
-        for (SyncedFolder syncedFolder : mProvider.getSyncedFolders()) {
-            if (syncedFolder.isEnabled()) {
-                Log_OC.d(TAG, "start observer: " + syncedFolder.getLocalPath());
-                SyncedFolderObserver observer = new SyncedFolderObserver(syncedFolder);
-                observer.startWatching();
-                syncedFolderMap.put(syncedFolder.getLocalPath(), observer);
-            }
-        }
-
-        return Service.START_NOT_STICKY;
-    }
-
-    @Override
-    public void onDestroy() {
-        for (SyncedFolderObserver observer : syncedFolderMap.values()) {
-            observer.stopWatching();
-            syncedFolderMap.remove(observer);
-        }
-    }
-
-    /**
-     * Restart oberver if it is enabled
-     * If syncedFolder exists already, use it, otherwise create new observer
-     * @param syncedFolder
-     */
-    public void restartObserver(SyncedFolder syncedFolder){
-        if (syncedFolderMap.containsKey(syncedFolder.getLocalPath())) {
-            Log_OC.d(TAG, "stop observer: " + syncedFolder.getLocalPath());
-            syncedFolderMap.get(syncedFolder.getLocalPath()).stopWatching();
-            syncedFolderMap.remove(syncedFolder.getLocalPath());
-        }
-
-        if (syncedFolder.isEnabled()) {
-            Log_OC.d(TAG, "start observer: " + syncedFolder.getLocalPath());
-            if (syncedFolderMap.containsKey(syncedFolder.getLocalPath())) {
-                syncedFolderMap.get(syncedFolder.getLocalPath()).startWatching();
-            } else {
-                SyncedFolderObserver observer = new SyncedFolderObserver(syncedFolder);
-                observer.startWatching();
-                syncedFolderMap.put(syncedFolder.getLocalPath(), observer);
-            }
-        }
-    }
-
-    @Override
-    public IBinder onBind(Intent arg0) {
-        return mBinder;
-    }
-
-    public class SyncedFolderObserverBinder extends Binder {
-        public SyncedFolderObserverService getService() {
-            return SyncedFolderObserverService.this;
-        }
-    }
-
-}

+ 0 - 27
src/com/owncloud/android/ui/fragment/AuthenticatorAccountDetailsFragment.java

@@ -1,27 +0,0 @@
-/**
- *   ownCloud Android client application
- *
- *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2015 ownCloud Inc.
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License version 2,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package com.owncloud.android.ui.fragment;
-
-import android.support.v4.app.Fragment;
-
-public class AuthenticatorAccountDetailsFragment extends Fragment {
-
-}

+ 0 - 27
src/com/owncloud/android/ui/fragment/AuthenticatorGetStartedFragment.java

@@ -1,27 +0,0 @@
-/**
- *   ownCloud Android client application
- *
- *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2015 ownCloud Inc.
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License version 2,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package com.owncloud.android.ui.fragment;
-
-import android.support.v4.app.Fragment;
-
-public class AuthenticatorGetStartedFragment extends Fragment {
-
-}

+ 0 - 525
src/com/owncloud/android/ui/fragment/ExtendedListFragment.java

@@ -1,525 +0,0 @@
-/**
- *   ownCloud Android client application
- *
- *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2016 ownCloud Inc.
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License version 2,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package com.owncloud.android.ui.fragment;
-
-import android.os.Bundle;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.StringRes;
-import android.support.v4.app.Fragment;
-import android.support.v4.view.MenuItemCompat;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.support.v7.widget.SearchView;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.GridView;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import com.getbase.floatingactionbutton.FloatingActionButton;
-import com.getbase.floatingactionbutton.FloatingActionsMenu;
-import com.owncloud.android.R;
-import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.ui.ExtendedListView;
-import com.owncloud.android.ui.activity.OnEnforceableRefreshListener;
-import com.owncloud.android.ui.adapter.FilterableListAdapter;
-
-import java.util.ArrayList;
-
-import third_parties.in.srain.cube.GridViewWithHeaderAndFooter;
-
-public class ExtendedListFragment extends Fragment
-        implements OnItemClickListener, OnEnforceableRefreshListener, SearchView.OnQueryTextListener {
-
-    protected static final String TAG = ExtendedListFragment.class.getSimpleName();
-
-    protected static final String KEY_SAVED_LIST_POSITION = "SAVED_LIST_POSITION"; 
-
-    private static final String KEY_INDEXES = "INDEXES";
-    private static final String KEY_FIRST_POSITIONS= "FIRST_POSITIONS";
-    private static final String KEY_TOPS = "TOPS";
-    private static final String KEY_HEIGHT_CELL = "HEIGHT_CELL";
-    private static final String KEY_EMPTY_LIST_MESSAGE = "EMPTY_LIST_MESSAGE";
-    private static final String KEY_IS_GRID_VISIBLE = "IS_GRID_VISIBLE";
-
-    protected SwipeRefreshLayout mRefreshListLayout;
-    private SwipeRefreshLayout mRefreshGridLayout;
-    protected SwipeRefreshLayout mRefreshEmptyLayout;
-    protected LinearLayout mEmptyListContainer;
-    protected TextView mEmptyListMessage;
-    protected TextView mEmptyListHeadline;
-    protected ImageView mEmptyListIcon;
-    protected ProgressBar mEmptyListProgress;
-
-    private FloatingActionsMenu mFabMain;
-    private FloatingActionButton mFabUpload;
-    private FloatingActionButton mFabMkdir;
-    private FloatingActionButton mFabUploadFromApp;
-
-    // Save the state of the scroll in browsing
-    private ArrayList<Integer> mIndexes;
-    private ArrayList<Integer> mFirstPositions;
-    private ArrayList<Integer> mTops;
-    private int mHeightCell = 0;
-
-    private SwipeRefreshLayout.OnRefreshListener mOnRefreshListener = null;
-
-    protected AbsListView mCurrentListView;
-    private ExtendedListView mListView;
-    private View mListFooterView;
-    private GridViewWithHeaderAndFooter mGridView;
-    private View mGridFooterView;
-
-    private FilterableListAdapter mAdapter;
-
-    protected void setListAdapter(FilterableListAdapter listAdapter) {
-        mAdapter = listAdapter;
-        mCurrentListView.setAdapter(listAdapter);
-        mCurrentListView.invalidateViews();
-    }
-
-    protected AbsListView getListView() {
-        return mCurrentListView;
-    }
-
-    public FloatingActionButton getFabUpload() {
-        return mFabUpload;
-    }
-
-    public FloatingActionButton getFabUploadFromApp() {
-        return mFabUploadFromApp;
-    }
-
-    public FloatingActionButton getFabMkdir() {
-        return mFabMkdir;
-    }
-
-    public FloatingActionsMenu getFabMain() {
-        return mFabMain;
-    }
-
-    public void switchToGridView() {
-        if (!isGridEnabled()) {
-            mListView.setAdapter(null);
-            mRefreshListLayout.setVisibility(View.GONE);
-            mRefreshGridLayout.setVisibility(View.VISIBLE);
-            mCurrentListView = mGridView;
-            setListAdapter(mAdapter);
-        }
-    }
-
-    public void switchToListView() {
-        if (isGridEnabled()) {
-            mGridView.setAdapter(null);
-            mRefreshGridLayout.setVisibility(View.GONE);
-            mRefreshListLayout.setVisibility(View.VISIBLE);
-            mCurrentListView = mListView;
-            setListAdapter(mAdapter);
-        }
-    }
-
-    public boolean isGridEnabled(){
-        return (mCurrentListView != null && mCurrentListView.equals(mGridView));
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        final MenuItem item = menu.findItem(R.id.action_search);
-        final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
-        searchView.setOnQueryTextListener(this);
-    }
-
-    public boolean onQueryTextChange(String query) {
-        mAdapter.filter(query);
-        return true;
-    }
-
-    @Override
-    public boolean onQueryTextSubmit(String query) {
-        mAdapter.filter(query);
-        return true;
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-                             Bundle savedInstanceState) {
-        Log_OC.d(TAG, "onCreateView");
-
-        View v = inflater.inflate(R.layout.list_fragment, null);
-        setupEmptyList(v);
-
-        mListView = (ExtendedListView)(v.findViewById(R.id.list_root));
-        mListView.setOnItemClickListener(this);
-        mListFooterView = inflater.inflate(R.layout.list_footer, null, false);
-
-        mGridView = (GridViewWithHeaderAndFooter) (v.findViewById(R.id.grid_root));
-        mGridView.setNumColumns(GridView.AUTO_FIT);
-        mGridView.setOnItemClickListener(this);
-
-        mGridFooterView = inflater.inflate(R.layout.list_footer, null, false);
-
-        // Pull-down to refresh layout
-        mRefreshListLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_containing_list);
-        mRefreshGridLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_containing_grid);
-        mRefreshEmptyLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_containing_empty);
-        
-        onCreateSwipeToRefresh(mRefreshListLayout);
-        onCreateSwipeToRefresh(mRefreshGridLayout);
-        onCreateSwipeToRefresh(mRefreshEmptyLayout);
-
-        mListView.setEmptyView(mRefreshEmptyLayout);
-        mGridView.setEmptyView(mRefreshEmptyLayout);
-
-        mFabMain = (FloatingActionsMenu) v.findViewById(R.id.fab_main);
-        mFabUpload = (FloatingActionButton) v.findViewById(R.id.fab_upload);
-        mFabMkdir = (FloatingActionButton) v.findViewById(R.id.fab_mkdir);
-        mFabUploadFromApp = (FloatingActionButton) v.findViewById(R.id.fab_upload_from_app);
-
-        mCurrentListView = mListView;   // list by default
-        if (savedInstanceState != null) {
-            if (savedInstanceState.getBoolean(KEY_IS_GRID_VISIBLE, false)) {
-                switchToGridView();
-            }
-            int referencePosition = savedInstanceState.getInt(KEY_SAVED_LIST_POSITION);
-            if (isGridEnabled()) {
-                Log_OC.v(TAG, "Setting grid position " + referencePosition);
-                mGridView.setSelection(referencePosition);
-            } else {
-                Log_OC.v(TAG, "Setting and centering around list position " + referencePosition);
-                mListView.setAndCenterSelection(referencePosition);
-            }
-        }
-
-        return v;
-    }
-
-    protected void setupEmptyList(View view) {
-        mEmptyListContainer = (LinearLayout) view.findViewById(R.id.empty_list_view);
-        mEmptyListMessage = (TextView) view.findViewById(R.id.empty_list_view_text);
-        mEmptyListHeadline = (TextView) view.findViewById(R.id.empty_list_view_headline);
-        mEmptyListIcon = (ImageView) view.findViewById(R.id.empty_list_icon);
-        mEmptyListProgress = (ProgressBar) view.findViewById(R.id.empty_list_progress);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        
-        if (savedInstanceState != null) {
-            mIndexes = savedInstanceState.getIntegerArrayList(KEY_INDEXES);
-            mFirstPositions = savedInstanceState.getIntegerArrayList(KEY_FIRST_POSITIONS);
-            mTops = savedInstanceState.getIntegerArrayList(KEY_TOPS);
-            mHeightCell = savedInstanceState.getInt(KEY_HEIGHT_CELL);
-            setMessageForEmptyList(savedInstanceState.getString(KEY_EMPTY_LIST_MESSAGE));
-            
-        } else {
-            mIndexes = new ArrayList<>();
-            mFirstPositions = new ArrayList<>();
-            mTops = new ArrayList<>();
-            mHeightCell = 0;
-        }
-    }    
-    
-    
-    @Override
-    public void onSaveInstanceState(Bundle savedInstanceState) {
-        super.onSaveInstanceState(savedInstanceState);
-        Log_OC.d(TAG, "onSaveInstanceState()");
-        savedInstanceState.putBoolean(KEY_IS_GRID_VISIBLE, isGridEnabled());
-        savedInstanceState.putInt(KEY_SAVED_LIST_POSITION, getReferencePosition());
-        savedInstanceState.putIntegerArrayList(KEY_INDEXES, mIndexes);
-        savedInstanceState.putIntegerArrayList(KEY_FIRST_POSITIONS, mFirstPositions);
-        savedInstanceState.putIntegerArrayList(KEY_TOPS, mTops);
-        savedInstanceState.putInt(KEY_HEIGHT_CELL, mHeightCell);
-        savedInstanceState.putString(KEY_EMPTY_LIST_MESSAGE, getEmptyViewText());
-    }
-
-    /**
-     * Calculates the position of the item that will be used as a reference to
-     * reposition the visible items in the list when the device is turned to
-     * other position.
-     * 
-     * The current policy is take as a reference the visible item in the center
-     * of the screen.
-     * 
-     * @return The position in the list of the visible item in the center of the
-     *         screen.
-     */
-    protected int getReferencePosition() {
-        if (mCurrentListView != null) {
-            return (mCurrentListView.getFirstVisiblePosition() +
-                    mCurrentListView.getLastVisiblePosition()) / 2;
-        } else {
-            return 0;
-        }
-    }
-
-
-    /*
-     * Restore index and position
-     */
-    protected void restoreIndexAndTopPosition() {
-        if (mIndexes.size() > 0) {  
-            // needs to be checked; not every browse-up had a browse-down before 
-            
-            int index = mIndexes.remove(mIndexes.size() - 1);
-            final int firstPosition = mFirstPositions.remove(mFirstPositions.size() -1);
-            int top = mTops.remove(mTops.size() - 1);
-
-            Log_OC.v(TAG, "Setting selection to position: " + firstPosition + "; top: "
-                    + top + "; index: " + index);
-
-            if (mCurrentListView!= null && mCurrentListView.equals(mListView)) {
-                if (mHeightCell*index <= mListView.getHeight()) {
-                    mListView.setSelectionFromTop(firstPosition, top);
-                } else {
-                    mListView.setSelectionFromTop(index, 0);
-                }
-
-            } else {
-                if (mHeightCell*index <= mGridView.getHeight()) {
-                    mGridView.setSelection(firstPosition);
-                    //mGridView.smoothScrollToPosition(firstPosition);
-                } else {
-                    mGridView.setSelection(index);
-                    //mGridView.smoothScrollToPosition(index);
-                }
-            }
-
-        }
-    }
-    
-    /*
-     * Save index and top position
-     */
-    protected void saveIndexAndTopPosition(int index) {
-        
-        mIndexes.add(index);
-        
-        int firstPosition = mCurrentListView.getFirstVisiblePosition();
-        mFirstPositions.add(firstPosition);
-        
-        View view = mCurrentListView.getChildAt(0);
-        int top = (view == null) ? 0 : view.getTop() ;
-
-        mTops.add(top);
-        
-        // Save the height of a cell
-        mHeightCell = (view == null || mHeightCell != 0) ? mHeightCell : view.getHeight();
-    }
-    
-    
-    @Override
-    public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
-        // to be @overriden
-    }
-
-    @Override
-    public void onRefresh() {
-        mRefreshListLayout.setRefreshing(false);
-        mRefreshGridLayout.setRefreshing(false);
-        mRefreshEmptyLayout.setRefreshing(false);
-
-        if (mOnRefreshListener != null) {
-            mOnRefreshListener.onRefresh();
-        }
-    }
-    public void setOnRefreshListener(OnEnforceableRefreshListener listener) {
-        mOnRefreshListener = listener;
-    }
-    
-
-    /**
-     * Disables swipe gesture.
-     *
-     * Sets the 'enabled' state of the refresh layouts contained in the fragment.
-     *
-     * When 'false' is set, prevents user gestures but keeps the option to refresh programatically,
-     *
-     * @param   enabled     Desired state for capturing swipe gesture.
-     */
-    public void setSwipeEnabled(boolean enabled) {
-        mRefreshListLayout.setEnabled(enabled);
-        mRefreshGridLayout.setEnabled(enabled);
-        mRefreshEmptyLayout.setEnabled(enabled);
-    }
-
-    /**
-     * Sets the 'visibility' state of the FAB contained in the fragment.
-     *
-     * When 'false' is set, FAB visibility is set to View.GONE programmatically,
-     *
-     * @param   enabled     Desired visibility for the FAB.
-     */
-    public void setFabEnabled(boolean enabled) {
-        if(enabled) {
-            mFabMain.setVisibility(View.VISIBLE);
-        } else {
-            mFabMain.setVisibility(View.GONE);
-        }
-    }
-
-    /**
-     * Set message for empty list view.
-     */
-    public void setMessageForEmptyList(String message) {
-        if (mEmptyListContainer != null && mEmptyListMessage != null) {
-            mEmptyListMessage.setText(message);
-        }
-    }
-
-    /**
-     * displays an empty list information with a headline, a message and an icon.
-     *
-     * @param headline the headline
-     * @param message  the message
-     * @param icon     the icon to be shown
-     */
-    public void setMessageForEmptyList(@StringRes int headline, @StringRes int message, @DrawableRes int icon) {
-        if (mEmptyListContainer != null && mEmptyListMessage != null) {
-            mEmptyListHeadline.setText(headline);
-            mEmptyListMessage.setText(message);
-            mEmptyListIcon.setImageResource(icon);
-
-            mEmptyListIcon.setVisibility(View.VISIBLE);
-            mEmptyListProgress.setVisibility(View.GONE);
-        }
-    }
-
-    /**
-     * Set message for empty list view.
-     */
-    public void setEmptyListMessage() {
-        setMessageForEmptyList(
-                R.string.file_list_empty_headline,
-                R.string.file_list_empty,
-                R.drawable.ic_list_empty_folder
-        );
-    }
-
-    /**
-     * Set message for empty list view.
-     */
-    public void setEmptyListLoadingMessage() {
-        if (mEmptyListContainer != null && mEmptyListMessage != null) {
-            mEmptyListHeadline.setText(R.string.file_list_loading);
-            mEmptyListMessage.setText("");
-
-            mEmptyListIcon.setVisibility(View.GONE);
-            mEmptyListProgress.setVisibility(View.VISIBLE);
-        }
-    }
-
-    /**
-     * Get the text of EmptyListMessage TextView.
-     * 
-     * @return String empty text view text-value
-     */
-    public String getEmptyViewText() {
-        return (mEmptyListContainer != null && mEmptyListMessage != null) ? mEmptyListMessage.getText().toString() : "";
-    }
-
-    protected void onCreateSwipeToRefresh(SwipeRefreshLayout refreshLayout) {
-        // Colors in animations
-        refreshLayout.setColorSchemeResources(R.color.color_accent, R.color.primary, R.color.primary_dark);
-
-        refreshLayout.setOnRefreshListener(this);
-    }
-
-    @Override
-    public void onRefresh(boolean ignoreETag) {
-        mRefreshListLayout.setRefreshing(false);
-        mRefreshGridLayout.setRefreshing(false);
-        mRefreshEmptyLayout.setRefreshing(false);
-
-        if (mOnRefreshListener != null) {
-            mOnRefreshListener.onRefresh();
-        }
-    }
-
-    protected void setChoiceMode(int choiceMode) {
-        mListView.setChoiceMode(choiceMode);
-        mGridView.setChoiceMode(choiceMode);
-    }
-
-    protected void setMultiChoiceModeListener(AbsListView.MultiChoiceModeListener listener) {
-        mListView.setMultiChoiceModeListener(listener);
-        mGridView.setMultiChoiceModeListener(listener);
-    }
-
-    /**
-     * TODO doc
-     * To be called before setAdapter, or GridViewWithHeaderAndFooter will throw an exception
-     *
-     * @param enabled flag if footer should be shown/calculated
-     */
-    protected void setFooterEnabled(boolean enabled) {
-        if (enabled) {
-            if (mGridView.getFooterViewCount() == 0 && mGridView.isCorrectAdapter()) {
-                if (mGridFooterView.getParent() != null ) {
-                    ((ViewGroup) mGridFooterView.getParent()).removeView(mGridFooterView);
-                }
-                mGridView.addFooterView(mGridFooterView, null, false);
-            }
-            mGridFooterView.invalidate();
-
-            if (mListView.getFooterViewsCount() == 0) {
-                if (mListFooterView.getParent() != null ) {
-                    ((ViewGroup) mListFooterView.getParent()).removeView(mListFooterView);
-                }
-                mListView.addFooterView(mListFooterView, null, false);
-            }
-            mListFooterView.invalidate();
-
-        } else {
-            mGridView.removeFooterView(mGridFooterView);
-            mListView.removeFooterView(mListFooterView);
-        }
-    }
-
-    /**
-     * set the list/grid footer text.
-     *
-     * @param text the footer text
-     */
-    protected void setFooterText(String text) {
-        if (text != null && text.length() > 0) {
-            ((TextView)mListFooterView.findViewById(R.id.footerText)).setText(text);
-            ((TextView)mGridFooterView.findViewById(R.id.footerText)).setText(text);
-            setFooterEnabled(true);
-
-        } else {
-            setFooterEnabled(false);
-        }
-    }
-
-}

+ 0 - 109
src/com/owncloud/android/utils/RecursiveFileObserver.java

@@ -1,109 +0,0 @@
-/**
- *   ownCloud Android client application
- *
- *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2015 ownCloud Inc.
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License version 2,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package com.owncloud.android.utils;
-
-import android.os.FileObserver;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Stack;
-
-public class RecursiveFileObserver extends FileObserver {
-
-    private final List<SingleFileObserver> mObservers =  new ArrayList<>();
-    private boolean watching = false;
-    private String mPath;
-    private int mMask;
-    
-    public RecursiveFileObserver(String path) {
-        this(path, ALL_EVENTS);
-    }
-    
-    public RecursiveFileObserver(String path, int mask) {
-        super(path, mask);
-        mPath = path;
-        mMask = mask;
-    }
-
-    @Override
-    public void startWatching() {
-        if (watching) {
-            return;
-        }
-        watching = true;
-        final Stack<String> stack = new Stack<String>();
-        stack.push(mPath);
-        
-        while (!stack.empty()) {
-            String parent = stack.pop();
-            mObservers.add(new SingleFileObserver(parent, mMask));
-            File path = new File(parent);
-            File[] files = path.listFiles();
-            if (files == null) {
-                continue;
-            }
-            for (final File file : files) {
-                if (file.isDirectory() && !file.getName().equals(".")
-                        && !file.getName().equals("..")) {
-                    stack.push(file.getPath());
-                }
-            }
-        }
-        for (int i = 0; i < mObservers.size(); i++) {
-            mObservers.get(i).startWatching();
-        }
-    }
-    
-    @Override
-    public void stopWatching() {
-        if (!watching) {
-            return;
-        }
-
-        for (int i = 0; i < mObservers.size(); ++i) {
-            mObservers.get(i).stopWatching();
-        }
-        mObservers.clear();
-        watching = false;
-    }
-    
-    @Override
-    public void onEvent(int event, String path) {
-        
-    }
-    
-    private class SingleFileObserver extends FileObserver {
-        private String mPath;
-
-        SingleFileObserver(String path, int mask) {
-            super(path, mask);
-            mPath = path;
-        }
-        
-        @Override
-        public void onEvent(int event, String path) {
-            String newPath = mPath + "/" + path;
-            RecursiveFileObserver.this.onEvent(event, newPath);
-        } 
-        
-    }
-}

+ 35 - 0
src/generic/google-services.json

@@ -0,0 +1,35 @@
+{
+  "project_info": {
+    "project_number": "",
+    "project_id": ""
+  },
+  "client": [
+    {
+      "client_info": {
+        "mobilesdk_app_id": "",
+        "android_client_info": {
+          "package_name": "com.nextcloud.client"
+        }
+      },
+      "oauth_client": [],
+      "api_key": [
+        {
+          "current_key": ""
+        }
+      ],
+      "services": {
+        "analytics_service": {
+          "status": 1
+        },
+        "appinvite_service": {
+          "status": 1,
+          "other_platform_oauth_client": []
+        },
+        "ads_service": {
+          "status": 1
+        }
+      }
+    }
+  ],
+  "configuration_version": "1"
+}

+ 14 - 8
AndroidManifest.xml → src/main/AndroidManifest.xml

@@ -20,12 +20,12 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.owncloud.android"
-    android:versionCode="10040201"
-    android:versionName="1.4.2 RC1">
+    android:versionCode="10040299"
+    android:versionName="1.4.2">
 
     <uses-sdk
         android:minSdkVersion="14"
-        android:targetSdkVersion="24" />
+        android:targetSdkVersion="25" />
 
     <!-- GET_ACCOUNTS is needed for API < 23.
         For API >= 23 results in the addition of CONTACTS group to the list of permissions that may be
@@ -61,6 +61,7 @@
         android:name=".MainApp"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"
+        android:fullBackupContent="@xml/backup_config"
         android:theme="@style/Theme.ownCloud.Toolbar"
         android:manageSpaceActivity="com.owncloud.android.ui.activity.ManageSpaceActivity">
         <activity
@@ -74,7 +75,9 @@
             </intent-filter>
         </activity>
         <activity android:name=".ui.activity.ManageAccountsActivity" />
+        <activity android:name=".ui.activity.UserInfoActivity" />
         <activity android:name=".ui.activity.ParticipateActivity" />
+        <activity android:name=".ui.activity.ActivitiesListActivity"/>
         <activity android:name=".ui.activity.FolderSyncActivity" />
         <activity android:name=".ui.activity.UploadFilesActivity" />
         <activity android:name=".ui.activity.ReceiveExternalFilesActivity"
@@ -128,10 +131,6 @@
                 android:name="android.content.SyncAdapter"
                 android:resource="@xml/syncadapter_files" />
         </service>
-        <service
-            android:name=".services.SyncedFolderJobService"
-            android:permission="android.permission.BIND_JOB_SERVICE"
-            android:exported="true"/>
 
         <provider
             android:name=".providers.FileContentProvider"
@@ -143,7 +142,7 @@
 
         <provider
             android:name=".providers.UsersAndGroupsSearchProvider"
-            android:authorities="com.nextcloud.android.providers.UsersAndGroupsSearchProvider"
+            android:authorities="@string/users_and_groups_search_authority"
             android:enabled="true"
             android:exported="false"
             android:label="@string/search_users_and_groups_hint" />
@@ -244,6 +243,13 @@
                 <action android:name="android.intent.action.BOOT_COMPLETED" />
             </intent-filter>
         </receiver>
+        <receiver android:name=".services.ShutdownReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.ACTION_SHUTDOWN" />
+                <action android:name="android.intent.action.QUICKBOOT_POWEROFF" />
+            </intent-filter>
+        </receiver>
+
 
         <service android:name=".services.observer.FileObserverService" />
 

+ 0 - 0
src/com/afollestad/sectionedrecyclerview/SectionedRecyclerViewAdapter.java → src/main/java/com/afollestad/sectionedrecyclerview/SectionedRecyclerViewAdapter.java


+ 98 - 42
src/com/owncloud/android/MainApp.java → src/main/java/com/owncloud/android/MainApp.java

@@ -1,27 +1,25 @@
 /**
- *   ownCloud Android client application
- *
- *   @author masensio
- *   @author David A. Velasco
- *   Copyright (C) 2015 ownCloud Inc.
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License version 2,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * ownCloud Android client application
  *
+ * @author masensio
+ * @author David A. Velasco
+ * Copyright (C) 2015 ownCloud Inc.
+ * <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;
 
 import android.app.Activity;
-import android.app.Application;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -32,29 +30,38 @@ import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.IBinder;
-import android.preference.PreferenceManager;
+import android.support.multidex.MultiDexApplication;
+import android.support.v4.util.Pair;
 
+import com.evernote.android.job.JobManager;
 import com.owncloud.android.authentication.PassCodeManager;
+import com.owncloud.android.datamodel.SyncedFolder;
+import com.owncloud.android.datamodel.SyncedFolderProvider;
 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
+import com.owncloud.android.db.PreferenceManager;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.services.NCJobCreator;
 import com.owncloud.android.services.observer.SyncedFolderObserverService;
 import com.owncloud.android.ui.activity.Preferences;
 import com.owncloud.android.ui.activity.WhatsNewActivity;
 
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
 
 /**
  * Main Application of the project
- * 
+ *
  * Contains methods to build the "static" strings. These strings were before constants in different
  * classes
  */
-public class MainApp extends Application {
+public class MainApp extends MultiDexApplication {
 
     private static final String TAG = MainApp.class.getSimpleName();
 
@@ -76,14 +83,16 @@ public class MainApp extends Application {
     @SuppressWarnings("unused")
     private boolean mBound;
 
-    @SuppressFBWarnings("ST")    public void onCreate(){
+    @SuppressFBWarnings("ST")
+    public void onCreate() {
         super.onCreate();
+        JobManager.create(this).addJobCreator(new NCJobCreator());
         MainApp.mContext = getApplicationContext();
 
         SharedPreferences appPrefs =
                 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
         MainApp.storagePath = appPrefs.getString(Preferences.PreferenceKeys.STORAGE_PATH, Environment.
-                              getExternalStorageDirectory().getAbsolutePath());
+                getExternalStorageDirectory().getAbsolutePath());
 
         boolean isSamlAuth = AUTH_ON.equals(getString(R.string.auth_method_saml_web_sso));
 
@@ -96,7 +105,7 @@ public class MainApp extends Application {
 
         // initialise thumbnails cache on background thread
         new ThumbnailsCacheManager.InitDiskCacheTask().execute();
-        
+
         if (BuildConfig.DEBUG) {
 
             String dataFolder = getDataFolder();
@@ -108,30 +117,34 @@ public class MainApp extends Application {
             Log_OC.d("Debug", "start logging");
         }
 
+        cleanOldEntries();
+        updateAutoUploadEntries();
+
         Log_OC.d("SyncedFolderObserverService", "Start service SyncedFolderObserverService");
         Intent i = new Intent(this, SyncedFolderObserverService.class);
         startService(i);
         bindService(i, syncedFolderObserverServiceConnection, Context.BIND_AUTO_CREATE);
 
+
         // register global protection with pass code
-        registerActivityLifecycleCallbacks( new ActivityLifecycleCallbacks() {
+        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
 
             @Override
             public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
-                Log_OC.d(activity.getClass().getSimpleName(),  "onCreate(Bundle) starting" );
+                Log_OC.d(activity.getClass().getSimpleName(), "onCreate(Bundle) starting");
                 WhatsNewActivity.runIfNeeded(activity);
                 PassCodeManager.getPassCodeManager().onActivityCreated(activity);
             }
 
             @Override
             public void onActivityStarted(Activity activity) {
-                Log_OC.d(activity.getClass().getSimpleName(),  "onStart() starting" );
+                Log_OC.d(activity.getClass().getSimpleName(), "onStart() starting");
                 PassCodeManager.getPassCodeManager().onActivityStarted(activity);
             }
 
             @Override
             public void onActivityResumed(Activity activity) {
-                Log_OC.d(activity.getClass().getSimpleName(), "onResume() starting" );
+                Log_OC.d(activity.getClass().getSimpleName(), "onResume() starting");
             }
 
             @Override
@@ -141,18 +154,18 @@ public class MainApp extends Application {
 
             @Override
             public void onActivityStopped(Activity activity) {
-                Log_OC.d(activity.getClass().getSimpleName(), "onStop() ending" );
+                Log_OC.d(activity.getClass().getSimpleName(), "onStop() ending");
                 PassCodeManager.getPassCodeManager().onActivityStopped(activity);
             }
 
             @Override
             public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
-                Log_OC.d(activity.getClass().getSimpleName(), "onSaveInstanceState(Bundle) starting" );
+                Log_OC.d(activity.getClass().getSimpleName(), "onSaveInstanceState(Bundle) starting");
             }
 
             @Override
             public void onActivityDestroyed(Activity activity) {
-                Log_OC.d(activity.getClass().getSimpleName(), "onDestroy() ending" );
+                Log_OC.d(activity.getClass().getSimpleName(), "onDestroy() ending");
             }
         });
     }
@@ -161,11 +174,11 @@ public class MainApp extends Application {
         return MainApp.mContext;
     }
 
-    public static String getStoragePath(){
+    public static String getStoragePath() {
         return MainApp.storagePath;
     }
 
-    public static void setStoragePath(String path){
+    public static void setStoragePath(String path) {
         MainApp.storagePath = path;
     }
 
@@ -192,42 +205,42 @@ public class MainApp extends Application {
     public static String getAuthority() {
         return getAppContext().getResources().getString(R.string.authority);
     }
-    
+
     //  From AccountAuthenticator
     //  public static final String AUTH_TOKEN_TYPE = "org.owncloud";
     public static String getAuthTokenType() {
         return getAppContext().getResources().getString(R.string.authority);
     }
-    
+
     //  From ProviderMeta 
     //  public static final String DB_FILE = "owncloud.db";
     public static String getDBFile() {
         return getAppContext().getResources().getString(R.string.db_file);
     }
-    
+
     //  From ProviderMeta
     //  private final String mDatabaseName = "ownCloud";
     public static String getDBName() {
         return getAppContext().getResources().getString(R.string.db_name);
     }
-     
+
     /**
      * name of data_folder, e.g., "owncloud"
      */
     public static String getDataFolder() {
         return getAppContext().getResources().getString(R.string.data_folder);
     }
-    
+
     // log_name
     public static String getLogName() {
         return getAppContext().getResources().getString(R.string.log_name);
     }
 
-    public static void showOnlyFilesOnDevice(boolean state){
+    public static void showOnlyFilesOnDevice(boolean state) {
         mOnlyOnDevice = state;
     }
 
-    public static boolean isOnlyOnDevice(){
+    public static boolean isOnlyOnDevice() {
         return mOnlyOnDevice;
     }
 
@@ -257,12 +270,55 @@ public class MainApp extends Application {
         return userAgent;
     }
 
+    private void updateAutoUploadEntries() {
+        // updates entries to reflect their true paths
+        if (!PreferenceManager.getAutoUploadPathsUpdate(this)) {
+            SyncedFolderProvider syncedFolderProvider =
+                    new SyncedFolderProvider(MainApp.getAppContext().getContentResolver());
+            syncedFolderProvider.updateAutoUploadPaths(mContext);
+        }
+    }
+    private void cleanOldEntries() {
+        // previous versions of application created broken entries in the SyncedFolderProvider
+        // database, and this cleans all that and leaves 1 (newest) entry per synced folder
+
+        if (!PreferenceManager.getLegacyClean(this)) {
+            SyncedFolderProvider syncedFolderProvider =
+                    new SyncedFolderProvider(MainApp.getAppContext().getContentResolver());
+
+            List<SyncedFolder> syncedFolderList = syncedFolderProvider.getSyncedFolders();
+            Map<Pair<String, String>, Long> syncedFolders = new HashMap<>();
+            ArrayList<Long> ids = new ArrayList<>();
+            for (SyncedFolder syncedFolder : syncedFolderList) {
+                Pair<String, String> checkPair = new Pair<>(syncedFolder.getAccount(), syncedFolder.getLocalPath());
+                if (syncedFolders.containsKey(checkPair)) {
+                    if (syncedFolder.getId() > syncedFolders.get(checkPair)) {
+                        syncedFolders.put(checkPair, syncedFolder.getId());
+                    }
+                } else {
+                    syncedFolders.put(checkPair, syncedFolder.getId());
+                }
+            }
+
+            for (Long idValue : syncedFolders.values()) {
+                ids.add(idValue);
+            }
+
+            if (ids.size() > 0) {
+                syncedFolderProvider.deleteSyncedFoldersNotInList(mContext, ids);
+            } else {
+                PreferenceManager.setLegacyClean(this, true);
+            }
+        }
+    }
+
     /** Defines callbacks for service binding, passed to bindService() */
     private ServiceConnection syncedFolderObserverServiceConnection = new ServiceConnection() {
 
         @Override
         public void onServiceConnected(ComponentName className, IBinder service) {
-            SyncedFolderObserverService.SyncedFolderObserverBinder binder = (SyncedFolderObserverService.SyncedFolderObserverBinder) service;
+            SyncedFolderObserverService.SyncedFolderObserverBinder binder =
+                    (SyncedFolderObserverService.SyncedFolderObserverBinder) service;
             mObserverService = binder.getService();
             mBound = true;
         }

+ 0 - 0
src/com/owncloud/android/authentication/AccountAuthenticator.java → src/main/java/com/owncloud/android/authentication/AccountAuthenticator.java


+ 0 - 0
src/com/owncloud/android/authentication/AccountAuthenticatorActivity.java → src/main/java/com/owncloud/android/authentication/AccountAuthenticatorActivity.java


+ 0 - 0
src/com/owncloud/android/authentication/AccountAuthenticatorService.java → src/main/java/com/owncloud/android/authentication/AccountAuthenticatorService.java


+ 8 - 9
src/com/owncloud/android/authentication/AccountUtils.java → src/main/java/com/owncloud/android/authentication/AccountUtils.java

@@ -182,6 +182,7 @@ public class AccountUtils {
             if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(authTokenType)) {
                 return SAML_SSO_PATH;
             }
+
             return WEBDAV_PATH_4_0_AND_LATER;
         }
         return null;
@@ -322,14 +323,12 @@ public class AccountUtils {
     }
 
     public static boolean hasSearchUsersSupport(Account account){
-        OwnCloudVersion serverVersion = null;
-        if (account != null) {
-            AccountManager accountMgr = AccountManager.get(MainApp.getAppContext());
-            String serverVersionStr = accountMgr.getUserData(account, Constants.KEY_OC_VERSION);
-            if (serverVersionStr != null) {
-                serverVersion = new OwnCloudVersion(serverVersionStr);
-            }
-        }
-        return (serverVersion != null ? serverVersion.isSearchUsersSupported() : false);
+        OwnCloudVersion serverVersion = getServerVersion(account);
+        return (serverVersion != null && serverVersion.isSearchUsersSupported());
+    }
+
+    public static boolean hasSearchSupport(Account account) {
+        OwnCloudVersion serverVersion = getServerVersion(account);
+        return (serverVersion != null && serverVersion.isSearchSupported());
     }
 }

+ 331 - 169
src/com/owncloud/android/authentication/AuthenticatorActivity.java → src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java

@@ -4,8 +4,10 @@
  * @author Bartek Przybylski
  * @author David A. Velasco
  * @author masensio
+ * @author Mario Danic
  * Copyright (C) 2012  Bartek Przybylski
  * Copyright (C) 2015 ownCloud Inc.
+ * Copyright (C) 2017 Mario Danic
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
@@ -18,6 +20,22 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * All changes by Mario Danic are distributed under the following terms:
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
  */
 
 package com.owncloud.android.authentication;
@@ -30,6 +48,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
+import android.content.pm.ActivityInfo;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
@@ -38,12 +57,14 @@ import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.preference.PreferenceManager;
+import android.support.annotation.Nullable;
 import android.support.v4.app.DialogFragment;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentTransaction;
 import android.text.Editable;
 import android.text.InputType;
+import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -54,6 +75,7 @@ import android.view.inputmethod.EditorInfo;
 import android.webkit.HttpAuthHandler;
 import android.webkit.SslErrorHandler;
 import android.webkit.WebView;
+import android.webkit.WebViewClient;
 import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.EditText;
@@ -85,6 +107,7 @@ import com.owncloud.android.operations.GetServerInfoOperation;
 import com.owncloud.android.operations.OAuth2GetAccessToken;
 import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
+import com.owncloud.android.ui.components.CustomEditText;
 import com.owncloud.android.ui.dialog.CredentialsDialogFragment;
 import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
 import com.owncloud.android.ui.dialog.SamlWebViewDialog;
@@ -107,6 +130,8 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
 
     private static final String TAG = AuthenticatorActivity.class.getSimpleName();
 
+    private static final String SCREEN_NAME = "Login";
+
     public static final String EXTRA_ACTION = "ACTION";
     public static final String EXTRA_ACCOUNT = "ACCOUNT";
 
@@ -144,8 +169,12 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     private static final String KEY_ASYNC_TASK_IN_PROGRESS = "AUTH_IN_PROGRESS";
     public static final String PROTOCOL_SUFFIX = "://";
     public static final String LOGIN_URL_DATA_KEY_VALUE_SEPARATOR = ":";
-    private static final String HTTPS_PROTOCOL = "https://";
-    private static final String HTTP_PROTOCOL = "http://";
+    public static final String HTTPS_PROTOCOL = "https://";
+    public static final String HTTP_PROTOCOL = "http://";
+
+    public static final String REGULAR_SERVER_INPUT_TYPE = "regular";
+    public static final String SUBDOMAIN_SERVER_INPUT_TYPE = "prefix";
+    public static final String DIRECTORY_SERVER_INPUT_TYPE = "suffix";
 
     /// parameters from EXTRAs in starter Intent
     private byte mAction;
@@ -162,7 +191,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
 
 
     /// Server PRE-Fragment elements 
-    private EditText mHostUrlInput;
+    private CustomEditText mHostUrlInput;
     private View mRefreshButton;
     private TextView mServerStatusView;
 
@@ -184,6 +213,8 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     private View mOkButton;
     private TextView mAuthStatusView;
 
+    private WebView mLoginWebView;
+
     private int mAuthStatusText = 0, mAuthStatusIcon = 0;
 
     private String mAuthToken = "";
@@ -198,6 +229,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     private final String OAUTH_TOKEN_TYPE = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType());
     private final String SAML_TOKEN_TYPE = AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType());
 
+    private boolean webViewLoginMethod;
+    private String webViewUser;
+    private String webViewPassword;
+
     /**
      * {@inheritDoc}
      *
@@ -235,42 +270,86 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             mIsFirstAuthAttempt = savedInstanceState.getBoolean(KEY_AUTH_IS_FIRST_ATTEMPT_TAG);
         }
 
+        webViewLoginMethod = !TextUtils.isEmpty(getResources().getString(R.string.webview_login_url));
+
+        if (webViewLoginMethod) {
+            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        }
+
         /// load user interface
-        setContentView(R.layout.account_setup);
+        if (!webViewLoginMethod) {
+            setContentView(R.layout.account_setup);
 
-        /// initialize general UI elements
-        initOverallUi();
+            /// initialize general UI elements
+            initOverallUi();
 
-        mOkButton = findViewById(R.id.buttonOK);
-        mOkButton.setOnClickListener(new View.OnClickListener() {
+            mOkButton = findViewById(R.id.buttonOK);
+            mOkButton.setOnClickListener(new View.OnClickListener() {
 
-            @Override
-            public void onClick(View v) {
-                onOkClick();
-            }
-        });
+                @Override
+                public void onClick(View v) {
+                    onOkClick();
+                }
+            });
 
-        findViewById(R.id.centeredRefreshButton).setOnClickListener(new View.OnClickListener() {
+            findViewById(R.id.centeredRefreshButton).setOnClickListener(new View.OnClickListener() {
 
-            @Override
-            public void onClick(View v) {
-                checkOcServer();
-            }
-        });
+                @Override
+                public void onClick(View v) {
+                    checkOcServer();
+                }
+            });
+
+            findViewById(R.id.embeddedRefreshButton).setOnClickListener(new View.OnClickListener() {
 
-        findViewById(R.id.embeddedRefreshButton).setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    checkOcServer();
+                }
+            });
+
+            /// initialize block to be moved to single Fragment to check server and get info about it
+
+            /// initialize block to be moved to single Fragment to retrieve and validate credentials
+            initAuthorizationPreFragment(savedInstanceState);
+
+        } else {
+            setContentView(R.layout.account_setup_webview);
+            mLoginWebView = (WebView) findViewById(R.id.login_webview);
+            initWebViewLogin();
+        }
+
+        initServerPreFragment(savedInstanceState);
+    }
 
+    private void initWebViewLogin() {
+        mLoginWebView.getSettings().setAllowFileAccess(false);
+        mLoginWebView.getSettings().setJavaScriptEnabled(true);
+        mLoginWebView.getSettings().setUserAgentString(MainApp.getUserAgent());
+        mLoginWebView.loadUrl(getResources().getString(R.string.webview_login_url));
+        mLoginWebView.setWebViewClient(new WebViewClient() {
             @Override
-            public void onClick(View v) {
-                checkOcServer();
+            public boolean shouldOverrideUrlLoading(WebView view, String url) {
+                if (url.startsWith(getString(R.string.login_data_own_scheme) + PROTOCOL_SUFFIX + "login/")) {
+                    parseAndLoginFromWebView(url);
+                    return true;
+                }
+                return false;
             }
         });
+    }
 
-        /// initialize block to be moved to single Fragment to check server and get info about it 
-        initServerPreFragment(savedInstanceState);
+    private void parseAndLoginFromWebView(String dataString) {
+        String prefix = getString(R.string.login_data_own_scheme) + PROTOCOL_SUFFIX + "login/";
+        LoginUrlInfo loginUrlInfo = parseLoginDataUrl(prefix, dataString);
+
+        if (loginUrlInfo != null) {
+            mServerInfo.mBaseUrl = normalizeUrlSuffix(loginUrlInfo.serverAddress);
+            webViewUser = loginUrlInfo.username;
+            webViewPassword = loginUrlInfo.password;
+            checkOcServer();
+        }
 
-        /// initialize block to be moved to single Fragment to retrieve and validate credentials 
-        initAuthorizationPreFragment(savedInstanceState);
     }
 
     private void populateLoginFields(String dataString) throws IllegalArgumentException {
@@ -294,7 +373,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     /**
      * parses a URI string and returns a login data object with the information from the URI string.
      *
-     * @param prefix URI beginning, e.g. cloud://login/
+     * @param prefix     URI beginning, e.g. cloud://login/
      * @param dataString the complete URI
      * @return login data
      * @throws IllegalArgumentException when
@@ -413,7 +492,11 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
                 mServerInfo.mIsSslConn = mServerInfo.mBaseUrl.startsWith(HTTPS_PROTOCOL);
                 mServerInfo.mVersion = AccountUtils.getServerVersion(mAccount);
             } else {
-                mServerInfo.mBaseUrl = getString(R.string.server_url).trim();
+                if (!webViewLoginMethod) {
+                    mServerInfo.mBaseUrl = getString(R.string.server_url).trim();
+                } else {
+                    mServerInfo.mBaseUrl = getString(R.string.webview_login_url).trim();
+                }
                 mServerInfo.mIsSslConn = mServerInfo.mBaseUrl.startsWith(HTTPS_PROTOCOL);
             }
         } else {
@@ -435,72 +518,74 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
 
         }
 
-        /// step 2 - set properties of UI elements (text, visibility, enabled...)
-        mHostUrlInput = (EditText) findViewById(R.id.hostUrlInput);
-        // Convert IDN to Unicode
-        mHostUrlInput.setText(DisplayUtils.convertIdn(mServerInfo.mBaseUrl, false));
-        if (mAction != ACTION_CREATE) {
-            /// lock things that should not change
-            mHostUrlInput.setEnabled(false);
-            mHostUrlInput.setFocusable(false);
-        }
-        if (isUrlInputAllowed) {
-            mRefreshButton = findViewById(R.id.embeddedRefreshButton);
-        } else {
-            findViewById(R.id.hostUrlFrame).setVisibility(View.GONE);
-            mRefreshButton = findViewById(R.id.centeredRefreshButton);
-        }
-        showRefreshButton(mServerIsChecked && !mServerIsValid &&
-                mWaitingForOpId > Integer.MAX_VALUE);
-        mServerStatusView = (TextView) findViewById(R.id.server_status_text);
-        showServerStatus();
+        if (!webViewLoginMethod) {
+            /// step 2 - set properties of UI elements (text, visibility, enabled...)
+            mHostUrlInput = (CustomEditText) findViewById(R.id.hostUrlInput);
+            // Convert IDN to Unicode
+            mHostUrlInput.setText(DisplayUtils.convertIdn(mServerInfo.mBaseUrl, false));
+            if (mAction != ACTION_CREATE) {
+                /// lock things that should not change
+                mHostUrlInput.setEnabled(false);
+                mHostUrlInput.setFocusable(false);
+            }
+            if (isUrlInputAllowed) {
+                mRefreshButton = findViewById(R.id.embeddedRefreshButton);
+            } else {
+                findViewById(R.id.hostUrlFrame).setVisibility(View.GONE);
+                mRefreshButton = findViewById(R.id.centeredRefreshButton);
+            }
+            showRefreshButton(mServerIsChecked && !mServerIsValid &&
+                    mWaitingForOpId > Integer.MAX_VALUE);
+            mServerStatusView = (TextView) findViewById(R.id.server_status_text);
+            showServerStatus();
 
-        /// step 3 - bind some listeners and options
-        mHostUrlInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
-        mHostUrlInput.setOnEditorActionListener(this);
+            /// step 3 - bind some listeners and options
+            mHostUrlInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
+            mHostUrlInput.setOnEditorActionListener(this);
 
-        /// step 4 - create listeners that will be bound at onResume
-        mHostUrlInputWatcher = new TextWatcher() {
+            /// step 4 - create listeners that will be bound at onResume
+            mHostUrlInputWatcher = new TextWatcher() {
 
-            @Override
-            public void afterTextChanged(Editable s) {
-                if (mOkButton.isEnabled() &&
-                        !mServerInfo.mBaseUrl.equals(
-                                normalizeUrl(s.toString(), mServerInfo.mIsSslConn))) {
-                    mOkButton.setEnabled(false);
+                @Override
+                public void afterTextChanged(Editable s) {
+                    if (mOkButton.isEnabled() &&
+                            !mServerInfo.mBaseUrl.equals(
+                                    normalizeUrl(s.toString(), mServerInfo.mIsSslConn))) {
+                        mOkButton.setEnabled(false);
+                    }
                 }
-            }
 
-            @Override
-            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-            }
-
-            @Override
-            public void onTextChanged(CharSequence s, int start, int before, int count) {
-                if (mAuthStatusIcon != 0) {
-                    Log_OC.d(TAG, "onTextChanged: hiding authentication status");
-                    mAuthStatusIcon = 0;
-                    mAuthStatusText = 0;
-                    showAuthStatus();
+                @Override
+                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                 }
-            }
-        };
-
 
-        // TODO find out if this is really necessary, or if it can done in a different way
-        findViewById(R.id.scroll).setOnTouchListener(new OnTouchListener() {
-            @Override
-            public boolean onTouch(View view, MotionEvent event) {
-                if (event.getAction() == MotionEvent.ACTION_DOWN &&
-                        AccountTypeUtils
-                                .getAuthTokenTypeSamlSessionCookie(MainApp
-                                        .getAccountType()).equals(mAuthTokenType) &&
-                        mHostUrlInput.hasFocus()) {
-                    checkOcServer();
+                @Override
+                public void onTextChanged(CharSequence s, int start, int before, int count) {
+                    if (mAuthStatusIcon != 0) {
+                        Log_OC.d(TAG, "onTextChanged: hiding authentication status");
+                        mAuthStatusIcon = 0;
+                        mAuthStatusText = 0;
+                        showAuthStatus();
+                    }
                 }
-                return false;
-            }
-        });
+            };
+
+
+            // TODO find out if this is really necessary, or if it can done in a different way
+            findViewById(R.id.scroll).setOnTouchListener(new OnTouchListener() {
+                @Override
+                public boolean onTouch(View view, MotionEvent event) {
+                    if (event.getAction() == MotionEvent.ACTION_DOWN &&
+                            AccountTypeUtils
+                                    .getAuthTokenTypeSamlSessionCookie(MainApp
+                                            .getAccountType()).equals(mAuthTokenType) &&
+                            mHostUrlInput.hasFocus()) {
+                        checkOcServer();
+                    }
+                    return false;
+                }
+            });
+        }
     }
 
 
@@ -629,11 +714,20 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
         outState.putString(KEY_AUTH_TOKEN_TYPE, mAuthTokenType);
         outState.putLong(KEY_WAITING_FOR_OP_ID, mWaitingForOpId);
 
-        /// Server PRE-fragment state
-        outState.putInt(KEY_SERVER_STATUS_TEXT, mServerStatusText);
-        outState.putInt(KEY_SERVER_STATUS_ICON, mServerStatusIcon);
-        outState.putBoolean(KEY_SERVER_CHECKED, mServerIsChecked);
-        outState.putBoolean(KEY_SERVER_VALID, mServerIsValid);
+        if (!webViewLoginMethod) {
+            /// Server PRE-fragment state
+            outState.putInt(KEY_SERVER_STATUS_TEXT, mServerStatusText);
+            outState.putInt(KEY_SERVER_STATUS_ICON, mServerStatusIcon);
+            outState.putBoolean(KEY_SERVER_CHECKED, mServerIsChecked);
+            outState.putBoolean(KEY_SERVER_VALID, mServerIsValid);
+
+            /// Authentication PRE-fragment state
+            outState.putBoolean(KEY_PASSWORD_EXPOSED, isPasswordVisible());
+            outState.putInt(KEY_AUTH_STATUS_ICON, mAuthStatusIcon);
+            outState.putInt(KEY_AUTH_STATUS_TEXT, mAuthStatusText);
+            outState.putString(KEY_AUTH_TOKEN, mAuthToken);
+        }
+
         outState.putBoolean(KEY_IS_SSL_CONN, mServerInfo.mIsSslConn);
         outState.putString(KEY_HOST_URL_TEXT, mServerInfo.mBaseUrl);
         if (mServerInfo.mVersion != null) {
@@ -641,18 +735,14 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
         }
         outState.putString(KEY_SERVER_AUTH_METHOD, mServerInfo.mAuthMethod.name());
 
-        /// Authentication PRE-fragment state
-        outState.putBoolean(KEY_PASSWORD_EXPOSED, isPasswordVisible());
-        outState.putInt(KEY_AUTH_STATUS_ICON, mAuthStatusIcon);
-        outState.putInt(KEY_AUTH_STATUS_TEXT, mAuthStatusText);
-        outState.putString(KEY_AUTH_TOKEN, mAuthToken);
-
         /// authentication
         outState.putBoolean(KEY_AUTH_IS_FIRST_ATTEMPT_TAG, mIsFirstAuthAttempt);
 
         /// AsyncTask (User and password)
-        outState.putString(KEY_USERNAME, mUsernameInput.getText().toString().trim());
-        outState.putString(KEY_PASSWORD, mPasswordInput.getText().toString());
+        if (!webViewLoginMethod) {
+            outState.putString(KEY_USERNAME, mUsernameInput.getText().toString().trim());
+            outState.putString(KEY_PASSWORD, mPasswordInput.getText().toString());
+        }
 
         if (mAsyncTask != null) {
             mAsyncTask.cancel(true);
@@ -714,21 +804,23 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     protected void onResume() {
         super.onResume();
 
-        // bound here to avoid spurious changes triggered by Android on device rotations
-        mHostUrlInput.setOnFocusChangeListener(this);
-        mHostUrlInput.addTextChangedListener(mHostUrlInputWatcher);
+        if (!webViewLoginMethod) {
+            // bound here to avoid spurious changes triggered by Android on device rotations
+            mHostUrlInput.setOnFocusChangeListener(this);
+            mHostUrlInput.addTextChangedListener(mHostUrlInputWatcher);
 
-        if (mNewCapturedUriFromOAuth2Redirection != null) {
-            getOAuth2AccessTokenFromCapturedRedirection();
-        }
+            if (mNewCapturedUriFromOAuth2Redirection != null) {
+                getOAuth2AccessTokenFromCapturedRedirection();
+            }
 
-        String dataString = getIntent().getDataString();
-        if (dataString != null) {
-            try {
-                populateLoginFields(dataString);
-            } catch (IllegalArgumentException e) {
-                Toast.makeText(this, "Illegal login data URL used", Toast.LENGTH_SHORT).show();
-                Log_OC.e(TAG, "Illegal login data URL used, no Login pre-fill!", e);
+            String dataString = getIntent().getDataString();
+            if (dataString != null) {
+                try {
+                    populateLoginFields(dataString);
+                } catch (IllegalArgumentException e) {
+                    Toast.makeText(this, "Illegal login data URL used", Toast.LENGTH_SHORT).show();
+                    Log_OC.e(TAG, "Illegal login data URL used, no Login pre-fill!", e);
+                }
             }
         }
 
@@ -756,8 +848,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             mOperationsServiceBinder.removeOperationListener(this);
         }
 
-        mHostUrlInput.removeTextChangedListener(mHostUrlInputWatcher);
-        mHostUrlInput.setOnFocusChangeListener(null);
+        if (!webViewLoginMethod) {
+            mHostUrlInput.removeTextChangedListener(mHostUrlInputWatcher);
+            mHostUrlInput.setOnFocusChangeListener(null);
+        }
 
         super.onPause();
     }
@@ -771,10 +865,14 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             unbindService(mOperationsServiceConnection);
             mOperationsServiceBinder = null;
         }
+
+        if (webViewLoginMethod) {
+            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
+        }
+
         super.onDestroy();
     }
 
-
     /**
      * Parses the redirection with the response to the GET AUTHORIZATION request to the
      * oAuth server and requests for the access token (GET ACCESS TOKEN)
@@ -847,15 +945,23 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
 
 
     private void checkOcServer() {
-        String uri = mHostUrlInput.getText().toString().trim();
+        String uri;
+        if (mHostUrlInput != null) {
+            uri = mHostUrlInput.getText().toString().trim();
+            mOkButton.setEnabled(false);
+            showRefreshButton(false);
+        } else {
+            uri = mServerInfo.mBaseUrl;
+        }
+
         mServerIsValid = false;
         mServerIsChecked = false;
-        mOkButton.setEnabled(false);
         mServerInfo = new GetServerInfoOperation.ServerInfo();
-        showRefreshButton(false);
 
         if (uri.length() != 0) {
-            uri = stripIndexPhpOrAppsFiles(uri, mHostUrlInput);
+            if (mHostUrlInput != null) {
+                uri = stripIndexPhpOrAppsFiles(uri, mHostUrlInput);
+            }
 
             // Handle internationalized domain names
             try {
@@ -864,9 +970,11 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
                 // Let Owncloud library check the error of the malformed URI
             }
 
-            mServerStatusText = R.string.auth_testing_connection;
-            mServerStatusIcon = R.drawable.progress_small;
-            showServerStatus();
+            if (mHostUrlInput != null) {
+                mServerStatusText = R.string.auth_testing_connection;
+                mServerStatusIcon = R.drawable.progress_small;
+                showServerStatus();
+            }
 
             Intent getServerInfoIntent = new Intent();
             getServerInfoIntent.setAction(OperationsService.ACTION_GET_SERVER_INFO);
@@ -874,6 +982,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
                     OperationsService.EXTRA_SERVER_URL,
                     normalizeUrlSuffix(uri)
             );
+
             if (mOperationsServiceBinder != null) {
                 mWaitingForOpId = mOperationsServiceBinder.queueNewOperation(getServerInfoIntent);
             } else {
@@ -883,7 +992,9 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
         } else {
             mServerStatusText = 0;
             mServerStatusIcon = 0;
-            showServerStatus();
+            if (!webViewLoginMethod) {
+                showServerStatus();
+            }
         }
     }
 
@@ -897,6 +1008,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
      *
      * @param hasFocus 'True' if focus is received, 'false' if is lost
      */
+
     private void onPasswordFocusChanged(boolean hasFocus) {
         if (hasFocus) {
             showViewPasswordButton();
@@ -976,7 +1088,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
 
             startSamlBasedFederatedSingleSignOnAuthorization();
         } else {
-            checkBasicAuthorization();
+            checkBasicAuthorization(null, null);
         }
 
     }
@@ -986,10 +1098,17 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
      * Tests the credentials entered by the user performing a check of existence on
      * the root folder of the ownCloud server.
      */
-    private void checkBasicAuthorization() {
+    private void checkBasicAuthorization(@Nullable String webViewUsername, @Nullable String webViewPassword) {
         /// get basic credentials entered by user
-        String username = mUsernameInput.getText().toString().trim();
-        String password = mPasswordInput.getText().toString();
+        String username;
+        String password;
+        if (!webViewLoginMethod) {
+            username = mUsernameInput.getText().toString().trim();
+            password = mPasswordInput.getText().toString();
+        } else {
+            username = webViewUsername;
+            password = webViewPassword;
+        }
 
         /// be gentle with the user
         IndeterminateProgressDialog dialog =
@@ -1093,11 +1212,13 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             }
 
             if (mAction == ACTION_CREATE) {
-                mUsernameInput.setText(username);
+                if (!webViewLoginMethod) {
+                    mUsernameInput.setText(username);
+                }
                 success = createAccount(result);
             } else {
 
-                if (!mUsernameInput.getText().toString().trim().equals(username)) {
+                if (!webViewLoginMethod && !mUsernameInput.getText().toString().trim().equals(username)) {
                     // fail - not a new account, but an existing one; disallow
                     result = new RemoteOperationResult(ResultCode.ACCOUNT_NOT_THE_SAME);
                     mAuthToken = "";
@@ -1122,8 +1243,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
                 finish();
             }
         } else {
-            updateStatusIconFailUserName();
-            showAuthStatus();
+            if (!webViewLoginMethod) {
+                updateStatusIconFailUserName();
+                showAuthStatus();
+            }
             Log_OC.e(TAG, "Access to user name failed: " + result.getLogMessage());
         }
 
@@ -1141,7 +1264,9 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
         mWaitingForOpId = Long.MAX_VALUE;
 
         // update server status, but don't show it yet
-        updateServerStatusIconAndText(result);
+        if (!webViewLoginMethod) {
+            updateServerStatusIconAndText(result);
+        }
 
         if (result.isSuccess()) {
             /// SUCCESS means:
@@ -1151,9 +1276,16 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             //      4. we got the authentication method required by the server 
             mServerInfo = (GetServerInfoOperation.ServerInfo) (result.getData().get(0));
 
+            if (webViewLoginMethod) {
+                checkBasicAuthorization(webViewUser, webViewPassword);
+            }
+
             if (!authSupported(mServerInfo.mAuthMethod)) {
 
-                updateServerStatusIconNoRegularAuth();  // overrides updateServerStatusIconAndText()  
+                if (!webViewLoginMethod) {
+                    // overrides updateServerStatusIconAndText()
+                    updateServerStatusIconNoRegularAuth();
+                }
                 mServerIsValid = false;
 
             } else {
@@ -1165,9 +1297,11 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
         }
 
         // refresh UI
-        showRefreshButton(!mServerIsValid);
-        showServerStatus();
-        mOkButton.setEnabled(mServerIsValid);
+        if (!webViewLoginMethod) {
+            showRefreshButton(!mServerIsValid);
+            showServerStatus();
+            mOkButton.setEnabled(mServerIsValid);
+        }
 
         /// very special case (TODO: move to a common place for all the remote operations)
         if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) {
@@ -1495,11 +1629,13 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             showServerStatus();
             mAuthStatusIcon = 0;
             mAuthStatusText = 0;
-            showAuthStatus();
+            if (!webViewLoginMethod) {
+                showAuthStatus();
 
-            // update input controls state
-            showRefreshButton(true);
-            mOkButton.setEnabled(false);
+                // update input controls state
+                showRefreshButton(true);
+                mOkButton.setEnabled(false);
+            }
 
             // very special case (TODO: move to a common place for all the remote operations)
             if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) {
@@ -1507,8 +1643,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             }
 
         } else {    // authorization fail due to client side - probably wrong credentials
-            updateAuthStatusIconAndText(result);
-            showAuthStatus();
+            if (!webViewLoginMethod) {
+                updateAuthStatusIconAndText(result);
+                showAuthStatus();
+            }
             Log_OC.d(TAG, "Access failed: " + result.getLogMessage());
         }
     }
@@ -1546,8 +1684,13 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
 
         } else {
-            response.putString(AccountManager.KEY_AUTHTOKEN, mPasswordInput.getText().toString());
-            mAccountMgr.setPassword(mAccount, mPasswordInput.getText().toString());
+            if (!webViewLoginMethod) {
+                response.putString(AccountManager.KEY_AUTHTOKEN, mPasswordInput.getText().toString());
+                mAccountMgr.setPassword(mAccount, mPasswordInput.getText().toString());
+            } else {
+                response.putString(AccountManager.KEY_AUTHTOKEN, webViewPassword);
+                mAccountMgr.setPassword(mAccount, webViewPassword);
+            }
         }
 
         // remove managed clients for this account to enforce creation with fresh credentials
@@ -1583,7 +1726,12 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
         }
 
         Uri uri = Uri.parse(mServerInfo.mBaseUrl);
-        String username = mUsernameInput.getText().toString().trim();
+        String username;
+        if (!webViewLoginMethod) {
+            username = mUsernameInput.getText().toString().trim();
+        } else {
+            username = webViewUser;
+        }
         if (isOAuth) {
             username = "OAuth_user" + (new java.util.Random(System.currentTimeMillis())).nextLong();
         }
@@ -1593,8 +1741,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
         if (AccountUtils.exists(newAccount, getApplicationContext())) {
             // fail - not a new account, but an existing one; disallow
             RemoteOperationResult result = new RemoteOperationResult(ResultCode.ACCOUNT_NOT_NEW);
-            updateAuthStatusIconAndText(result);
-            showAuthStatus();
+            if (!webViewLoginMethod) {
+                updateAuthStatusIconAndText(result);
+                showAuthStatus();
+            }
             Log_OC.d(TAG, result.getLogMessage());
             return false;
 
@@ -1605,9 +1755,15 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
                 // with external authorizations, the password is never input in the app
                 mAccountMgr.addAccountExplicitly(mAccount, "", null);
             } else {
-                mAccountMgr.addAccountExplicitly(
-                        mAccount, mPasswordInput.getText().toString(), null
-                );
+                if (!webViewLoginMethod) {
+                    mAccountMgr.addAccountExplicitly(
+                            mAccount, mPasswordInput.getText().toString(), null
+                    );
+                } else {
+                    mAccountMgr.addAccountExplicitly(
+                            mAccount, webViewPassword, null
+                    );
+                }
             }
 
             // include account version with the new account
@@ -1690,15 +1846,16 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
      * to the last check on the ownCloud server.
      */
     private void showServerStatus() {
-        if (mServerStatusIcon == 0 && mServerStatusText == 0) {
-            mServerStatusView.setVisibility(View.INVISIBLE);
+        if (!webViewLoginMethod) {
+            if (mServerStatusIcon == 0 && mServerStatusText == 0) {
+                mServerStatusView.setVisibility(View.INVISIBLE);
 
-        } else {
-            mServerStatusView.setText(mServerStatusText);
-            mServerStatusView.setCompoundDrawablesWithIntrinsicBounds(mServerStatusIcon, 0, 0, 0);
-            mServerStatusView.setVisibility(View.VISIBLE);
+            } else {
+                mServerStatusView.setText(mServerStatusText);
+                mServerStatusView.setCompoundDrawablesWithIntrinsicBounds(mServerStatusIcon, 0, 0, 0);
+                mServerStatusView.setVisibility(View.VISIBLE);
+            }
         }
-
     }
 
 
@@ -1707,22 +1864,26 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
      * to the interactions with the OAuth authorization server.
      */
     private void showAuthStatus() {
-        if (mAuthStatusIcon == 0 && mAuthStatusText == 0) {
-            mAuthStatusView.setVisibility(View.INVISIBLE);
+        if (!webViewLoginMethod) {
+            if (mAuthStatusIcon == 0 && mAuthStatusText == 0) {
+                mAuthStatusView.setVisibility(View.INVISIBLE);
 
-        } else {
-            mAuthStatusView.setText(mAuthStatusText);
-            mAuthStatusView.setCompoundDrawablesWithIntrinsicBounds(mAuthStatusIcon, 0, 0, 0);
-            mAuthStatusView.setVisibility(View.VISIBLE);
+            } else {
+                mAuthStatusView.setText(mAuthStatusText);
+                mAuthStatusView.setCompoundDrawablesWithIntrinsicBounds(mAuthStatusIcon, 0, 0, 0);
+                mAuthStatusView.setVisibility(View.VISIBLE);
+            }
         }
     }
 
 
     private void showRefreshButton(boolean show) {
-        if (show) {
-            mRefreshButton.setVisibility(View.VISIBLE);
-        } else {
-            mRefreshButton.setVisibility(View.GONE);
+        if (webViewLoginMethod) {
+            if (show) {
+                mRefreshButton.setVisibility(View.VISIBLE);
+            } else {
+                mRefreshButton.setVisibility(View.GONE);
+            }
         }
     }
 
@@ -1779,7 +1940,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
                 inputField.equals(mHostUrlInput) &&
                 AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).
                         equals(mAuthTokenType)) {
-                checkOcServer();
+            checkOcServer();
         }
         return false;   // always return false to grant that the software keyboard is hidden anyway
     }
@@ -1935,7 +2096,8 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             mOperationsServiceBinder.dispatchResultIfFinished((int) mWaitingForOpId, this);
         }
 
-        if (mHostUrlInput.getText() != null && mHostUrlInput.getText().length() > 0 && !mServerIsChecked) {
+        if (!webViewLoginMethod && mHostUrlInput.getText() != null && mHostUrlInput.getText().length() > 0
+                && !mServerIsChecked) {
             checkOcServer();
         }
     }

+ 0 - 0
src/com/owncloud/android/authentication/AuthenticatorAsyncTask.java → src/main/java/com/owncloud/android/authentication/AuthenticatorAsyncTask.java


+ 0 - 0
src/com/owncloud/android/authentication/LoginUrlInfo.java → src/main/java/com/owncloud/android/authentication/LoginUrlInfo.java


+ 0 - 0
src/com/owncloud/android/authentication/OAuth2Constants.java → src/main/java/com/owncloud/android/authentication/OAuth2Constants.java


+ 0 - 0
src/com/owncloud/android/authentication/PassCodeManager.java → src/main/java/com/owncloud/android/authentication/PassCodeManager.java


+ 0 - 0
src/com/owncloud/android/authentication/SsoWebViewClient.java → src/main/java/com/owncloud/android/authentication/SsoWebViewClient.java


+ 9 - 5
src/com/owncloud/android/datamodel/FileDataStorageManager.java → src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -190,7 +190,7 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
         cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
         cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
-        cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.isFavorite() ? 1 : 0);
+        cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.isAvailableOffline() ? 1 : 0);
         cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
         cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
         cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
@@ -303,7 +303,7 @@ public class FileDataStorageManager {
             cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
             cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
             cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
-            cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.isFavorite() ? 1 : 0);
+            cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.isAvailableOffline() ? 1 : 0);
             cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
             cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
             cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
@@ -313,6 +313,7 @@ public class FileDataStorageManager {
             cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail());
             cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading());
             cv.put(ProviderTableMeta.FILE_ETAG_IN_CONFLICT, file.getEtagInConflict());
+            cv.put(ProviderTableMeta.FILE_FAVORITE, file.getIsFavorite());
 
             boolean existsByPath = fileExists(file.getRemotePath());
             if (existsByPath || fileExists(file.getFileId())) {
@@ -380,13 +381,14 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
         cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, folder.getLastSyncDateForProperties());
         cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, folder.getLastSyncDateForData());
-        cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, folder.isFavorite() ? 1 : 0);
+        cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, folder.isAvailableOffline() ? 1 : 0);
         cv.put(ProviderTableMeta.FILE_ETAG, folder.getEtag());
         cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, folder.isSharedViaLink() ? 1 : 0);
         cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, folder.isSharedWithSharee() ? 1 : 0);
         cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, folder.getPublicLink());
         cv.put(ProviderTableMeta.FILE_PERMISSIONS, folder.getPermissions());
         cv.put(ProviderTableMeta.FILE_REMOTE_ID, folder.getRemoteId());
+        cv.put(ProviderTableMeta.FILE_FAVORITE, folder.getIsFavorite());
 
         operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
                 withValues(cv).
@@ -895,7 +897,7 @@ public class FileDataStorageManager {
                     c.getColumnIndex(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA)));
             file.setLastSyncDateForProperties(c.getLong(c.getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE)));
             file.setLastSyncDateForData(c.getLong(c.getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA)));
-            file.setFavorite(c.getInt(c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false);
+            file.setAvailableOffline(c.getInt(c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false);
             file.setEtag(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_ETAG)));
             file.setShareViaLink(c.getInt(
                     c.getColumnIndex(ProviderTableMeta.FILE_SHARED_VIA_LINK)) == 1 ? true : false);
@@ -909,6 +911,7 @@ public class FileDataStorageManager {
             file.setDownloading(c.getInt(
                     c.getColumnIndex(ProviderTableMeta.FILE_IS_DOWNLOADING)) == 1 ? true : false);
             file.setEtagInConflict(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_ETAG_IN_CONFLICT)));
+            file.setFavorite(c.getInt(c.getColumnIndex(ProviderTableMeta.FILE_FAVORITE)) == 1 ? true : false);
 
         }
         return file;
@@ -1315,13 +1318,14 @@ public class FileDataStorageManager {
                         ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA,
                         file.getLastSyncDateForData()
                 );
-                cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.isFavorite() ? 1 : 0);
+                cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.isAvailableOffline() ? 1 : 0);
                 cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
                 cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
                 cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
                 cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
                 cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
                 cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
+                cv.put(ProviderTableMeta.FILE_FAVORITE, file.getIsFavorite());
                 cv.put(
                         ProviderTableMeta.FILE_UPDATE_THUMBNAIL,
                         file.needsUpdateThumbnail() ? 1 : 0

+ 0 - 0
src/com/owncloud/android/datamodel/MediaFolder.java → src/main/java/com/owncloud/android/datamodel/MediaFolder.java


+ 1 - 2
src/com/owncloud/android/datamodel/MediaProvider.java → src/main/java/com/owncloud/android/datamodel/MediaProvider.java

@@ -86,8 +86,7 @@ public class MediaProvider {
                         filePath = cursorImages.getString(cursorImages.getColumnIndexOrThrow(
                                 MediaStore.MediaColumns.DATA));
                         mediaFolder.filePaths.add(filePath);
-                        mediaFolder.absolutePath = filePath.substring(0, filePath.lastIndexOf(folderName)
-                                + folderName.length());
+                        mediaFolder.absolutePath = filePath.substring(0, filePath.lastIndexOf("/"));
                     }
                     cursorImages.close();
 

+ 24 - 12
src/com/owncloud/android/datamodel/OCFile.java → src/main/java/com/owncloud/android/datamodel/OCFile.java

@@ -74,7 +74,7 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
     private boolean mNeedsUpdating;
     private long mLastSyncDateForProperties;
     private long mLastSyncDateForData;
-    private boolean mFavorite;
+    private boolean mAvailableOffline;
 
     private String mEtag;
 
@@ -92,6 +92,8 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
 
     private boolean mShareWithSharee;
 
+    private boolean mIsFavorite;
+
     /**
      * URI to the local path of the file contents, if stored in the device; cached after first call
      * to {@link #getStorageUri()}
@@ -139,7 +141,7 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
         mLocalPath = source.readString();
         mMimeType = source.readString();
         mNeedsUpdating = source.readInt() == 0;
-        mFavorite = source.readInt() == 1;
+        mAvailableOffline = source.readInt() == 1;
         mLastSyncDateForProperties = source.readLong();
         mLastSyncDateForData = source.readLong();
         mEtag = source.readString();
@@ -151,7 +153,7 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
         mIsDownloading = source.readInt() == 1;
         mEtagInConflict = source.readString();
         mShareWithSharee = source.readInt() == 1;
-
+        mIsFavorite = source.readInt() == 1;
     }
 
     @Override
@@ -166,7 +168,7 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
         dest.writeString(mLocalPath);
         dest.writeString(mMimeType);
         dest.writeInt(mNeedsUpdating ? 1 : 0);
-        dest.writeInt(mFavorite ? 1 : 0);
+        dest.writeInt(mAvailableOffline ? 1 : 0);
         dest.writeLong(mLastSyncDateForProperties);
         dest.writeLong(mLastSyncDateForData);
         dest.writeString(mEtag);
@@ -178,6 +180,15 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
         dest.writeInt(mIsDownloading ? 1 : 0);
         dest.writeString(mEtagInConflict);
         dest.writeInt(mShareWithSharee ? 1 : 0);
+        dest.writeInt(mIsFavorite ? 1 : 0);
+    }
+
+    public boolean getIsFavorite() {
+        return mIsFavorite;
+    }
+
+    public void setFavorite(boolean mIsFavorite) {
+        this.mIsFavorite = mIsFavorite;
     }
 
     /**
@@ -412,7 +423,7 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
         mModifiedTimestampAtLastSyncForData = 0;
         mLastSyncDateForProperties = 0;
         mLastSyncDateForData = 0;
-        mFavorite = false;
+        mAvailableOffline = false;
         mNeedsUpdating = false;
         mEtag = null;
         mShareByLink = false;
@@ -423,6 +434,7 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
         mIsDownloading = false;
         mEtagInConflict = null;
         mShareWithSharee = false;
+        mIsFavorite = false;
     }
 
     /**
@@ -521,12 +533,12 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
         mLastSyncDateForData = lastSyncDate;
     }
 
-    public void setFavorite(boolean favorite) {
-        mFavorite = favorite;
+    public void setAvailableOffline(boolean availableOffline) {
+        mAvailableOffline = availableOffline;
     }
 
-    public boolean isFavorite() {
-        return mFavorite;
+    public boolean isAvailableOffline() {
+        return mAvailableOffline;
     }
 
     @Override
@@ -570,10 +582,10 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
     @Override
     public String toString() {
         String asString = "[id=%s, name=%s, mime=%s, downloaded=%s, local=%s, remote=%s, " +
-                "parentId=%s, favorite=%s etag=%s]";
+                "parentId=%s, availableOffline=%s etag=%s favourite=%s]";
         asString = String.format(asString, mId, getFileName(), mMimeType, isDown(),
-                mLocalPath, mRemotePath, mParentId, mFavorite,
-                mEtag);
+                mLocalPath, mRemotePath, mParentId, mAvailableOffline,
+                mEtag, mIsFavorite);
         return asString;
     }
 

+ 4 - 1
src/com/owncloud/android/datamodel/SyncedFolder.java → src/main/java/com/owncloud/android/datamodel/SyncedFolder.java

@@ -21,11 +21,14 @@
 
 package com.owncloud.android.datamodel;
 
+import java.io.Serializable;
+
 /**
  * Synced folder entity containing all information per synced folder.
  */
-public class SyncedFolder {
+public class SyncedFolder implements Serializable {
     public static final long UNPERSISTED_ID = Long.MIN_VALUE;
+    private static final long serialVersionUID = -793476118299906429L;
     private long id = UNPERSISTED_ID;
     private String localPath;
     private String remotePath;

+ 8 - 0
src/com/owncloud/android/datamodel/SyncedFolderDisplayItem.java → src/main/java/com/owncloud/android/datamodel/SyncedFolderDisplayItem.java

@@ -57,6 +57,14 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
         this.numberOfFiles = numberOfFiles;
     }
 
+    public SyncedFolderDisplayItem(long id, String localPath, String remotePath, Boolean wifiOnly, Boolean chargingOnly,
+                                   Boolean subfolderByDate, String account, Integer uploadAction, Boolean enabled,
+                                   String folderName) {
+        super(id, localPath, remotePath, wifiOnly, chargingOnly, subfolderByDate, account, uploadAction, enabled);
+        this.folderName = folderName;
+    }
+
+
     public List<String> getFilePaths() {
         return filePaths;
     }

+ 94 - 12
src/com/owncloud/android/datamodel/SyncedFolderProvider.java → src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java

@@ -21,14 +21,17 @@ package com.owncloud.android.datamodel;
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
+import android.content.Context;
 import android.database.Cursor;
 import android.net.Uri;
 import android.support.annotation.NonNull;
 
 import com.owncloud.android.MainApp;
+import com.owncloud.android.db.PreferenceManager;
 import com.owncloud.android.db.ProviderMeta;
 import com.owncloud.android.lib.common.utils.Log_OC;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Observable;
@@ -165,7 +168,7 @@ public class SyncedFolderProvider extends Observable {
         Cursor cursor = mContentResolver.query(
                 ProviderMeta.ProviderTableMeta.CONTENT_URI_SYNCED_FOLDERS,
                 null,
-                ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_LOCAL_PATH + "==" + localPath,
+                ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_LOCAL_PATH + "== \"" + localPath + "\"",
                 null,
                 null
         );
@@ -186,6 +189,73 @@ public class SyncedFolderProvider extends Observable {
 
     }
 
+    /**
+     * Delete a synced folder from the db
+     *
+     * @param id for the synced folder.
+     */
+
+    private int deleteSyncFolderWithId(long id) {
+        int result = mContentResolver.delete(
+                ProviderMeta.ProviderTableMeta.CONTENT_URI_SYNCED_FOLDERS,
+                ProviderMeta.ProviderTableMeta._ID + " = ?",
+                new String[]{String.valueOf(id)}
+        );
+
+        return result;
+    }
+
+    /**
+     * Try to figure out if a path exists for synced folder, and if not, go one folder back
+     * Otherwise, delete the entry
+     *
+     * @param context the context.
+     */
+    public void updateAutoUploadPaths(Context context) {
+        List<SyncedFolder> syncedFolders = getSyncedFolders();
+        for (int i = 0; i < syncedFolders.size(); i++) {
+            SyncedFolder syncedFolder = syncedFolders.get(i);
+            if (!new File(syncedFolder.getLocalPath()).exists()) {
+                String localPath = syncedFolder.getLocalPath();
+                if (localPath.endsWith("/")) {
+                    localPath = localPath.substring(0, localPath.lastIndexOf("/"));
+                }
+                localPath = localPath.substring(0, localPath.lastIndexOf("/"));
+                if (new File(localPath).exists()) {
+                    syncedFolders.get(i).setLocalPath(localPath);
+                    updateSyncFolder(syncedFolder);
+                } else {
+                    deleteSyncFolderWithId(syncedFolder.getId());
+                }
+            }
+        }
+
+        if (context != null) {
+            PreferenceManager.setAutoUploadPathsUpdate(context, true);
+        }
+    }
+
+    /**
+     * delete any records of synchronized folders that are not within the given list of ids.
+     *
+     * @param context the context.
+     * @param ids     the list of ids to be excluded from deletion.
+     * @return number of deleted records.
+     */
+    public int deleteSyncedFoldersNotInList(Context context, ArrayList<Long> ids) {
+        int result = mContentResolver.delete(
+                ProviderMeta.ProviderTableMeta.CONTENT_URI_SYNCED_FOLDERS,
+                ProviderMeta.ProviderTableMeta._ID + " NOT IN (?)",
+                new String[]{String.valueOf(ids)}
+        );
+
+        if (result > 0 && context != null) {
+            PreferenceManager.setLegacyClean(context, true);
+        }
+
+        return result;
+    }
+
     /**
      * update given synced folder.
      *
@@ -214,21 +284,29 @@ public class SyncedFolderProvider extends Observable {
     /**
      * maps a cursor into a SyncedFolder object.
      *
-     * @param cursor the cursor
+     * @param cursor the db cursor
      * @return the mapped SyncedFolder, null if cursor is null
      */
     private SyncedFolder createSyncedFolderFromCursor(Cursor cursor) {
         SyncedFolder syncedFolder = null;
         if (cursor != null) {
             long id = cursor.getLong(cursor.getColumnIndex(ProviderMeta.ProviderTableMeta._ID));
-            String localPath = cursor.getString(cursor.getColumnIndex(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_LOCAL_PATH));
-            String remotePath = cursor.getString(cursor.getColumnIndex(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_REMOTE_PATH));
-            Boolean wifiOnly = cursor.getInt(cursor.getColumnIndex(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_WIFI_ONLY)) == 1;
-            Boolean chargingOnly = cursor.getInt(cursor.getColumnIndex(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_CHARGING_ONLY)) == 1;
-            Boolean subfolderByDate = cursor.getInt(cursor.getColumnIndex(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_BY_DATE)) == 1;
-            String accountName = cursor.getString(cursor.getColumnIndex(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_ACCOUNT));
-            Integer uploadAction = cursor.getInt(cursor.getColumnIndex(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_UPLOAD_ACTION));
-            Boolean enabled = cursor.getInt(cursor.getColumnIndex(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_ENABLED)) == 1;
+            String localPath = cursor.getString(cursor.getColumnIndex(
+                    ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_LOCAL_PATH));
+            String remotePath = cursor.getString(cursor.getColumnIndex(
+                    ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_REMOTE_PATH));
+            Boolean wifiOnly = cursor.getInt(cursor.getColumnIndex(
+                    ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_WIFI_ONLY)) == 1;
+            Boolean chargingOnly = cursor.getInt(cursor.getColumnIndex(
+                    ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_CHARGING_ONLY)) == 1;
+            Boolean subfolderByDate = cursor.getInt(cursor.getColumnIndex(
+                    ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_BY_DATE)) == 1;
+            String accountName = cursor.getString(cursor.getColumnIndex(
+                    ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_ACCOUNT));
+            Integer uploadAction = cursor.getInt(cursor.getColumnIndex(
+                    ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_UPLOAD_ACTION));
+            Boolean enabled = cursor.getInt(cursor.getColumnIndex(
+                    ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_ENABLED)) == 1;
 
             syncedFolder = new SyncedFolder(id, localPath, remotePath, wifiOnly, chargingOnly, subfolderByDate,
                     accountName, uploadAction, enabled);
@@ -258,9 +336,13 @@ public class SyncedFolderProvider extends Observable {
 
     /**
      * Inform all observers about data change.
+     *
+     * @param syncedFolder changed, synchronized folder
      */
     private void notifyFolderSyncObservers(SyncedFolder syncedFolder) {
-        MainApp.getSyncedFolderObserverService().restartObserver(syncedFolder);
-        Log_OC.d(TAG, "notifying folder sync data observers for changed/added: " + syncedFolder.getLocalPath());
+        if (syncedFolder != null) {
+            MainApp.getSyncedFolderObserverService().restartObserver(syncedFolder);
+            Log_OC.d(TAG, "notifying folder sync data observers for changed/added: " + syncedFolder.getLocalPath());
+        }
     }
 }

+ 0 - 0
src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java → src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java


+ 28 - 21
src/com/owncloud/android/datamodel/UploadsStorageManager.java → src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java

@@ -20,17 +20,17 @@
  */
 package com.owncloud.android.datamodel;
 
-import android.app.job.JobInfo;
-import android.app.job.JobScheduler;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Build;
-import android.os.PersistableBundle;
 import android.support.annotation.RequiresApi;
 
+import com.evernote.android.job.JobManager;
+import com.evernote.android.job.JobRequest;
+import com.evernote.android.job.util.support.PersistableBundleCompat;
 import com.owncloud.android.db.OCUpload;
 import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
 import com.owncloud.android.db.UploadResult;
@@ -44,6 +44,7 @@ import java.util.Calendar;
 import java.util.Collections;
 import java.util.List;
 import java.util.Observable;
+import java.util.Set;
 
 /**
  * Database helper for storing list of files to be uploaded, including status
@@ -395,17 +396,17 @@ public class UploadsStorageManager extends Observable {
 
     @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
     private List<OCUpload> getPendingJobs() {
-        JobScheduler js = (JobScheduler) mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+        Set<JobRequest> jobRequests = JobManager.create(mContext).getAllJobRequests();
 
         ArrayList<OCUpload> list = new ArrayList<>();
 
-        for (JobInfo ji: js.getAllPendingJobs()) {
-            PersistableBundle extras = ji.getExtras();
-            OCUpload upload  = new OCUpload(extras.getString("filePath"),
-                    extras.getString("remotePath"),
-                    extras.getString("account"));
+        for (JobRequest ji : jobRequests) {
+            PersistableBundleCompat extras = ji.getExtras();
+                OCUpload upload = new OCUpload(extras.getString("filePath", ""),
+                        extras.getString("remotePath", ""),
+                        extras.getString("account", ""));
 
-            list.add(upload);
+                list.add(upload);
         }
 
         return list;
@@ -413,13 +414,14 @@ public class UploadsStorageManager extends Observable {
 
     @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
     public void cancelPendingJob(String accountName, String remotePath){
-        JobScheduler js = (JobScheduler) mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
-
-        for (JobInfo ji: js.getAllPendingJobs()) {
-            PersistableBundle extras = ji.getExtras();
-            if (remotePath.equalsIgnoreCase(extras.getString("remotePath")) &&
-                accountName.equalsIgnoreCase(extras.getString("account"))){
-                js.cancel(ji.getId());
+        JobManager jobManager = JobManager.create(mContext);
+        Set<JobRequest> jobRequests = jobManager.getAllJobRequests();
+
+        for (JobRequest ji : jobRequests) {
+            PersistableBundleCompat extras = ji.getExtras();
+            if (remotePath.equalsIgnoreCase(extras.getString("remotePath", "")) &&
+                    accountName.equalsIgnoreCase(extras.getString("account", ""))) {
+                jobManager.cancel(ji.getJobId());
                 break;
             }
         }
@@ -429,13 +431,16 @@ public class UploadsStorageManager extends Observable {
      * Get all failed uploads.
      */
     public OCUpload[] getFailedUploads() {
-        return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value, null);
+
+        return getUploads(
+                ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value, null);
     }
 
     /**
      * Get all uploads which where successfully completed.
      */
     public OCUpload[] getFinishedUploads() {
+
         return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_SUCCEEDED.value, null);
     }
 
@@ -444,8 +449,8 @@ public class UploadsStorageManager extends Observable {
      * @return      Array of failed uploads, except for those that were not performed due to lack of Wifi connection.
      */
     public OCUpload[] getFailedButNotDelayedUploads() {
-        return getUploads(
-            ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value + AND +
+
+        return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value + AND +
                 ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_WIFI.getValue() + AND +
                 ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_CHARGING.getValue(),
             null
@@ -459,7 +464,7 @@ public class UploadsStorageManager extends Observable {
     public long clearFailedButNotDelayedUploads() {
         long result = getDB().delete(
             ProviderTableMeta.CONTENT_URI_UPLOADS,
-            ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value + AND +
+                ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value + AND +
                 ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_WIFI.getValue() + AND +
                 ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.DELAYED_FOR_CHARGING.getValue(),
             null
@@ -472,6 +477,7 @@ public class UploadsStorageManager extends Observable {
     }
 
     public long clearSuccessfulUploads() {
+
         long result = getDB().delete(
                 ProviderTableMeta.CONTENT_URI_UPLOADS,
                 ProviderTableMeta.UPLOADS_STATUS + "=="+ UploadStatus.UPLOAD_SUCCEEDED.value, null
@@ -484,6 +490,7 @@ public class UploadsStorageManager extends Observable {
     }
 
     public long clearAllFinishedButNotDelayedUploads() {
+
         String[] whereArgs = new String[2];
         whereArgs[0] = String.valueOf(UploadStatus.UPLOAD_SUCCEEDED.value);
         whereArgs[1] = String.valueOf(UploadStatus.UPLOAD_FAILED.value);

+ 0 - 0
src/com/owncloud/android/datastorage/DataStorageProvider.java → src/main/java/com/owncloud/android/datastorage/DataStorageProvider.java


+ 0 - 0
src/com/owncloud/android/datastorage/StoragePoint.java → src/main/java/com/owncloud/android/datastorage/StoragePoint.java


+ 0 - 0
src/com/owncloud/android/datastorage/UniqueStorageList.java → src/main/java/com/owncloud/android/datastorage/UniqueStorageList.java


+ 0 - 0
src/com/owncloud/android/datastorage/providers/AbstractCommandLineStoragePoint.java → src/main/java/com/owncloud/android/datastorage/providers/AbstractCommandLineStoragePoint.java


+ 0 - 0
src/com/owncloud/android/datastorage/providers/AbstractStoragePointProvider.java → src/main/java/com/owncloud/android/datastorage/providers/AbstractStoragePointProvider.java


+ 0 - 0
src/com/owncloud/android/datastorage/providers/EnvironmentStoragePointProvider.java → src/main/java/com/owncloud/android/datastorage/providers/EnvironmentStoragePointProvider.java


+ 0 - 0
src/com/owncloud/android/datastorage/providers/HardcodedStoragePointProvider.java → src/main/java/com/owncloud/android/datastorage/providers/HardcodedStoragePointProvider.java


+ 0 - 0
src/com/owncloud/android/datastorage/providers/IStoragePointProvider.java → src/main/java/com/owncloud/android/datastorage/providers/IStoragePointProvider.java


+ 0 - 0
src/com/owncloud/android/datastorage/providers/MountCommandStoragePointProvider.java → src/main/java/com/owncloud/android/datastorage/providers/MountCommandStoragePointProvider.java


+ 0 - 0
src/com/owncloud/android/datastorage/providers/SystemDefaultStoragePointProvider.java → src/main/java/com/owncloud/android/datastorage/providers/SystemDefaultStoragePointProvider.java


+ 0 - 0
src/com/owncloud/android/datastorage/providers/VDCStoragePointProvider.java → src/main/java/com/owncloud/android/datastorage/providers/VDCStoragePointProvider.java


+ 0 - 0
src/com/owncloud/android/db/OCUpload.java → src/main/java/com/owncloud/android/db/OCUpload.java


+ 46 - 2
src/com/owncloud/android/db/PreferenceManager.java → src/main/java/com/owncloud/android/db/PreferenceManager.java

@@ -44,6 +44,9 @@ public abstract class PreferenceManager {
     private static final String PREF__INSTANT_UPLOAD_ON_WIFI = "instant_upload_on_wifi";
     private static final String PREF__INSTANT_VIDEO_UPLOAD_ON_WIFI = "instant_video_upload_on_wifi";
     private static final String PREF__INSTANT_VIDEO_UPLOAD_PATH_USE_SUBFOLDERS = "instant_video_upload_path_use_subfolders";
+    private static final String PREF__LEGACY_CLEAN = "legacyClean";
+    private static final String PREF__AUTO_UPLOAD_UPDATE_PATH = "autoUploadPathUpdate";
+
 
     public static boolean instantPictureUploadEnabled(Context context) {
         return getDefaultSharedPreferences(context).getBoolean(PREF__INSTANT_UPLOADING, false);
@@ -184,6 +187,48 @@ public abstract class PreferenceManager {
         saveBooleanPreference(context, AUTO_PREF__SORT_ASCENDING, ascending);
     }
 
+    /**
+     * Gets the legacy cleaning flag last set.
+     *
+     * @param context Caller {@link Context}, used to access to shared preferences manager.
+     * @return ascending order     the legacy cleaning flag, default is false
+     */
+    public static boolean getLegacyClean(Context context) {
+        return getDefaultSharedPreferences(context).getBoolean(PREF__LEGACY_CLEAN, false);
+    }
+
+    /**
+     * Gets the auto upload paths flag last set.
+     *
+     * @param context Caller {@link Context}, used to access to shared preferences manager.
+     * @return ascending order     the legacy cleaning flag, default is false
+     */
+    public static boolean getAutoUploadPathsUpdate(Context context) {
+        return getDefaultSharedPreferences(context).getBoolean(PREF__AUTO_UPLOAD_UPDATE_PATH, false);
+    }
+
+
+    /**
+     * Saves the legacy cleaning flag which the user has set last.
+     *
+     * @param context   Caller {@link Context}, used to access to shared preferences manager.
+     * @param legacyClean flag if it is a legacy cleaning
+     */
+    public static void setLegacyClean(Context context, boolean legacyClean) {
+        saveBooleanPreference(context, PREF__LEGACY_CLEAN, legacyClean);
+    }
+
+    /**
+     * Saves the legacy cleaning flag which the user has set last.
+     *
+     * @param context   Caller {@link Context}, used to access to shared preferences manager.
+     * @param pathUpdate flag if it is a auto upload path update
+     */
+    public static void setAutoUploadPathsUpdate(Context context, boolean pathUpdate) {
+        saveBooleanPreference(context, PREF__AUTO_UPLOAD_UPDATE_PATH, pathUpdate);
+    }
+
+
     /**
      * Gets the uploader behavior which the user has set last.
      *
@@ -191,8 +236,7 @@ public abstract class PreferenceManager {
      * @return uploader behavior     the uploader behavior
      */
     public static int getUploaderBehaviour(Context context) {
-        return getDefaultSharedPreferences(context)
-                .getInt(AUTO_PREF__UPLOADER_BEHAVIOR, 1);
+        return getDefaultSharedPreferences(context).getInt(AUTO_PREF__UPLOADER_BEHAVIOR, 1);
     }
 
     /**

+ 2 - 1
src/com/owncloud/android/db/ProviderMeta.java → src/main/java/com/owncloud/android/db/ProviderMeta.java

@@ -33,7 +33,7 @@ import com.owncloud.android.MainApp;
 public class ProviderMeta {
 
     public static final String DB_NAME = "filelist";
-    public static final int DB_VERSION = 16;
+    public static final int DB_VERSION = 17;
 
     private ProviderMeta() {
     }
@@ -88,6 +88,7 @@ public class ProviderMeta {
         public static final String FILE_UPDATE_THUMBNAIL = "update_thumbnail";
         public static final String FILE_IS_DOWNLOADING= "is_downloading";
         public static final String FILE_ETAG_IN_CONFLICT = "etag_in_conflict";
+        public static final String FILE_FAVORITE = "favorite";
 
         public static final String FILE_DEFAULT_SORT_ORDER = FILE_NAME
                 + " collate nocase asc";

+ 0 - 0
src/com/owncloud/android/db/UploadResult.java → src/main/java/com/owncloud/android/db/UploadResult.java


+ 0 - 0
src/com/owncloud/android/features/FeatureList.java → src/main/java/com/owncloud/android/features/FeatureList.java


+ 3 - 3
src/com/owncloud/android/files/BootupBroadcastReceiver.java → src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java

@@ -21,13 +21,13 @@
 
 package com.owncloud.android.files;
 
-import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.services.observer.FileObserverService;
-
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.services.observer.FileObserverService;
+
 
 /**
  * App-registered receiver catching the broadcast intent reporting that the system was 

+ 43 - 10
src/com/owncloud/android/files/FileMenuFilter.java → src/main/java/com/owncloud/android/files/FileMenuFilter.java

@@ -229,20 +229,35 @@ public class FileMenuFilter {
             toShow.add(R.id.action_send_file);
         }
 
-        // FAVORITES
+        // Kept available offline
+        if (!allFiles() || synchronizing || allKeptAvailableOffline()) {
+            toHide.add(R.id.action_keep_files_offline);
+        } else {
+            toShow.add(R.id.action_keep_files_offline);
+        }
+
+        // Not kept available offline
+        if (!allFiles() || synchronizing || allNotKeptAvailableOffline()) {
+            toHide.add(R.id.action_unset_keep_files_offline);
+        } else {
+            toShow.add(R.id.action_unset_keep_files_offline);
+        }
+
+        // Favorite
         if (!allFiles() || synchronizing || allFavorites()) {
-            toHide.add(R.id.action_favorite_file);
+            toHide.add(R.id.action_favorite);
         } else {
-            toShow.add(R.id.action_favorite_file);
+            toShow.add(R.id.action_favorite);
         }
 
-        // UNFAVORITES
-        if (!allFiles() || synchronizing || allUnfavorites()) {
-            toHide.add(R.id.action_unfavorite_file);
+        // Unfavorite
+        if (!allFiles() || synchronizing || allNotFavorites()) {
+            toHide.add(R.id.action_unset_favorite);
         } else {
-            toShow.add(R.id.action_unfavorite_file);
+            toShow.add(R.id.action_unset_favorite);
         }
 
+
     }
 
     private boolean anyFileSynchronizing() {
@@ -320,18 +335,36 @@ public class FileMenuFilter {
         return false;
     }
 
+    private boolean allKeptAvailableOffline() {
+        for(OCFile file: mFiles) {
+            if(!file.isAvailableOffline()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     private boolean allFavorites() {
         for(OCFile file: mFiles) {
-            if(!file.isFavorite()) {
+            if(!file.getIsFavorite()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean allNotFavorites() {
+        for(OCFile file: mFiles) {
+            if(file.getIsFavorite()) {
                 return false;
             }
         }
         return true;
     }
 
-    private boolean allUnfavorites() {
+    private boolean allNotKeptAvailableOffline() {
         for(OCFile file: mFiles) {
-            if(file.isFavorite()) {
+            if(file.isAvailableOffline()) {
                 return false;
             }
         }

+ 1 - 1
src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java → src/main/java/com/owncloud/android/files/InstantUploadBroadcastReceiver.java

@@ -58,7 +58,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
 
     @Override
     public void onReceive(Context context, Intent intent) {
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
             Log_OC.d(TAG, "Received: " + intent.getAction());
             if (intent.getAction().equals(NEW_PHOTO_ACTION_UNOFFICIAL)) {
                 handleNewPictureAction(context, intent);

+ 0 - 0
src/com/owncloud/android/files/services/ConnectivityActionReceiver.java → src/main/java/com/owncloud/android/files/services/ConnectivityActionReceiver.java


+ 11 - 0
src/com/owncloud/android/files/services/FileDownloader.java → src/main/java/com/owncloud/android/files/services/FileDownloader.java

@@ -23,6 +23,7 @@ package com.owncloud.android.files.services;
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.OnAccountsUpdateListener;
+import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
@@ -79,6 +80,8 @@ public class FileDownloader extends Service
     public static final String EXTRA_LINKED_TO_PATH = "LINKED_TO";
     public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
 
+    private static final int FOREGROUND_SERVICE_ID = 412;
+
     private static final String TAG = FileDownloader.class.getSimpleName();
 
     private Looper mServiceLooper;
@@ -96,6 +99,7 @@ public class FileDownloader extends Service
     private NotificationCompat.Builder mNotificationBuilder;
     private int mLastPercent;
 
+    private Notification mNotification;
 
     public static String getDownloadAddedMessage() {
         return FileDownloader.class.getName() + DOWNLOAD_ADDED_MESSAGE;
@@ -120,6 +124,10 @@ public class FileDownloader extends Service
         mServiceHandler = new ServiceHandler(mServiceLooper, this);
         mBinder = new FileDownloaderBinder();
 
+        mNotification = new NotificationCompat.Builder(this).setContentTitle(getApplicationContext().
+                getResources().getString(R.string.app_name))
+                .build();
+
         // add AccountsUpdatedListener
         AccountManager am = AccountManager.get(getApplicationContext());
         am.addOnAccountsUpdatedListener(this, null, false);
@@ -156,6 +164,8 @@ public class FileDownloader extends Service
     public int onStartCommand(Intent intent, int flags, int startId) {
         Log_OC.d(TAG, "Starting command with id " + startId);
 
+        startForeground(FOREGROUND_SERVICE_ID, mNotification);
+
         if (!intent.hasExtra(EXTRA_ACCOUNT) ||
                 !intent.hasExtra(EXTRA_FILE)
                 ) {
@@ -383,6 +393,7 @@ public class FileDownloader extends Service
                 }
             }
             Log_OC.d(TAG, "Stopping after command with id " + msg.arg1);
+            mService.stopForeground(true);
             mService.stopSelf(msg.arg1);
         }
     }

+ 14 - 0
src/com/owncloud/android/files/services/FileUploader.java → src/main/java/com/owncloud/android/files/services/FileUploader.java

@@ -27,6 +27,7 @@ package com.owncloud.android.files.services;
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.OnAccountsUpdateListener;
+import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
@@ -103,11 +104,15 @@ public class FileUploader extends Service
     public static final String EXTRA_LINKED_TO_PATH = "LINKED_TO";
     public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
 
+    private static final int FOREGROUND_SERVICE_ID = 411;
+
     public static final String KEY_FILE = "FILE";
     public static final String KEY_LOCAL_FILE = "LOCAL_FILE";
     public static final String KEY_REMOTE_FILE = "REMOTE_FILE";
     public static final String KEY_MIME_TYPE = "MIME_TYPE";
 
+    private Notification mNotification;
+
     /**
      * Call this Service with only this Intent key if all pending uploads are to be retried.
      */
@@ -348,6 +353,10 @@ public class FileUploader extends Service
 
         mUploadsStorageManager = new UploadsStorageManager(getContentResolver(), getApplicationContext());
 
+        mNotification = new NotificationCompat.Builder(this).setContentTitle(getApplicationContext().
+                getResources().getString(R.string.app_name))
+                .build();
+
         int failedCounter = mUploadsStorageManager.failInProgressUploads(
             UploadResult.SERVICE_INTERRUPTED    // Add UploadResult.KILLED?
         );
@@ -401,6 +410,8 @@ public class FileUploader extends Service
     public int onStartCommand(Intent intent, int flags, int startId) {
         Log_OC.d(TAG, "Starting command with id " + startId);
 
+        startForeground(FOREGROUND_SERVICE_ID, mNotification);
+
         boolean retry = intent.getBooleanExtra(KEY_RETRY, false);
         AbstractList<String> requestedUploads = new Vector<String>();
 
@@ -845,6 +856,7 @@ public class FileUploader extends Service
 
     }
 
+
     /**
      * Upload worker. Performs the pending uploads in the order they were
      * requested.
@@ -876,7 +888,9 @@ public class FileUploader extends Service
                 }
             }
             Log_OC.d(TAG, "Stopping command after id " + msg.arg1);
+            mService.stopForeground(true);
             mService.stopSelf(msg.arg1);
+
         }
     }
 

+ 0 - 0
src/com/owncloud/android/files/services/IndexedForest.java → src/main/java/com/owncloud/android/files/services/IndexedForest.java


+ 0 - 0
src/com/owncloud/android/media/MediaControlView.java → src/main/java/com/owncloud/android/media/MediaControlView.java


+ 0 - 0
src/com/owncloud/android/media/MediaService.java → src/main/java/com/owncloud/android/media/MediaService.java


+ 0 - 0
src/com/owncloud/android/media/MediaServiceBinder.java → src/main/java/com/owncloud/android/media/MediaServiceBinder.java


+ 0 - 0
src/com/owncloud/android/operations/CheckCurrentCredentialsOperation.java → src/main/java/com/owncloud/android/operations/CheckCurrentCredentialsOperation.java


+ 0 - 0
src/com/owncloud/android/operations/CopyFileOperation.java → src/main/java/com/owncloud/android/operations/CopyFileOperation.java


+ 0 - 0
src/com/owncloud/android/operations/CreateFolderOperation.java → src/main/java/com/owncloud/android/operations/CreateFolderOperation.java


+ 0 - 0
src/com/owncloud/android/operations/CreateShareViaLinkOperation.java → src/main/java/com/owncloud/android/operations/CreateShareViaLinkOperation.java


+ 0 - 0
src/com/owncloud/android/operations/CreateShareWithShareeOperation.java → src/main/java/com/owncloud/android/operations/CreateShareWithShareeOperation.java


+ 0 - 0
src/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java → src/main/java/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java


Някои файлове не бяха показани, защото твърде много файлове са промени