diff --git a/app/build.gradle b/app/build.gradle index 4c9120fe5..556ea79e3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -38,9 +38,9 @@ repositories { // Version number def versionMajor = 5 // Major UI overhauls -def versionMinor = 6 // Some new functionality +def versionMinor = 7 // Some new functionality def versionPatch = 0 // Bug fixes -def versionBuild = 0 // Bump for dogfood builds, public betas, etc. +def versionBuild = 1 // Bump for dogfood builds, public betas, etc. // Version name from git def getVersionName = { -> @@ -64,6 +64,11 @@ android { abortOnError false } + packagingOptions { + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/NOTICE.txt' + } + defaultConfig { applicationId "com.nononsenseapps.notepad" minSdkVersion 14 @@ -129,20 +134,6 @@ apt { } } -// Dropbox -task nativeLibsToJar(type: Zip) { - destinationDir file("$buildDir/native-libs") - baseName 'native-libs' - extension 'jar' - from fileTree(dir: 'src/play/libs', include: '**/*.so') - into 'lib/' -} - -// If non-free, depend on dropbox -tasks.withType(JavaCompile) { - compileTask -> if (compileTask.toString().contains("Play")) compileTask.dependsOn(nativeLibsToJar) -} - dependencies { //compile fileTree(dir: 'libs', include: '*.jar') compile 'com.android.support:support-v4:19.0.1' @@ -164,9 +155,7 @@ dependencies { // Dropbox and non-free stuff playCompile fileTree(dir: 'src/play/libs', include: '*.jar') playBetaCompile fileTree(dir: 'src/play/libs', include: '*.jar') - playCompile fileTree(dir: "$buildDir/native-libs", include: "*.jar") playCompile 'com.google.android.gms:play-services:5.0.89' - playBetaCompile fileTree(dir: "$buildDir/native-libs", include: "*.jar") playBetaCompile 'com.google.android.gms:play-services:5.0.89' // Tests androidTestCompile 'com.squareup.spoon:spoon-client:1.1.1' diff --git a/app/src/androidTest/java/com/nononsenseapps/notepad/test/ConfigTest.java b/app/src/androidTest/java/com/nononsenseapps/notepad/test/ConfigTest.java index 7611c7c0e..1317c4e2d 100644 --- a/app/src/androidTest/java/com/nononsenseapps/notepad/test/ConfigTest.java +++ b/app/src/androidTest/java/com/nononsenseapps/notepad/test/ConfigTest.java @@ -56,10 +56,10 @@ public void testProps() { assertNotNull(Config.getGtasksApiKey(context)); assertFalse(Config.getGtasksApiKey(context).isEmpty()); - assertNotNull(Config.getKeyDropboxSyncPublic(context)); - assertFalse(Config.getKeyDropboxSyncPublic(context).isEmpty()); + assertNotNull(Config.getKeyDropboxAPI(context)); + assertFalse(Config.getKeyDropboxAPI(context).isEmpty()); - assertNotNull(Config.getKeyDropboxSyncSecret(context)); - assertFalse(Config.getKeyDropboxSyncSecret(context).isEmpty()); + assertNotNull(Config.getKeyDropboxAPISecret(context)); + assertFalse(Config.getKeyDropboxAPISecret(context).isEmpty()); } } diff --git a/app/src/free/java/com/nononsenseapps/notepad/sync/orgsync/DropboxSyncHelper.java b/app/src/free/java/com/nononsenseapps/notepad/sync/orgsync/DropboxSyncHelper.java index 2574da52f..7180c7bd2 100644 --- a/app/src/free/java/com/nononsenseapps/notepad/sync/orgsync/DropboxSyncHelper.java +++ b/app/src/free/java/com/nononsenseapps/notepad/sync/orgsync/DropboxSyncHelper.java @@ -1,17 +1,18 @@ /* - * Copyright (c) 2014 Jonas Kalderstam. + * Copyright (c) 2015 Jonas Kalderstam. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package com.nononsenseapps.notepad.sync.orgsync; @@ -22,11 +23,24 @@ * Dummy file, see play flavor. */ public class DropboxSyncHelper { - public static boolean hasSynced(Activity activity) { + + public DropboxSyncHelper(Activity activity) { + + } + + public boolean isLinked() { return false; } - public static void doFirstSync(Activity activity) { + public void linkAccount() { + + } + + public void unlinkAccount() { } + + public boolean handleLinkResult() { + return false; + } } diff --git a/app/src/main/java/com/nononsenseapps/build/Config.java b/app/src/main/java/com/nononsenseapps/build/Config.java index c07980877..ec9dc4e7e 100644 --- a/app/src/main/java/com/nononsenseapps/build/Config.java +++ b/app/src/main/java/com/nononsenseapps/build/Config.java @@ -32,8 +32,8 @@ public class Config { public final static boolean LOGGING = true; public static final String KEY_GTASKS_API_KEY = "gtasks_api_key"; - public static final String KEY_DROPBOX_SYNC_PUBLIC = "dropbox_sync_public"; - public static final String KEY_DROPBOX_SYNC_SECRET = "dropbox_sync_secret"; + public static final String KEY_DROPBOX_API = "dropbox_api"; + public static final String KEY_DROPBOX_API_SECRET = "dropbox_api_secret"; private static final String propFile = "secretkeys.properties"; private static Properties props; @@ -59,11 +59,11 @@ public static String getGtasksApiKey(final Context context) { "AIzaSyCAjRk2GfPARlIU3JsaEiExLMtj_rdN2i4"); } - public static String getKeyDropboxSyncPublic(final Context context) { - return getProperties(context).getProperty(KEY_DROPBOX_SYNC_PUBLIC); + public static String getKeyDropboxAPI(final Context context) { + return getProperties(context).getProperty(KEY_DROPBOX_API); } - public static String getKeyDropboxSyncSecret(final Context context) { - return getProperties(context).getProperty(KEY_DROPBOX_SYNC_SECRET); + public static String getKeyDropboxAPISecret(final Context context) { + return getProperties(context).getProperty(KEY_DROPBOX_API_SECRET); } } diff --git a/app/src/main/java/com/nononsenseapps/notepad/prefs/SyncPrefs.java b/app/src/main/java/com/nononsenseapps/notepad/prefs/SyncPrefs.java index 4310d6aea..9e9f6a89d 100644 --- a/app/src/main/java/com/nononsenseapps/notepad/prefs/SyncPrefs.java +++ b/app/src/main/java/com/nononsenseapps/notepad/prefs/SyncPrefs.java @@ -79,7 +79,6 @@ public class SyncPrefs extends PreferenceFragment implements public static final String KEY_DROPBOX_ENABLE = "pref_sync_dropbox_enabled"; public static final String KEY_DROPBOX_DIR = "pref_sync_dropbox_dir"; private static final int PICK_SD_DIR_CODE = 1; - private static final int DROPBOX_LINK_CODE = 3895; private static final int PICK_DROPBOX_DIR_CODE = 2; @@ -88,6 +87,7 @@ public class SyncPrefs extends PreferenceFragment implements private Preference prefAccount; private Preference prefSdDir; private Preference prefDropboxDir; + private DropboxSyncHelper mDropboxHelper = null; // private Preference prefSyncFreq; @@ -200,9 +200,9 @@ public boolean onPreferenceClick(final Preference preference) { // Dropbox, disable if no key present findPreference(KEY_DROPBOX_ENABLE) .setEnabled(BuildConfig.DROPBOX_ENABLED && - Config.getKeyDropboxSyncSecret(getActivity()) != + Config.getKeyDropboxAPI(getActivity()) != null && - !Config.getKeyDropboxSyncSecret(getActivity()) + !Config.getKeyDropboxAPISecret(getActivity()) .contains(" ")); prefDropboxDir = findPreference(KEY_DROPBOX_DIR); prefDropboxDir.setEnabled(BuildConfig.DROPBOX_ENABLED); @@ -213,7 +213,10 @@ public boolean onPreferenceClick(final Preference preference) { public boolean onPreferenceClick( final Preference preference) { // See if initial sync is complete - if (DropboxSyncHelper.hasSynced(getActivity())) { + if (mDropboxHelper == null) { + mDropboxHelper = new DropboxSyncHelper(getActivity()); + } + if (mDropboxHelper.isLinked()) { // Start the filepicker Intent i = new Intent(getActivity(), DropboxFilePickerActivity.class); @@ -232,13 +235,6 @@ public boolean onPreferenceClick( startActivityForResult(i, PICK_DROPBOX_DIR_CODE); - } else { - // Start first sync - DropboxSyncHelper.doFirstSync(getActivity()); - // Notify the user to wait - Toast.makeText(getActivity(), - R.string.wait_for_dropbox, - Toast.LENGTH_SHORT).show(); } return true; @@ -292,11 +288,18 @@ public void onSharedPreferenceChanged(SharedPreferences prefs, } else if (KEY_SD_DIR.equals(key)) { setSdDirSummary(prefs); } else if (KEY_DROPBOX_ENABLE.equals(key)) { + // TODO + if (mDropboxHelper == null) { + mDropboxHelper = new DropboxSyncHelper(getActivity()); + } if (prefs.getBoolean(key, false)) { - DropboxSynchronizer.linkAccount(this, - DROPBOX_LINK_CODE); + // authorize the user + mDropboxHelper.linkAccount(); +// DropboxSynchronizer.linkAccount(this, +// DROPBOX_LINK_CODE); } else { - DropboxSynchronizer.unlink(getActivity()); + mDropboxHelper.unlinkAccount(); +// DropboxSynchronizer.unlink(getActivity()); } // Restart sync service OrgSyncService.stop(getActivity()); @@ -315,17 +318,23 @@ public void onSharedPreferenceChanged(SharedPreferences prefs, } @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == DROPBOX_LINK_CODE) { - if (resultCode == Activity.RESULT_OK) { - // Start first sync - DropboxSyncHelper.doFirstSync(getActivity()); + public void onResume() { + super.onResume(); + + if (mDropboxHelper != null) { + if (mDropboxHelper.handleLinkResult()) { + // Success } else { - // ... Link failed or was cancelled by the user. + // Link failed or was cancelled by the user. PreferenceManager.getDefaultSharedPreferences(getActivity()).edit() .putBoolean(KEY_DROPBOX_ENABLE, false).commit(); } - } else if (requestCode == PICK_DROPBOX_DIR_CODE) { + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == PICK_DROPBOX_DIR_CODE) { if (resultCode == Activity.RESULT_OK) { PreferenceManager.getDefaultSharedPreferences(getActivity ()).edit().putString(KEY_DROPBOX_DIR, diff --git a/app/src/main/java/com/nononsenseapps/notepad/sync/orgsync/OrgSyncService.java b/app/src/main/java/com/nononsenseapps/notepad/sync/orgsync/OrgSyncService.java index 9e1aa77de..6a4f75fa0 100644 --- a/app/src/main/java/com/nononsenseapps/notepad/sync/orgsync/OrgSyncService.java +++ b/app/src/main/java/com/nononsenseapps/notepad/sync/orgsync/OrgSyncService.java @@ -284,6 +284,7 @@ public void handleMessage(Message msg) { } } catch (IOException ignored) { + Log.e(TAG, ignored.getMessage()); } catch (ParseException ignored) { } } diff --git a/app/src/main/java/com/nononsenseapps/notepad/sync/orgsync/SynchronizerInterface.java b/app/src/main/java/com/nononsenseapps/notepad/sync/orgsync/SynchronizerInterface.java index 8d08aa91b..4c4a17632 100644 --- a/app/src/main/java/com/nononsenseapps/notepad/sync/orgsync/SynchronizerInterface.java +++ b/app/src/main/java/com/nononsenseapps/notepad/sync/orgsync/SynchronizerInterface.java @@ -78,7 +78,7 @@ public OrgFile getNewFile(final String desiredName) throws IOException, * @param orgFile * The file to delete. */ - public void deleteRemoteFile(final OrgFile orgFile); + public void deleteRemoteFile(final OrgFile orgFile) throws IOException; /** * Rename the file on the remote end. @@ -88,7 +88,7 @@ public OrgFile getNewFile(final String desiredName) throws IOException, * @param orgFile * This contains the new name. */ - public void renameRemoteFile(final String oldName, final OrgFile orgFile); + public void renameRemoteFile(final String oldName, final OrgFile orgFile) throws IOException; /** * Returns a BufferedReader to the remote file. Null if it doesn't exist. @@ -96,13 +96,13 @@ public OrgFile getNewFile(final String desiredName) throws IOException, * @param filename * Name of the file, without path */ - public BufferedReader getRemoteFile(final String filename); + public BufferedReader getRemoteFile(final String filename) throws IOException; /** * * @return a set of all remote files. */ - public HashSet getRemoteFilenames(); + public HashSet getRemoteFilenames() throws IOException; /** * Do a full 2-way sync. diff --git a/app/src/play/AndroidManifest.xml b/app/src/play/AndroidManifest.xml index 22012ce3a..c79bf2671 100644 --- a/app/src/play/AndroidManifest.xml +++ b/app/src/play/AndroidManifest.xml @@ -98,30 +98,19 @@ android:label="@string/app_name" android:theme="@style/FilePicker.Theme"> - - + android:launchMode="singleTask" + android:configChanges="orientation|keyboard" > - - - diff --git a/app/src/play/java/com/nononsenseapps/filepicker/DropboxFilePickerActivity.java b/app/src/play/java/com/nononsenseapps/filepicker/DropboxFilePickerActivity.java index f80c23303..2ae42c440 100644 --- a/app/src/play/java/com/nononsenseapps/filepicker/DropboxFilePickerActivity.java +++ b/app/src/play/java/com/nononsenseapps/filepicker/DropboxFilePickerActivity.java @@ -18,30 +18,21 @@ import android.os.Bundle; -import com.dropbox.sync.android.DbxAccountManager; -import com.dropbox.sync.android.DbxException; -import com.dropbox.sync.android.DbxFileSystem; -import com.dropbox.sync.android.DbxPath; -import com.nononsenseapps.build.Config; +import com.dropbox.client2.DropboxAPI; +import com.dropbox.client2.android.AndroidAuthSession; +import com.nononsenseapps.notepad.sync.orgsync.DropboxSyncHelper; public class DropboxFilePickerActivity extends - AbstractFilePickerActivity { + AbstractFilePickerActivity { - private DbxFileSystem fs; + // In the class declaration section: + private DropboxAPI mDBApi; @Override - public void onCreate(Bundle b) {// Make sure we are linked - DbxAccountManager accountManager = DbxAccountManager.getInstance(getApplicationContext(), - Config.getKeyDropboxSyncPublic(this), - Config.getKeyDropboxSyncSecret(this)); - - if (accountManager.hasLinkedAccount()) { - try { - fs = DbxFileSystem.forAccount(accountManager.getLinkedAccount()); - } catch (DbxException.Unauthorized unauthorized) { - finish(); - } - } else { + public void onCreate(Bundle b) { + mDBApi = DropboxSyncHelper.getDBApi(this); + if (!mDBApi.getSession().isLinked()) { + // No valid authentication finish(); } @@ -49,12 +40,19 @@ public void onCreate(Bundle b) {// Make sure we are linked } @Override - protected AbstractFilePickerFragment getFragment(final String startPath, - final int mode, - final boolean allowMultiple, - final boolean allowCreateDir) { - DropboxFilePickerFragment fragment = new DropboxFilePickerFragment(fs); + protected AbstractFilePickerFragment getFragment( + final String startPath, final int mode, final boolean allowMultiple, + final boolean allowCreateDir) { + if (mDBApi == null || !mDBApi.getSession().isLinked()) { + // No valid authentication + finish(); + return null; + } + + DropboxFilePickerFragment fragment = + new DropboxFilePickerFragment(mDBApi); fragment.setArgs(startPath, mode, allowMultiple, allowCreateDir); return fragment; } + } diff --git a/app/src/play/java/com/nononsenseapps/filepicker/DropboxFilePickerFragment.java b/app/src/play/java/com/nononsenseapps/filepicker/DropboxFilePickerFragment.java index 40598f301..0171ac388 100644 --- a/app/src/play/java/com/nononsenseapps/filepicker/DropboxFilePickerFragment.java +++ b/app/src/play/java/com/nononsenseapps/filepicker/DropboxFilePickerFragment.java @@ -20,114 +20,160 @@ import android.content.AsyncTaskLoader; import android.content.Loader; import android.net.Uri; +import android.os.AsyncTask; import android.widget.Toast; -import com.dropbox.sync.android.DbxException; -import com.dropbox.sync.android.DbxFileInfo; -import com.dropbox.sync.android.DbxFileSystem; -import com.dropbox.sync.android.DbxPath; +import com.dropbox.client2.DropboxAPI; +import com.dropbox.client2.android.AndroidAuthSession; +import com.dropbox.client2.exception.DropboxException; import com.nononsenseapps.notepad.R; +import java.io.File; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @SuppressLint("ValidFragment") -public class DropboxFilePickerFragment extends - AbstractFilePickerFragment { +public class DropboxFilePickerFragment + extends AbstractFilePickerFragment { - private final DbxFileSystem fs; + private final DropboxAPI dbApi; + private FolderCreator folderCreator; @SuppressLint("ValidFragment") - public DropboxFilePickerFragment(final DbxFileSystem fs) { + public DropboxFilePickerFragment(final DropboxAPI api) { super(); - if (fs == null) { + if (api == null) { throw new NullPointerException("FileSystem may not be null"); + } else if (!api.getSession().isLinked()) { + throw new IllegalArgumentException("Must be linked with Dropbox"); } - this.fs = fs; + + this.dbApi = api; } - @Override - protected boolean isDir(final DbxPath dbxPath) { - try { - return fs.isFolder(dbxPath); - } catch (DbxException e) { - return false; + public void onNewFolder(final String name) { + File folder = new File(currentPath.path, name); + + if (folderCreator == null) { + folderCreator = new FolderCreator(); + } + + folderCreator.execute(folder.getPath()); + } + + private class FolderCreator extends AsyncTask { + + @Override + protected Void doInBackground(final String... paths) { + for (String path : paths) { + try { + dbApi.createFolder(path); + currentPath = dbApi.metadata(path, 1, null, false, null); + refresh(); + } catch (DropboxException e) { + Toast.makeText(getActivity(), R.string.create_folder_error, + Toast.LENGTH_SHORT).show(); + } + } + return null; } } @Override - protected DbxPath getParent(final DbxPath dbxPath) { - DbxPath parent = dbxPath.getParent(); - if (parent == null) { - parent = dbxPath; + protected boolean isDir(final DropboxAPI.Entry file) { + return file.isDir; + } + + @Override + protected DropboxAPI.Entry getParent(final DropboxAPI.Entry from) { + // Take care of a slight limitation in Dropbox code: + if (from.path.length() > 1 && from.path.endsWith("/")) { + from.path = from.path.substring(0, from.path.length() - 1); } + String parent = from.parentPath(); + if (parent.isEmpty()) { + parent = "/"; + } + + return getPath(parent); - return parent; } @Override - protected DbxPath getPath(final String s) { - return new DbxPath(s); + protected DropboxAPI.Entry getPath(final String path) { + final DropboxAPI.Entry entry = new DropboxAPI.Entry(); + entry.path = path; + entry.isDir = true; + return entry; + } @Override - protected String getFullPath(final DbxPath dbxPath) { - return dbxPath.toString(); + protected String getFullPath(final DropboxAPI.Entry file) { + return file.path; } @Override - protected String getName(final DbxPath dbxPath) { - return dbxPath.getName(); + protected String getName(final DropboxAPI.Entry file) { + return file.fileName(); } @Override - protected DbxPath getRoot() { - return new DbxPath("/"); + protected DropboxAPI.Entry getRoot() { + return getPath("/"); } @Override - protected Uri toUri(final DbxPath dbxPath) { - return new Uri.Builder().scheme("dropbox") - .path(dbxPath.toString()).build(); + protected Uri toUri(final DropboxAPI.Entry file) { + return new Uri.Builder().scheme("dropbox").path(file.path).build(); } @Override - protected Comparator getComparator() { - return new Comparator() { + protected Comparator getComparator() { + return new Comparator() { @Override - public int compare(final DbxPath lhs, final DbxPath rhs) { + public int compare(final DropboxAPI.Entry lhs, + final DropboxAPI.Entry rhs) { if (isDir(lhs) && !isDir(rhs)) { return -1; } else if (isDir(rhs) && !isDir(lhs)) { return 1; } else { - return lhs.getName().toLowerCase().compareTo(rhs.getName() - .toLowerCase()); + return lhs.fileName().toLowerCase() + .compareTo(rhs.fileName().toLowerCase()); } } }; } @Override - protected Loader> getLoader() { - return new AsyncTaskLoader>(getActivity()) { - DbxPath listenPath; - public DbxFileSystem.PathListener pathListener; + protected Loader> getLoader() { + return new AsyncTaskLoader>(getActivity()) { @Override - public List loadInBackground() { - ArrayList files = new ArrayList(); + public List loadInBackground() { + ArrayList files = + new ArrayList(); try { - for (DbxFileInfo fileInfo : fs.listFolder(currentPath)) { - if ((mode == MODE_FILE || mode == MODE_FILE_AND_DIR) - || fileInfo.isFolder) { - files.add(fileInfo.path); + + if (!dbApi.metadata(currentPath.path, 1, null, false, + null).isDir) { + currentPath = getRoot(); + } + + DropboxAPI.Entry dirEntry = + dbApi.metadata(currentPath.path, 0, null, true, + null); + for (DropboxAPI.Entry entry : dirEntry.contents) { + if ((mode == MODE_FILE || mode == MODE_FILE_AND_DIR) || + entry.isDir) { + files.add(entry); } } - } catch (DbxException e) { - // e.printStackTrace(); + } catch (DropboxException e) { } + return files; } @@ -138,30 +184,10 @@ public List loadInBackground() { protected void onStartLoading() { super.onStartLoading(); - if (pathListener == null) { - pathListener = new DbxFileSystem.PathListener() { - @Override - public void onPathChange(final DbxFileSystem dbxFileSystem, final DbxPath dbxPath, final Mode mode) { - // Reload - onContentChanged(); - } - }; - } - - // Make sure it's valid - try { - if (!fs.exists(currentPath)) { - currentPath = getRoot(); - } - } catch (DbxException e) { + if (currentPath == null || !currentPath.isDir) { currentPath = getRoot(); } - // Start watching for changes - listenPath = currentPath; - fs.addPathListener(pathListener, listenPath, - DbxFileSystem.PathListener.Mode.PATH_OR_CHILD); - forceLoad(); } @@ -171,28 +197,9 @@ public void onPathChange(final DbxFileSystem dbxFileSystem, final DbxPath dbxPat @Override protected void onReset() { super.onReset(); - - // Stop watching - if (listenPath != null) { - fs.removePathListener(pathListener, listenPath, - DbxFileSystem.PathListener.Mode.PATH_OR_CHILD); - listenPath = null; - } } }; } - @Override - public void onNewFolder(final String s) { - DbxPath path = new DbxPath(s); - - try { - fs.createFolder(path); - currentPath = path; - refresh(); - } catch (DbxException e) { - Toast.makeText(getActivity(), R.string.create_folder_error, - Toast.LENGTH_SHORT).show(); - } - } + } \ No newline at end of file diff --git a/app/src/play/java/com/nononsenseapps/notepad/sync/orgsync/DropboxSyncHelper.java b/app/src/play/java/com/nononsenseapps/notepad/sync/orgsync/DropboxSyncHelper.java index 52bda3fcf..7ed0b25ba 100644 --- a/app/src/play/java/com/nononsenseapps/notepad/sync/orgsync/DropboxSyncHelper.java +++ b/app/src/play/java/com/nononsenseapps/notepad/sync/orgsync/DropboxSyncHelper.java @@ -1,107 +1,146 @@ /* - * Copyright (c) 2014 Jonas Kalderstam. + * Copyright (c) 2015 Jonas Kalderstam * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 Lesser General Public License for more details. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . */ package com.nononsenseapps.notepad.sync.orgsync; -import android.app.IntentService; -import android.content.Intent; +import android.app.Activity; import android.content.Context; +import android.preference.PreferenceManager; -import com.dropbox.sync.android.DbxAccountManager; -import com.dropbox.sync.android.DbxException; -import com.dropbox.sync.android.DbxFileSystem; +import com.dropbox.client2.DropboxAPI; +import com.dropbox.client2.android.AndroidAuthSession; +import com.dropbox.client2.session.AppKeyPair; import com.nononsenseapps.build.Config; /** - * An {@link IntentService} subclass that synchronizes the Dropbox Cache in - * the background + * This class has some utility functions for dealing with Dropbox. You need + * to input your API keys below. + * See Dropbox for more information: + * https://www.dropbox.com/developers/core/start/android + *

+ * You also need to drop your APP_KEY in the manifest in + * com.dropbox.client2.android.AuthActivity + * See here for info: + * https://www.dropbox.com/developers/core/sdks/android */ -public class DropboxSyncHelper extends IntentService { +public class DropboxSyncHelper { - public final static String ACTION_SYNC_FULL = "ACTION_SYNC_FULL"; - public final static String ACTION_SYNC_FIRST = "ACTION_SYNC_FIRST"; + public static final String PREF_DROPBOX_TOKEN = "dropboxtoken"; + private final Context mActivity; + + public DropboxAPI mDBApi = null; + + public DropboxSyncHelper(Activity activity) { + mActivity = activity; + // TODO + } + + public static DropboxAPI getDBApi( + final Context context) { + final DropboxAPI mDBApi; + + final AppKeyPair appKeys = new AppKeyPair(Config.getKeyDropboxAPI(context), Config.getKeyDropboxAPISecret(context)); + final AndroidAuthSession session; + + if (PreferenceManager.getDefaultSharedPreferences(context) + .contains(PREF_DROPBOX_TOKEN)) { + session = new AndroidAuthSession(appKeys, + PreferenceManager.getDefaultSharedPreferences(context) + .getString(PREF_DROPBOX_TOKEN, "")); + } else { + session = new AndroidAuthSession(appKeys); + } + mDBApi = new DropboxAPI(session); + return mDBApi; + } /** - * Execute first sync. If first sync has been completed, - * this method does nothing. + * Save the dropbox oauth token so we can reuse the session without + * logging in again. + * @param context + * @param token */ - public static void doFirstSync(final Context context) { - Intent intent = new Intent(context, DropboxSyncHelper.class); - intent.setAction(ACTION_SYNC_FIRST); - context.startService(intent); + public static void saveToken(final Context context, final String token) { + PreferenceManager.getDefaultSharedPreferences(context).edit() + .putString(PREF_DROPBOX_TOKEN, token).apply(); } /** - * Do a full sync regardless of state. + * Must add a call to handleLinkResult in your onResume method. + * + * @return true if already linked, else false (and opens auth-window) */ - public static void doFullSync(final Context context) { - Intent intent = new Intent(context, DropboxSyncHelper.class); - intent.setAction(ACTION_SYNC_FULL); - context.startService(intent); + public boolean linkAccount() { + if (mDBApi == null) { + mDBApi = getDBApi(mActivity); + } + + // If not authorized, then ask user for login/permission + if (!mDBApi.getSession().isLinked()) { + mDBApi.getSession().startOAuth2Authentication(mActivity); + return false; + } else { + return true; + } } /** * - * @param context - * @return true if we have synced and it's ok to bring up the file picker. + * @return true if user has authorized connection to dropbox */ - public static boolean hasSynced(final Context context) { - final DbxAccountManager accountManager = DbxAccountManager.getInstance - (context.getApplicationContext(), - Config.getKeyDropboxSyncPublic(context), - Config.getKeyDropboxSyncSecret(context)); + public boolean isLinked() { + if (mDBApi == null) { + mDBApi = getDBApi(mActivity); + } + + // If not authorized, then ask user for login/permission + return mDBApi.getSession().isLinked(); + } - if (accountManager.hasLinkedAccount()) { + /** + * + * @return true if successfully linked, and token saved. False otherwise. + */ + public boolean handleLinkResult() { + if (mDBApi != null && mDBApi.getSession().authenticationSuccessful()) { try { - final DbxFileSystem fs = DbxFileSystem.forAccount(accountManager - .getLinkedAccount()); - return fs.hasSynced(); - } catch (DbxException.Unauthorized ignored) { - } catch (DbxException ignored) { + // Required to complete auth, sets the access token on the session + mDBApi.getSession().finishAuthentication(); + + String accessToken = mDBApi.getSession().getOAuth2AccessToken(); + saveToken(mActivity, accessToken); + return true; + } catch (IllegalStateException e) { + //Log.i("DbAuthLog", "Error authenticating", e); } } return false; } - public DropboxSyncHelper() { - super("DropboxSyncHelper"); - } - - @Override - protected void onHandleIntent(Intent intent) { - final DbxAccountManager accountManager = DbxAccountManager.getInstance - (getApplicationContext(), - Config.getKeyDropboxSyncPublic(this), - Config.getKeyDropboxSyncSecret(this)); + /** + * Does nothing is already unlinked. + */ + public void unlinkAccount() { + if (mDBApi == null) { + mDBApi = getDBApi(mActivity); + } - if (accountManager.hasLinkedAccount()) { - try { - final DbxFileSystem fs = DbxFileSystem.forAccount(accountManager - .getLinkedAccount()); - - if (ACTION_SYNC_FULL.equals(intent.getAction())) { - fs.syncNowAndWait(); - } else if (ACTION_SYNC_FIRST.equals(intent.getAction()) && - !fs.hasSynced()) { - fs.syncNowAndWait(); - } - - } catch (DbxException.Unauthorized ignored) { - } catch (DbxException ignored) { - } + if (mDBApi.getSession().isLinked()) { + mDBApi.getSession().unlink(); } } } diff --git a/app/src/play/java/com/nononsenseapps/notepad/sync/orgsync/DropboxSynchronizer.java b/app/src/play/java/com/nononsenseapps/notepad/sync/orgsync/DropboxSynchronizer.java index 9d3323b90..f4f73f8ac 100644 --- a/app/src/play/java/com/nononsenseapps/notepad/sync/orgsync/DropboxSynchronizer.java +++ b/app/src/play/java/com/nononsenseapps/notepad/sync/orgsync/DropboxSynchronizer.java @@ -23,24 +23,24 @@ import android.preference.PreferenceManager; import android.util.Log; -import com.dropbox.sync.android.DbxAccount; -import com.dropbox.sync.android.DbxAccountManager; -import com.dropbox.sync.android.DbxException; -import com.dropbox.sync.android.DbxFile; -import com.dropbox.sync.android.DbxFileInfo; -import com.dropbox.sync.android.DbxFileStatus; -import com.dropbox.sync.android.DbxFileSystem; -import com.dropbox.sync.android.DbxPath; +import com.dropbox.client2.DropboxAPI; +import com.dropbox.client2.android.AndroidAuthSession; +import com.dropbox.client2.exception.DropboxException; +import com.dropbox.client2.exception.DropboxServerException; import com.nononsenseapps.build.Config; import com.nononsenseapps.notepad.prefs.SyncPrefs; import org.cowboyprogrammer.org.OrgFile; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.StringReader; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.HashSet; -import java.util.List; public class DropboxSynchronizer extends Synchronizer implements @@ -52,64 +52,21 @@ public class DropboxSynchronizer extends Synchronizer implements public static final String PREF_ENABLED = SyncPrefs.KEY_DROPBOX_ENABLE; public final static String SERVICENAME = "DROPBOXORG"; protected final boolean enabled; - protected DbxPath DIR; - private DbxAccountManager accountManager = null; - private DbxAccount account = null; - private DbxFileSystem fs = null; + private final DropboxAPI mDBApi; + private final String folderpath; + protected DropboxAPI.Entry DIR; + private DropboxAPI dbApi = null; public DropboxSynchronizer(final Context context) { super(context); final SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(context); enabled = prefs.getBoolean(PREF_ENABLED, false); - DIR = new DbxPath(prefs.getString(PREF_DIR, DEFAULT_DIR)); + mDBApi = DropboxSyncHelper.getDBApi(context); + folderpath = prefs.getString(PREF_DIR, DEFAULT_DIR); } - /** - * Link a DropboxAccount. Must be called from a GUI. Activity - * receives result in OnActivityResult with the specific code. Returns - * RESULT_OK if all is good. - * - * @param activity - * @param requestCode - */ - public static void linkAccount(final Activity activity, - final int requestCode) { - final String APP_KEY = Config.getKeyDropboxSyncPublic(activity); - final String APP_SECRET = Config.getKeyDropboxSyncSecret(activity); - DbxAccountManager.getInstance(activity.getApplicationContext(), - APP_KEY, APP_SECRET).startLink(activity, requestCode); - } - - /** - * Link a DropboxAccount. Must be called from a GUI. Activity - * receives result in OnActivityResult with the specific code. Returns - * RESULT_OK if all is good. - * - * @param fragment - * @param requestCode - */ - public static void linkAccount(final Fragment fragment, - final int requestCode) { - final String APP_KEY = Config.getKeyDropboxSyncPublic(fragment.getActivity()); - final String APP_SECRET = Config.getKeyDropboxSyncSecret(fragment.getActivity()); - DbxAccountManager.getInstance(fragment.getActivity().getApplicationContext(), - APP_KEY, APP_SECRET).startLink(fragment, requestCode); - } - - /** - * Unlink a Dropbox Connection. - * - * @param activity - */ - public static void unlink(final Activity activity) { - final String APP_KEY = Config.getKeyDropboxSyncPublic(activity); - final String APP_SECRET = Config.getKeyDropboxSyncSecret(activity); - DbxAccountManager.getInstance(activity.getApplicationContext(), - APP_KEY, APP_SECRET).unlink(); - } - /** * @return A unique name for this service. Should be descriptive, like * DropboxOrg, SDOrg or SSHOrg. @@ -124,7 +81,11 @@ public String getServiceName() { */ @Override public String getAccountName() { - return accountManager.getLinkedAccount().getUserId(); + try { + return mDBApi.accountInfo().email; + } catch (DropboxException e) { + return "ERROR"; + } } /** @@ -137,36 +98,27 @@ public boolean isConfigured() { if (!enabled) return false; // Need to ask dropbox if we are linked. - if (accountManager == null) { - final String APP_KEY = Config.getKeyDropboxSyncPublic(context); - final String APP_SECRET = Config.getKeyDropboxSyncSecret(context); - - if (APP_KEY.contains(" ") || APP_SECRET.contains(" ")) { - return false; - } - - accountManager = DbxAccountManager.getInstance(context - .getApplicationContext(), APP_KEY, APP_SECRET); - - if (accountManager.hasLinkedAccount()) { - account = accountManager.getLinkedAccount(); - try { - fs = DbxFileSystem.forAccount(account); - - fs.syncNowAndWait(); - - if (!fs.isFolder(DIR)) { - fs.createFolder(DIR); + if (mDBApi.getSession().isLinked()) { + // Create default dir if necessary + try { + DIR = mDBApi.metadata(folderpath, 1, null, false, null); + return DIR.isDir; + } catch (DropboxServerException e) { + if (e.error == 404) { + try { + DIR = mDBApi.createFolder(folderpath); + return DIR.isDir; + } catch (DropboxException e1) { + Log.e(TAG, "isConfigured: " + e.reason); } - } catch (DbxException.Unauthorized unauthorized) { - return false; - } catch (DbxException e) { - return false; + } else { + Log.e(TAG, "isConfigured: " + e.reason); } + } catch (DropboxException e) { + Log.e(TAG, "isConfigured catchall"); } } - - return accountManager.hasLinkedAccount(); + return false; } /** @@ -194,16 +146,46 @@ public OrgFile getNewFile(final String desiredName) throws IOException, IllegalA } else { filename = desiredName + i + ".org"; } - if (!fs.exists(new DbxPath(DIR, filename))) { - return new OrgFile(filename); + try { + DropboxAPI.Entry entry = mDBApi.metadata(join(folderpath, filename), 1, null, false, null); + // If entry is returned, it exists, move to next iteration step + } catch (DropboxServerException e) { + if (404 == e.error) { + // No such file exists, great! + return new OrgFile(filename); + } else { + throw e; + } } } - } catch (DbxPath.InvalidPathException e) { - throw new IOException(e); + } catch (DropboxServerException e) { + throw new IOException("" + e.reason); + } catch (DropboxException e) { + throw new IOException(); } throw new IllegalArgumentException("Filename not accessible"); } + private String join(String folderpath, String filename) { + if (folderpath == null || filename == null) { + throw new NullPointerException(); + } + + if (folderpath.endsWith("/")) { + if (filename.startsWith("/")) { + return folderpath + filename.substring(1); + } else { + return folderpath + filename; + } + } else { + if (filename.startsWith("/")) { + return folderpath + filename; + } else { + return folderpath + "/" + filename; + } + } + } + /** * Replaces the file on the remote end with the given content. * @@ -211,19 +193,14 @@ public OrgFile getNewFile(final String desiredName) throws IOException, IllegalA */ @Override public void putRemoteFile(final OrgFile orgFile) throws IOException { - DbxPath path = new DbxPath(DIR, orgFile.getFilename()); try { - DbxFile file; - try { - file = fs.open(path); - waitUntilSynced(file); - } catch (DbxException.NotFound e) { - file = fs.create(path); - } - file.writeString(orgFile.treeToString()); - file.close(); - } catch (DbxException e) { - throw new IOException(e); + byte[] bytes = orgFile.treeToString().getBytes(StandardCharsets.UTF_8); + InputStream stream = new ByteArrayInputStream(orgFile.treeToString().getBytes(StandardCharsets.UTF_8)); + mDBApi.putFileOverwrite(join(folderpath, orgFile.getFilename()), stream, bytes.length, null); + } catch (DropboxServerException e) { + throw new IOException("" + e.reason); + } catch (DropboxException e) { + throw new IOException("" + e.getMessage()); } } @@ -233,22 +210,22 @@ public void putRemoteFile(final OrgFile orgFile) throws IOException { * @param orgFile The file to delete. */ @Override - public void deleteRemoteFile(final OrgFile orgFile) { + public void deleteRemoteFile(final OrgFile orgFile) throws IOException { if (orgFile == null || orgFile.getFilename() == null) { // Nothing to do return; } - DbxPath path = new DbxPath(DIR, orgFile.getFilename()); try { - // Get latest version - DbxFile file = fs.open(path); - waitUntilSynced(file); - // Can close it again now - file.close(); - // Now remove the updated file - fs.delete(path); - } catch (DbxException e) { - //e.printStackTrace(); + mDBApi.delete(join(folderpath, orgFile.getFilename())); + } catch (DropboxServerException e) { + if (404 == e.error) { + // This is ok, already deleted + // ignore + } else { + throw new IOException("" + e.reason); + } + } catch (DropboxException e) { + throw new IOException("" + e.getMessage()); } } @@ -259,18 +236,17 @@ public void deleteRemoteFile(final OrgFile orgFile) { * @param orgFile */ @Override - public void renameRemoteFile(final String oldName, final OrgFile orgFile) { + public void renameRemoteFile(final String oldName, final OrgFile orgFile) throws IOException { if (orgFile == null || orgFile.getFilename() == null) { throw new NullPointerException("No new filename"); } - DbxPath newPath = new DbxPath(DIR, orgFile.getFilename()); - DbxPath oldPath = new DbxPath(DIR, oldName); - try { - fs.move(oldPath, newPath); - } catch (DbxException e) { - //e.printStackTrace(); + mDBApi.move(join(folderpath, oldName), join(folderpath, orgFile.getFilename())); + } catch (DropboxServerException e) { + throw new IOException("" + e.reason); + } catch (DropboxException e) { + throw new IOException("" + e.getMessage()); } } @@ -280,60 +256,17 @@ public void renameRemoteFile(final String oldName, final OrgFile orgFile) { * @param filename Name of the file, without path */ @Override - public BufferedReader getRemoteFile(final String filename) { - DbxPath path = new DbxPath(DIR, filename); - BufferedReader br = null; + public BufferedReader getRemoteFile(final String filename) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { - if (fs.isFile(path)) { - DbxFile file = fs.open(path); - // Get latest version - waitUntilSynced(file); - // Read it - br = new BufferedReader(new StringReader(file.readString())); - file.close(); - } - // In case of errors, throw null pointers. Trying to see if this - // the place that deletes files. - } catch (DbxException e) { - Log.d(TAG, e.getLocalizedMessage()); - //br = null; - throw new NullPointerException(e.getLocalizedMessage()); - } catch (IOException e) { - Log.d(TAG, e.getLocalizedMessage()); - //br = null; - throw new NullPointerException(e.getLocalizedMessage()); - } - - return br; - } - - /** - * Wait until the file has been synced to the newest state. Will wait a - * maximum of 30s. - * @param file - */ - private void waitUntilSynced(final DbxFile file) { - final long MAXTIME = 30*1000; - final long STARTTIME = System.currentTimeMillis(); - try { - DbxFileStatus status = file.getNewerStatus(); - - while (MAXTIME > (System.currentTimeMillis() - STARTTIME) && - status != null && !status.isCached && !status.isLatest) { - Log.d(TAG, "Waiting on latest version: " + status - .bytesTransferred + " / " + status.bytesTotal); - try { - Thread.sleep(1000); - } catch (InterruptedException ignored) { - } - // Check latest - file.update(); - status = file.getNewerStatus(); - } - // Update - file.update(); - } catch (DbxException e) { - e.printStackTrace(); + mDBApi.getFile(join(folderpath, filename), null, baos, null); + return new BufferedReader(new StringReader(baos.toString("UTF-8"))); + } catch (DropboxServerException e) { + throw new IOException("" + e.reason); + } catch (DropboxException e) { + throw new IOException("" + e.getMessage()); + } catch (UnsupportedEncodingException e) { + throw new IOException("" + e.getMessage()); } } @@ -341,35 +274,20 @@ private void waitUntilSynced(final DbxFile file) { * @return a set of all remote files. */ @Override - public HashSet getRemoteFilenames() { + public HashSet getRemoteFilenames() throws IOException { final HashSet filenames = new HashSet(); try { - while (fs.getSyncStatus().download.inProgress) { - Log.d(TAG, "Waiting on Dropbox sync..."); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - //e.printStackTrace(); - } - } - List fileInfos = fs.listFolder(DIR); - for (DbxFileInfo fileInfo : fileInfos) { - if (fileInfo.path.getName().toLowerCase().endsWith((".org"))) { - if (fs.isFile(fileInfo.path)) { - Log.d(TAG, "Adding: " + fileInfo.path.getName()); - filenames.add(fileInfo.path.getName()); - } else { - Log.d(TAG, "Caught invalid file: " + fileInfo.path - .getName()); - } + DropboxAPI.Entry entry = mDBApi.metadata(folderpath, -1, null, true, null); + + for (DropboxAPI.Entry file: entry.contents) { + if (!file.isDir && file.fileName().toLowerCase().endsWith(".org")) { + filenames.add(file.fileName()); } } - } catch (DbxException e) { - Log.d(TAG, e.getLocalizedMessage()); - // In case of errors, throw null pointers. Trying to see if this - // the place that deletes files. - throw new NullPointerException(e.getLocalizedMessage()); - //e.printStackTrace(); + } catch (DropboxServerException e) { + throw new IOException("" + e.reason); + } catch (DropboxException e) { + throw new IOException("" + e.getMessage()); } return filenames; } @@ -382,50 +300,11 @@ public void postSynchronize() { } + /** + * @return a Monitor for this source. May be null. + */ @Override public Monitor getMonitor() { - return new DropboxMonitor(fs, DIR); - } - - public final class DropboxMonitor implements Monitor, - DbxFileSystem.PathListener { - - private DbxFileSystem fs; - private final DbxPath dir; - private OrgSyncService.SyncHandler handler; - - public DropboxMonitor(final DbxFileSystem fs, final DbxPath dir) { - this.fs = fs; - this.dir = dir; - } - - @Override - public void startMonitor(final OrgSyncService.SyncHandler handler) { - this.handler = handler; - if (fs != null) { - fs.addPathListener(this, dir, DbxFileSystem.PathListener.Mode.PATH_OR_CHILD); - } - } - - @Override - public void pauseMonitor() { - if (fs != null) { - fs.removePathListenerForAll(this); - } - } - - @Override - public void terminate() { - pauseMonitor(); - fs = null; - } - - @Override - public void onPathChange(final DbxFileSystem dbxFileSystem, - final DbxPath dbxPath, final Mode mode) { - if (handler != null) { - handler.onMonitorChange(); - } - } + return null; } } diff --git a/app/src/play/libs/ALL_LIBS_ARE_FOR_DROPBOX b/app/src/play/libs/ALL_LIBS_ARE_FOR_DROPBOX new file mode 100644 index 000000000..e69de29bb diff --git a/app/src/play/libs/HTTPCOMPONENTS-LICENSE.txt b/app/src/play/libs/HTTPCOMPONENTS-LICENSE.txt new file mode 100644 index 000000000..2c41ec88f --- /dev/null +++ b/app/src/play/libs/HTTPCOMPONENTS-LICENSE.txt @@ -0,0 +1,182 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + +This project contains annotations derived from JCIP-ANNOTATIONS +Copyright (c) 2005 Brian Goetz and Tim Peierls. +See http://www.jcip.net and the Creative Commons Attribution License +(http://creativecommons.org/licenses/by/2.5) + diff --git a/app/src/play/libs/JSON-SIMPLE-LICENSE.txt b/app/src/play/libs/JSON-SIMPLE-LICENSE.txt new file mode 100644 index 000000000..57bc88a15 --- /dev/null +++ b/app/src/play/libs/JSON-SIMPLE-LICENSE.txt @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/app/src/play/libs/armeabi-v7 b/app/src/play/libs/armeabi-v7 deleted file mode 120000 index fb2068a19..000000000 --- a/app/src/play/libs/armeabi-v7 +++ /dev/null @@ -1 +0,0 @@ -armeabi \ No newline at end of file diff --git a/app/src/play/libs/armeabi-v7a b/app/src/play/libs/armeabi-v7a deleted file mode 120000 index fb2068a19..000000000 --- a/app/src/play/libs/armeabi-v7a +++ /dev/null @@ -1 +0,0 @@ -armeabi \ No newline at end of file diff --git a/app/src/play/libs/armeabi/libDropboxSync.so b/app/src/play/libs/armeabi/libDropboxSync.so deleted file mode 100755 index 587d81554..000000000 Binary files a/app/src/play/libs/armeabi/libDropboxSync.so and /dev/null differ diff --git a/app/src/play/libs/dropbox-android-sdk-1.6.3.jar b/app/src/play/libs/dropbox-android-sdk-1.6.3.jar new file mode 100644 index 000000000..1a0ee3686 Binary files /dev/null and b/app/src/play/libs/dropbox-android-sdk-1.6.3.jar differ diff --git a/app/src/play/libs/dropbox-sync-sdk-android.jar b/app/src/play/libs/dropbox-sync-sdk-android.jar deleted file mode 100644 index 807aaa1f7..000000000 Binary files a/app/src/play/libs/dropbox-sync-sdk-android.jar and /dev/null differ diff --git a/app/src/play/libs/httpmime-4.0.3.jar b/app/src/play/libs/httpmime-4.0.3.jar new file mode 100644 index 000000000..0dfd33128 Binary files /dev/null and b/app/src/play/libs/httpmime-4.0.3.jar differ diff --git a/app/src/play/libs/json_simple-1.1.jar b/app/src/play/libs/json_simple-1.1.jar new file mode 100644 index 000000000..f395f4147 Binary files /dev/null and b/app/src/play/libs/json_simple-1.1.jar differ diff --git a/app/src/play/libs/mips/libDropboxSync.so b/app/src/play/libs/mips/libDropboxSync.so deleted file mode 100755 index fcfeb2986..000000000 Binary files a/app/src/play/libs/mips/libDropboxSync.so and /dev/null differ diff --git a/app/src/play/libs/x86/libDropboxSync.so b/app/src/play/libs/x86/libDropboxSync.so deleted file mode 100755 index 54cd33d9a..000000000 Binary files a/app/src/play/libs/x86/libDropboxSync.so and /dev/null differ