Browse Source

Merge pull request #554 from TacoTheDank/master

Major library updates
pull/565/head
Eric Kok 5 years ago committed by GitHub
parent
commit
531527d5ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      app/build.gradle
  2. 86
      app/src/main/java/com/android/internalcopy/http/multipart/ByteArrayPartSource.java
  3. 244
      app/src/main/java/com/android/internalcopy/http/multipart/FilePart.java
  4. 131
      app/src/main/java/com/android/internalcopy/http/multipart/FilePartSource.java
  5. 225
      app/src/main/java/com/android/internalcopy/http/multipart/MultipartEntity.java
  6. 425
      app/src/main/java/com/android/internalcopy/http/multipart/Part.java
  7. 150
      app/src/main/java/com/android/internalcopy/http/multipart/PartBase.java
  8. 72
      app/src/main/java/com/android/internalcopy/http/multipart/PartSource.java
  9. 143
      app/src/main/java/com/android/internalcopy/http/multipart/StringPart.java
  10. 16
      app/src/main/java/de/timroes/axmlrpc/Call.java
  11. 15
      app/src/main/java/de/timroes/axmlrpc/ResponseParser.java
  12. 35
      app/src/main/java/de/timroes/axmlrpc/XMLRPCClient.java
  13. 2
      app/src/main/java/de/timroes/axmlrpc/XMLRPCServerException.java
  14. 4
      app/src/main/java/de/timroes/axmlrpc/XMLUtil.java
  15. 17
      app/src/main/java/de/timroes/axmlrpc/serializer/ArraySerializer.java
  16. 4
      app/src/main/java/de/timroes/axmlrpc/serializer/BooleanSerializer.java
  17. 8
      app/src/main/java/de/timroes/axmlrpc/serializer/DateTimeSerializer.java
  18. 60
      app/src/main/java/de/timroes/axmlrpc/serializer/SerializerHandler.java
  19. 7
      app/src/main/java/de/timroes/axmlrpc/serializer/StringSerializer.java
  20. 10
      app/src/main/java/de/timroes/axmlrpc/serializer/StructSerializer.java
  21. 12
      app/src/main/java/de/timroes/base64/Base64.java
  22. 141
      app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
  23. 321
      app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
  24. 210
      app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
  25. 551
      app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
  26. 1357
      app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
  27. 65
      app/src/main/java/org/apache/openjpa/lib/util/Base16Encoder.java
  28. 1998
      app/src/main/java/org/base64/android/Base64.java
  29. 4
      app/src/main/java/org/transdroid/core/app/settings/SettingsUtils.java
  30. 4
      app/src/main/java/org/transdroid/core/gui/DetailsActivity.java
  31. 6
      app/src/main/java/org/transdroid/core/gui/DetailsFragment.java
  32. 4
      app/src/main/java/org/transdroid/core/gui/TorrentTasksExecutor.java
  33. 16
      app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java
  34. 8
      app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java
  35. 4
      app/src/main/java/org/transdroid/core/gui/TransdroidApp.java
  36. 2
      app/src/main/java/org/transdroid/core/gui/log/DatabaseHelper.java
  37. 6
      app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java
  38. 2
      app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssFragment.java
  39. 14
      app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java
  40. 2
      app/src/main/java/org/transdroid/core/gui/rss/RssFeedsFragment.java
  41. 4
      app/src/main/java/org/transdroid/core/gui/rss/RssItemsActivity.java
  42. 4
      app/src/main/java/org/transdroid/core/gui/rss/RssItemsFragment.java
  43. 6
      app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java
  44. 2
      app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java
  45. 2
      app/src/main/java/org/transdroid/core/gui/settings/InterceptableEditTextPreference.java
  46. 10
      app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java
  47. 2
      app/src/main/java/org/transdroid/core/gui/settings/ServerSettingsActivity.java
  48. 2
      app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java
  49. 2
      app/src/main/java/org/transdroid/core/service/AppUpdateJob.java
  50. 2
      app/src/main/java/org/transdroid/core/service/AppUpdateJobRunner.java
  51. 6
      app/src/main/java/org/transdroid/core/service/ConnectivityHelper.java
  52. 2
      app/src/main/java/org/transdroid/core/service/RssCheckerJob.java
  53. 2
      app/src/main/java/org/transdroid/core/service/RssCheckerJobRunner.java
  54. 4
      app/src/main/java/org/transdroid/core/service/ScheduledJobCreator.java
  55. 2
      app/src/main/java/org/transdroid/core/service/ServerCheckerJob.java
  56. 2
      app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java
  57. 4
      app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java
  58. 2
      app/src/main/java/org/transdroid/core/widget/ListWidgetProvider.java
  59. 48
      app/src/main/java/org/transdroid/daemon/Aria2c/Aria2Adapter.java
  60. 16
      app/src/main/java/org/transdroid/daemon/BitComet/BitCometAdapter.java
  61. 28
      app/src/main/java/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java
  62. 46
      app/src/main/java/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java
  63. 2
      app/src/main/java/org/transdroid/daemon/DaemonException.java
  64. 8
      app/src/main/java/org/transdroid/daemon/Deluge/DelugeAdapter.java
  65. 2
      app/src/main/java/org/transdroid/daemon/Deluge/DelugeCommon.java
  66. 4
      app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcAdapter.java
  67. 2
      app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcClient.java
  68. 14
      app/src/main/java/org/transdroid/daemon/Ktorrent/KtorrentAdapter.java
  69. 6
      app/src/main/java/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java
  70. 16
      app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java
  71. 14
      app/src/main/java/org/transdroid/daemon/Tfb4rt/Tfb4rtAdapter.java
  72. 6
      app/src/main/java/org/transdroid/daemon/Transmission/TransmissionAdapter.java
  73. 14
      app/src/main/java/org/transdroid/daemon/Ttorrent/TtorrentAdapter.java
  74. 14
      app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java
  75. 108
      app/src/main/java/org/transdroid/daemon/Vuze/VuzeXmlOverHttpClient.java
  76. 480
      app/src/main/java/org/transdroid/multipart/BitCometFilePart.java
  77. 88
      app/src/main/java/org/transdroid/multipart/Utf8StringPart.java
  78. 131
      app/src/main/res/layout-land/dialog_color_picker.xml
  79. 2
      app/src/main/res/layout-w600dp/activity_search.xml
  80. 8
      app/src/main/res/layout-w600dp/activity_torrents.xml
  81. 8
      app/src/main/res/layout-w900dp/activity_rssfeeds.xml
  82. 10
      app/src/main/res/layout-w900dp/activity_torrents.xml
  83. 2
      app/src/main/res/layout/activity_details.xml
  84. 8
      app/src/main/res/layout/activity_rssfeeds.xml
  85. 2
      app/src/main/res/layout/activity_rssitems.xml
  86. 4
      app/src/main/res/layout/activity_search.xml
  87. 12
      app/src/main/res/layout/activity_torrents.xml
  88. 137
      app/src/main/res/layout/dialog_color_picker.xml
  89. 8
      app/src/main/res/layout/fragment_details.xml
  90. 4
      app/src/main/res/layout/fragment_torrents.xml
  91. 2
      app/src/main/res/menu/activity_search.xml
  92. 2
      app/src/main/res/menu/activity_torrents_main.xml
  93. 15
      build.gradle
  94. 2
      gradle.properties
  95. BIN
      gradle/wrapper/gradle-wrapper.jar
  96. 3
      gradle/wrapper/gradle-wrapper.properties
  97. 117
      gradlew
  98. 34
      gradlew.bat

36
app/build.gradle

@ -2,8 +2,7 @@ apply plugin: 'com.android.application' @@ -2,8 +2,7 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion '28.0.3'
useLibrary 'org.apache.http.legacy'
buildToolsVersion '29.0.3'
defaultConfig {
minSdkVersion 15
@ -20,6 +19,7 @@ android { @@ -20,6 +19,7 @@ android {
}
}
}
signingConfigs {
releaseConfig {
def propsFile = rootProject.file('keystore.properties')
@ -35,6 +35,7 @@ android { @@ -35,6 +35,7 @@ android {
}
}
}
buildTypes {
debug {
minifyEnabled false
@ -46,6 +47,7 @@ android { @@ -46,6 +47,7 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
flavorDimensions "version"
productFlavors {
full {
@ -59,30 +61,44 @@ android { @@ -59,30 +61,44 @@ android {
resValue "string", "search_history_authority", applicationId + ".search.SearchHistoryProvider"
}
}
lintOptions {
disable 'MissingTranslation', 'ExtraTranslation', 'StringFormatInvalid', 'ValidFragment', 'Registered'
}
compileOptions {
encoding = 'UTF-8'
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
useLibrary 'org.apache.http.legacy'
}
dependencies {
// Android support
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
implementation 'com.google.android.material:material:1.1.0'
// Other
implementation 'org.androidannotations:androidannotations-api:4.7.0'
implementation 'org.androidannotations:ormlite-api:4.7.0'
implementation 'com.j256.ormlite:ormlite-core:4.48'
implementation 'com.j256.ormlite:ormlite-android:4.48'
implementation 'com.j256.ormlite:ormlite-core:5.1'
implementation 'com.j256.ormlite:ormlite-android:5.1'
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:support-annotations:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.getbase:floatingactionbutton:1.10.1'
implementation 'com.nispok:snackbar:2.11.0'
implementation 'com.github.aegnor:rencode-java:cb628e824e'
implementation 'org.apache.openjpa:openjpa-lib:3.1.1'
implementation 'net.iharder:base64:2.3.9'
//implementation 'fr.turri:aXMLRPC:1.12.0'
implementation('com.github.afollestad.material-dialogs:core:0.9.6.0@aar') {
transitive = true
}
implementation 'com.evernote:android-job:1.2.6'
annotationProcessor 'org.androidannotations:androidannotations:4.7.0'
annotationProcessor 'org.androidannotations:ormlite:4.7.0'
}

86
app/src/main/java/com/android/internalcopy/http/multipart/ByteArrayPartSource.java

@ -1,86 +0,0 @@ @@ -1,86 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/ByteArrayPartSource.java,v 1.7 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/**
* A PartSource that reads from a byte array. This class should be used when
* the data to post is already loaded into memory.
*
* @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
*
* @since 2.0
*/
public class ByteArrayPartSource implements PartSource {
/** Name of the source file. */
private String fileName;
/** Byte array of the source file. */
private byte[] bytes;
/**
* Constructor for ByteArrayPartSource.
*
* @param fileName the name of the file these bytes represent
* @param bytes the content of this part
*/
public ByteArrayPartSource(String fileName, byte[] bytes) {
this.fileName = fileName;
this.bytes = bytes;
}
/**
* @see PartSource#getLength()
*/
public long getLength() {
return bytes.length;
}
/**
* @see PartSource#getFileName()
*/
public String getFileName() {
return fileName;
}
/**
* @see PartSource#createInputStream()
*/
public InputStream createInputStream() {
return new ByteArrayInputStream(bytes);
}
}

244
app/src/main/java/com/android/internalcopy/http/multipart/FilePart.java

@ -1,244 +0,0 @@ @@ -1,244 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java,v 1.19 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.http.util.EncodingUtils;
/**
* This class implements a part of a Multipart post object that
* consists of a file.
*
* @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a>
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
* @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a>
* @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
* @author <a href="mailto:mdiggory@latte.harvard.edu">Mark Diggory</a>
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
*
* @since 2.0
*
*/
public class FilePart extends PartBase {
/** Default content encoding of file attachments. */
public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
/** Default charset of file attachments. */
public static final String DEFAULT_CHARSET = "ISO-8859-1";
/** Default transfer encoding of file attachments. */
public static final String DEFAULT_TRANSFER_ENCODING = "binary";
/** Attachment's file name */
protected static final String FILE_NAME = "; filename=";
/** Attachment's file name as a byte array */
private static final byte[] FILE_NAME_BYTES =
EncodingUtils.getAsciiBytes(FILE_NAME);
/** Source of the file part. */
private PartSource source;
/**
* FilePart Constructor.
*
* @param name the name for this part
* @param partSource the source for this part
* @param contentType the content type for this part, if <code>null</code> the
* {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
* {@link #DEFAULT_CHARSET default} is used
*/
public FilePart(String name, PartSource partSource, String contentType, String charset) {
super(
name,
contentType == null ? DEFAULT_CONTENT_TYPE : contentType,
charset == null ? "ISO-8859-1" : charset,
DEFAULT_TRANSFER_ENCODING
);
if (partSource == null) {
throw new IllegalArgumentException("Source may not be null");
}
this.source = partSource;
}
/**
* FilePart Constructor.
*
* @param name the name for this part
* @param partSource the source for this part
*/
public FilePart(String name, PartSource partSource) {
this(name, partSource, null, null);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param file the file to post
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public FilePart(String name, File file)
throws FileNotFoundException {
this(name, new FilePartSource(file), null, null);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param file the file to post
* @param contentType the content type for this part, if <code>null</code> the
* {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
* {@link #DEFAULT_CHARSET default} is used
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public FilePart(String name, File file, String contentType, String charset)
throws FileNotFoundException {
this(name, new FilePartSource(file), contentType, charset);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param fileName the file name
* @param file the file to post
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public FilePart(String name, String fileName, File file)
throws FileNotFoundException {
this(name, new FilePartSource(fileName, file), null, null);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param fileName the file name
* @param file the file to post
* @param contentType the content type for this part, if <code>null</code> the
* {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
* {@link #DEFAULT_CHARSET default} is used
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public FilePart(String name, String fileName, File file, String contentType, String charset)
throws FileNotFoundException {
this(name, new FilePartSource(fileName, file), contentType, charset);
}
/**
* Write the disposition header to the output stream
* @param out The output stream
* @throws IOException If an IO problem occurs
* @see Part#sendDispositionHeader(OutputStream)
*/
@Override
protected void sendDispositionHeader(OutputStream out)
throws IOException {
super.sendDispositionHeader(out);
String filename = this.source.getFileName();
if (filename != null) {
out.write(FILE_NAME_BYTES);
out.write(QUOTE_BYTES);
out.write(EncodingUtils.getAsciiBytes(filename));
out.write(QUOTE_BYTES);
}
}
/**
* Write the data in "source" to the specified stream.
* @param out The output stream.
* @throws IOException if an IO problem occurs.
* @see Part#sendData(OutputStream)
*/
@Override
protected void sendData(OutputStream out) throws IOException {
if (lengthOfData() == 0) {
// this file contains no data, so there is nothing to send.
// we don't want to create a zero length buffer as this will
// cause an infinite loop when reading.
return;
}
byte[] tmp = new byte[4096];
InputStream instream = source.createInputStream();
try {
int len;
while ((len = instream.read(tmp)) >= 0) {
out.write(tmp, 0, len);
}
} finally {
// we're done with the stream, close it
instream.close();
}
}
/**
* Returns the source of the file part.
*
* @return The source.
*/
protected PartSource getSource() {
return this.source;
}
/**
* Return the length of the data.
* @return The length.
* @see Part#lengthOfData()
*/
@Override
protected long lengthOfData() {
return source.getLength();
}
}

131
app/src/main/java/com/android/internalcopy/http/multipart/FilePartSource.java

@ -1,131 +0,0 @@ @@ -1,131 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePartSource.java,v 1.10 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* A PartSource that reads from a File.
*
* @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
* @author <a href="mailto:mdiggory@latte.harvard.edu">Mark Diggory</a>
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
*
* @since 2.0
*/
public class FilePartSource implements PartSource {
/** File part file. */
private File file = null;
/** File part file name. */
private String fileName = null;
/**
* Constructor for FilePartSource.
*
* @param file the FilePart source File.
*
* @throws FileNotFoundException if the file does not exist or
* cannot be read
*/
public FilePartSource(File file) throws FileNotFoundException {
this.file = file;
if (file != null) {
if (!file.isFile()) {
throw new FileNotFoundException("File is not a normal file.");
}
if (!file.canRead()) {
throw new FileNotFoundException("File is not readable.");
}
this.fileName = file.getName();
}
}
/**
* Constructor for FilePartSource.
*
* @param fileName the file name of the FilePart
* @param file the source File for the FilePart
*
* @throws FileNotFoundException if the file does not exist or
* cannot be read
*/
public FilePartSource(String fileName, File file)
throws FileNotFoundException {
this(file);
if (fileName != null) {
this.fileName = fileName;
}
}
/**
* Return the length of the file
* @return the length of the file.
* @see PartSource#getLength()
*/
public long getLength() {
if (this.file != null) {
return this.file.length();
} else {
return 0;
}
}
/**
* Return the current filename
* @return the filename.
* @see PartSource#getFileName()
*/
public String getFileName() {
return (fileName == null) ? "noname" : fileName;
}
/**
* Return a new {@link FileInputStream} for the current filename.
* @return the new input stream.
* @throws IOException If an IO problem occurs.
* @see PartSource#createInputStream()
*/
public InputStream createInputStream() throws IOException {
if (this.file != null) {
return new FileInputStream(this.file);
} else {
return new ByteArrayInputStream(new byte[] {});
}
}
}

225
app/src/main/java/com/android/internalcopy/http/multipart/MultipartEntity.java

@ -1,225 +0,0 @@ @@ -1,225 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/MultipartRequestEntity.java,v 1.1 2004/10/06 03:39:59 mbecke Exp $
* $Revision: 502647 $
* $Date: 2007-02-02 17:22:54 +0100 (Fri, 02 Feb 2007) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;
import org.apache.http.Header;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EncodingUtils;
/**
* Implements a request entity suitable for an HTTP multipart POST method.
* <p>
* The HTTP multipart POST method is defined in section 3.3 of
* <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC1867</a>:
* <blockquote>
* The media-type multipart/form-data follows the rules of all multipart
* MIME data streams as outlined in RFC 1521. The multipart/form-data contains
* a series of parts. Each part is expected to contain a content-disposition
* header where the value is "form-data" and a name attribute specifies
* the field name within the form, e.g., 'content-disposition: form-data;
* name="xxxxx"', where xxxxx is the field name corresponding to that field.
* Field names originally in non-ASCII character sets may be encoded using
* the method outlined in RFC 1522.
* </blockquote>
* </p>
* <p>This entity is designed to be used in conjunction with the
* {@link org.apache.http.HttpRequest} to provide
* multipart posts. Example usage:</p>
* <pre>
* File f = new File("/path/fileToUpload.txt");
* HttpRequest request = new HttpRequest("http://host/some_path");
* Part[] parts = {
* new StringPart("param_name", "value"),
* new FilePart(f.getName(), f)
* };
* filePost.setEntity(
* new MultipartRequestEntity(parts, filePost.getParams())
* );
* HttpClient client = new HttpClient();
* int status = client.executeMethod(filePost);
* </pre>
*
* @since 3.0
*/
public class MultipartEntity extends AbstractHttpEntity {
/** The Content-Type for multipart/form-data. */
private static final String MULTIPART_FORM_CONTENT_TYPE = "multipart/form-data";
/**
* Sets the value to use as the multipart boundary.
* <p>
* This parameter expects a value if type {@link String}.
* </p>
*/
public static final String MULTIPART_BOUNDARY = "http.method.multipart.boundary";
/**
* The pool of ASCII chars to be used for generating a multipart boundary.
*/
private static byte[] MULTIPART_CHARS = EncodingUtils.getAsciiBytes(
"-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
/**
* Generates a random multipart boundary string.
*/
private static byte[] generateMultipartBoundary() {
Random rand = new Random();
byte[] bytes = new byte[rand.nextInt(11) + 30]; // a random size from 30 to 40
for (int i = 0; i < bytes.length; i++) {
bytes[i] = MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)];
}
return bytes;
}
/** The MIME parts as set by the constructor */
protected Part[] parts;
private byte[] multipartBoundary;
private HttpParams params;
private boolean contentConsumed = false;
/**
* Creates a new multipart entity containing the given parts.
* @param parts The parts to include.
* @param params The params of the HttpMethod using this entity.
*/
public MultipartEntity(Part[] parts, HttpParams params) {
if (parts == null) {
throw new IllegalArgumentException("parts cannot be null");
}
if (params == null) {
throw new IllegalArgumentException("params cannot be null");
}
this.parts = parts;
this.params = params;
}
public MultipartEntity(Part[] parts) {
setContentType(MULTIPART_FORM_CONTENT_TYPE);
if (parts == null) {
throw new IllegalArgumentException("parts cannot be null");
}
this.parts = parts;
this.params = null;
}
/**
* Returns the MIME boundary string that is used to demarcate boundaries of
* this part. The first call to this method will implicitly create a new
* boundary string. To create a boundary string first the
* HttpMethodParams.MULTIPART_BOUNDARY parameter is considered. Otherwise
* a random one is generated.
*
* @return The boundary string of this entity in ASCII encoding.
*/
protected byte[] getMultipartBoundary() {
if (multipartBoundary == null) {
String temp = null;
if (params != null) {
temp = (String) params.getParameter(MULTIPART_BOUNDARY);
}
if (temp != null) {
multipartBoundary = EncodingUtils.getAsciiBytes(temp);
} else {
multipartBoundary = generateMultipartBoundary();
}
}
return multipartBoundary;
}
/**
* Returns <code>true</code> if all parts are repeatable, <code>false</code> otherwise.
*/
public boolean isRepeatable() {
for (int i = 0; i < parts.length; i++) {
if (!parts[i].isRepeatable()) {
return false;
}
}
return true;
}
/* (non-Javadoc)
*/
public void writeTo(OutputStream out) throws IOException {
Part.sendParts(out, parts, getMultipartBoundary());
}
/* (non-Javadoc)
* @see org.apache.commons.http.AbstractHttpEntity.#getContentType()
*/
@Override
public Header getContentType() {
StringBuffer buffer = new StringBuffer(MULTIPART_FORM_CONTENT_TYPE);
buffer.append("; boundary=");
buffer.append(EncodingUtils.getAsciiString(getMultipartBoundary()));
return new BasicHeader(HTTP.CONTENT_TYPE, buffer.toString());
}
/* (non-Javadoc)
*/
public long getContentLength() {
try {
return Part.getLengthOfParts(parts, getMultipartBoundary());
} catch (Exception e) {
return 0;
}
}
public InputStream getContent() throws IOException, IllegalStateException {
if(!isRepeatable() && this.contentConsumed ) {
throw new IllegalStateException("Content has been consumed");
}
this.contentConsumed = true;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Part.sendParts(baos, this.parts, this.multipartBoundary);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
return bais;
}
public boolean isStreaming() {
return false;
}
}

425
app/src/main/java/com/android/internalcopy/http/multipart/Part.java

@ -1,425 +0,0 @@ @@ -1,425 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/Part.java,v 1.16 2005/01/14 21:16:40 olegk Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.http.util.EncodingUtils;
/**
* Abstract class for one Part of a multipart post object.
*
* @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a>
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
* @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a>
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
*
* @since 2.0
*/
public abstract class Part {
/**
* The boundary
* @deprecated use {@link org.apache.http.client.methods.multipart#MULTIPART_BOUNDARY}
*/
protected static final String BOUNDARY = "----------------314159265358979323846";
/**
* The boundary as a byte array.
* @deprecated
*/
protected static final byte[] BOUNDARY_BYTES = EncodingUtils.getAsciiBytes(BOUNDARY);
/**
* The default boundary to be used if {@link #setPartBoundary(byte[])} has not
* been called.
*/
private static final byte[] DEFAULT_BOUNDARY_BYTES = BOUNDARY_BYTES;
/** Carriage return/linefeed */
protected static final String CRLF = "\r\n";
/** Carriage return/linefeed as a byte array */
protected static final byte[] CRLF_BYTES = EncodingUtils.getAsciiBytes(CRLF);
/** Content dispostion characters */
protected static final String QUOTE = "\"";
/** Content dispostion as a byte array */
protected static final byte[] QUOTE_BYTES =
EncodingUtils.getAsciiBytes(QUOTE);
/** Extra characters */
protected static final String EXTRA = "--";
/** Extra characters as a byte array */
protected static final byte[] EXTRA_BYTES =
EncodingUtils.getAsciiBytes(EXTRA);
/** Content dispostion characters */
protected static final String CONTENT_DISPOSITION = "Content-Disposition: form-data; name=";
/** Content dispostion as a byte array */
protected static final byte[] CONTENT_DISPOSITION_BYTES =
EncodingUtils.getAsciiBytes(CONTENT_DISPOSITION);
/** Content type header */
protected static final String CONTENT_TYPE = "Content-Type: ";
/** Content type header as a byte array */
protected static final byte[] CONTENT_TYPE_BYTES =
EncodingUtils.getAsciiBytes(CONTENT_TYPE);
/** Content charset */
protected static final String CHARSET = "; charset=";
/** Content charset as a byte array */
protected static final byte[] CHARSET_BYTES =
EncodingUtils.getAsciiBytes(CHARSET);
/** Content type header */
protected static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding: ";
/** Content type header as a byte array */
protected static final byte[] CONTENT_TRANSFER_ENCODING_BYTES =
EncodingUtils.getAsciiBytes(CONTENT_TRANSFER_ENCODING);
/**
* Return the boundary string.
* @return the boundary string
* @deprecated uses a constant string. Rather use {@link #getPartBoundary}
*/
public static String getBoundary() {
return BOUNDARY;
}
/**
* The ASCII bytes to use as the multipart boundary.
*/
private byte[] boundaryBytes;
/**
* Return the name of this part.
* @return The name.
*/
public abstract String getName();
/**
* Returns the content type of this part.
* @return the content type, or <code>null</code> to exclude the content type header
*/
public abstract String getContentType();
/**
* Return the character encoding of this part.
* @return the character encoding, or <code>null</code> to exclude the character
* encoding header
*/
public abstract String getCharSet();
/**
* Return the transfer encoding of this part.
* @return the transfer encoding, or <code>null</code> to exclude the transfer encoding header
*/
public abstract String getTransferEncoding();
/**
* Gets the part boundary to be used.
* @return the part boundary as an array of bytes.
*
* @since 3.0
*/
protected byte[] getPartBoundary() {
if (boundaryBytes == null) {
// custom boundary bytes have not been set, use the default.
return DEFAULT_BOUNDARY_BYTES;
} else {
return boundaryBytes;
}
}
/**
* Sets the part boundary. Only meant to be used by
* {@link Part#sendParts(OutputStream, Part[], byte[])}
* and {@link Part#getLengthOfParts(Part[], byte[])}
* @param boundaryBytes An array of ASCII bytes.
* @since 3.0
*/
void setPartBoundary(byte[] boundaryBytes) {
this.boundaryBytes = boundaryBytes;
}
/**
* Tests if this part can be sent more than once.
* @return <code>true</code> if {@link #sendData(OutputStream)} can be successfully called
* more than once.
* @since 3.0
*/
public boolean isRepeatable() {
return true;
}
/**
* Write the start to the specified output stream
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected void sendStart(OutputStream out) throws IOException {
out.write(EXTRA_BYTES);
out.write(getPartBoundary());
out.write(CRLF_BYTES);
}
/**
* Write the content disposition header to the specified output stream
*
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected void sendDispositionHeader(OutputStream out) throws IOException {
out.write(CONTENT_DISPOSITION_BYTES);
out.write(QUOTE_BYTES);
out.write(EncodingUtils.getAsciiBytes(getName()));
out.write(QUOTE_BYTES);
}
/**
* Write the content type header to the specified output stream
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected void sendContentTypeHeader(OutputStream out) throws IOException {
String contentType = getContentType();
if (contentType != null) {
out.write(CRLF_BYTES);
out.write(CONTENT_TYPE_BYTES);
out.write(EncodingUtils.getAsciiBytes(contentType));
String charSet = getCharSet();
if (charSet != null) {
out.write(CHARSET_BYTES);
out.write(EncodingUtils.getAsciiBytes(charSet));
}
}
}
/**
* Write the content transfer encoding header to the specified
* output stream
*
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected void sendTransferEncodingHeader(OutputStream out) throws IOException {
String transferEncoding = getTransferEncoding();
if (transferEncoding != null) {
out.write(CRLF_BYTES);
out.write(CONTENT_TRANSFER_ENCODING_BYTES);
out.write(EncodingUtils.getAsciiBytes(transferEncoding));
}
}
/**
* Write the end of the header to the output stream
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected void sendEndOfHeader(OutputStream out) throws IOException {
out.write(CRLF_BYTES);
out.write(CRLF_BYTES);
}
/**
* Write the data to the specified output stream
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected abstract void sendData(OutputStream out) throws IOException;
/**
* Return the length of the main content
*
* @return long The length.
* @throws IOException If an IO problem occurs
*/
protected abstract long lengthOfData() throws IOException;
/**
* Write the end data to the output stream.
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected void sendEnd(OutputStream out) throws IOException {
out.write(CRLF_BYTES);
}
/**
* Write all the data to the output stream.
* If you override this method make sure to override
* #length() as well
*
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
public void send(OutputStream out) throws IOException {
sendStart(out);
sendDispositionHeader(out);
sendContentTypeHeader(out);
sendTransferEncodingHeader(out);
sendEndOfHeader(out);
sendData(out);
sendEnd(out);
}
/**
* Return the full length of all the data.
* If you override this method make sure to override
* #send(OutputStream) as well
*
* @return long The length.
* @throws IOException If an IO problem occurs
*/
public long length() throws IOException {
if (lengthOfData() < 0) {
return -1;
}
ByteArrayOutputStream overhead = new ByteArrayOutputStream();
sendStart(overhead);
sendDispositionHeader(overhead);
sendContentTypeHeader(overhead);
sendTransferEncodingHeader(overhead);
sendEndOfHeader(overhead);
sendEnd(overhead);
return overhead.size() + lengthOfData();
}
/**
* Return a string representation of this object.
* @return A string representation of this object.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.getName();
}
/**
* Write all parts and the last boundary to the specified output stream.
*
* @param out The stream to write to.
* @param parts The parts to write.
*
* @throws IOException If an I/O error occurs while writing the parts.
*/
public static void sendParts(OutputStream out, final Part[] parts)
throws IOException {
sendParts(out, parts, DEFAULT_BOUNDARY_BYTES);
}
/**
* Write all parts and the last boundary to the specified output stream.
*
* @param out The stream to write to.
* @param parts The parts to write.
* @param partBoundary The ASCII bytes to use as the part boundary.
*
* @throws IOException If an I/O error occurs while writing the parts.
*
* @since 3.0
*/
public static void sendParts(OutputStream out, Part[] parts, byte[] partBoundary)
throws IOException {
if (parts == null) {
throw new IllegalArgumentException("Parts may not be null");
}
if (partBoundary == null || partBoundary.length == 0) {
throw new IllegalArgumentException("partBoundary may not be empty");
}
for (int i = 0; i < parts.length; i++) {
// set the part boundary before the part is sent
parts[i].setPartBoundary(partBoundary);
parts[i].send(out);
}
out.write(EXTRA_BYTES);
out.write(partBoundary);
out.write(EXTRA_BYTES);
out.write(CRLF_BYTES);
}
/**
* Return the total sum of all parts and that of the last boundary
*
* @param parts The parts.
* @return The total length
*
* @throws IOException If an I/O error occurs while writing the parts.
*/
public static long getLengthOfParts(Part[] parts)
throws IOException {
return getLengthOfParts(parts, DEFAULT_BOUNDARY_BYTES);
}
/**
* Gets the length of the multipart message including the given parts.
*
* @param parts The parts.
* @param partBoundary The ASCII bytes to use as the part boundary.
* @return The total length
*
* @throws IOException If an I/O error occurs while writing the parts.
*
* @since 3.0
*/
public static long getLengthOfParts(Part[] parts, byte[] partBoundary) throws IOException {
if (parts == null) {
throw new IllegalArgumentException("Parts may not be null");
}
long total = 0;
for (int i = 0; i < parts.length; i++) {
// set the part boundary before we calculate the part's length
parts[i].setPartBoundary(partBoundary);
long l = parts[i].length();
if (l < 0) {
return -1;
}
total += l;
}
total += EXTRA_BYTES.length;
total += partBoundary.length;
total += EXTRA_BYTES.length;
total += CRLF_BYTES.length;
return total;
}
}

150
app/src/main/java/com/android/internalcopy/http/multipart/PartBase.java

@ -1,150 +0,0 @@ @@ -1,150 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/PartBase.java,v 1.5 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
/**
* Provides setters and getters for the basic Part properties.
*
* @author Michael Becke
*/
public abstract class PartBase extends Part {
/** Name of the file part. */
private String name;
/** Content type of the file part. */
private String contentType;
/** Content encoding of the file part. */
private String charSet;
/** The transfer encoding. */
private String transferEncoding;
/**
* Constructor.
*
* @param name The name of the part
* @param contentType The content type, or <code>null</code>
* @param charSet The character encoding, or <code>null</code>
* @param transferEncoding The transfer encoding, or <code>null</code>
*/
public PartBase(String name, String contentType, String charSet, String transferEncoding) {
if (name == null) {
throw new IllegalArgumentException("Name must not be null");
}
this.name = name;
this.contentType = contentType;
this.charSet = charSet;
this.transferEncoding = transferEncoding;
}
/**
* Returns the name.
* @return The name.
* @see Part#getName()
*/
@Override
public String getName() {
return this.name;
}
/**
* Returns the content type of this part.
* @return String The name.
*/
@Override
public String getContentType() {
return this.contentType;
}
/**
* Return the character encoding of this part.
* @return String The name.
*/
@Override
public String getCharSet() {
return this.charSet;
}
/**
* Returns the transfer encoding of this part.
* @return String The name.
*/
@Override
public String getTransferEncoding() {
return transferEncoding;
}
/**
* Sets the character encoding.
*
* @param charSet the character encoding, or <code>null</code> to exclude the character
* encoding header
*/
public void setCharSet(String charSet) {
this.charSet = charSet;
}
/**
* Sets the content type.
*
* @param contentType the content type, or <code>null</code> to exclude the content type header
*/
public void setContentType(String contentType) {
this.contentType = contentType;
}
/**
* Sets the part name.
*
* @param name
*/
public void setName(String name) {
if (name == null) {
throw new IllegalArgumentException("Name must not be null");
}
this.name = name;
}
/**
* Sets the transfer encoding.
*
* @param transferEncoding the transfer encoding, or <code>null</code> to exclude the
* transfer encoding header
*/
public void setTransferEncoding(String transferEncoding) {
this.transferEncoding = transferEncoding;
}
}

72
app/src/main/java/com/android/internalcopy/http/multipart/PartSource.java

@ -1,72 +0,0 @@ @@ -1,72 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/PartSource.java,v 1.6 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.IOException;
import java.io.InputStream;
/**
* An interface for providing access to data when posting MultiPart messages.
*
* @see FilePart
*
* @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
*
* @since 2.0
*/
public interface PartSource {
/**
* Gets the number of bytes contained in this source.
*
* @return a value >= 0
*/
long getLength();
/**
* Gets the name of the file this source represents.
*
* @return the fileName used for posting a MultiPart file part
*/
String getFileName();
/**
* Gets a new InputStream for reading this source. This method can be
* called more than once and should therefore return a new stream every
* time.
*
* @return a new InputStream
*
* @throws IOException if an error occurs when creating the InputStream
*/
InputStream createInputStream() throws IOException;
}

143
app/src/main/java/com/android/internalcopy/http/multipart/StringPart.java

@ -1,143 +0,0 @@ @@ -1,143 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/StringPart.java,v 1.11 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.OutputStream;
import java.io.IOException;
import org.apache.http.util.EncodingUtils;
/**
* Simple string parameter for a multipart post
*
* @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a>
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
*
* @since 2.0
*/
public class StringPart extends PartBase {
/** Default content encoding of string parameters. */
public static final String DEFAULT_CONTENT_TYPE = "text/plain";
/** Default charset of string parameters*/
public static final String DEFAULT_CHARSET = "US-ASCII";
/** Default transfer encoding of string parameters*/
public static final String DEFAULT_TRANSFER_ENCODING = "8bit";
/** Contents of this StringPart. */
private byte[] content;
/** The String value of this part. */
private String value;
/**
* Constructor.
*
* @param name The name of the part
* @param value the string to post
* @param charset the charset to be used to encode the string, if <code>null</code>
* the {@link #DEFAULT_CHARSET default} is used
*/
public StringPart(String name, String value, String charset) {
super(
name,
DEFAULT_CONTENT_TYPE,
charset == null ? DEFAULT_CHARSET : charset,
DEFAULT_TRANSFER_ENCODING
);
if (value == null) {
throw new IllegalArgumentException("Value may not be null");
}
if (value.indexOf(0) != -1) {
// See RFC 2048, 2.8. "8bit Data"
throw new IllegalArgumentException("NULs may not be present in string parts");
}
this.value = value;
}
/**
* Constructor.
*
* @param name The name of the part
* @param value the string to post
*/
public StringPart(String name, String value) {
this(name, value, null);
}
/**
* Gets the content in bytes. Bytes are lazily created to allow the charset to be changed
* after the part is created.
*
* @return the content in bytes
*/
private byte[] getContent() {
if (content == null) {
content = EncodingUtils.getBytes(value, getCharSet());
}
return content;
}
/**
* Writes the data to the given OutputStream.
* @param out the OutputStream to write to
* @throws IOException if there is a write error
*/
@Override
protected void sendData(OutputStream out) throws IOException {
out.write(getContent());
}
/**
* Return the length of the data.
* @return The length of the data.
* @see Part#lengthOfData()
*/
@Override
protected long lengthOfData() {
return getContent().length;
}
/* (non-Javadoc)
* @see org.apache.commons.httpclient.methods.multipart.BasePart#setCharSet(java.lang.String)
*/
@Override
public void setCharSet(String charSet) {
super.setCharSet(charSet);
this.content = null;
}
}

16
app/src/main/java/de/timroes/axmlrpc/Call.java

@ -16,13 +16,14 @@ public class Call { @@ -16,13 +16,14 @@ public class Call {
private String method;
private Object[] params;
private final SerializerHandler serializerHandler;
/**
* Create a new method call with the given name and no parameters.
* @param method The method to be called.
*/
public Call(String method) {
this(method, null);
public Call(SerializerHandler serializerHandler, String method) {
this(serializerHandler, method, null);
}
/**
@ -30,9 +31,10 @@ public class Call { @@ -30,9 +31,10 @@ public class Call {
* @param method The method to be called.
* @param params An array of parameters for the method.
*/
public Call(String method, Object[] params) {
public Call(SerializerHandler serializerHandler, String method, Object[] params) {
this.method = method;
this.params = params;
this.serializerHandler = serializerHandler;
}
/**
@ -57,11 +59,11 @@ public class Call { @@ -57,11 +59,11 @@ public class Call {
methodCall.addChildren(methodName);
if(params != null && params.length > 0) {
XmlElement params = new XmlElement(XMLRPCClient.PARAMS);
methodCall.addChildren(params);
XmlElement callParams = new XmlElement(XMLRPCClient.PARAMS);
methodCall.addChildren(callParams);
for(Object o : this.params) {
params.addChildren(getXMLParam(o));
callParams.addChildren(getXMLParam(o));
}
}
@ -79,7 +81,7 @@ public class Call { @@ -79,7 +81,7 @@ public class Call {
XmlElement param = new XmlElement(XMLRPCClient.PARAM);
XmlElement value = new XmlElement(XMLRPCClient.VALUE);
param.addChildren(value);
value.addChildren(SerializerHandler.getDefault().serialize(o));
value.addChildren(serializerHandler.serialize(o));
return param;
}

15
app/src/main/java/de/timroes/axmlrpc/ResponseParser.java

@ -16,7 +16,7 @@ import org.xmlpull.v1.XmlPullParserFactory; @@ -16,7 +16,7 @@ import org.xmlpull.v1.XmlPullParserFactory;
*
* @author Tim Roes
*/
class ResponseParser {
public class ResponseParser {
private static final String FAULT_CODE = "faultCode";
private static final String FAULT_STRING = "faultString";
@ -71,13 +71,13 @@ class ResponseParser { @@ -71,13 +71,13 @@ class ResponseParser {
pullParser.nextTag(); // TAG_VALUE (<value>)
// no parser.require() here since its called in XMLRPCSerializer.deserialize() below
// deserialize result
Object obj = SerializerHandler.getDefault().deserialize(pullParser);
Object obj = SerializerHandler.deserialize(pullParser);
consumeHttpEntity(response, entity);
return obj;
} else if (tag.equals(XMLRPCClient.FAULT)) {
// fault response
pullParser.nextTag(); // TAG_VALUE (<value>)
Map<String, Object> map = (Map<String, Object>) SerializerHandler.getDefault().deserialize(pullParser);
Map<String, Object> map = (Map<String, Object>) SerializerHandler.deserialize(pullParser);
consumeHttpEntity(response, entity);
//Check that required tags are in the response
@ -92,12 +92,11 @@ class ResponseParser { @@ -92,12 +92,11 @@ class ResponseParser {
} catch (XmlPullParserException ex) {
consumeHttpEntity(response, entity);
throw new XMLRPCException("Error parsing response.", ex);
} catch(XMLRPCServerException e) {
throw e;
} catch (Exception ex) {
consumeHttpEntity(response, entity);
if(ex instanceof XMLRPCServerException)
throw (XMLRPCServerException)ex;
else
throw new XMLRPCException("Error getting result from server.", ex);
throw new XMLRPCException("Error getting result from server.", ex);
}
}
}
}

35
app/src/main/java/de/timroes/axmlrpc/XMLRPCClient.java

@ -127,6 +127,11 @@ public class XMLRPCClient { @@ -127,6 +127,11 @@ public class XMLRPCClient {
*/
public static final int FLAGS_NO_STRING_ENCODE = 0x1000;
/**
* Accepts response containing eg: <dateTime.iso8601/>
*/
public static final int FLAGS_ACCEPT_NULL_DATES = 0x4000;
/**
* This flag should be used if the server is an apache ws xmlrpc server.
* This will set some flags, so that the not standard conform behavior
@ -140,28 +145,30 @@ public class XMLRPCClient { @@ -140,28 +145,30 @@ public class XMLRPCClient {
private final int flags;
private DefaultHttpClient httpclient;
private String url;
private Map<Long,Caller> backgroundCalls = new ConcurrentHashMap<Long, Caller>();
private ResponseParser responseParser;
private final SerializerHandler serializerHandler;
/**
* Create a new XMLRPC client for the given URL.
*
*
* @param httpclient The already-initialized Apache HttpClient to use for connection.
* @param url The URL to send the requests to.
* @param flags A combination of flags to be set.
*/
public XMLRPCClient(DefaultHttpClient httpclient, String url, int flags) {
SerializerHandler.initialize(flags);
this.serializerHandler = new SerializerHandler(flags);
this.httpclient = httpclient;
this.url = url;
this.flags = flags;
// Create a parser for the http responses.
responseParser = new ResponseParser();
@ -260,7 +267,7 @@ public class XMLRPCClient { @@ -260,7 +267,7 @@ public class XMLRPCClient {
throw new XMLRPCRuntimeException("Method name must only contain A-Z a-z . : _ / ");
}
return new Call(method, params);
return new Call(serializerHandler, method, params);
}
@ -368,7 +375,7 @@ public class XMLRPCClient { @@ -368,7 +375,7 @@ public class XMLRPCClient {
try {
Call c = createCall(methodName, params);
// Prepare POST request
// FIXME: where creating a new HttpPost so calling #cancel isn't going to do anything
HttpPost post = new HttpPost(url);
@ -377,10 +384,10 @@ public class XMLRPCClient { @@ -377,10 +384,10 @@ public class XMLRPCClient {
StringEntity entity = new StringEntity(c.getXML(), HTTP.UTF_8);
entity.setContentType(TYPE_XML);
post.setEntity(entity);
HttpResponse response = httpclient.execute(post);
int statusCode = response.getStatusLine().getStatusCode();
InputStream istream;
// If status code was 401 or 403 throw exception or if appropriate
@ -406,7 +413,7 @@ public class XMLRPCClient { @@ -406,7 +413,7 @@ public class XMLRPCClient {
|| statusCode == HttpURLConnection.HTTP_MOVED_TEMP) {
// ... do either a foward
if(isFlagSet(FLAGS_FORWARD)) {
boolean temporaryForward = (statusCode == HttpURLConnection.HTTP_MOVED_TEMP);
boolean temporaryForward = statusCode == HttpURLConnection.HTTP_MOVED_TEMP;
// Get new location from header field.
String newLocation = response.getFirstHeader("Location").getValue();
@ -440,10 +447,8 @@ public class XMLRPCClient { @@ -440,10 +447,8 @@ public class XMLRPCClient {
}
// Check for strict parameters
if(isFlagSet(FLAGS_STRICT)) {
if(!response.getFirstHeader("Content-Type").getValue().startsWith(TYPE_XML)) {
if(isFlagSet(FLAGS_STRICT) && !response.getFirstHeader("Content-Type").getValue().startsWith(TYPE_XML)) {
throw new XMLRPCException("The Content-Type of the response must be text/xml.");
}
}
return responseParser.parse(istream, entity);
@ -462,9 +467,9 @@ public class XMLRPCClient { @@ -462,9 +467,9 @@ public class XMLRPCClient {
}
}
}
public static class CancelException extends Exception {
private static final long serialVersionUID = 9125122307255855136L;
}
@ -475,5 +480,5 @@ public class XMLRPCClient { @@ -475,5 +480,5 @@ public class XMLRPCClient {
public UnauthorizdException(int statusCode) { this.statusCode = statusCode; }
public int getStatusCode() { return statusCode; }
}
}

2
app/src/main/java/de/timroes/axmlrpc/XMLRPCServerException.java

@ -8,7 +8,7 @@ package de.timroes.axmlrpc; @@ -8,7 +8,7 @@ package de.timroes.axmlrpc;
*/
public class XMLRPCServerException extends XMLRPCException {
private int errornr;
private final int errornr;
public XMLRPCServerException(String ex, int errnr) {
super(ex);

4
app/src/main/java/de/timroes/axmlrpc/XMLUtil.java

@ -9,6 +9,8 @@ import de.timroes.axmlrpc.xmlcreator.XmlElement; @@ -9,6 +9,8 @@ import de.timroes.axmlrpc.xmlcreator.XmlElement;
*/
public class XMLUtil {
private XMLUtil() {}
/**
* Creates an xml tag with a given type and content.
*
@ -22,4 +24,4 @@ public class XMLUtil { @@ -22,4 +24,4 @@ public class XMLUtil {
return xml;
}
}
}

17
app/src/main/java/de/timroes/axmlrpc/serializer/ArraySerializer.java

@ -3,6 +3,7 @@ package de.timroes.axmlrpc.serializer; @@ -3,6 +3,7 @@ package de.timroes.axmlrpc.serializer;
import de.timroes.axmlrpc.XMLRPCException;
import de.timroes.axmlrpc.XMLRPCRuntimeException;
import de.timroes.axmlrpc.xmlcreator.XmlElement;
import java.util.Arrays;
/**
*
@ -12,10 +13,20 @@ public class ArraySerializer implements Serializer { @@ -12,10 +13,20 @@ public class ArraySerializer implements Serializer {
private static final String ARRAY_DATA = "data";
private static final String ARRAY_VALUE = "value";
private final SerializerHandler serializerHandler;
public ArraySerializer(SerializerHandler serializerHandler){
this.serializerHandler = serializerHandler;
}
public XmlElement serialize(Object object) {
Iterable<?> iter = (Iterable<?>)object;
Iterable<?> iter;
if ( object instanceof Iterable<?>){
iter = (Iterable<?>)object;
} else {
iter = Arrays.asList((Object[]) object);
}
XmlElement array = new XmlElement(SerializerHandler.TYPE_ARRAY);
XmlElement data = new XmlElement(ARRAY_DATA);
array.addChildren(data);
@ -25,7 +36,7 @@ public class ArraySerializer implements Serializer { @@ -25,7 +36,7 @@ public class ArraySerializer implements Serializer {
XmlElement e;
for(Object obj : iter) {
e = new XmlElement(ARRAY_VALUE);
e.addChildren(SerializerHandler.getDefault().serialize(obj));
e.addChildren(serializerHandler.serialize(obj));
data.addChildren(e);
}
@ -37,4 +48,4 @@ public class ArraySerializer implements Serializer { @@ -37,4 +48,4 @@ public class ArraySerializer implements Serializer {
}
}
}

4
app/src/main/java/de/timroes/axmlrpc/serializer/BooleanSerializer.java

@ -11,7 +11,7 @@ public class BooleanSerializer implements Serializer { @@ -11,7 +11,7 @@ public class BooleanSerializer implements Serializer {
public XmlElement serialize(Object object) {
return XMLUtil.makeXmlTag(SerializerHandler.TYPE_BOOLEAN,
((Boolean)object == true) ? "1" : "0");
(Boolean) object ? "1" : "0");
}
}
}

8
app/src/main/java/de/timroes/axmlrpc/serializer/DateTimeSerializer.java

@ -10,9 +10,15 @@ import java.text.SimpleDateFormat; @@ -10,9 +10,15 @@ import java.text.SimpleDateFormat;
*/
public class DateTimeSerializer implements Serializer {
public static final String DATETIME_FORMAT = "yyyyMMdd'T'HH:mm:ss";
public static final String DATETIME_FORMAT = "yyyyMMdd'T'HHmmss";
public static final SimpleDateFormat DATE_FORMATER = new SimpleDateFormat(DATETIME_FORMAT);
public final boolean accepts_null_input;
public DateTimeSerializer(boolean accepts_null_input) {
this.accepts_null_input = accepts_null_input;
}
public XmlElement serialize(Object object) {
return XMLUtil.makeXmlTag(SerializerHandler.TYPE_DATETIME,
DATE_FORMATER.format(object));

60
app/src/main/java/de/timroes/axmlrpc/serializer/SerializerHandler.java

@ -2,7 +2,6 @@ package de.timroes.axmlrpc.serializer; @@ -2,7 +2,6 @@ package de.timroes.axmlrpc.serializer;
import de.timroes.axmlrpc.XMLRPCClient;
import de.timroes.axmlrpc.XMLRPCException;
import de.timroes.axmlrpc.XMLRPCRuntimeException;
import de.timroes.axmlrpc.xmlcreator.XmlElement;
import java.io.BufferedReader;
@ -60,54 +59,29 @@ public class SerializerHandler { @@ -60,54 +59,29 @@ public class SerializerHandler {
public static final String TYPE_BASE64 = "base64";
public static final String TYPE_NULL = "nil";
private static SerializerHandler instance;
/**
* Initialize the serialization handler. This method must be called before
* the get method returns any object.
*
* @param flags The flags that has been set in the XMLRPCClient.
* @see XMLRPCClient
*/
public static void initialize(int flags) {
instance = new SerializerHandler(flags);
}
/**
* Return the instance of the SerializerHandler.
* It must have been initialized with initialize() before.
*
* @return The instance of the SerializerHandler.
*/
public static SerializerHandler getDefault() {
if(instance == null) {
throw new XMLRPCRuntimeException("The SerializerHandler has not been initialized.");
}
return instance;
}
private StringSerializer string;
private BooleanSerializer bool = new BooleanSerializer();
private IntSerializer integer = new IntSerializer();
private LongSerializer long8 = new LongSerializer();
private StructSerializer struct = new StructSerializer();
private StructSerializer struct;
private DoubleSerializer floating = new DoubleSerializer();
private DateTimeSerializer datetime = new DateTimeSerializer();
private ArraySerializer array = new ArraySerializer();
private DateTimeSerializer datetime;
public static boolean accepts_null_input;
public SerializerHandler(boolean accepts_null_input) {
SerializerHandler.accepts_null_input = accepts_null_input;
}
private ArraySerializer array;
private Base64Serializer base64 = new Base64Serializer();
private NullSerializer nil = new NullSerializer();
private int flags;
/**
* Generates the SerializerHandler.
* This method can only called from within the class (the initialize method).
*
* @param flags The flags to use.
*/
private SerializerHandler(int flags) {
public SerializerHandler(int flags) {
this.flags = flags;
string = new StringSerializer((flags & XMLRPCClient.FLAGS_NO_STRING_ENCODE) == 0);
struct = new StructSerializer(this);
array = new ArraySerializer(this);
datetime = new DateTimeSerializer((flags & XMLRPCClient.FLAGS_ACCEPT_NULL_DATES) != 0);
}
/**
@ -152,8 +126,12 @@ public class SerializerHandler { @@ -152,8 +126,12 @@ public class SerializerHandler {
obj = parser.nextText();
} else
if (typeNodeName.equals(TYPE_DATE_TIME_ISO8601)) {
dateFormat.setCalendar(cal);
String value = parser.nextText();
if (accepts_null_input && (value==null || value.trim().length()==0)) {
return null;
}
try {
obj = dateFormat.parseObject(value);
} catch (ParseException e) {
@ -232,7 +210,7 @@ public class SerializerHandler { @@ -232,7 +210,7 @@ public class SerializerHandler {
*/
public XmlElement serialize(Object object) throws XMLRPCException {
Serializer s = null;
Serializer s;
if((flags & XMLRPCClient.FLAGS_NIL) != 0 && object == null) {
s = nil;
@ -277,7 +255,7 @@ public class SerializerHandler { @@ -277,7 +255,7 @@ public class SerializerHandler {
s = base64;
} else if(object instanceof Byte[]) {
s = base64;
} else if(object instanceof Iterable<?>) {
} else if(object instanceof Iterable<?> || object instanceof Object[]) {
s = array;
} else {
throw new XMLRPCException("No serializer found for type '"
@ -288,4 +266,4 @@ public class SerializerHandler { @@ -288,4 +266,4 @@ public class SerializerHandler {
}
}
}

7
app/src/main/java/de/timroes/axmlrpc/serializer/StringSerializer.java

@ -19,9 +19,12 @@ public class StringSerializer implements Serializer { @@ -19,9 +19,12 @@ public class StringSerializer implements Serializer {
public XmlElement serialize(Object object) {
String content = object.toString();
if(encodeStrings) {
content = content.replaceAll("&", "&amp;").replaceAll("<", "&lt;");
content = content
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll("]]>", "]]&gt;");
}
return XMLUtil.makeXmlTag(SerializerHandler.TYPE_STRING, content);
}
}
}

10
app/src/main/java/de/timroes/axmlrpc/serializer/StructSerializer.java

@ -15,6 +15,12 @@ public class StructSerializer implements Serializer { @@ -15,6 +15,12 @@ public class StructSerializer implements Serializer {
private static final String STRUCT_NAME = "name";
private static final String STRUCT_VALUE = "value";
private final SerializerHandler serializerHandler;
public StructSerializer(SerializerHandler serializerHandler) {
this.serializerHandler = serializerHandler;
}
public XmlElement serialize(Object object) {
XmlElement struct = new XmlElement(SerializerHandler.TYPE_STRUCT);
@ -33,7 +39,7 @@ public class StructSerializer implements Serializer { @@ -33,7 +39,7 @@ public class StructSerializer implements Serializer {
name = new XmlElement(STRUCT_NAME);
value = new XmlElement(STRUCT_VALUE);
name.setContent(member.getKey());
value.addChildren(SerializerHandler.getDefault().serialize(member.getValue()));
value.addChildren(serializerHandler.serialize(member.getValue()));
entry.addChildren(name);
entry.addChildren(value);
struct.addChildren(entry);
@ -46,4 +52,4 @@ public class StructSerializer implements Serializer { @@ -46,4 +52,4 @@ public class StructSerializer implements Serializer {
return struct;
}
}
}

12
app/src/main/java/de/timroes/base64/Base64.java

@ -14,6 +14,8 @@ public class Base64 { @@ -14,6 +14,8 @@ public class Base64 {
private static final HashMap<Character,Byte> map = new HashMap<Character, Byte>();
private Base64() {}
static {
for(int i = 0; i < code.length; i++) {
map.put(code[i], (byte)i);
@ -44,10 +46,10 @@ public class Base64 { @@ -44,10 +46,10 @@ public class Base64 {
int outi = 0;
int b1, b2, b3, b4;
for(int i = 0; i < input.length; i+=4) {
b1 = (map.get(input[i]) - 1);
b2 = (map.get(input[i+1]) - 1);
b3 = (map.get(input[i+2]) - 1);
b4 = (map.get(input[i+3]) - 1);
b1 = map.get(input[i]) - 1;
b2 = map.get(input[i+1]) - 1;
b3 = map.get(input[i+2]) - 1;
b4 = map.get(input[i+3]) - 1;
out[outi++] = (byte)(b1 << 2 | b2 >>> 4);
out[outi++] = (byte)((b2 & 0x0F) << 4 | b3 >>> 2);
out[outi++] = (byte)((b3 & 0x03) << 6 | (b4 & 0x3F));
@ -158,4 +160,4 @@ public class Base64 { @@ -158,4 +160,4 @@ public class Base64 {
return out;
}
}
}

141
app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java

@ -14,6 +14,8 @@ @@ -14,6 +14,8 @@
* limitations under the License.
*/
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
package net.margaritov.preference.colorpicker;
import android.graphics.Bitmap;
@ -28,101 +30,102 @@ import android.graphics.drawable.Drawable; @@ -28,101 +30,102 @@ import android.graphics.drawable.Drawable;
* This drawable that draws a simple white and gray chessboard pattern.
* It's pattern you will often see as a background behind a
* partly transparent image in many applications.
*
* @author Daniel Nilsson
*/
public class AlphaPatternDrawable extends Drawable {
private int mRectangleSize = 10;
private int mRectangleSize = 10;
private Paint mPaint = new Paint();
private Paint mPaintWhite = new Paint();
private Paint mPaintGray = new Paint();
private Paint mPaint = new Paint();
private Paint mPaintWhite = new Paint();
private Paint mPaintGray = new Paint();
private int numRectanglesHorizontal;
private int numRectanglesVertical;
private int numRectanglesHorizontal;
private int numRectanglesVertical;
/**
* Bitmap in which the pattern will be cahched.
*/
private Bitmap mBitmap;
/**
* Bitmap in which the pattern will be cahched.
*/
private Bitmap mBitmap;
public AlphaPatternDrawable(int rectangleSize) {
mRectangleSize = rectangleSize;
mPaintWhite.setColor(0xffffffff);
mPaintGray.setColor(0xffcbcbcb);
}
public AlphaPatternDrawable(int rectangleSize) {
mRectangleSize = rectangleSize;
mPaintWhite.setColor(0xffffffff);
mPaintGray.setColor(0xffcbcbcb);
}
@Override
public void draw(Canvas canvas) {
canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
}
@Override
public void draw(Canvas canvas) {
canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
}
@Override
public int getOpacity() {
return 0;
}
@Override
public int getOpacity() {
return 0;
}
@Override
public void setAlpha(int alpha) {
throw new UnsupportedOperationException("Alpha is not supported by this drawwable.");
}
@Override
public void setAlpha(int alpha) {
throw new UnsupportedOperationException("Alpha is not supported by this drawwable.");
}
@Override
public void setColorFilter(ColorFilter cf) {
throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable.");
}
@Override
public void setColorFilter(ColorFilter cf) {
throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable.");
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
int height = bounds.height();
int width = bounds.width();
int height = bounds.height();
int width = bounds.width();
numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
generatePatternBitmap();
generatePatternBitmap();
}
}
/**
* This will generate a bitmap with the pattern
* as big as the rectangle we were allow to draw on.
* We do this to chache the bitmap so we don't need to
* recreate it each time draw() is called since it
* takes a few milliseconds.
*/
private void generatePatternBitmap() {
/**
* This will generate a bitmap with the pattern
* as big as the rectangle we were allow to draw on.
* We do this to chache the bitmap so we don't need to
* recreate it each time draw() is called since it
* takes a few milliseconds.
*/
private void generatePatternBitmap() {
if (getBounds().width() <= 0 || getBounds().height() <= 0) {
return;
}
if (getBounds().width() <= 0 || getBounds().height() <= 0) {
return;
}
mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
Canvas canvas = new Canvas(mBitmap);
mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
Canvas canvas = new Canvas(mBitmap);
Rect r = new Rect();
boolean verticalStartWhite = true;
for (int i = 0; i <= numRectanglesVertical; i++) {
Rect r = new Rect();
boolean verticalStartWhite = true;
for (int i = 0; i <= numRectanglesVertical; i++) {
boolean isWhite = verticalStartWhite;
for (int j = 0; j <= numRectanglesHorizontal; j++) {
boolean isWhite = verticalStartWhite;
for (int j = 0; j <= numRectanglesHorizontal; j++) {
r.top = i * mRectangleSize;
r.left = j * mRectangleSize;
r.bottom = r.top + mRectangleSize;
r.right = r.left + mRectangleSize;
r.top = i * mRectangleSize;
r.left = j * mRectangleSize;
r.bottom = r.top + mRectangleSize;
r.right = r.left + mRectangleSize;
canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray);
canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray);
isWhite = !isWhite;
}
isWhite = !isWhite;
}
verticalStartWhite = !verticalStartWhite;
verticalStartWhite = !verticalStartWhite;
}
}
}
}
}
}

321
app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java

@ -14,123 +14,240 @@ @@ -14,123 +14,240 @@
* limitations under the License.
*/
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
package net.margaritov.preference.colorpicker;
import android.app.Dialog;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.text.InputFilter;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.transdroid.R;
public class ColorPickerDialog extends Dialog implements ColorPickerView.OnColorChangedListener, View.OnClickListener {
private ColorPickerView mColorPicker;
private ColorPickerPanelView mOldColor;
private ColorPickerPanelView mNewColor;
private OnColorChangedListener mListener;
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
public ColorPickerDialog(Context context, int initialColor) {
super(context);
init(initialColor);
}
private void init(int color) {
// To fight color banding.
getWindow().setFormat(PixelFormat.RGBA_8888);
setUp(color);
}
import androidx.appcompat.app.AppCompatDialog;
private void setUp(int color) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.dialog_color_picker, null);
setContentView(layout);
setTitle(R.string.dialog_color_picker);
mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
mOldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel);
mNewColor = (ColorPickerPanelView) layout.findViewById(R.id.new_color_panel);
((LinearLayout) mOldColor.getParent())
.setPadding(Math.round(mColorPicker.getDrawingOffset()), 0, Math.round(mColorPicker.getDrawingOffset()),
0);
mOldColor.setOnClickListener(this);
mNewColor.setOnClickListener(this);
mColorPicker.setOnColorChangedListener(this);
mOldColor.setColor(color);
mColorPicker.setColor(color, true);
}
@Override
public void onColorChanged(int color) {
import org.transdroid.R;
mNewColor.setColor(color);
import java.util.Locale;
public class ColorPickerDialog
extends
AppCompatDialog
implements
ColorPickerView.OnColorChangedListener,
View.OnClickListener, ViewTreeObserver.OnGlobalLayoutListener {
private ColorPickerView mColorPicker;
private ColorPickerPanelView mOldColor;
private ColorPickerPanelView mNewColor;
private EditText mHexVal;
private boolean mHexValueEnabled = false;
private ColorStateList mHexDefaultTextColor;
private OnColorChangedListener mListener;
private int mOrientation;
private View mLayout;
private String mTitle;
@Override
public void onGlobalLayout() {
if (getContext().getResources().getConfiguration().orientation != mOrientation) {
final int oldcolor = mOldColor.getColor();
final int newcolor = mNewColor.getColor();
mLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
setUp(oldcolor);
mNewColor.setColor(newcolor);
mColorPicker.setColor(newcolor);
}
}
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
public ColorPickerDialog(Context context, int initialColor, String title) {
super(context);
mTitle = title;
init(initialColor);
}
private void init(int color) {
// To fight color banding.
getWindow().setFormat(PixelFormat.RGBA_8888);
setUp(color);
}
private void setUp(int color) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mLayout = inflater.inflate(R.layout.dialog_color_picker, null);
mLayout.getViewTreeObserver().addOnGlobalLayoutListener(this);
mOrientation = getContext().getResources().getConfiguration().orientation;
setContentView(mLayout);
setTitle(mTitle);
mColorPicker = (ColorPickerView) mLayout.findViewById(R.id.color_picker_view);
mOldColor = (ColorPickerPanelView) mLayout.findViewById(R.id.old_color_panel);
mNewColor = (ColorPickerPanelView) mLayout.findViewById(R.id.new_color_panel);
mHexVal = (EditText) mLayout.findViewById(R.id.hex_val);
mHexVal.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
mHexDefaultTextColor = mHexVal.getTextColors();
mHexVal.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
String s = mHexVal.getText().toString();
if (s.length() > 5 || s.length() < 10) {
try {
int c = ColorPickerPreference.convertToColorInt(s.toString());
mColorPicker.setColor(c, true);
mHexVal.setTextColor(mHexDefaultTextColor);
} catch (IllegalArgumentException e) {
mHexVal.setTextColor(Color.RED);
}
} else {
mHexVal.setTextColor(Color.RED);
}
return true;
}
return false;
}
});
((LinearLayout) mOldColor.getParent()).setPadding(
Math.round(mColorPicker.getDrawingOffset()),
0,
Math.round(mColorPicker.getDrawingOffset()),
0
);
mOldColor.setOnClickListener(this);
mNewColor.setOnClickListener(this);
mColorPicker.setOnColorChangedListener(this);
mOldColor.setColor(color);
mColorPicker.setColor(color, true);
}
@Override
public void onColorChanged(int color) {
mNewColor.setColor(color);
if (mHexValueEnabled)
updateHexValue(color);
/*
if (mListener != null) {
if (mListener != null) {
mListener.onColorChanged(color);
}
*/
}
public void setAlphaSliderVisible(boolean visible) {
mColorPicker.setAlphaSliderVisible(visible);
}
/**
* Set a OnColorChangedListener to get notified when the color
* selected by the user has changed.
* @param listener
*/
public void setOnColorChangedListener(OnColorChangedListener listener) {
mListener = listener;
}
public int getColor() {
return mColorPicker.getColor();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.new_color_panel) {
if (mListener != null) {
mListener.onColorChanged(mNewColor.getColor());
}
}
dismiss();
}
@Override
public Bundle onSaveInstanceState() {
Bundle state = super.onSaveInstanceState();
state.putInt("old_color", mOldColor.getColor());
state.putInt("new_color", mNewColor.getColor());
return state;
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mOldColor.setColor(savedInstanceState.getInt("old_color"));
mColorPicker.setColor(savedInstanceState.getInt("new_color"), true);
}
}
public void setHexValueEnabled(boolean enable) {
mHexValueEnabled = enable;
if (enable) {
mHexVal.setVisibility(View.VISIBLE);
updateHexLengthFilter();
updateHexValue(getColor());
} else
mHexVal.setVisibility(View.GONE);
}
public boolean getHexValueEnabled() {
return mHexValueEnabled;
}
private void updateHexLengthFilter() {
if (getAlphaSliderVisible())
mHexVal.setFilters(new InputFilter[]{new InputFilter.LengthFilter(9)});
else
mHexVal.setFilters(new InputFilter[]{new InputFilter.LengthFilter(7)});
}
private void updateHexValue(int color) {
if (getAlphaSliderVisible()) {
mHexVal.setText(ColorPickerPreference.convertToARGB(color).toUpperCase(Locale.getDefault()));
} else {
mHexVal.setText(ColorPickerPreference.convertToRGB(color).toUpperCase(Locale.getDefault()));
}
mHexVal.setTextColor(mHexDefaultTextColor);
}
public void setAlphaSliderVisible(boolean visible) {
mColorPicker.setAlphaSliderVisible(visible);
if (mHexValueEnabled) {
updateHexLengthFilter();
updateHexValue(getColor());
}
}
public boolean getAlphaSliderVisible() {
return mColorPicker.getAlphaSliderVisible();
}
/**
* Set a OnColorChangedListener to get notified when the color
* selected by the user has changed.
*
* @param listener
*/
public void setOnColorChangedListener(OnColorChangedListener listener) {
mListener = listener;
}
public int getColor() {
return mColorPicker.getColor();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.new_color_panel) {
if (mListener != null) {
mListener.onColorChanged(mNewColor.getColor());
}
}
dismiss();
}
@Override
public Bundle onSaveInstanceState() {
Bundle state = super.onSaveInstanceState();
state.putInt("old_color", mOldColor.getColor());
state.putInt("new_color", mNewColor.getColor());
return state;
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mOldColor.setColor(savedInstanceState.getInt("old_color"));
mColorPicker.setColor(savedInstanceState.getInt("new_color"), true);
}
}

210
app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java

@ -14,6 +14,8 @@ @@ -14,6 +14,8 @@
* limitations under the License.
*/
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
package net.margaritov.preference.colorpicker;
import android.content.Context;
@ -27,140 +29,148 @@ import android.view.View; @@ -27,140 +29,148 @@ import android.view.View;
* This class draws a panel which which will be filled with a color which can be set.
* It can be used to show the currently selected color which you will get from
* the {@link ColorPickerView}.
*
* @author Daniel Nilsson
*/
public class ColorPickerPanelView extends View {
/**
* The width in pixels of the border
* surrounding the color panel.
*/
private final static float BORDER_WIDTH_PX = 1;
private float mDensity = 1f;
private int mBorderColor = 0xff6E6E6E;
private int mColor = 0xff000000;
/**
* The width in pixels of the border
* surrounding the color panel.
*/
private final static float BORDER_WIDTH_PX = 1;
private Paint mBorderPaint;
private Paint mColorPaint;
private float mDensity = 1f;
private RectF mDrawingRect;
private RectF mColorRect;
private int mBorderColor = 0xff6E6E6E;
private int mColor = 0xff000000;
private AlphaPatternDrawable mAlphaPattern;
private Paint mBorderPaint;
private Paint mColorPaint;
private RectF mDrawingRect;
private RectF mColorRect;
public ColorPickerPanelView(Context context) {
this(context, null);
}
private AlphaPatternDrawable mAlphaPattern;
public ColorPickerPanelView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public ColorPickerPanelView(Context context) {
this(context, null);
}
private void init() {
mBorderPaint = new Paint();
mColorPaint = new Paint();
mDensity = getContext().getResources().getDisplayMetrics().density;
}
public ColorPickerPanelView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
@Override
protected void onDraw(Canvas canvas) {
private void init() {
mBorderPaint = new Paint();
mColorPaint = new Paint();
mDensity = getContext().getResources().getDisplayMetrics().density;
}
final RectF rect = mColorRect;
if (BORDER_WIDTH_PX > 0) {
mBorderPaint.setColor(mBorderColor);
canvas.drawRect(mDrawingRect, mBorderPaint);
}
@Override
protected void onDraw(Canvas canvas) {
if (mAlphaPattern != null) {
mAlphaPattern.draw(canvas);
}
final RectF rect = mColorRect;
mColorPaint.setColor(mColor);
if (BORDER_WIDTH_PX > 0) {
mBorderPaint.setColor(mBorderColor);
canvas.drawRect(mDrawingRect, mBorderPaint);
}
canvas.drawRect(rect, mColorPaint);
}
if (mAlphaPattern != null) {
mAlphaPattern.draw(canvas);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mColorPaint.setColor(mColor);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
canvas.drawRect(rect, mColorPaint);
}
setMeasuredDimension(width, height);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
mDrawingRect = new RectF();
mDrawingRect.left = getPaddingLeft();
mDrawingRect.right = w - getPaddingRight();
mDrawingRect.top = getPaddingTop();
mDrawingRect.bottom = h - getPaddingBottom();
setMeasuredDimension(width, height);
}
setUpColorRect();
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
mDrawingRect = new RectF();
mDrawingRect.left = getPaddingLeft();
mDrawingRect.right = w - getPaddingRight();
mDrawingRect.top = getPaddingTop();
mDrawingRect.bottom = h - getPaddingBottom();
private void setUpColorRect() {
final RectF dRect = mDrawingRect;
setUpColorRect();
float left = dRect.left + BORDER_WIDTH_PX;
float top = dRect.top + BORDER_WIDTH_PX;
float bottom = dRect.bottom - BORDER_WIDTH_PX;
float right = dRect.right - BORDER_WIDTH_PX;
}
mColorRect = new RectF(left, top, right, bottom);
private void setUpColorRect() {
final RectF dRect = mDrawingRect;
mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
float left = dRect.left + BORDER_WIDTH_PX;
float top = dRect.top + BORDER_WIDTH_PX;
float bottom = dRect.bottom - BORDER_WIDTH_PX;
float right = dRect.right - BORDER_WIDTH_PX;
mAlphaPattern.setBounds(Math.round(mColorRect.left), Math.round(mColorRect.top), Math.round(mColorRect.right),
Math.round(mColorRect.bottom));
mColorRect = new RectF(left, top, right, bottom);
}
mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
/**
* Set the color that should be shown by this view.
* @param color
*/
public void setColor(int color) {
mColor = color;
invalidate();
}
mAlphaPattern.setBounds(
Math.round(mColorRect.left),
Math.round(mColorRect.top),
Math.round(mColorRect.right),
Math.round(mColorRect.bottom)
);
/**
* Get the color currently show by this view.
* @return
*/
public int getColor() {
return mColor;
}
}
/**
* Set the color of the border surrounding the panel.
* @param color
*/
public void setBorderColor(int color) {
mBorderColor = color;
invalidate();
}
/**
* Set the color that should be shown by this view.
*
* @param color
*/
public void setColor(int color) {
mColor = color;
invalidate();
}
/**
* Get the color of the border surrounding the panel.
*/
public int getBorderColor() {
return mBorderColor;
}
/**
* Get the color currently show by this view.
*
* @return
*/
public int getColor() {
return mColor;
}
/**
* Set the color of the border surrounding the panel.
*
* @param color
*/
public void setBorderColor(int color) {
mBorderColor = color;
invalidate();
}
/**
* Get the color of the border surrounding the panel.
*/
public int getBorderColor() {
return mBorderColor;
}
}
}

551
app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java

@ -14,6 +14,8 @@ @@ -14,6 +14,8 @@
* limitations under the License.
*/
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
package net.margaritov.preference.colorpicker;
import android.content.Context;
@ -24,259 +26,312 @@ import android.graphics.Color; @@ -24,259 +26,312 @@ import android.graphics.Color;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.Preference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
/**
* A preference type that allows a user to choose a time
* A preference type that allows a user to choose a color
*
* @author Sergey Margaritov
*/
public class ColorPickerPreference extends Preference
implements Preference.OnPreferenceClickListener, ColorPickerDialog.OnColorChangedListener {
View mView;
ColorPickerDialog mDialog;
private int mValue = Color.BLACK;
private float mDensity = 0;
private boolean mAlphaSliderEnabled = false;
public ColorPickerPreference(Context context) {
super(context);
init(context, null);
}
public ColorPickerPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getColor(index, Color.BLACK);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
onColorChanged(restoreValue ? getPersistedInt(mValue) : (Integer) defaultValue);
}
private void init(Context context, AttributeSet attrs) {
mDensity = getContext().getResources().getDisplayMetrics().density;
setOnPreferenceClickListener(this);
if (attrs != null) {
mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider", false);
}
}
@Override
protected void onBindView(View view) {
super.onBindView(view);
mView = view;
setPreviewColor();
}
private void setPreviewColor() {
if (mView == null) {
return;
}
ImageView iView = new ImageView(getContext());
LinearLayout widgetFrameView = ((LinearLayout) mView.findViewById(android.R.id.widget_frame));
if (widgetFrameView == null) {
return;
}
widgetFrameView.setVisibility(View.VISIBLE);
widgetFrameView
.setPadding(widgetFrameView.getPaddingLeft(), widgetFrameView.getPaddingTop(), (int) (mDensity * 8),
widgetFrameView.getPaddingBottom());
// remove already create preview image
int count = widgetFrameView.getChildCount();
if (count > 0) {
widgetFrameView.removeViews(0, count);
}
widgetFrameView.addView(iView);
widgetFrameView.setMinimumWidth(0);
iView.setBackgroundDrawable(new AlphaPatternDrawable((int) (5 * mDensity)));
iView.setImageBitmap(getPreviewBitmap());
}
private Bitmap getPreviewBitmap() {
int d = (int) (mDensity * 31); //30dip
int color = mValue;
Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888);
int w = bm.getWidth();
int h = bm.getHeight();
int c = color;
for (int i = 0; i < w; i++) {
for (int j = i; j < h; j++) {
c = (i <= 1 || j <= 1 || i >= w - 2 || j >= h - 2) ? Color.GRAY : color;
bm.setPixel(i, j, c);
if (i != j) {
bm.setPixel(j, i, c);
}
}
}
return bm;
}
@Override
public void onColorChanged(int color) {
if (isPersistent()) {
persistInt(color);
}
mValue = color;
setPreviewColor();
try {
getOnPreferenceChangeListener().onPreferenceChange(this, color);
} catch (NullPointerException e) {
}
}
public boolean onPreferenceClick(Preference preference) {
showDialog(null);
return false;
}
protected void showDialog(Bundle state) {
mDialog = new ColorPickerDialog(getContext(), mValue);
mDialog.setOnColorChangedListener(this);
if (mAlphaSliderEnabled) {
mDialog.setAlphaSliderVisible(true);
}
if (state != null) {
mDialog.onRestoreInstanceState(state);
}
mDialog.show();
}
/**
* Toggle Alpha Slider visibility (by default it's disabled)
* @param enable
*/
public void setAlphaSliderEnabled(boolean enable) {
mAlphaSliderEnabled = enable;
}
/**
* For custom purposes. Not used by ColorPickerPreferrence
* @param color
* @author Unknown
*/
public static String convertToARGB(int color) {
String alpha = Integer.toHexString(Color.alpha(color));
String red = Integer.toHexString(Color.red(color));
String green = Integer.toHexString(Color.green(color));
String blue = Integer.toHexString(Color.blue(color));
if (alpha.length() == 1) {
alpha = "0" + alpha;
}
if (red.length() == 1) {
red = "0" + red;
}
if (green.length() == 1) {
green = "0" + green;
}
if (blue.length() == 1) {
blue = "0" + blue;
}
return "#" + alpha + red + green + blue;
}
/**
* For custom purposes. Not used by ColorPickerPreferrence
* @param argb
* @throws NumberFormatException
* @author Unknown
*/
public static int convertToColorInt(String argb) throws NumberFormatException {
if (argb.startsWith("#")) {
argb = argb.replace("#", "");
}
int alpha = -1, red = -1, green = -1, blue = -1;
if (argb.length() == 8) {
alpha = Integer.parseInt(argb.substring(0, 2), 16);
red = Integer.parseInt(argb.substring(2, 4), 16);
green = Integer.parseInt(argb.substring(4, 6), 16);
blue = Integer.parseInt(argb.substring(6, 8), 16);
} else if (argb.length() == 6) {
alpha = 255;
red = Integer.parseInt(argb.substring(0, 2), 16);
green = Integer.parseInt(argb.substring(2, 4), 16);
blue = Integer.parseInt(argb.substring(4, 6), 16);
}
return Color.argb(alpha, red, green, blue);
}
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (mDialog == null || !mDialog.isShowing()) {
return superState;
}
final SavedState myState = new SavedState(superState);
myState.dialogBundle = mDialog.onSaveInstanceState();
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !(state instanceof SavedState)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
showDialog(myState.dialogBundle);
}
private static class SavedState extends BaseSavedState {
Bundle dialogBundle;
public SavedState(Parcel source) {
super(source);
dialogBundle = source.readBundle();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeBundle(dialogBundle);
}
public SavedState(Parcelable superState) {
super(superState);
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
public class ColorPickerPreference
extends
Preference
implements
Preference.OnPreferenceClickListener,
ColorPickerDialog.OnColorChangedListener {
View mView;
ColorPickerDialog mDialog;
private int mValue = Color.BLACK;
private float mDensity = 0;
private boolean mAlphaSliderEnabled = false;
private boolean mHexValueEnabled = false;
public ColorPickerPreference(Context context) {
super(context);
init(context, null);
}
public ColorPickerPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
/**Method edited by
* @author Anna Berkovitch
* added functionality to accept hex string as defaultValue
* and to properly persist resources reference string, such as @color/someColor
* previously persisted 0*/
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
int colorInt;
String mHexDefaultValue = a.getString(index);
if (mHexDefaultValue != null && mHexDefaultValue.startsWith("#")) {
colorInt = convertToColorInt(mHexDefaultValue);
return colorInt;
} else {
return a.getColor(index, Color.BLACK);
}
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
onColorChanged(restoreValue ? getPersistedInt(mValue) : (Integer) defaultValue);
}
private void init(Context context, AttributeSet attrs) {
mDensity = getContext().getResources().getDisplayMetrics().density;
setOnPreferenceClickListener(this);
if (attrs != null) {
mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider", false);
mHexValueEnabled = attrs.getAttributeBooleanValue(null, "hexValue", false);
}
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mView = holder.itemView;
setPreviewColor();
}
private void setPreviewColor() {
if (mView == null) return;
ImageView iView = new ImageView(getContext());
LinearLayout widgetFrameView = ((LinearLayout) mView.findViewById(android.R.id.widget_frame));
if (widgetFrameView == null) return;
widgetFrameView.setVisibility(View.VISIBLE);
widgetFrameView.setPadding(
widgetFrameView.getPaddingLeft(),
widgetFrameView.getPaddingTop(),
(int) (mDensity * 8),
widgetFrameView.getPaddingBottom()
);
// remove already create preview image
int count = widgetFrameView.getChildCount();
if (count > 0) {
widgetFrameView.removeViews(0, count);
}
widgetFrameView.addView(iView);
widgetFrameView.setMinimumWidth(0);
iView.setBackgroundDrawable(new AlphaPatternDrawable((int) (5 * mDensity)));
iView.setImageBitmap(getPreviewBitmap());
}
private Bitmap getPreviewBitmap() {
int d = (int) (mDensity * 31); //30dip
int color = mValue;
Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888);
int w = bm.getWidth();
int h = bm.getHeight();
int c = color;
for (int i = 0; i < w; i++) {
for (int j = i; j < h; j++) {
c = (i <= 1 || j <= 1 || i >= w - 2 || j >= h - 2) ? Color.GRAY : color;
bm.setPixel(i, j, c);
if (i != j) {
bm.setPixel(j, i, c);
}
}
}
return bm;
}
@Override
public void onColorChanged(int color) {
if (isPersistent()) {
persistInt(color);
}
mValue = color;
setPreviewColor();
try {
getOnPreferenceChangeListener().onPreferenceChange(this, color);
} catch (NullPointerException e) {
}
}
public boolean onPreferenceClick(Preference preference) {
showDialog(null);
return false;
}
protected void showDialog(Bundle state) {
mDialog = new ColorPickerDialog(getContext(), mValue, getTitle().toString());
mDialog.setOnColorChangedListener(this);
if (mAlphaSliderEnabled) {
mDialog.setAlphaSliderVisible(true);
}
if (mHexValueEnabled) {
mDialog.setHexValueEnabled(true);
}
if (state != null) {
mDialog.onRestoreInstanceState(state);
}
mDialog.show();
}
/**
* Toggle Alpha Slider visibility (by default it's disabled)
*
* @param enable
*/
public void setAlphaSliderEnabled(boolean enable) {
mAlphaSliderEnabled = enable;
}
/**
* Toggle Hex Value visibility (by default it's disabled)
*
* @param enable
*/
public void setHexValueEnabled(boolean enable) {
mHexValueEnabled = enable;
}
/**
* For custom purposes. Not used by ColorPickerPreferrence
*
* @param color
* @author Unknown
*/
public static String convertToARGB(int color) {
String alpha = Integer.toHexString(Color.alpha(color));
String red = Integer.toHexString(Color.red(color));
String green = Integer.toHexString(Color.green(color));
String blue = Integer.toHexString(Color.blue(color));
if (alpha.length() == 1) {
alpha = "0" + alpha;
}
if (red.length() == 1) {
red = "0" + red;
}
if (green.length() == 1) {
green = "0" + green;
}
if (blue.length() == 1) {
blue = "0" + blue;
}
return "#" + alpha + red + green + blue;
}
/**
* Method currently used by onGetDefaultValue method to
* convert hex string provided in android:defaultValue to color integer.
*
* @param color
* @return A string representing the hex value of color,
* without the alpha value
* @author Charles Rosaaen
*/
public static String convertToRGB(int color) {
String red = Integer.toHexString(Color.red(color));
String green = Integer.toHexString(Color.green(color));
String blue = Integer.toHexString(Color.blue(color));
if (red.length() == 1) {
red = "0" + red;
}
if (green.length() == 1) {
green = "0" + green;
}
if (blue.length() == 1) {
blue = "0" + blue;
}
return "#" + red + green + blue;
}
/**
* For custom purposes. Not used by ColorPickerPreferrence
*
* @param argb
* @throws NumberFormatException
* @author Unknown
*/
public static int convertToColorInt(String argb) throws IllegalArgumentException {
if (!argb.startsWith("#")) {
argb = "#" + argb;
}
return Color.parseColor(argb);
}
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (mDialog == null || !mDialog.isShowing()) {
return superState;
}
final SavedState myState = new SavedState(superState);
myState.dialogBundle = mDialog.onSaveInstanceState();
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !(state instanceof SavedState)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
showDialog(myState.dialogBundle);
}
private static class SavedState extends BaseSavedState {
Bundle dialogBundle;
public SavedState(Parcel source) {
super(source);
dialogBundle = source.readBundle();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeBundle(dialogBundle);
}
public SavedState(Parcelable superState) {
super(superState);
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}

1357
app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java

File diff suppressed because it is too large Load Diff

65
app/src/main/java/org/apache/openjpa/lib/util/Base16Encoder.java

@ -1,65 +0,0 @@ @@ -1,65 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.lib.util;
/**
* Base 16 encoder.
*
* @author Marc Prud'hommeaux
* @nojavadoc
*/
public class Base16Encoder {
private final static char[] HEX = new char[]{
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/**
* Convert bytes to a base16 string.
*/
public static String encode(byte[] byteArray) {
StringBuffer hexBuffer = new StringBuffer(byteArray.length * 2);
for (int i = 0; i < byteArray.length; i++)
for (int j = 1; j >= 0; j--)
hexBuffer.append(HEX[(byteArray[i] >> (j * 4)) & 0xF]);
return hexBuffer.toString();
}
/**
* Convert a base16 string into a byte array.
*/
public static byte[] decode(String s) {
int len = s.length();
byte[] r = new byte[len / 2];
for (int i = 0; i < r.length; i++) {
int digit1 = s.charAt(i * 2), digit2 = s.charAt(i * 2 + 1);
if (digit1 >= '0' && digit1 <= '9')
digit1 -= '0';
else if (digit1 >= 'A' && digit1 <= 'F')
digit1 -= 'A' - 10;
if (digit2 >= '0' && digit2 <= '9')
digit2 -= '0';
else if (digit2 >= 'A' && digit2 <= 'F')
digit2 -= 'A' - 10;
r[i] = (byte) ((digit1 << 4) + digit2);
}
return r;
}
}

1998
app/src/main/java/org/base64/android/Base64.java

File diff suppressed because it is too large Load Diff

4
app/src/main/java/org/transdroid/core/app/settings/SettingsUtils.java

@ -2,8 +2,8 @@ package org.transdroid.core.app.settings; @@ -2,8 +2,8 @@ package org.transdroid.core.app.settings;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDelegate;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.Theme;

4
app/src/main/java/org/transdroid/core/gui/DetailsActivity.java

@ -20,8 +20,8 @@ import android.annotation.TargetApi; @@ -20,8 +20,8 @@ import android.annotation.TargetApi;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import com.nispok.snackbar.Snackbar;
import com.nispok.snackbar.SnackbarManager;

6
app/src/main/java/org/transdroid/core/gui/DetailsFragment.java

@ -23,9 +23,9 @@ import android.content.ClipboardManager; @@ -23,9 +23,9 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.ActionMenuView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.ActionMenuView;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;

4
app/src/main/java/org/transdroid/core/gui/TorrentTasksExecutor.java

@ -16,8 +16,8 @@ @@ -16,8 +16,8 @@
*/
package org.transdroid.core.gui;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.Toolbar;
import androidx.appcompat.widget.ActionMenuView;
import androidx.appcompat.widget.Toolbar;
import org.transdroid.daemon.Priority;
import org.transdroid.daemon.Torrent;

16
app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java

@ -24,14 +24,14 @@ import android.net.Uri; @@ -24,14 +24,14 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.core.view.MenuItemCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.ActionMenuView;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

8
app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java

@ -18,10 +18,10 @@ package org.transdroid.core.gui; @@ -18,10 +18,10 @@ package org.transdroid.core.gui;
import android.app.Fragment;
import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.Toolbar;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.ActionMenuView;
import androidx.appcompat.widget.Toolbar;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;

4
app/src/main/java/org/transdroid/core/gui/TransdroidApp.java

@ -17,8 +17,8 @@ @@ -17,8 +17,8 @@
package org.transdroid.core.gui;
import android.app.Application;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.evernote.android.job.JobConfig;
import com.evernote.android.job.JobManager;
import com.evernote.android.job.util.JobLogger;

2
app/src/main/java/org/transdroid/core/gui/log/DatabaseHelper.java

@ -20,7 +20,7 @@ import java.sql.SQLException; @@ -20,7 +20,7 @@ import java.sql.SQLException;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.Keep;
import androidx.annotation.Keep;
import android.util.Log;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;

6
app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java

@ -26,9 +26,9 @@ import android.content.pm.PackageManager; @@ -26,9 +26,9 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.TypefaceSpan;

2
app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssFragment.java

@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
package org.transdroid.core.gui.remoterss;
import android.support.v4.app.Fragment;
import androidx.fragment.app.Fragment;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;

14
app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java

@ -22,13 +22,13 @@ import android.net.Uri; @@ -22,13 +22,13 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.tabs.TabLayout;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;

2
app/src/main/java/org/transdroid/core/gui/rss/RssFeedsFragment.java

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
*/
package org.transdroid.core.gui.rss;
import android.support.v4.app.Fragment;
import androidx.fragment.app.Fragment;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

4
app/src/main/java/org/transdroid/core/gui/rss/RssItemsActivity.java

@ -20,8 +20,8 @@ import android.annotation.TargetApi; @@ -20,8 +20,8 @@ import android.annotation.TargetApi;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;

4
app/src/main/java/org/transdroid/core/gui/rss/RssItemsFragment.java

@ -23,8 +23,8 @@ import android.content.ClipboardManager; @@ -23,8 +23,8 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.appcompat.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.ActionMode;
import android.view.Menu;

6
app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java

@ -23,9 +23,9 @@ import android.net.Uri; @@ -23,9 +23,9 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.SearchRecentSuggestions;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import androidx.core.view.MenuItemCompat;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

2
app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java

@ -20,7 +20,7 @@ import android.app.Fragment; @@ -20,7 +20,7 @@ import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.ActionMode;
import android.view.Menu;

2
app/src/main/java/org/transdroid/core/gui/settings/InterceptableEditTextPreference.java

@ -3,7 +3,7 @@ package org.transdroid.core.gui.settings; @@ -3,7 +3,7 @@ package org.transdroid.core.gui.settings;
import android.content.Context;
import android.os.Build;
import android.preference.EditTextPreference;
import android.support.annotation.RequiresApi;
import androidx.annotation.RequiresApi;
import android.util.AttributeSet;
public class InterceptableEditTextPreference extends EditTextPreference {

10
app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java

@ -3,11 +3,11 @@ package org.transdroid.core.gui.settings; @@ -3,11 +3,11 @@ package org.transdroid.core.gui.settings;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatCallback;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.view.ActionMode;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatCallback;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.view.ActionMode;
public class PreferenceCompatActivity extends PreferenceActivity implements AppCompatCallback {

2
app/src/main/java/org/transdroid/core/gui/settings/ServerSettingsActivity.java

@ -28,7 +28,7 @@ import android.os.Bundle; @@ -28,7 +28,7 @@ import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import androidx.annotation.NonNull;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.OptionsItem;

2
app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java

@ -28,7 +28,7 @@ import android.os.Bundle; @@ -28,7 +28,7 @@ import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import androidx.annotation.NonNull;
import android.text.TextUtils;
import com.nispok.snackbar.Snackbar;

2
app/src/main/java/org/transdroid/core/service/AppUpdateJob.java

@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
package org.transdroid.core.service;
import android.content.Context;
import android.support.annotation.NonNull;
import androidx.annotation.NonNull;
import com.evernote.android.job.Job;
import com.evernote.android.job.JobManager;
import com.evernote.android.job.JobRequest;

2
app/src/main/java/org/transdroid/core/service/AppUpdateJobRunner.java

@ -23,7 +23,7 @@ import android.content.Intent; @@ -23,7 +23,7 @@ import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import androidx.core.app.NotificationCompat;
import com.evernote.android.job.Job;

6
app/src/main/java/org/transdroid/core/service/ConnectivityHelper.java

@ -23,9 +23,9 @@ import android.content.DialogInterface; @@ -23,9 +23,9 @@ import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AlertDialog;
import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.EBean.Scope;
import org.androidannotations.annotations.SystemService;

2
app/src/main/java/org/transdroid/core/service/RssCheckerJob.java

@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
package org.transdroid.core.service;
import android.content.Context;
import android.support.annotation.NonNull;
import androidx.annotation.NonNull;
import com.evernote.android.job.Job;
import com.evernote.android.job.JobManager;
import com.evernote.android.job.JobRequest;

2
app/src/main/java/org/transdroid/core/service/RssCheckerJobRunner.java

@ -20,7 +20,7 @@ import android.app.NotificationManager; @@ -20,7 +20,7 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import androidx.core.app.NotificationCompat;
import com.evernote.android.job.Job;

4
app/src/main/java/org/transdroid/core/service/ScheduledJobCreator.java

@ -16,8 +16,8 @@ @@ -16,8 +16,8 @@
*/
package org.transdroid.core.service;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.evernote.android.job.Job;
import com.evernote.android.job.JobCreator;

2
app/src/main/java/org/transdroid/core/service/ServerCheckerJob.java

@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
package org.transdroid.core.service;
import android.content.Context;
import android.support.annotation.NonNull;
import androidx.annotation.NonNull;
import com.evernote.android.job.Job;
import com.evernote.android.job.JobManager;
import com.evernote.android.job.JobRequest;

2
app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java

@ -20,7 +20,7 @@ import android.app.NotificationManager; @@ -20,7 +20,7 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import androidx.core.app.NotificationCompat;
import android.text.TextUtils;
import com.evernote.android.job.Job;
import org.androidannotations.annotations.Bean;

4
app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java

@ -22,8 +22,8 @@ import android.appwidget.AppWidgetManager; @@ -22,8 +22,8 @@ import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;

2
app/src/main/java/org/transdroid/core/widget/ListWidgetProvider.java

@ -24,7 +24,7 @@ import android.content.Context; @@ -24,7 +24,7 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import androidx.annotation.NonNull;
import android.widget.RemoteViews;
import org.androidannotations.annotations.Bean;

48
app/src/main/java/org/transdroid/daemon/Aria2c/Aria2Adapter.java

@ -1,19 +1,19 @@ @@ -1,19 +1,19 @@
/*
* This file is part of Transdroid <http://www.transdroid.org>
*
*
* Transdroid 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.
*
*
* Transdroid 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 Transdroid. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.transdroid.daemon.Aria2c;
@ -25,7 +25,7 @@ import org.apache.http.HttpResponse; @@ -25,7 +25,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.base64.android.Base64;
import net.iharder.Base64;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -360,27 +360,27 @@ public class Aria2Adapter implements IDaemonAdapter { @@ -360,27 +360,27 @@ public class Aria2Adapter implements IDaemonAdapter {
}
// @formatter:off
torrents.add(new Torrent(
j,
tor.getString("gid"),
name,
status,
tor.getString("dir"),
j,
tor.getString("gid"),
name,
status,
tor.getString("dir"),
downloadSpeed,
tor.getInt("uploadSpeed"),
tor.getInt("connections"),
numSeeders ,
tor.getInt("connections"),
numSeeders,
(downloadSpeed > 0? (int) (totalLength / downloadSpeed): -1),
completedLength,
tor.getInt("uploadSpeed"),
tor.getInt("connections"),
numSeeders ,
tor.getInt("connections"),
numSeeders,
(downloadSpeed > 0? (int) (totalLength / downloadSpeed): -1),
completedLength,
tor.getLong("uploadLength"),
totalLength,
totalLength,
completedLength / (float) totalLength, // Percentage to [0..1]
0f, // Not available
null, // Not available
null, // Not available
null, // Not available
error,
error,
settings.getType()));
// @formatter:on
@ -403,12 +403,12 @@ public class Aria2Adapter implements IDaemonAdapter { @@ -403,12 +403,12 @@ public class Aria2Adapter implements IDaemonAdapter {
}
// @formatter:off
files.add(new TorrentFile(
Integer.toString(file.getInt("index")),
rel,
rel,
file.getString("path"),
Integer.toString(file.getInt("index")),
rel,
rel,
file.getString("path"),
file.getLong("length"),
file.getLong("completedLength"),
file.getLong("completedLength"),
file.getBoolean("selected") ? Priority.Normal : Priority.Off));
// @formatter:on

16
app/src/main/java/org/transdroid/daemon/BitComet/BitCometAdapter.java

@ -1,26 +1,26 @@ @@ -1,26 +1,26 @@
/*
* This file is part of Transdroid <http://www.transdroid.org>
*
*
* Transdroid 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.
*
*
* Transdroid 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 Transdroid. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.transdroid.daemon.BitComet;
import com.android.internalcopy.http.multipart.BitCometFilePart;
import com.android.internalcopy.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part;
import com.android.internalcopy.http.multipart.Utf8StringPart;
import org.transdroid.multipart.BitCometFilePart;
import com.android.internal.http.multipart.MultipartEntity;
import com.android.internal.http.multipart.Part;
import org.transdroid.multipart.Utf8StringPart;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;

28
app/src/main/java/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java

@ -1,25 +1,25 @@ @@ -1,25 +1,25 @@
/*
* This file is part of Transdroid <http://www.transdroid.org>
*
*
* Transdroid 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.
*
*
* Transdroid 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 Transdroid. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.transdroid.daemon.BuffaloNas;
import com.android.internalcopy.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part;
import com.android.internal.http.multipart.FilePart;
import com.android.internal.http.multipart.MultipartEntity;
import com.android.internal.http.multipart.Part;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
@ -108,8 +108,8 @@ public class BuffaloNasAdapter implements IDaemonAdapter { @@ -108,8 +108,8 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
// Request to add a torrent by URL
String url = ((AddByUrlTask) task).getUrl();
// @formatter:off
makeRequest(log, "/api/torrent-add",
new BasicNameValuePair("url", url),
makeRequest(log, "/api/torrent-add",
new BasicNameValuePair("url", url),
new BasicNameValuePair("start", "yes"));
// @formatter:on
return new DaemonTaskSuccessResult(task);
@ -119,9 +119,9 @@ public class BuffaloNasAdapter implements IDaemonAdapter { @@ -119,9 +119,9 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
// Remove a torrent
RemoveTask removeTask = (RemoveTask) task;
// @formatter:off
makeRequest(log, "/api/torrent-remove",
new BasicNameValuePair("hash", removeTask.getTargetTorrent().getUniqueID()),
new BasicNameValuePair("delete-torrent", "yes"),
makeRequest(log, "/api/torrent-remove",
new BasicNameValuePair("hash", removeTask.getTargetTorrent().getUniqueID()),
new BasicNameValuePair("delete-torrent", "yes"),
new BasicNameValuePair("delete-data", (removeTask.includingData() ? "yes" : "no")));
// @formatter:on
return new DaemonTaskSuccessResult(task);
@ -149,9 +149,9 @@ public class BuffaloNasAdapter implements IDaemonAdapter { @@ -149,9 +149,9 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
String ul = Integer.toString(
(ratesTask.getUploadRate() == null ? -1 : ratesTask.getUploadRate() * 1024));
// @formatter:off
makeRequest(log, "/api/app-settings-set",
makeRequest(log, "/api/app-settings-set",
new BasicNameValuePair("auto_bandwidth_management", "0"),
new BasicNameValuePair("max_dl_rate", dl),
new BasicNameValuePair("max_dl_rate", dl),
new BasicNameValuePair("max_ul_rate", ul),
new BasicNameValuePair("max_ul_rate_seed", ul));
// @formatter:on

46
app/src/main/java/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java

@ -1,25 +1,25 @@ @@ -1,25 +1,25 @@
/*
* This file is part of Transdroid <http://www.transdroid.org>
*
*
* Transdroid 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.
*
*
* Transdroid 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 Transdroid. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.transdroid.daemon.DLinkRouterBT;
import com.android.internalcopy.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part;
import com.android.internal.http.multipart.FilePart;
import com.android.internal.http.multipart.MultipartEntity;
import com.android.internal.http.multipart.Part;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
@ -358,23 +358,23 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter { @@ -358,23 +358,23 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter {
// @formatter:off
Torrent new_t = new Torrent(
i,
tor.getString(BT_HASH),
tor.getString(BT_CAPTION),
i,
tor.getString(BT_HASH),
tor.getString(BT_CAPTION),
status,
null, // Not supported?
tor.getInt(BT_DOWNLOAD_RATE),
tor.getInt(BT_UPLOAD_RATE),
tor.getInt(BT_PEERS_CONNECTED),
tor.getInt(BT_PEERS_TOTAL),
tor.getInt(BT_SEEDS_CONNECTED),
tor.getInt(BT_DOWNLOAD_RATE),
tor.getInt(BT_UPLOAD_RATE),
tor.getInt(BT_PEERS_CONNECTED),
tor.getInt(BT_PEERS_TOTAL),
tor.getInt(BT_SEEDS_CONNECTED),
tor.getInt(BT_SEEDS_TOTAL),
eta,
tor.getLong(BT_DONE),
tor.getLong(BT_PAYLOAD_UPLOAD),
tor.getLong(BT_SIZE),
tor.getLong(BT_DONE),
tor.getLong(BT_PAYLOAD_UPLOAD),
tor.getLong(BT_SIZE),
tor.getLong(BT_DONE) / (float) tor.getLong(BT_SIZE),
Float.parseFloat(tor.getString(BT_COPYS)),
Float.parseFloat(tor.getString(BT_COPYS)),
null,
null,
null,
@ -402,11 +402,11 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter { @@ -402,11 +402,11 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter {
// @formatter:off
torrentfiles.add(new TorrentFile(
String.valueOf(i),
file.getString(BT_FILE_NAME),
file.getString(BT_FILE_NAME),
file.getString(BT_FILE_NAME),
file.getString(BT_FILE_NAME),
null, // Not supported?
file.getLong(BT_FILE_SIZE),
file.getLong(BT_FILE_DONE),
file.getLong(BT_FILE_SIZE),
file.getLong(BT_FILE_DONE),
convertTransmissionPriority(file.getInt(BT_FILE_PRIORITY))));
// @formatter:on
}

2
app/src/main/java/org/transdroid/daemon/DaemonException.java

@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
package org.transdroid.daemon;
import android.support.annotation.NonNull;
import androidx.annotation.NonNull;
/**
* An exception thrown when an error occurs inside a server daemon adapter.

8
app/src/main/java/org/transdroid/daemon/Deluge/DelugeAdapter.java

@ -17,9 +17,9 @@ @@ -17,9 +17,9 @@
*/
package org.transdroid.daemon.Deluge;
import com.android.internalcopy.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part;
import com.android.internal.http.multipart.FilePart;
import com.android.internal.http.multipart.MultipartEntity;
import com.android.internal.http.multipart.Part;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
@ -418,7 +418,7 @@ public class DelugeAdapter implements IDaemonAdapter { @@ -418,7 +418,7 @@ public class DelugeAdapter implements IDaemonAdapter {
return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.FileAccessError, e.toString()));
}
}
/*private JSONArray buildSetTorrentOptions(String torrent, String key, String value) throws JSONException {
JSONArray params = new JSONArray();
params.put(new JSONArray().put(torrent)); // torrent_id

2
app/src/main/java/org/transdroid/daemon/Deluge/DelugeCommon.java

@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
*/
package org.transdroid.daemon.Deluge;
import android.support.annotation.NonNull;
import androidx.annotation.NonNull;
import org.transdroid.daemon.Priority;
import org.transdroid.daemon.TorrentStatus;

4
app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcAdapter.java

@ -17,8 +17,8 @@ @@ -17,8 +17,8 @@
*/
package org.transdroid.daemon.Deluge;
import android.support.annotation.NonNull;
import org.base64.android.Base64;
import androidx.annotation.NonNull;
import net.iharder.Base64;
import org.transdroid.core.gui.log.Log;
import org.transdroid.core.gui.remoterss.data.RemoteRssChannel;
import org.transdroid.core.gui.remoterss.data.RemoteRssItem;

2
app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcClient.java

@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
*/
package org.transdroid.daemon.Deluge;
import android.support.annotation.NonNull;
import androidx.annotation.NonNull;
import org.transdroid.daemon.DaemonException;
import org.transdroid.daemon.DaemonException.ExceptionType;
import org.transdroid.daemon.DaemonSettings;

14
app/src/main/java/org/transdroid/daemon/Ktorrent/KtorrentAdapter.java

@ -1,25 +1,25 @@ @@ -1,25 +1,25 @@
/*
* This file is part of Transdroid <http://www.transdroid.org>
*
*
* Transdroid 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.
*
*
* Transdroid 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 Transdroid. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.transdroid.daemon.Ktorrent;
import com.android.internalcopy.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part;
import com.android.internal.http.multipart.FilePart;
import com.android.internal.http.multipart.MultipartEntity;
import com.android.internal.http.multipart.Part;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;

6
app/src/main/java/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java

@ -17,9 +17,9 @@ @@ -17,9 +17,9 @@
*/
package org.transdroid.daemon.Qbittorrent;
import com.android.internalcopy.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part;
import com.android.internal.http.multipart.FilePart;
import com.android.internal.http.multipart.MultipartEntity;
import com.android.internal.http.multipart.Part;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;

16
app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java

@ -1,26 +1,26 @@ @@ -1,26 +1,26 @@
/*
* This file is part of Transdroid <http://www.transdroid.org>
*
*
* Transdroid 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.
*
*
* Transdroid 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 Transdroid. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.transdroid.daemon.Synology;
import com.android.internalcopy.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part;
import com.android.internalcopy.http.multipart.Utf8StringPart;
import com.android.internal.http.multipart.FilePart;
import com.android.internal.http.multipart.MultipartEntity;
import com.android.internal.http.multipart.Part;
import org.transdroid.multipart.Utf8StringPart;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;

14
app/src/main/java/org/transdroid/daemon/Tfb4rt/Tfb4rtAdapter.java

@ -1,19 +1,19 @@ @@ -1,19 +1,19 @@
/*
* This file is part of Transdroid <http://www.transdroid.org>
*
*
* Transdroid 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.
*
*
* Transdroid 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 Transdroid. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.transdroid.daemon.Tfb4rt;
@ -47,9 +47,9 @@ import org.transdroid.daemon.task.RemoveTask; @@ -47,9 +47,9 @@ import org.transdroid.daemon.task.RemoveTask;
import org.transdroid.daemon.task.RetrieveTask;
import org.transdroid.daemon.task.RetrieveTaskSuccessResult;
import org.transdroid.daemon.util.HttpHelper;
import com.android.internalcopy.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part;
import com.android.internal.http.multipart.FilePart;
import com.android.internal.http.multipart.MultipartEntity;
import com.android.internal.http.multipart.Part;
/**
* An adapter that allows for easy access to Torrentflux-b4rt installs. Communication is handled via HTTP GET requests

6
app/src/main/java/org/transdroid/daemon/Transmission/TransmissionAdapter.java

@ -22,8 +22,8 @@ import org.apache.http.HttpResponse; @@ -22,8 +22,8 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.base64.android.Base64;
import org.base64.android.Base64.InputStream;
import net.iharder.Base64;
import net.iharder.Base64.InputStream;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -192,7 +192,7 @@ public class TransmissionAdapter implements IDaemonAdapter { @@ -192,7 +192,7 @@ public class TransmissionAdapter implements IDaemonAdapter {
// Encode the .torrent file's data
InputStream in =
new Base64.InputStream(new FileInputStream(new File(URI.create(file))), Base64.ENCODE);
new InputStream(new FileInputStream(new File(URI.create(file))), Base64.ENCODE);
StringWriter writer = new StringWriter();
int c;
while ((c = in.read()) != -1) {

14
app/src/main/java/org/transdroid/daemon/Ttorrent/TtorrentAdapter.java

@ -1,25 +1,25 @@ @@ -1,25 +1,25 @@
/*
* This file is part of Transdroid <http://www.transdroid.org>
*
*
* Transdroid 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.
*
*
* Transdroid 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 Transdroid. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.transdroid.daemon.Ttorrent;
import com.android.internalcopy.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part;
import com.android.internal.http.multipart.FilePart;
import com.android.internal.http.multipart.MultipartEntity;
import com.android.internal.http.multipart.Part;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;

14
app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java

@ -1,25 +1,25 @@ @@ -1,25 +1,25 @@
/*
* This file is part of Transdroid <http://www.transdroid.org>
*
*
* Transdroid 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.
*
*
* Transdroid 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 Transdroid. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.transdroid.daemon.Utorrent;
import com.android.internalcopy.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part;
import com.android.internal.http.multipart.FilePart;
import com.android.internal.http.multipart.MultipartEntity;
import com.android.internal.http.multipart.Part;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;

108
app/src/main/java/org/transdroid/daemon/Vuze/VuzeXmlOverHttpClient.java

@ -1,19 +1,19 @@ @@ -1,19 +1,19 @@
/*
* This file is part of Transdroid <http://www.transdroid.org>
*
*
* Transdroid 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.
*
*
* Transdroid 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 Transdroid. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.transdroid.daemon.Vuze;
@ -43,7 +43,7 @@ import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; @@ -43,7 +43,7 @@ import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.base64.android.Base64;
import net.iharder.Base64;
import org.transdroid.daemon.DaemonException;
import org.transdroid.daemon.DaemonSettings;
import org.transdroid.daemon.DaemonException.ExceptionType;
@ -56,16 +56,16 @@ import org.xmlpull.v1.XmlSerializer; @@ -56,16 +56,16 @@ import org.xmlpull.v1.XmlSerializer;
import android.util.Xml;
/**
* Implements an XML-RPC-like client that build and parses XML following
* Implements an XML-RPC-like client that build and parses XML following
* Vuze's XML over HTTP plug-in (which unfortunately is incompatible with
* the default XML-RPC protocol).
*
*
* The documentation can be found at http://azureus.sourceforge.net/plugin_details.php?plugin=xml_http_if&docu=1#1
* and some stuff is at http://wiki.vuze.com/index.php/XML_over_HTTP
*
*
* A lot of it is copied from the org.xmlrpc.android library's XMLRPCClient
* as can be found at http://code.google.com/p/android-xmlrpc
*
*
* @author erickok
*
*/
@ -87,7 +87,7 @@ public class VuzeXmlOverHttpClient { @@ -87,7 +87,7 @@ public class VuzeXmlOverHttpClient {
private final static String TAG_ANNOUNCE = "announce_result";
private final static String TAG_SCRAPE = "scrape_result";
private final static String TAG_CACHED_PROPERTY_NAMES = "cached_property_names";
private DefaultHttpClient client;
private HttpPost postMethod;
private Random random;
@ -105,14 +105,14 @@ public class VuzeXmlOverHttpClient { @@ -105,14 +105,14 @@ public class VuzeXmlOverHttpClient {
postMethod.addHeader("Content-Type", "text/xml");
// WARNING
// I had to disable "Expect: 100-Continue" header since I had
// two second delay between sending http POST request and POST body
// I had to disable "Expect: 100-Continue" header since I had
// two second delay between sending http POST request and POST body
HttpParams httpParams = postMethod.getParams();
HttpProtocolParams.setUseExpectContinue(httpParams, false);
HttpConnectionParams.setConnectionTimeout(httpParams, settings.getTimeoutInMilliseconds());
HttpConnectionParams.setSoTimeout(httpParams, settings.getTimeoutInMilliseconds());
HttpConnectionParams.setSoTimeout(httpParams, settings.getTimeoutInMilliseconds());
SchemeRegistry registry = new SchemeRegistry();
SocketFactory httpsSocketFactory;
if (settings.getSslTrustKey() != null) {
@ -124,7 +124,7 @@ public class VuzeXmlOverHttpClient { @@ -124,7 +124,7 @@ public class VuzeXmlOverHttpClient {
}
registry.register(new Scheme("http", new PlainSocketFactory(), 80));
registry.register(new Scheme("https", httpsSocketFactory, 443));
client = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, registry), httpParams);
if (settings.shouldUseAuthentication()) {
if (settings.getUsername() == null || settings.getPassword() == null) {
@ -137,11 +137,11 @@ public class VuzeXmlOverHttpClient { @@ -137,11 +137,11 @@ public class VuzeXmlOverHttpClient {
new UsernamePasswordCredentials(username, password));
}
}
random = new Random();
random.nextInt();
}
/**
* Convenience constructor. Creates new instance based on server String address
* @param settings The server connection settings
@ -151,23 +151,23 @@ public class VuzeXmlOverHttpClient { @@ -151,23 +151,23 @@ public class VuzeXmlOverHttpClient {
public VuzeXmlOverHttpClient(DaemonSettings settings, String url) throws DaemonException {
this(settings, URI.create(url));
}
protected Map<String, Object> callXMLRPC(Long object, String method, Object[] params, Long connectionID, boolean paramsAreVuzeObjects) throws DaemonException {
try {
// prepare POST body
XmlSerializer serializer = Xml.newSerializer();
StringWriter bodyWriter = new StringWriter();
serializer.setOutput(bodyWriter);
serializer.startDocument(null, null);
serializer.startTag(null, TAG_REQUEST);
// set object
if (object != null) {
serializer.startTag(null, TAG_OBJECT).startTag(null, TAG_OBJECT_ID)
.text(object.toString()).endTag(null, TAG_OBJECT_ID).endTag(null, TAG_OBJECT);
}
// set method
serializer.startTag(null, TAG_METHOD).text(method).endTag(null, TAG_METHOD);
if (params != null && params.length != 0) {
@ -188,7 +188,7 @@ public class VuzeXmlOverHttpClient { @@ -188,7 +188,7 @@ public class VuzeXmlOverHttpClient {
}
serializer.endTag(null, TAG_PARAMS);
}
// set connection id
if (connectionID != null) {
serializer.startTag(null, TAG_CONNECTION_ID).text(connectionID.toString()).endTag(null, TAG_CONNECTION_ID);
@ -199,16 +199,16 @@ public class VuzeXmlOverHttpClient { @@ -199,16 +199,16 @@ public class VuzeXmlOverHttpClient {
serializer.endTag(null, TAG_REQUEST);
serializer.endDocument();
// set POST body
HttpEntity entity = new StringEntity(bodyWriter.toString());
postMethod.setEntity(entity);
// Force preemptive authentication
// This makes sure there is an 'Authentication: ' header being send before trying and failing and retrying
// This makes sure there is an 'Authentication: ' header being send before trying and failing and retrying
// by the basic authentication mechanism of DefaultHttpClient
postMethod.addHeader("Authorization", "Basic " + Base64.encodeBytes((username + ":" + password).getBytes()));
// execute HTTP POST request
HttpResponse response = client.execute(postMethod);
@ -225,33 +225,33 @@ public class VuzeXmlOverHttpClient { @@ -225,33 +225,33 @@ public class VuzeXmlOverHttpClient {
// setup pull parser
XmlPullParser pullParser = XmlPullParserFactory.newInstance().newPullParser();
entity = response.getEntity();
//String temp = HttpHelper.ConvertStreamToString(entity.getContent());
//String temp = HttpHelper.ConvertStreamToString(entity.getContent());
//Reader reader = new StringReader(temp);
Reader reader = new InputStreamReader(entity.getContent());
pullParser.setInput(reader);
// lets start pulling...
pullParser.nextTag();
pullParser.require(XmlPullParser.START_TAG, null, TAG_RESPONSE);
// build list of returned values
int next = pullParser.nextTag(); // skip to first start tag in list
String name = pullParser.getName(); // get name of the first start tag
// Empty response?
if (next == XmlPullParser.END_TAG && name.equals(TAG_RESPONSE)) {
return null;
} else if (name.equals(TAG_ERROR)) {
// Error
String errorText = pullParser.nextText(); // the value of the ERROR
entity.consumeContent();
throw new DaemonException(ExceptionType.ConnectionError, errorText);
} else {
// Consume a list of ENTRYs?
if (name.equals(TAG_ENTRY)) {
@ -262,15 +262,15 @@ public class VuzeXmlOverHttpClient { @@ -262,15 +262,15 @@ public class VuzeXmlOverHttpClient {
}
entity.consumeContent();
return entries;
} else {
// Only a single object was returned, not an entry listing
return consumeObject(pullParser);
}
}
} catch (IOException e) {
throw new DaemonException(ExceptionType.ConnectionError, e.toString());
} catch (XmlPullParserException e) {
@ -282,11 +282,11 @@ public class VuzeXmlOverHttpClient { @@ -282,11 +282,11 @@ public class VuzeXmlOverHttpClient {
int next = pullParser.nextTag();
String name = pullParser.getName();
// Consume the ENTRY objects
Map<String, Object> returnValues = new HashMap<String, Object>();
while (next == XmlPullParser.START_TAG) {
if (name.equals(TAG_TORRENT) || name.equals(TAG_ANNOUNCE) || name.equals(TAG_SCRAPE) || name.equals(TAG_STATS)) {
// One of the objects contained inside an entry
pullParser.nextTag();
@ -297,21 +297,21 @@ public class VuzeXmlOverHttpClient { @@ -297,21 +297,21 @@ public class VuzeXmlOverHttpClient {
}
next = pullParser.nextTag(); // skip to next start tag
name = pullParser.getName(); // get name of the new start tag
}
// Consume ENTRY ending
pullParser.nextTag();
return returnValues;
}
private Map<String, Object> consumeObject(XmlPullParser pullParser) throws XmlPullParserException, IOException {
int next = XmlPullParser.START_TAG;
String name = pullParser.getName();
// Consume bottom-level (contains no objects of its own) object
Map<String, Object> returnValues = new HashMap<String, Object>();
while (next == XmlPullParser.START_TAG && !(name.equals(TAG_CACHED_PROPERTY_NAMES))) {
@ -326,11 +326,11 @@ public class VuzeXmlOverHttpClient { @@ -326,11 +326,11 @@ public class VuzeXmlOverHttpClient {
}
next = pullParser.nextTag(); // skip to next start tag
name = pullParser.getName(); // get name of the new start tag
}
return returnValues;
}
private String serialize(Object value) {
@ -344,7 +344,7 @@ public class VuzeXmlOverHttpClient { @@ -344,7 +344,7 @@ public class VuzeXmlOverHttpClient {
return null;
}
/* For now cast all integers as Long; this prevents casting problems later on when
/* For now cast all integers as Long; this prevents casting problems later on when
* we know it's a long but the value was small so it is casted to an Integer here
// Integer?
try {
@ -353,7 +353,7 @@ public class VuzeXmlOverHttpClient { @@ -353,7 +353,7 @@ public class VuzeXmlOverHttpClient {
} catch (NumberFormatException e) {
// Just continue trying the next type
}*/
// Long?
try {
Long longnum = Long.parseLong(rawText);
@ -361,7 +361,7 @@ public class VuzeXmlOverHttpClient { @@ -361,7 +361,7 @@ public class VuzeXmlOverHttpClient {
} catch (NumberFormatException e) {
// Just continue trying the next type
}
// Double?
try {
Double doublenum = Double.parseDouble(rawText);
@ -369,9 +369,9 @@ public class VuzeXmlOverHttpClient { @@ -369,9 +369,9 @@ public class VuzeXmlOverHttpClient {
} catch (NumberFormatException e) {
// Just continue trying the next type
}
// String otherwise
return rawText;
}
}

480
app/src/main/java/com/android/internalcopy/http/multipart/BitCometFilePart.java → app/src/main/java/org/transdroid/multipart/BitCometFilePart.java

@ -1,238 +1,242 @@ @@ -1,238 +1,242 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java,v 1.19 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.http.util.EncodingUtils;
/**
* This class implements a part of a Multipart post object that
* consists of a file.
*
* @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a>
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
* @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a>
* @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
* @author <a href="mailto:mdiggory@latte.harvard.edu">Mark Diggory</a>
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
*
* @since 2.0
*
*/
public class BitCometFilePart extends PartBase {
/** Default content encoding of file attachments. */
public static final String DEFAULT_CONTENT_TYPE = "application/x-bittorrent";
/** Attachment's file name */
protected static final String FILE_NAME = "; filename=";
/** Attachment's file name as a byte array */
private static final byte[] FILE_NAME_BYTES =
EncodingUtils.getAsciiBytes(FILE_NAME);
/** Source of the file part. */
private PartSource source;
/**
* FilePart Constructor.
*
* @param name the name for this part
* @param partSource the source for this part
* @param contentType the content type for this part, if <code>null</code> the
* {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
* {@link #DEFAULT_CHARSET default} is used
*/
public BitCometFilePart(String name, PartSource partSource, String contentType, String charset) {
super(
name,
contentType == null ? DEFAULT_CONTENT_TYPE : contentType,
charset == null ? "ISO-8859-1" : charset,
null
);
if (partSource == null) {
throw new IllegalArgumentException("Source may not be null");
}
this.source = partSource;
}
/**
* FilePart Constructor.
*
* @param name the name for this part
* @param partSource the source for this part
*/
public BitCometFilePart(String name, PartSource partSource) {
this(name, partSource, null, null);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param file the file to post
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public BitCometFilePart(String name, File file)
throws FileNotFoundException {
this(name, new FilePartSource(file), null, null);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param file the file to post
* @param contentType the content type for this part, if <code>null</code> the
* {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
* {@link #DEFAULT_CHARSET default} is used
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public BitCometFilePart(String name, File file, String contentType, String charset)
throws FileNotFoundException {
this(name, new FilePartSource(file), contentType, charset);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param fileName the file name
* @param file the file to post
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public BitCometFilePart(String name, String fileName, File file)
throws FileNotFoundException {
this(name, new FilePartSource(fileName, file), null, null);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param fileName the file name
* @param file the file to post
* @param contentType the content type for this part, if <code>null</code> the
* {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
* {@link #DEFAULT_CHARSET default} is used
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public BitCometFilePart(String name, String fileName, File file, String contentType, String charset)
throws FileNotFoundException {
this(name, new FilePartSource(fileName, file), contentType, charset);
}
/**
* Write the disposition header to the output stream
* @param out The output stream
* @throws IOException If an IO problem occurs
* @see Part#sendDispositionHeader(OutputStream)
*/
@Override
protected void sendDispositionHeader(OutputStream out)
throws IOException {
super.sendDispositionHeader(out);
String filename = this.source.getFileName();
if (filename != null) {
out.write(FILE_NAME_BYTES);
out.write(QUOTE_BYTES);
out.write(EncodingUtils.getAsciiBytes(filename));
out.write(QUOTE_BYTES);
}
}
/**
* Write the data in "source" to the specified stream.
* @param out The output stream.
* @throws IOException if an IO problem occurs.
* @see Part#sendData(OutputStream)
*/
@Override
protected void sendData(OutputStream out) throws IOException {
if (lengthOfData() == 0) {
// this file contains no data, so there is nothing to send.
// we don't want to create a zero length buffer as this will
// cause an infinite loop when reading.
return;
}
byte[] tmp = new byte[4096];
InputStream instream = source.createInputStream();
try {
int len;
while ((len = instream.read(tmp)) >= 0) {
out.write(tmp, 0, len);
}
} finally {
// we're done with the stream, close it
instream.close();
}
}
/**
* Returns the source of the file part.
*
* @return The source.
*/
protected PartSource getSource() {
return this.source;
}
/**
* Return the length of the data.
* @return The length.
* @see Part#lengthOfData()
*/
@Override
protected long lengthOfData() {
return source.getLength();
}
}
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java,v 1.19 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.transdroid.multipart;
import com.android.internal.http.multipart.FilePartSource;
import com.android.internal.http.multipart.PartBase;
import com.android.internal.http.multipart.PartSource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.http.util.EncodingUtils;
/**
* This class implements a part of a Multipart post object that
* consists of a file.
*
* @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a>
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
* @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a>
* @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
* @author <a href="mailto:mdiggory@latte.harvard.edu">Mark Diggory</a>
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
*
* @since 2.0
*
*/
public class BitCometFilePart extends PartBase {
/** Default content encoding of file attachments. */
public static final String DEFAULT_CONTENT_TYPE = "application/x-bittorrent";
/** Attachment's file name */
protected static final String FILE_NAME = "; filename=";
/** Attachment's file name as a byte array */
private static final byte[] FILE_NAME_BYTES =
EncodingUtils.getAsciiBytes(FILE_NAME);
/** Source of the file part. */
private PartSource source;
/**
* FilePart Constructor.
*
* @param name the name for this part
* @param partSource the source for this part
* @param contentType the content type for this part, if <code>null</code> the
* {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
* {@link #DEFAULT_CHARSET default} is used
*/
public BitCometFilePart(String name, PartSource partSource, String contentType, String charset) {
super(
name,
contentType == null ? DEFAULT_CONTENT_TYPE : contentType,
charset == null ? "ISO-8859-1" : charset,
null
);
if (partSource == null) {
throw new IllegalArgumentException("Source may not be null");
}
this.source = partSource;
}
/**
* FilePart Constructor.
*
* @param name the name for this part
* @param partSource the source for this part
*/
public BitCometFilePart(String name, PartSource partSource) {
this(name, partSource, null, null);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param file the file to post
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public BitCometFilePart(String name, File file)
throws FileNotFoundException {
this(name, new FilePartSource(file), null, null);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param file the file to post
* @param contentType the content type for this part, if <code>null</code> the
* {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
* {@link #DEFAULT_CHARSET default} is used
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public BitCometFilePart(String name, File file, String contentType, String charset)
throws FileNotFoundException {
this(name, new FilePartSource(file), contentType, charset);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param fileName the file name
* @param file the file to post
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public BitCometFilePart(String name, String fileName, File file)
throws FileNotFoundException {
this(name, new FilePartSource(fileName, file), null, null);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param fileName the file name
* @param file the file to post
* @param contentType the content type for this part, if <code>null</code> the
* {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
* {@link #DEFAULT_CHARSET default} is used
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public BitCometFilePart(String name, String fileName, File file, String contentType, String charset)
throws FileNotFoundException {
this(name, new FilePartSource(fileName, file), contentType, charset);
}
/**
* Write the disposition header to the output stream
* @param out The output stream
* @throws IOException If an IO problem occurs
* @see Part#sendDispositionHeader(OutputStream)
*/
@Override
protected void sendDispositionHeader(OutputStream out)
throws IOException {
super.sendDispositionHeader(out);
String filename = this.source.getFileName();
if (filename != null) {
out.write(FILE_NAME_BYTES);
out.write(QUOTE_BYTES);
out.write(EncodingUtils.getAsciiBytes(filename));
out.write(QUOTE_BYTES);
}
}
/**
* Write the data in "source" to the specified stream.
* @param out The output stream.
* @throws IOException if an IO problem occurs.
* @see Part#sendData(OutputStream)
*/
@Override
protected void sendData(OutputStream out) throws IOException {
if (lengthOfData() == 0) {
// this file contains no data, so there is nothing to send.
// we don't want to create a zero length buffer as this will
// cause an infinite loop when reading.
return;
}
byte[] tmp = new byte[4096];
InputStream instream = source.createInputStream();
try {
int len;
while ((len = instream.read(tmp)) >= 0) {
out.write(tmp, 0, len);
}
} finally {
// we're done with the stream, close it
instream.close();
}
}
/**
* Returns the source of the file part.
*
* @return The source.
*/
protected PartSource getSource() {
return this.source;
}
/**
* Return the length of the data.
* @return The length.
* @see Part#lengthOfData()
*/
@Override
protected long lengthOfData() {
return source.getLength();
}
}

88
app/src/main/java/com/android/internalcopy/http/multipart/Utf8StringPart.java → app/src/main/java/org/transdroid/multipart/Utf8StringPart.java

@ -1,43 +1,45 @@ @@ -1,43 +1,45 @@
package com.android.internalcopy.http.multipart;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.http.util.EncodingUtils;
public class Utf8StringPart extends PartBase {
/** Contents of this StringPart. */
private byte[] content;
/** The String value of this part. */
private String value;
public Utf8StringPart(String name, String value) {
super(name, null, null, null);
this.value = value;
}
/**
* Gets the content in bytes. Bytes are lazily created to allow the charset to be changed
* after the part is created.
*
* @return the content in bytes
*/
private byte[] getContent() {
if (content == null) {
content = EncodingUtils.getBytes(value, "utf-8");
}
return content;
}
@Override
protected void sendData(OutputStream out) throws IOException {
out.write(getContent());
}
@Override
protected long lengthOfData() throws IOException {
return getContent().length;
}
}
package org.transdroid.multipart;
import com.android.internal.http.multipart.PartBase;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.http.util.EncodingUtils;
public class Utf8StringPart extends PartBase {
/** Contents of this StringPart. */
private byte[] content;
/** The String value of this part. */
private String value;
public Utf8StringPart(String name, String value) {
super(name, null, null, null);
this.value = value;
}
/**
* Gets the content in bytes. Bytes are lazily created to allow the charset to be changed
* after the part is created.
*
* @return the content in bytes
*/
private byte[] getContent() {
if (content == null) {
content = EncodingUtils.getBytes(value, "utf-8");
}
return content;
}
@Override
protected void sendData(OutputStream out) throws IOException {
out.write(getContent());
}
@Override
protected long lengthOfData() throws IOException {
return getContent().length;
}
}

131
app/src/main/res/layout-land/dialog_color_picker.xml

@ -1,77 +1,82 @@ @@ -1,77 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Daniel Nilsson
<?xml version="1.0" encoding="utf-8"?><!--
Copyright (C) 2010 Daniel Nilsson
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.
See the License for the specific language governing permissions and limitations under the License.
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:orientation="horizontal">
<net.margaritov.preference.colorpicker.ColorPickerView
android:id="@+id/color_picker_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="landscape"
android:layerType="software"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/press_color_to_apply"
android:gravity="center"
android:layout_marginTop="6dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginBottom="5dp"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
android:paddingRight="5dp">
<net.margaritov.preference.colorpicker.ColorPickerView
android:id="@+id/color_picker_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layerType="software"
android:tag="landscape" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:orientation="vertical">
<EditText
android:id="@+id/hex_val"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="HEX"
android:imeOptions="actionDone"
android:maxLength="7"
android:singleLine="true"
android:inputType="textCapCharacters"
android:visibility="gone"></EditText>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="6dp"
android:gravity="center"
android:text="@string/press_color_to_apply"
android:textAppearance="?android:attr/textAppearanceSmall" />
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/old_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="↓"
android:textSize="20sp" />
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5" />
</LinearLayout>
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/old_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="↓"
android:textSize="20sp"
android:gravity="center"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

2
app/src/main/res/layout-w600dp/activity_search.xml

@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
android:orientation="horizontal"
tools:context=".core.gui.search.SearchActivity_">
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/search_toolbar"
style="@style/DefaultToolbar"
android:layout_width="match_parent"

8
app/src/main/res/layout-w600dp/activity_torrents.xml

@ -31,14 +31,14 @@ @@ -31,14 +31,14 @@
android:focusable="true"
android:focusableInTouchMode="true"/>
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/torrents_toolbar"
style="@style/DefaultToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize" />
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/actions_toolbar"
style="@style/SplitToolbar"
android:layout_width="match_parent"
@ -48,7 +48,7 @@ @@ -48,7 +48,7 @@
android:paddingEnd="@dimen/ui_actions_padding"
android:paddingRight="@dimen/ui_actions_padding" />
<android.support.v7.widget.ActionMenuView
<androidx.appcompat.widget.ActionMenuView
android:id="@+id/contextual_menu"
style="@style/SplitToolbar"
android:layout_width="match_parent"
@ -58,7 +58,7 @@ @@ -58,7 +58,7 @@
android:visibility="gone"
tools:visibility="visible" />
<android.support.v7.widget.SearchView
<androidx.appcompat.widget.SearchView
android:id="@+id/filter_search"
android:layout_width="@dimen/ui_filters_list"
android:layout_height="wrap_content"

8
app/src/main/res/layout-w900dp/activity_rssfeeds.xml

@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
android:layout_height="match_parent"
tools:context=".core.gui.rss.RssFeedsActivity_">
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/rssfeeds_toolbar"
style="@style/DefaultToolbar"
android:layout_width="match_parent"
@ -32,13 +32,13 @@ @@ -32,13 +32,13 @@
style="@style/DefaultToolbarShadow"
android:layout_below="@id/rssfeeds_toolbar" />
<android.support.v4.view.ViewPager
<androidx.viewpager.widget.ViewPager
android:id="@+id/rssfeeds_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/rssfeeds_toolbar">
<android.support.design.widget.TabLayout
<com.google.android.material.tabs.TabLayout
android:id="@+id/rssfeeds_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
@ -79,6 +79,6 @@ @@ -79,6 +79,6 @@
android:layout_height="match_parent"
tools:layout="@layout/fragment_torrents" />
</LinearLayout>
</android.support.v4.view.ViewPager>
</androidx.viewpager.widget.ViewPager>
</RelativeLayout>

10
app/src/main/res/layout-w900dp/activity_torrents.xml

@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
android:focusable="true"
android:focusableInTouchMode="true"/>
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/selection_toolbar"
style="@style/DefaultToolbar"
android:layout_width="match_parent"
@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
android:layout_alignRight="@id/filters_list"
android:minHeight="?attr/actionBarSize" />
<android.support.v7.widget.SearchView
<androidx.appcompat.widget.SearchView
android:id="@+id/filter_search"
android:layout_width="@dimen/ui_filters_list"
android:layout_height="wrap_content"
@ -80,7 +80,7 @@ @@ -80,7 +80,7 @@
android:layout_height="1dp"
android:layout_centerHorizontal="true" />
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/actions_toolbar"
style="@style/DefaultToolbar"
android:layout_width="match_parent"
@ -89,7 +89,7 @@ @@ -89,7 +89,7 @@
android:layout_toStartOf="@id/fragments_divider"
android:minHeight="?attr/actionBarSize" />
<android.support.v7.widget.ActionMenuView
<androidx.appcompat.widget.ActionMenuView
android:id="@+id/contextual_toolbar"
style="@style/SplitToolbar"
android:layout_width="match_parent"
@ -101,7 +101,7 @@ @@ -101,7 +101,7 @@
android:visibility="gone"
tools:visibility="visible" />
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/torrents_toolbar"
style="@style/DefaultToolbar"
android:layout_width="match_parent"

2
app/src/main/res/layout/activity_details.xml

@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
android:layout_height="match_parent"
tools:context=".DetailsActivity">
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/selection_toolbar"
style="@style/DefaultToolbar"
android:layout_width="match_parent"

8
app/src/main/res/layout/activity_rssfeeds.xml

@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
android:layout_height="match_parent"
tools:context=".core.gui.rss.RssFeedsActivity_">
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/rssfeeds_toolbar"
style="@style/DefaultToolbar"
android:layout_width="match_parent"
@ -32,14 +32,14 @@ @@ -32,14 +32,14 @@
style="@style/DefaultToolbarShadow"
android:layout_below="@id/rssfeeds_toolbar" />
<android.support.v4.view.ViewPager
<androidx.viewpager.widget.ViewPager
android:id="@+id/rssfeeds_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/rssfeeds_toolbar"
android:layout_marginTop="-2dp">
<android.support.design.widget.TabLayout
<com.google.android.material.tabs.TabLayout
android:id="@+id/rssfeeds_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
@ -73,6 +73,6 @@ @@ -73,6 +73,6 @@
tools:layout="@layout/fragment_torrents" />
</LinearLayout>
</android.support.v4.view.ViewPager>
</androidx.viewpager.widget.ViewPager>
</RelativeLayout>

2
app/src/main/res/layout/activity_rssitems.xml

@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
android:layout_height="match_parent"
tools:context=".core.gui.rss.RssItemsActivity_">
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/rssfeeds_toolbar"
style="@style/DefaultToolbar"
android:layout_width="match_parent"

4
app/src/main/res/layout/activity_search.xml

@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
android:layout_height="match_parent"
tools:context=".core.gui.search.SearchActivity_">
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/search_toolbar"
style="@style/DefaultToolbar"
android:layout_width="match_parent"
@ -33,7 +33,7 @@ @@ -33,7 +33,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.v7.widget.Toolbar>
</androidx.appcompat.widget.Toolbar>
<FrameLayout
android:layout_width="match_parent"

12
app/src/main/res/layout/activity_torrents.xml

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
-->
<!-- This layout is for phones in portrait and shows the torrents list with the filters as navigation drawer. -->
<android.support.v4.widget.DrawerLayout
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
@ -31,14 +31,14 @@ @@ -31,14 +31,14 @@
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/torrents_toolbar"
style="@style/DefaultToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize" />
<android.support.v7.widget.Toolbar
<androidx.appcompat.widget.Toolbar
android:id="@+id/actions_toolbar"
style="@style/SplitToolbar"
android:layout_width="match_parent"
@ -48,7 +48,7 @@ @@ -48,7 +48,7 @@
android:paddingEnd="@dimen/ui_actions_padding"
android:paddingRight="@dimen/ui_actions_padding" />
<android.support.v7.widget.ActionMenuView
<androidx.appcompat.widget.ActionMenuView
android:id="@+id/contextual_menu"
style="@style/SplitToolbar"
android:layout_width="match_parent"
@ -107,7 +107,7 @@ @@ -107,7 +107,7 @@
android:divider="@null"
tools:listitem="@layout/list_item_filter" />
<android.support.v7.widget.SearchView
<androidx.appcompat.widget.SearchView
android:id="@+id/filter_search"
android:layout_width="@dimen/ui_filters_list"
android:layout_height="wrap_content"
@ -121,4 +121,4 @@ @@ -121,4 +121,4 @@
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
</androidx.drawerlayout.widget.DrawerLayout>

137
app/src/main/res/layout/dialog_color_picker.xml

@ -1,77 +1,88 @@ @@ -1,77 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Daniel Nilsson
<?xml version="1.0" encoding="utf-8"?><!--
Copyright (C) 2010 Daniel Nilsson
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.
See the License for the specific language governing permissions and limitations under the License.
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:orientation="vertical">
<net.margaritov.preference.colorpicker.ColorPickerView
android:id="@+id/color_picker_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:tag="portrait"
android:layerType="software"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/press_color_to_apply"
android:gravity="left"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginBottom="5dp"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="40dp"
android:orientation="horizontal"
android:layout_marginBottom="10dp">
android:paddingRight="5dp">
<net.margaritov.preference.colorpicker.ColorPickerView
android:id="@+id/color_picker_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layerType="software"
android:tag="portrait" />
<LinearLayout
android:id="@+id/text_hex_wrapper"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:text="@string/press_color_to_apply"
android:textAppearance="?android:attr/textAppearanceSmall" />
<EditText
android:id="@+id/hex_val"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="HEX"
android:imeOptions="actionDone"
android:maxLength="7"
android:singleLine="true"
android:inputType="textCapCharacters"
android:visibility="gone"></EditText>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/old_color_panel"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_weight="0.5" />
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center"
android:text="→"
android:textSize="20sp" />
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="0.5" />
</LinearLayout>
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/old_color_panel"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_weight="0.5"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="→"
android:textSize="20sp"
android:gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="0.5"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

8
app/src/main/res/layout/fragment_details.xml

@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
android:layout_height="match_parent"
tools:context=".core.gui.DetailsActivity_">
<android.support.v7.widget.ActionMenuView
<androidx.appcompat.widget.ActionMenuView
android:id="@+id/details_menu"
style="@style/SplitToolbar"
android:layout_width="match_parent"
@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
android:layout_alignParentBottom="true"
android:minHeight="?attr/actionBarSize" />
<android.support.v7.widget.ActionMenuView
<androidx.appcompat.widget.ActionMenuView
android:id="@+id/contextual_menu"
style="@style/SplitToolbar"
android:layout_width="match_parent"
@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
android:visibility="gone"
tools:visibility="visible"/>
<android.support.v4.widget.SwipeRefreshLayout
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -56,7 +56,7 @@ @@ -56,7 +56,7 @@
android:dividerHeight="0dip"
android:visibility="gone" />
</android.support.v4.widget.SwipeRefreshLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<ProgressBar
android:id="@+id/loading_progress"

4
app/src/main/res/layout/fragment_torrents.xml

@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -36,7 +36,7 @@ @@ -36,7 +36,7 @@
tools:listitem="@layout/list_item_torrent"
tools:visibility="visible" />
</android.support.v4.widget.SwipeRefreshLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<ProgressBar
android:id="@+id/loading_progress"

2
app/src/main/res/menu/activity_search.xml

@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom" />
<item
android:id="@+id/action_refresh"

2
app/src/main/res/menu/activity_torrents_main.xml

@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom" />
<item
android:id="@+id/action_rss"

15
build.gradle

@ -1,19 +1,30 @@ @@ -1,19 +1,30 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.android.tools.build:gradle:4.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
mavenCentral()
jcenter()
maven { url "https://jitpack.io" }
mavenCentral()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

2
gradle.properties

@ -11,3 +11,5 @@ @@ -11,3 +11,5 @@
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
android.enableJetifier=true
android.useAndroidX=true

BIN
gradle/wrapper/gradle-wrapper.jar vendored

Binary file not shown.

3
gradle/wrapper/gradle-wrapper.properties vendored

@ -1,6 +1,5 @@ @@ -1,6 +1,5 @@
#Sun Feb 09 15:35:10 AEDT 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

117
gradlew vendored

@ -1,4 +1,20 @@ @@ -1,4 +1,20 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# 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
#
# https://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.
#
##############################################################################
##
@ -6,20 +22,38 @@ @@ -6,20 +22,38 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
warn () {
echo "$*"
}
die ( ) {
die () {
echo
echo "$*"
echo
@ -30,6 +64,7 @@ die ( ) { @@ -30,6 +64,7 @@ die ( ) {
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
@ -40,33 +75,14 @@ case "`uname`" in @@ -40,33 +75,14 @@ case "`uname`" in
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@ -90,7 +106,7 @@ location of your Java installation." @@ -90,7 +106,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@ -110,10 +126,12 @@ if $darwin; then @@ -110,10 +126,12 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@ -138,27 +156,30 @@ if $cygwin ; then @@ -138,27 +156,30 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
exec "$JAVACMD" "$@"

34
gradlew.bat vendored

@ -1,3 +1,19 @@ @@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@ -8,14 +24,17 @@ @@ -8,14 +24,17 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@ -46,10 +65,9 @@ echo location of your Java installation. @@ -46,10 +65,9 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@ -60,17 +78,13 @@ set _SKIP=2 @@ -60,17 +78,13 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

Loading…
Cancel
Save