diff --git a/FasterGPS/build.gradle b/FasterGPS/build.gradle
index 8a13331..65dc96a 100644
--- a/FasterGPS/build.gradle
+++ b/FasterGPS/build.gradle
@@ -2,14 +2,14 @@ apply plugin: 'com.android.application'
dependencies {
compile 'com.android.support:support-v4:21.0.3'
- compile project(':libraries:Donations')
- compile project(':libraries:HtmlTextView')
+ compile 'org.sufficientlysecure:donations:2.4'
+ compile 'org.sufficientlysecure:html-textview:2.0'
compile project(':libraries:RootCommands')
}
android {
compileSdkVersion 21
- buildToolsVersion "21.1.2"
+ buildToolsVersion "25.0.0"
defaultConfig {
minSdkVersion 16
diff --git a/FasterGPS/src/main/java/org/fastergps/ui/HelpAboutFragment.java b/FasterGPS/src/main/java/org/fastergps/ui/HelpAboutFragment.java
index 94483f4..ade3afb 100644
--- a/FasterGPS/src/main/java/org/fastergps/ui/HelpAboutFragment.java
+++ b/FasterGPS/src/main/java/org/fastergps/ui/HelpAboutFragment.java
@@ -58,7 +58,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
HtmlTextView aboutTextView = (HtmlTextView) view.findViewById(R.id.help_about_text);
// load html into textview
- aboutTextView.setHtmlFromRawResource(getActivity(), R.raw.help_about);
+ aboutTextView.setHtml(R.raw.help_about);
// no flickering when clicking textview for Android < 4
aboutTextView.setTextColor(getResources().getColor(
diff --git a/FasterGPS/src/main/java/org/fastergps/ui/HelpActivity.java b/FasterGPS/src/main/java/org/fastergps/ui/HelpActivity.java
index ff73ce9..66d99e4 100644
--- a/FasterGPS/src/main/java/org/fastergps/ui/HelpActivity.java
+++ b/FasterGPS/src/main/java/org/fastergps/ui/HelpActivity.java
@@ -44,7 +44,7 @@ public class HelpActivity extends FragmentActivity {
/**
* PayPal
*/
- private static final String PAYPAL_USER = "dominik@dominikschuermann.de";
+ private static final String PAYPAL_USER = "dominik@sufficientlysecure.org";
private static final String PAYPAL_CURRENCY_CODE = "EUR";
@@ -69,10 +69,10 @@ public void onCreate(Bundle savedInstanceState) {
if (BuildConfig.DONATIONS_GOOGLE) {
donationsFragment = DonationsFragment.newInstance(BuildConfig.DEBUG, true, GOOGLE_PUBKEY, GOOGLE_CATALOG,
getResources().getStringArray(R.array.help_donation_google_catalog_values), false, null, null,
- null, false, null, null);
+ null, false, null, null, false, null);
} else {
donationsFragment = DonationsFragment.newInstance(BuildConfig.DEBUG, false, null, null, null, true, PAYPAL_USER,
- PAYPAL_CURRENCY_CODE, getString(R.string.help_donation_paypal_item), true, FLATTR_PROJECT_URL, FLATTR_URL);
+ PAYPAL_CURRENCY_CODE, getString(R.string.help_donation_paypal_item), true, FLATTR_PROJECT_URL, FLATTR_URL, false, null);
}
ft.replace(R.id.help_donations_container, donationsFragment, "donationsFragment");
diff --git a/FasterGPS/src/main/java/org/fastergps/ui/HelpHtmlFragment.java b/FasterGPS/src/main/java/org/fastergps/ui/HelpHtmlFragment.java
index c67f129..37722d0 100644
--- a/FasterGPS/src/main/java/org/fastergps/ui/HelpHtmlFragment.java
+++ b/FasterGPS/src/main/java/org/fastergps/ui/HelpHtmlFragment.java
@@ -62,7 +62,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
layout.addView(text);
// load html into textview
- text.setHtmlFromRawResource(mActivity, R.raw.help);
+ text.setHtml(R.raw.help);
// no flickering when clicking textview for Android < 4
text.setTextColor(getResources().getColor(android.R.color.secondary_text_dark_nodisable));
diff --git a/build.gradle b/build.gradle
index fd84509..00e6910 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,19 +1,18 @@
buildscript {
repositories {
- mavenCentral()
+ jcenter()
}
-
dependencies {
- classpath 'com.android.tools.build:gradle:1.0.0'
+ classpath 'com.android.tools.build:gradle:2.2.2'
}
}
allprojects {
repositories {
- mavenCentral()
+ jcenter()
}
}
task wrapper(type: Wrapper) {
- gradleVersion = '2.2.1'
+ gradleVersion = '3.1'
}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 8c0fb64..6ffa237 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 0c71e76..ae2abab 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Apr 10 15:27:10 PDT 2013
+#Fri Oct 28 14:50:17 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-bin.zip
diff --git a/gradlew b/gradlew
index 91a7e26..9aa616c 100755
--- a/gradlew
+++ b/gradlew
@@ -6,12 +6,30 @@
##
##############################################################################
-# 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=""
+
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -30,6 +48,7 @@ die ( ) {
cygwin=false
msys=false
darwin=false
+nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
@@ -40,31 +59,11 @@ 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.
@@ -90,7 +89,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
@@ -114,6 +113,7 @@ fi
if $cygwin ; 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`
@@ -161,4 +161,9 @@ function splitJvmOpts() {
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then
+ cd "$(dirname "$0")"
+fi
+
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
index aec9973..e95643d 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -8,14 +8,14 @@
@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 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=
+
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +46,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,11 +59,6 @@ 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
diff --git a/libraries/Donations/.gitignore b/libraries/Donations/.gitignore
deleted file mode 100644
index afa9dfc..0000000
--- a/libraries/Donations/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-#Android specific
-bin
-gen
-obj
-libs/armeabi
-lint.xml
-local.properties
-release.properties
-ant.properties
-*.class
-*.apk
-
-#Gradle
-.gradle
-build
-gradle.properties
-gradlew
-gradlew.bat
-gradle
-
-#Maven
-target
-pom.xml.*
-
-#Eclipse
-.project
-.classpath
-.settings
-.metadata
-
-#IntelliJ IDEA
-.idea
-*.iml
diff --git a/libraries/Donations/build.gradle b/libraries/Donations/build.gradle
deleted file mode 100644
index 334b87c..0000000
--- a/libraries/Donations/build.gradle
+++ /dev/null
@@ -1,20 +0,0 @@
-apply plugin: 'android-library'
-
-android {
- compileSdkVersion 21
- buildToolsVersion "21.1.2"
-
- defaultConfig {
- minSdkVersion 16
- targetSdkVersion 21
- }
-
- // Do not abort build if lint finds errors
- lintOptions {
- abortOnError false
- }
-}
-
-dependencies {
- compile 'com.android.support:support-v4:21.0.3'
-}
\ No newline at end of file
diff --git a/libraries/Donations/src/main/AndroidManifest.xml b/libraries/Donations/src/main/AndroidManifest.xml
deleted file mode 100644
index eeae23a..0000000
--- a/libraries/Donations/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/libraries/Donations/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl b/libraries/Donations/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl
deleted file mode 100644
index 2a492f7..0000000
--- a/libraries/Donations/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.android.vending.billing;
-
-import android.os.Bundle;
-
-/**
- * InAppBillingService is the service that provides in-app billing version 3 and beyond.
- * This service provides the following features:
- * 1. Provides a new API to get details of in-app items published for the app including
- * price, type, title and description.
- * 2. The purchase flow is synchronous and purchase information is available immediately
- * after it completes.
- * 3. Purchase information of in-app purchases is maintained within the Google Play system
- * till the purchase is consumed.
- * 4. An API to consume a purchase of an inapp item. All purchases of one-time
- * in-app items are consumable and thereafter can be purchased again.
- * 5. An API to get current purchases of the user immediately. This will not contain any
- * consumed purchases.
- *
- * All calls will give a response code with the following possible values
- * RESULT_OK = 0 - success
- * RESULT_USER_CANCELED = 1 - user pressed back or canceled a dialog
- * RESULT_BILLING_UNAVAILABLE = 3 - this billing API version is not supported for the type requested
- * RESULT_ITEM_UNAVAILABLE = 4 - requested SKU is not available for purchase
- * RESULT_DEVELOPER_ERROR = 5 - invalid arguments provided to the API
- * RESULT_ERROR = 6 - Fatal error during the API action
- * RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned
- * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned
- */
-interface IInAppBillingService {
- /**
- * Checks support for the requested billing API version, package and in-app type.
- * Minimum API version supported by this interface is 3.
- * @param apiVersion the billing version which the app is using
- * @param packageName the package name of the calling app
- * @param type type of the in-app item being purchased "inapp" for one-time purchases
- * and "subs" for subscription.
- * @return RESULT_OK(0) on success, corresponding result code on failures
- */
- int isBillingSupported(int apiVersion, String packageName, String type);
-
- /**
- * Provides details of a list of SKUs
- * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle
- * with a list JSON strings containing the productId, price, title and description.
- * This API can be called with a maximum of 20 SKUs.
- * @param apiVersion billing API version that the Third-party is using
- * @param packageName the package name of the calling app
- * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST"
- * @return Bundle containing the following key-value pairs
- * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
- * failure as listed above.
- * "DETAILS_LIST" with a StringArrayList containing purchase information
- * in JSON format similar to:
- * '{ "productId" : "exampleSku", "type" : "inapp", "price" : "$5.00",
- * "title : "Example Title", "description" : "This is an example description" }'
- */
- Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle);
-
- /**
- * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU,
- * the type, a unique purchase token and an optional developer payload.
- * @param apiVersion billing API version that the app is using
- * @param packageName package name of the calling app
- * @param sku the SKU of the in-app item as published in the developer console
- * @param type the type of the in-app item ("inapp" for one-time purchases
- * and "subs" for subscription).
- * @param developerPayload optional argument to be sent back with the purchase information
- * @return Bundle containing the following key-value pairs
- * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
- * failure as listed above.
- * "BUY_INTENT" - PendingIntent to start the purchase flow
- *
- * The Pending intent should be launched with startIntentSenderForResult. When purchase flow
- * has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
- * If the purchase is successful, the result data will contain the following key-value pairs
- * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
- * failure as listed above.
- * "INAPP_PURCHASE_DATA" - String in JSON format similar to
- * '{"orderId":"12999763169054705758.1371079406387615",
- * "packageName":"com.example.app",
- * "productId":"exampleSku",
- * "purchaseTime":1345678900000,
- * "purchaseToken" : "122333444455555",
- * "developerPayload":"example developer payload" }'
- * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
- * was signed with the private key of the developer
- * TODO: change this to app-specific keys.
- */
- Bundle getBuyIntent(int apiVersion, String packageName, String sku, String type,
- String developerPayload);
-
- /**
- * Returns the current SKUs owned by the user of the type and package name specified along with
- * purchase information and a signature of the data to be validated.
- * This will return all SKUs that have been purchased in V3 and managed items purchased using
- * V1 and V2 that have not been consumed.
- * @param apiVersion billing API version that the app is using
- * @param packageName package name of the calling app
- * @param type the type of the in-app items being requested
- * ("inapp" for one-time purchases and "subs" for subscription).
- * @param continuationToken to be set as null for the first call, if the number of owned
- * skus are too many, a continuationToken is returned in the response bundle.
- * This method can be called again with the continuation token to get the next set of
- * owned skus.
- * @return Bundle containing the following key-value pairs
- * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
- * failure as listed above.
- * "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs
- * "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information
- * "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures
- * of the purchase information
- * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
- * next set of in-app purchases. Only set if the
- * user has more owned skus than the current list.
- */
- Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken);
-
- /**
- * Consume the last purchase of the given SKU. This will result in this item being removed
- * from all subsequent responses to getPurchases() and allow re-purchase of this item.
- * @param apiVersion billing API version that the app is using
- * @param packageName package name of the calling app
- * @param purchaseToken token in the purchase information JSON that identifies the purchase
- * to be consumed
- * @return 0 if consumption succeeded. Appropriate error values for failures.
- */
- int consumePurchase(int apiVersion, String packageName, String purchaseToken);
-}
diff --git a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/DonationsFragment.java b/libraries/Donations/src/main/java/org/sufficientlysecure/donations/DonationsFragment.java
deleted file mode 100644
index 9f700ad..0000000
--- a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/DonationsFragment.java
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (C) 2011-2013 Dominik Schürmann
- *
- * 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.
- */
-
-package org.sufficientlysecure.donations;
-
-import android.content.ActivityNotFoundException;
-import android.view.*;
-import android.widget.*;
-import org.sufficientlysecure.donations.google.util.IabHelper;
-import org.sufficientlysecure.donations.google.util.IabResult;
-
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
-import android.app.AlertDialog;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.util.Log;
-import android.view.View.OnClickListener;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.webkit.WebView.HitTestResult;
-
-import android.content.DialogInterface;
-import android.os.Handler;
-import org.sufficientlysecure.donations.google.util.Purchase;
-
-public class DonationsFragment extends Fragment {
-
- public static final String ARG_DEBUG = "debug";
-
- public static final String ARG_GOOGLE_ENABLED = "googleEnabled";
- public static final String ARG_GOOGLE_PUBKEY = "googlePubkey";
- public static final String ARG_GOOGLE_CATALOG = "googleCatalog";
- public static final String ARG_GOOGLE_CATALOG_VALUES = "googleCatalogValues";
-
- public static final String ARG_PAYPAL_ENABLED = "paypalEnabled";
- public static final String ARG_PAYPAL_USER = "paypalUser";
- public static final String ARG_PAYPAL_CURRENCY_CODE = "paypalCurrencyCode";
- public static final String ARG_PAYPAL_ITEM_NAME = "mPaypalItemName";
-
- public static final String ARG_FLATTR_ENABLED = "flattrEnabled";
- public static final String ARG_FLATTR_PROJECT_URL = "flattrProjectUrl";
- public static final String ARG_FLATTR_URL = "flattrUrl";
-
- private static final String TAG = "Donations Library";
-
- // http://developer.android.com/google/play/billing/billing_testing.html
- private static final String[] CATALOG_DEBUG = new String[]{"android.test.purchased",
- "android.test.canceled", "android.test.refunded", "android.test.item_unavailable"};
-
- private Spinner mGoogleSpinner;
- private TextView mFlattrUrlTextView;
-
- // Google Play helper object
- private IabHelper mHelper;
-
- protected boolean mDebug = false;
-
- protected boolean mGoogleEnabled = false;
- protected String mGooglePubkey = "";
- protected String[] mGgoogleCatalog = new String[]{};
- protected String[] mGoogleCatalogValues = new String[]{};
-
- protected boolean mPaypalEnabled = false;
- protected String mPaypalUser = "";
- protected String mPaypalCurrencyCode = "";
- protected String mPaypalItemName = "";
-
- protected boolean mFlattrEnabled = false;
- protected String mFlattrProjectUrl = "";
- protected String mFlattrUrl = "";
-
- /**
- * Instantiate DonationsFragment.
- *
- * @param debug You can use BuildConfig.DEBUG to propagate the debug flag from your app to the Donations library
- * @param googleEnabled Enabled Google Play donations
- * @param googlePubkey Your Google Play public key
- * @param googleCatalog Possible item names that can be purchased from Google Play
- * @param googleCatalogValues Values for the names
- * @param paypalEnabled Enable PayPal donations
- * @param paypalUser Your PayPal email address
- * @param paypalCurrencyCode Currency code like EUR. See here for other codes:
- * https://developer.paypal.com/webapps/developer/docs/classic/api/currency_codes/#id09A6G0U0GYK
- * @param paypalItemName Display item name on PayPal, like "Donation for NTPSync"
- * @param flattrEnabled Enable Flattr donations
- * @param flattrProjectUrl The project URL used on Flattr
- * @param flattrUrl The Flattr URL to your thing. NOTE: Enter without http://
- * @return DonationsFragment
- */
- public static DonationsFragment newInstance(boolean debug, boolean googleEnabled, String googlePubkey, String[] googleCatalog,
- String[] googleCatalogValues, boolean paypalEnabled, String paypalUser,
- String paypalCurrencyCode, String paypalItemName, boolean flattrEnabled,
- String flattrProjectUrl, String flattrUrl) {
- DonationsFragment donationsFragment = new DonationsFragment();
- Bundle args = new Bundle();
-
- args.putBoolean(ARG_DEBUG, debug);
-
- args.putBoolean(ARG_GOOGLE_ENABLED, googleEnabled);
- args.putString(ARG_GOOGLE_PUBKEY, googlePubkey);
- args.putStringArray(ARG_GOOGLE_CATALOG, googleCatalog);
- args.putStringArray(ARG_GOOGLE_CATALOG_VALUES, googleCatalogValues);
-
- args.putBoolean(ARG_PAYPAL_ENABLED, paypalEnabled);
- args.putString(ARG_PAYPAL_USER, paypalUser);
- args.putString(ARG_PAYPAL_CURRENCY_CODE, paypalCurrencyCode);
- args.putString(ARG_PAYPAL_ITEM_NAME, paypalItemName);
-
- args.putBoolean(ARG_FLATTR_ENABLED, flattrEnabled);
- args.putString(ARG_FLATTR_PROJECT_URL, flattrProjectUrl);
- args.putString(ARG_FLATTR_URL, flattrUrl);
-
- donationsFragment.setArguments(args);
- return donationsFragment;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mDebug = getArguments().getBoolean(ARG_DEBUG);
-
- mGoogleEnabled = getArguments().getBoolean(ARG_GOOGLE_ENABLED);
- mGooglePubkey = getArguments().getString(ARG_GOOGLE_PUBKEY);
- mGgoogleCatalog = getArguments().getStringArray(ARG_GOOGLE_CATALOG);
- mGoogleCatalogValues = getArguments().getStringArray(ARG_GOOGLE_CATALOG_VALUES);
-
- mPaypalEnabled = getArguments().getBoolean(ARG_PAYPAL_ENABLED);
- mPaypalUser = getArguments().getString(ARG_PAYPAL_USER);
- mPaypalCurrencyCode = getArguments().getString(ARG_PAYPAL_CURRENCY_CODE);
- mPaypalItemName = getArguments().getString(ARG_PAYPAL_ITEM_NAME);
-
- mFlattrEnabled = getArguments().getBoolean(ARG_FLATTR_ENABLED);
- mFlattrProjectUrl = getArguments().getString(ARG_FLATTR_PROJECT_URL);
- mFlattrUrl = getArguments().getString(ARG_FLATTR_URL);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.donations__fragment, container, false);
-
- return view;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- /* Flattr */
- if (mFlattrEnabled) {
- // inflate flattr view into stub
- ViewStub flattrViewStub = (ViewStub) getActivity().findViewById(
- R.id.donations__flattr_stub);
- flattrViewStub.inflate();
-
- buildFlattrView();
- }
-
- /* Google */
- if (mGoogleEnabled) {
- // inflate google view into stub
- ViewStub googleViewStub = (ViewStub) getActivity().findViewById(
- R.id.donations__google_stub);
- googleViewStub.inflate();
-
- // choose donation amount
- mGoogleSpinner = (Spinner) getActivity().findViewById(
- R.id.donations__google_android_market_spinner);
- ArrayAdapter adapter;
- if (mDebug) {
- adapter = new ArrayAdapter(getActivity(),
- android.R.layout.simple_spinner_item, CATALOG_DEBUG);
- } else {
- adapter = new ArrayAdapter(getActivity(),
- android.R.layout.simple_spinner_item, mGoogleCatalogValues);
- }
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mGoogleSpinner.setAdapter(adapter);
-
- Button btGoogle = (Button) getActivity().findViewById(
- R.id.donations__google_android_market_donate_button);
- btGoogle.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- donateGoogleOnClick(v);
- }
- });
-
- // Create the helper, passing it our context and the public key to verify signatures with
- if (mDebug)
- Log.d(TAG, "Creating IAB helper.");
- mHelper = new IabHelper(getActivity(), mGooglePubkey);
-
- // enable debug logging (for a production application, you should set this to false).
- mHelper.enableDebugLogging(mDebug);
-
- // Start setup. This is asynchronous and the specified listener
- // will be called once setup completes.
- if (mDebug)
- Log.d(TAG, "Starting setup.");
- mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
- public void onIabSetupFinished(IabResult result) {
- if (mDebug)
- Log.d(TAG, "Setup finished.");
-
- if (!result.isSuccess()) {
- // Oh noes, there was a problem.
- openDialog(android.R.drawable.ic_dialog_alert, R.string.donations__google_android_market_not_supported_title,
- getString(R.string.donations__google_android_market_not_supported));
- return;
- }
-
- // Have we been disposed of in the meantime? If so, quit.
- if (mHelper == null) return;
- }
- });
- }
-
- /* PayPal */
- if (mPaypalEnabled) {
- // inflate paypal view into stub
- ViewStub paypalViewStub = (ViewStub) getActivity().findViewById(
- R.id.donations__paypal_stub);
- paypalViewStub.inflate();
-
- Button btPayPal = (Button) getActivity().findViewById(
- R.id.donations__paypal_donate_button);
- btPayPal.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- donatePayPalOnClick(v);
- }
- });
- }
- }
-
- /**
- * Open dialog
- *
- * @param icon
- * @param title
- * @param message
- */
- void openDialog(int icon, int title, String message) {
- AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
- dialog.setIcon(icon);
- dialog.setTitle(title);
- dialog.setMessage(message);
- dialog.setCancelable(true);
- dialog.setNeutralButton(R.string.donations__button_close,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- });
- dialog.show();
- }
-
- /**
- * Donate button executes donations based on selection in spinner
- *
- * @param view
- */
- public void donateGoogleOnClick(View view) {
- final int index;
- index = mGoogleSpinner.getSelectedItemPosition();
- if (mDebug)
- Log.d(TAG, "selected item in spinner: " + index);
-
- if (mDebug) {
- // when debugging, choose android.test.x item
- mHelper.launchPurchaseFlow(getActivity(),
- CATALOG_DEBUG[index], IabHelper.ITEM_TYPE_INAPP,
- 0, mPurchaseFinishedListener, null);
- } else {
- mHelper.launchPurchaseFlow(getActivity(),
- mGgoogleCatalog[index], IabHelper.ITEM_TYPE_INAPP,
- 0, mPurchaseFinishedListener, null);
- }
- }
-
- // Callback for when a purchase is finished
- IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
- public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
- if (mDebug)
- Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
-
- // if we were disposed of in the meantime, quit.
- if (mHelper == null) return;
-
- if (result.isSuccess()) {
- if (mDebug)
- Log.d(TAG, "Purchase successful.");
-
- // directly consume in-app purchase, so that people can donate multiple times
- mHelper.consumeAsync(purchase, mConsumeFinishedListener);
-
- // show thanks openDialog
- openDialog(android.R.drawable.ic_dialog_info, R.string.donations__thanks_dialog_title,
- getString(R.string.donations__thanks_dialog));
- }
- }
- };
-
- // Called when consumption is complete
- IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
- public void onConsumeFinished(Purchase purchase, IabResult result) {
- if (mDebug)
- Log.d(TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result);
-
- // if we were disposed of in the meantime, quit.
- if (mHelper == null) return;
-
- if (result.isSuccess()) {
- if (mDebug)
- Log.d(TAG, "Consumption successful. Provisioning.");
- }
- if (mDebug)
- Log.d(TAG, "End consumption flow.");
- }
- };
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (mDebug)
- Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
- if (mHelper == null) return;
-
- // Pass on the fragment result to the helper for handling
- if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
- // not handled, so handle it ourselves (here's where you'd
- // perform any handling of activity results not related to in-app
- // billing...
- super.onActivityResult(requestCode, resultCode, data);
- } else {
- if (mDebug)
- Log.d(TAG, "onActivityResult handled by IABUtil.");
- }
- }
-
-
- /**
- * Donate button with PayPal by opening browser with defined URL For possible parameters see:
- * https://developer.paypal.com/webapps/developer/docs/classic/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables/
- *
- * @param view
- */
- public void donatePayPalOnClick(View view) {
- Uri.Builder uriBuilder = new Uri.Builder();
- uriBuilder.scheme("https").authority("www.paypal.com").path("cgi-bin/webscr");
- uriBuilder.appendQueryParameter("cmd", "_donations");
-
- uriBuilder.appendQueryParameter("business", mPaypalUser);
- uriBuilder.appendQueryParameter("lc", "US");
- uriBuilder.appendQueryParameter("item_name", mPaypalItemName);
- uriBuilder.appendQueryParameter("no_note", "1");
- // uriBuilder.appendQueryParameter("no_note", "0");
- // uriBuilder.appendQueryParameter("cn", "Note to the developer");
- uriBuilder.appendQueryParameter("no_shipping", "1");
- uriBuilder.appendQueryParameter("currency_code", mPaypalCurrencyCode);
- Uri payPalUri = uriBuilder.build();
-
- if (mDebug)
- Log.d(TAG, "Opening the browser with the url: " + payPalUri.toString());
-
- // Start your favorite browser
- try {
- Intent viewIntent = new Intent(Intent.ACTION_VIEW, payPalUri);
- startActivity(viewIntent);
- } catch (ActivityNotFoundException e) {
- openDialog(android.R.drawable.ic_dialog_alert, R.string.donations__alert_dialog_title,
- getString(R.string.donations__alert_dialog_no_browser));
- }
- }
-
- /**
- * Build view for Flattr. see Flattr API for more information:
- * http://developers.flattr.net/button/
- */
- @SuppressLint("SetJavaScriptEnabled")
- @TargetApi(11)
- private void buildFlattrView() {
- final FrameLayout mLoadingFrame;
- final WebView mFlattrWebview;
-
- mFlattrWebview = (WebView) getActivity().findViewById(R.id.donations__flattr_webview);
- mLoadingFrame = (FrameLayout) getActivity().findViewById(R.id.donations__loading_frame);
-
- // disable hardware acceleration for this webview to get transparent background working
- if (Build.VERSION.SDK_INT >= 11) {
- mFlattrWebview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
- }
-
- // define own webview client to override loading behaviour
- mFlattrWebview.setWebViewClient(new WebViewClient() {
- /**
- * Open all links in browser, not in webview
- */
- @Override
- public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
- try {
- view.getContext().startActivity(
- new Intent(Intent.ACTION_VIEW, Uri.parse(urlNewString)));
- } catch (ActivityNotFoundException e) {
- openDialog(android.R.drawable.ic_dialog_alert, R.string.donations__alert_dialog_title,
- getString(R.string.donations__alert_dialog_no_browser));
- }
-
- return false;
- }
-
- /**
- * Links in the flattr iframe should load in the browser not in the iframe itself,
- * http:/
- * /stackoverflow.com/questions/5641626/how-to-get-webview-iframe-link-to-launch-the
- * -browser
- */
- @Override
- public void onLoadResource(WebView view, String url) {
- if (url.contains("flattr")) {
- HitTestResult result = view.getHitTestResult();
- if (result != null && result.getType() > 0) {
- try {
- view.getContext().startActivity(
- new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
- } catch (ActivityNotFoundException e) {
- openDialog(android.R.drawable.ic_dialog_alert, R.string.donations__alert_dialog_title,
- getString(R.string.donations__alert_dialog_no_browser));
- }
- view.stopLoading();
- }
- }
- }
-
- /**
- * After loading is done, remove frame with progress circle
- */
- @Override
- public void onPageFinished(WebView view, String url) {
- // remove loading frame, show webview
- if (mLoadingFrame.getVisibility() == View.VISIBLE) {
- mLoadingFrame.setVisibility(View.GONE);
- mFlattrWebview.setVisibility(View.VISIBLE);
- }
- }
- });
-
- // get flattr values from xml config
- String projectUrl = mFlattrProjectUrl;
- String flattrUrl = this.mFlattrUrl;
-
- // make text white and background transparent
- String htmlStart = " ";
-
- // https is not working in android 2.1 and 2.2
- String flattrScheme;
- if (Build.VERSION.SDK_INT >= 9) {
- flattrScheme = "https://";
- } else {
- flattrScheme = "http://";
- }
-
- // set url of flattr link
- mFlattrUrlTextView = (TextView) getActivity().findViewById(R.id.donations__flattr_url);
- mFlattrUrlTextView.setText(flattrScheme + flattrUrl);
-
- String flattrJavascript = "";
- String htmlMiddle = "
";
-
- String flattrCode = htmlStart + flattrJavascript + htmlMiddle + flattrHtml + htmlEnd;
-
- mFlattrWebview.getSettings().setJavaScriptEnabled(true);
-
- mFlattrWebview.loadData(flattrCode, "text/html", "utf-8");
-
- // disable scroll on touch
- mFlattrWebview.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View view, MotionEvent motionEvent) {
- // already handled (returns true) when moving
- return (motionEvent.getAction() == MotionEvent.ACTION_MOVE);
- }
- });
-
- // make background of webview transparent
- // has to be called AFTER loadData
- // http://stackoverflow.com/questions/5003156/android-webview-style-background-colortransparent-ignored-on-android-2-2
- mFlattrWebview.setBackgroundColor(0x00000000);
- }
-}
diff --git a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Base64.java b/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Base64.java
deleted file mode 100644
index df6120e..0000000
--- a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Base64.java
+++ /dev/null
@@ -1,570 +0,0 @@
-// Portions copyright 2002, Google, Inc.
-//
-// 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.
-
-package org.sufficientlysecure.donations.google.util;
-
-// This code was converted from code at http://iharder.sourceforge.net/base64/
-// Lots of extraneous features were removed.
-/* The original code said:
- *
- * I am placing this code in the Public Domain. Do with it as you will.
- * This software comes with no guarantees or warranties but with
- * plenty of well-wishing instead!
- * Please visit
- * http://iharder.net/xmlizable
- * periodically to check for updates or to contribute improvements.
- *
- *
- * @author Robert Harder
- * @author rharder@usa.net
- * @version 1.3
- */
-
-/**
- * Base64 converter class. This code is not a complete MIME encoder;
- * it simply converts binary data to base64 data and back.
- *
- *
Note {@link CharBase64} is a GWT-compatible implementation of this
- * class.
- */
-public class Base64 {
- /** Specify encoding (value is {@code true}). */
- public final static boolean ENCODE = true;
-
- /** Specify decoding (value is {@code false}). */
- public final static boolean DECODE = false;
-
- /** The equals sign (=) as a byte. */
- private final static byte EQUALS_SIGN = (byte) '=';
-
- /** The new line character (\n) as a byte. */
- private final static byte NEW_LINE = (byte) '\n';
-
- /**
- * The 64 valid Base64 values.
- */
- private final static byte[] ALPHABET =
- {(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
- (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K',
- (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P',
- (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
- (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
- (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e',
- (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',
- (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o',
- (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't',
- (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y',
- (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3',
- (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8',
- (byte) '9', (byte) '+', (byte) '/'};
-
- /**
- * The 64 valid web safe Base64 values.
- */
- private final static byte[] WEBSAFE_ALPHABET =
- {(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
- (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K',
- (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P',
- (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
- (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
- (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e',
- (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',
- (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o',
- (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't',
- (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y',
- (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3',
- (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8',
- (byte) '9', (byte) '-', (byte) '_'};
-
- /**
- * Translates a Base64 value to either its 6-bit reconstruction value
- * or a negative number indicating some other meaning.
- **/
- private final static byte[] DECODABET = {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
- -5, -5, // Whitespace: Tab and Linefeed
- -9, -9, // Decimal 11 - 12
- -5, // Whitespace: Carriage Return
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
- -9, -9, -9, -9, -9, // Decimal 27 - 31
- -5, // Whitespace: Space
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
- 62, // Plus sign at decimal 43
- -9, -9, -9, // Decimal 44 - 46
- 63, // Slash at decimal 47
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
- -9, -9, -9, // Decimal 58 - 60
- -1, // Equals sign at decimal 61
- -9, -9, -9, // Decimal 62 - 64
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
- -9, -9, -9, -9, -9, -9, // Decimal 91 - 96
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
- -9, -9, -9, -9, -9 // Decimal 123 - 127
- /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
- };
-
- /** The web safe decodabet */
- private final static byte[] WEBSAFE_DECODABET =
- {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
- -5, -5, // Whitespace: Tab and Linefeed
- -9, -9, // Decimal 11 - 12
- -5, // Whitespace: Carriage Return
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
- -9, -9, -9, -9, -9, // Decimal 27 - 31
- -5, // Whitespace: Space
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 44
- 62, // Dash '-' sign at decimal 45
- -9, -9, // Decimal 46-47
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
- -9, -9, -9, // Decimal 58 - 60
- -1, // Equals sign at decimal 61
- -9, -9, -9, // Decimal 62 - 64
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
- -9, -9, -9, -9, // Decimal 91-94
- 63, // Underscore '_' at decimal 95
- -9, // Decimal 96
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
- -9, -9, -9, -9, -9 // Decimal 123 - 127
- /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
- };
-
- // Indicates white space in encoding
- private final static byte WHITE_SPACE_ENC = -5;
- // Indicates equals sign in encoding
- private final static byte EQUALS_SIGN_ENC = -1;
-
- /** Defeats instantiation. */
- private Base64() {
- }
-
- /* ******** E N C O D I N G M E T H O D S ******** */
-
- /**
- * Encodes up to three bytes of the array source
- * and writes the resulting four Base64 bytes to destination.
- * The source and destination arrays can be manipulated
- * anywhere along their length by specifying
- * srcOffset and destOffset.
- * This method does not check to make sure your arrays
- * are large enough to accommodate srcOffset + 3 for
- * the source array or destOffset + 4 for
- * the destination array.
- * The actual number of significant bytes in your array is
- * given by numSigBytes.
- *
- * @param source the array to convert
- * @param srcOffset the index where conversion begins
- * @param numSigBytes the number of significant bytes in your array
- * @param destination the array to hold the conversion
- * @param destOffset the index where output will be put
- * @param alphabet is the encoding alphabet
- * @return the destination array
- * @since 1.3
- */
- private static byte[] encode3to4(byte[] source, int srcOffset,
- int numSigBytes, byte[] destination, int destOffset, byte[] alphabet) {
- // 1 2 3
- // 01234567890123456789012345678901 Bit position
- // --------000000001111111122222222 Array position from threeBytes
- // --------| || || || | Six bit groups to index alphabet
- // >>18 >>12 >> 6 >> 0 Right shift necessary
- // 0x3f 0x3f 0x3f Additional AND
-
- // Create buffer with zero-padding if there are only one or two
- // significant bytes passed in the array.
- // We have to shift left 24 in order to flush out the 1's that appear
- // when Java treats a value as negative that is cast from a byte to an int.
- int inBuff =
- (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0)
- | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0)
- | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
-
- switch (numSigBytes) {
- case 3:
- destination[destOffset] = alphabet[(inBuff >>> 18)];
- destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
- destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
- destination[destOffset + 3] = alphabet[(inBuff) & 0x3f];
- return destination;
- case 2:
- destination[destOffset] = alphabet[(inBuff >>> 18)];
- destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
- destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
- destination[destOffset + 3] = EQUALS_SIGN;
- return destination;
- case 1:
- destination[destOffset] = alphabet[(inBuff >>> 18)];
- destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
- destination[destOffset + 2] = EQUALS_SIGN;
- destination[destOffset + 3] = EQUALS_SIGN;
- return destination;
- default:
- return destination;
- } // end switch
- } // end encode3to4
-
- /**
- * Encodes a byte array into Base64 notation.
- * Equivalent to calling
- * {@code encodeBytes(source, 0, source.length)}
- *
- * @param source The data to convert
- * @since 1.4
- */
- public static String encode(byte[] source) {
- return encode(source, 0, source.length, ALPHABET, true);
- }
-
- /**
- * Encodes a byte array into web safe Base64 notation.
- *
- * @param source The data to convert
- * @param doPadding is {@code true} to pad result with '=' chars
- * if it does not fall on 3 byte boundaries
- */
- public static String encodeWebSafe(byte[] source, boolean doPadding) {
- return encode(source, 0, source.length, WEBSAFE_ALPHABET, doPadding);
- }
-
- /**
- * Encodes a byte array into Base64 notation.
- *
- * @param source the data to convert
- * @param off offset in array where conversion should begin
- * @param len length of data to convert
- * @param alphabet the encoding alphabet
- * @param doPadding is {@code true} to pad result with '=' chars
- * if it does not fall on 3 byte boundaries
- * @since 1.4
- */
- public static String encode(byte[] source, int off, int len, byte[] alphabet,
- boolean doPadding) {
- byte[] outBuff = encode(source, off, len, alphabet, Integer.MAX_VALUE);
- int outLen = outBuff.length;
-
- // If doPadding is false, set length to truncate '='
- // padding characters
- while (doPadding == false && outLen > 0) {
- if (outBuff[outLen - 1] != '=') {
- break;
- }
- outLen -= 1;
- }
-
- return new String(outBuff, 0, outLen);
- }
-
- /**
- * Encodes a byte array into Base64 notation.
- *
- * @param source the data to convert
- * @param off offset in array where conversion should begin
- * @param len length of data to convert
- * @param alphabet is the encoding alphabet
- * @param maxLineLength maximum length of one line.
- * @return the BASE64-encoded byte array
- */
- public static byte[] encode(byte[] source, int off, int len, byte[] alphabet,
- int maxLineLength) {
- int lenDiv3 = (len + 2) / 3; // ceil(len / 3)
- int len43 = lenDiv3 * 4;
- byte[] outBuff = new byte[len43 // Main 4:3
- + (len43 / maxLineLength)]; // New lines
-
- int d = 0;
- int e = 0;
- int len2 = len - 2;
- int lineLength = 0;
- for (; d < len2; d += 3, e += 4) {
-
- // The following block of code is the same as
- // encode3to4( source, d + off, 3, outBuff, e, alphabet );
- // but inlined for faster encoding (~20% improvement)
- int inBuff =
- ((source[d + off] << 24) >>> 8)
- | ((source[d + 1 + off] << 24) >>> 16)
- | ((source[d + 2 + off] << 24) >>> 24);
- outBuff[e] = alphabet[(inBuff >>> 18)];
- outBuff[e + 1] = alphabet[(inBuff >>> 12) & 0x3f];
- outBuff[e + 2] = alphabet[(inBuff >>> 6) & 0x3f];
- outBuff[e + 3] = alphabet[(inBuff) & 0x3f];
-
- lineLength += 4;
- if (lineLength == maxLineLength) {
- outBuff[e + 4] = NEW_LINE;
- e++;
- lineLength = 0;
- } // end if: end of line
- } // end for: each piece of array
-
- if (d < len) {
- encode3to4(source, d + off, len - d, outBuff, e, alphabet);
-
- lineLength += 4;
- if (lineLength == maxLineLength) {
- // Add a last newline
- outBuff[e + 4] = NEW_LINE;
- e++;
- }
- e += 4;
- }
-
- assert (e == outBuff.length);
- return outBuff;
- }
-
-
- /* ******** D E C O D I N G M E T H O D S ******** */
-
-
- /**
- * Decodes four bytes from array source
- * and writes the resulting bytes (up to three of them)
- * to destination.
- * The source and destination arrays can be manipulated
- * anywhere along their length by specifying
- * srcOffset and destOffset.
- * This method does not check to make sure your arrays
- * are large enough to accommodate srcOffset + 4 for
- * the source array or destOffset + 3 for
- * the destination array.
- * This method returns the actual number of bytes that
- * were converted from the Base64 encoding.
- *
- *
- * @param source the array to convert
- * @param srcOffset the index where conversion begins
- * @param destination the array to hold the conversion
- * @param destOffset the index where output will be put
- * @param decodabet the decodabet for decoding Base64 content
- * @return the number of decoded bytes converted
- * @since 1.3
- */
- private static int decode4to3(byte[] source, int srcOffset,
- byte[] destination, int destOffset, byte[] decodabet) {
- // Example: Dk==
- if (source[srcOffset + 2] == EQUALS_SIGN) {
- int outBuff =
- ((decodabet[source[srcOffset]] << 24) >>> 6)
- | ((decodabet[source[srcOffset + 1]] << 24) >>> 12);
-
- destination[destOffset] = (byte) (outBuff >>> 16);
- return 1;
- } else if (source[srcOffset + 3] == EQUALS_SIGN) {
- // Example: DkL=
- int outBuff =
- ((decodabet[source[srcOffset]] << 24) >>> 6)
- | ((decodabet[source[srcOffset + 1]] << 24) >>> 12)
- | ((decodabet[source[srcOffset + 2]] << 24) >>> 18);
-
- destination[destOffset] = (byte) (outBuff >>> 16);
- destination[destOffset + 1] = (byte) (outBuff >>> 8);
- return 2;
- } else {
- // Example: DkLE
- int outBuff =
- ((decodabet[source[srcOffset]] << 24) >>> 6)
- | ((decodabet[source[srcOffset + 1]] << 24) >>> 12)
- | ((decodabet[source[srcOffset + 2]] << 24) >>> 18)
- | ((decodabet[source[srcOffset + 3]] << 24) >>> 24);
-
- destination[destOffset] = (byte) (outBuff >> 16);
- destination[destOffset + 1] = (byte) (outBuff >> 8);
- destination[destOffset + 2] = (byte) (outBuff);
- return 3;
- }
- } // end decodeToBytes
-
-
- /**
- * Decodes data from Base64 notation.
- *
- * @param s the string to decode (decoded in default encoding)
- * @return the decoded data
- * @since 1.4
- */
- public static byte[] decode(String s) throws Base64DecoderException {
- byte[] bytes = s.getBytes();
- return decode(bytes, 0, bytes.length);
- }
-
- /**
- * Decodes data from web safe Base64 notation.
- * Web safe encoding uses '-' instead of '+', '_' instead of '/'
- *
- * @param s the string to decode (decoded in default encoding)
- * @return the decoded data
- */
- public static byte[] decodeWebSafe(String s) throws Base64DecoderException {
- byte[] bytes = s.getBytes();
- return decodeWebSafe(bytes, 0, bytes.length);
- }
-
- /**
- * Decodes Base64 content in byte array format and returns
- * the decoded byte array.
- *
- * @param source The Base64 encoded data
- * @return decoded data
- * @since 1.3
- * @throws Base64DecoderException
- */
- public static byte[] decode(byte[] source) throws Base64DecoderException {
- return decode(source, 0, source.length);
- }
-
- /**
- * Decodes web safe Base64 content in byte array format and returns
- * the decoded data.
- * Web safe encoding uses '-' instead of '+', '_' instead of '/'
- *
- * @param source the string to decode (decoded in default encoding)
- * @return the decoded data
- */
- public static byte[] decodeWebSafe(byte[] source)
- throws Base64DecoderException {
- return decodeWebSafe(source, 0, source.length);
- }
-
- /**
- * Decodes Base64 content in byte array format and returns
- * the decoded byte array.
- *
- * @param source the Base64 encoded data
- * @param off the offset of where to begin decoding
- * @param len the length of characters to decode
- * @return decoded data
- * @since 1.3
- * @throws Base64DecoderException
- */
- public static byte[] decode(byte[] source, int off, int len)
- throws Base64DecoderException {
- return decode(source, off, len, DECODABET);
- }
-
- /**
- * Decodes web safe Base64 content in byte array format and returns
- * the decoded byte array.
- * Web safe encoding uses '-' instead of '+', '_' instead of '/'
- *
- * @param source the Base64 encoded data
- * @param off the offset of where to begin decoding
- * @param len the length of characters to decode
- * @return decoded data
- */
- public static byte[] decodeWebSafe(byte[] source, int off, int len)
- throws Base64DecoderException {
- return decode(source, off, len, WEBSAFE_DECODABET);
- }
-
- /**
- * Decodes Base64 content using the supplied decodabet and returns
- * the decoded byte array.
- *
- * @param source the Base64 encoded data
- * @param off the offset of where to begin decoding
- * @param len the length of characters to decode
- * @param decodabet the decodabet for decoding Base64 content
- * @return decoded data
- */
- public static byte[] decode(byte[] source, int off, int len, byte[] decodabet)
- throws Base64DecoderException {
- int len34 = len * 3 / 4;
- byte[] outBuff = new byte[2 + len34]; // Upper limit on size of output
- int outBuffPosn = 0;
-
- byte[] b4 = new byte[4];
- int b4Posn = 0;
- int i = 0;
- byte sbiCrop = 0;
- byte sbiDecode = 0;
- for (i = 0; i < len; i++) {
- sbiCrop = (byte) (source[i + off] & 0x7f); // Only the low seven bits
- sbiDecode = decodabet[sbiCrop];
-
- if (sbiDecode >= WHITE_SPACE_ENC) { // White space Equals sign or better
- if (sbiDecode >= EQUALS_SIGN_ENC) {
- // An equals sign (for padding) must not occur at position 0 or 1
- // and must be the last byte[s] in the encoded value
- if (sbiCrop == EQUALS_SIGN) {
- int bytesLeft = len - i;
- byte lastByte = (byte) (source[len - 1 + off] & 0x7f);
- if (b4Posn == 0 || b4Posn == 1) {
- throw new Base64DecoderException(
- "invalid padding byte '=' at byte offset " + i);
- } else if ((b4Posn == 3 && bytesLeft > 2)
- || (b4Posn == 4 && bytesLeft > 1)) {
- throw new Base64DecoderException(
- "padding byte '=' falsely signals end of encoded value "
- + "at offset " + i);
- } else if (lastByte != EQUALS_SIGN && lastByte != NEW_LINE) {
- throw new Base64DecoderException(
- "encoded value has invalid trailing byte");
- }
- break;
- }
-
- b4[b4Posn++] = sbiCrop;
- if (b4Posn == 4) {
- outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
- b4Posn = 0;
- }
- }
- } else {
- throw new Base64DecoderException("Bad Base64 input character at " + i
- + ": " + source[i + off] + "(decimal)");
- }
- }
-
- // Because web safe encoding allows non padding base64 encodes, we
- // need to pad the rest of the b4 buffer with equal signs when
- // b4Posn != 0. There can be at most 2 equal signs at the end of
- // four characters, so the b4 buffer must have two or three
- // characters. This also catches the case where the input is
- // padded with EQUALS_SIGN
- if (b4Posn != 0) {
- if (b4Posn == 1) {
- throw new Base64DecoderException("single trailing character at offset "
- + (len - 1));
- }
- b4[b4Posn++] = EQUALS_SIGN;
- outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
- }
-
- byte[] out = new byte[outBuffPosn];
- System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
- return out;
- }
-}
diff --git a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Base64DecoderException.java b/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Base64DecoderException.java
deleted file mode 100644
index 86a8f48..0000000
--- a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Base64DecoderException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2002, Google, Inc.
-//
-// 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.
-
-package org.sufficientlysecure.donations.google.util;
-
-/**
- * Exception thrown when encountering an invalid Base64 input character.
- *
- * @author nelson
- */
-public class Base64DecoderException extends Exception {
- public Base64DecoderException() {
- super();
- }
-
- public Base64DecoderException(String s) {
- super(s);
- }
-
- private static final long serialVersionUID = 1L;
-}
diff --git a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/IabException.java b/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/IabException.java
deleted file mode 100644
index 6bbd378..0000000
--- a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/IabException.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (c) 2012 Google Inc.
- *
- * 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.
- */
-
-package org.sufficientlysecure.donations.google.util;
-
-/**
- * Exception thrown when something went wrong with in-app billing.
- * An IabException has an associated IabResult (an error).
- * To get the IAB result that caused this exception to be thrown,
- * call {@link #getResult()}.
- */
-public class IabException extends Exception {
- IabResult mResult;
-
- public IabException(IabResult r) {
- this(r, null);
- }
- public IabException(int response, String message) {
- this(new IabResult(response, message));
- }
- public IabException(IabResult r, Exception cause) {
- super(r.getMessage(), cause);
- mResult = r;
- }
- public IabException(int response, String message, Exception cause) {
- this(new IabResult(response, message), cause);
- }
-
- /** Returns the IAB result (error) that this exception signals. */
- public IabResult getResult() { return mResult; }
-}
\ No newline at end of file
diff --git a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/IabHelper.java b/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/IabHelper.java
deleted file mode 100644
index 1506cd6..0000000
--- a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/IabHelper.java
+++ /dev/null
@@ -1,991 +0,0 @@
-/* Copyright (c) 2012 Google Inc.
- *
- * 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.
- */
-
-package org.sufficientlysecure.donations.google.util;
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentSender.SendIntentException;
-import android.content.ServiceConnection;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.vending.billing.IInAppBillingService;
-
-import org.json.JSONException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Provides convenience methods for in-app billing. You can create one instance of this
- * class for your application and use it to process in-app billing operations.
- * It provides synchronous (blocking) and asynchronous (non-blocking) methods for
- * many common in-app billing operations, as well as automatic signature
- * verification.
- *
- * After instantiating, you must perform setup in order to start using the object.
- * To perform setup, call the {@link #startSetup} method and provide a listener;
- * that listener will be notified when setup is complete, after which (and not before)
- * you may call other methods.
- *
- * After setup is complete, you will typically want to request an inventory of owned
- * items and subscriptions. See {@link #queryInventory}, {@link #queryInventoryAsync}
- * and related methods.
- *
- * When you are done with this object, don't forget to call {@link #dispose}
- * to ensure proper cleanup. This object holds a binding to the in-app billing
- * service, which will leak unless you dispose of it correctly. If you created
- * the object on an Activity's onCreate method, then the recommended
- * place to dispose of it is the Activity's onDestroy method.
- *
- * A note about threading: When using this object from a background thread, you may
- * call the blocking versions of methods; when using from a UI thread, call
- * only the asynchronous versions and handle the results via callbacks.
- * Also, notice that you can only call one asynchronous operation at a time;
- * attempting to start a second asynchronous operation while the first one
- * has not yet completed will result in an exception being thrown.
- *
- * @author Bruno Oliveira (Google)
- *
- */
-public class IabHelper {
- // Is debug logging enabled?
- boolean mDebugLog = false;
- String mDebugTag = "IabHelper";
-
- // Is setup done?
- boolean mSetupDone = false;
-
- // Has this object been disposed of? (If so, we should ignore callbacks, etc)
- boolean mDisposed = false;
-
- // Are subscriptions supported?
- boolean mSubscriptionsSupported = false;
-
- // Is an asynchronous operation in progress?
- // (only one at a time can be in progress)
- boolean mAsyncInProgress = false;
-
- // (for logging/debugging)
- // if mAsyncInProgress == true, what asynchronous operation is in progress?
- String mAsyncOperation = "";
-
- // Context we were passed during initialization
- Context mContext;
-
- // Connection to the service
- IInAppBillingService mService;
- ServiceConnection mServiceConn;
-
- // The request code used to launch purchase flow
- int mRequestCode;
-
- // The item type of the current purchase flow
- String mPurchasingItemType;
-
- // Public key for verifying signature, in base64 encoding
- String mSignatureBase64 = null;
-
- // Billing response codes
- public static final int BILLING_RESPONSE_RESULT_OK = 0;
- public static final int BILLING_RESPONSE_RESULT_USER_CANCELED = 1;
- public static final int BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE = 3;
- public static final int BILLING_RESPONSE_RESULT_ITEM_UNAVAILABLE = 4;
- public static final int BILLING_RESPONSE_RESULT_DEVELOPER_ERROR = 5;
- public static final int BILLING_RESPONSE_RESULT_ERROR = 6;
- public static final int BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED = 7;
- public static final int BILLING_RESPONSE_RESULT_ITEM_NOT_OWNED = 8;
-
- // IAB Helper error codes
- public static final int IABHELPER_ERROR_BASE = -1000;
- public static final int IABHELPER_REMOTE_EXCEPTION = -1001;
- public static final int IABHELPER_BAD_RESPONSE = -1002;
- public static final int IABHELPER_VERIFICATION_FAILED = -1003;
- public static final int IABHELPER_SEND_INTENT_FAILED = -1004;
- public static final int IABHELPER_USER_CANCELLED = -1005;
- public static final int IABHELPER_UNKNOWN_PURCHASE_RESPONSE = -1006;
- public static final int IABHELPER_MISSING_TOKEN = -1007;
- public static final int IABHELPER_UNKNOWN_ERROR = -1008;
- public static final int IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE = -1009;
- public static final int IABHELPER_INVALID_CONSUMPTION = -1010;
-
- // Keys for the responses from InAppBillingService
- public static final String RESPONSE_CODE = "RESPONSE_CODE";
- public static final String RESPONSE_GET_SKU_DETAILS_LIST = "DETAILS_LIST";
- public static final String RESPONSE_BUY_INTENT = "BUY_INTENT";
- public static final String RESPONSE_INAPP_PURCHASE_DATA = "INAPP_PURCHASE_DATA";
- public static final String RESPONSE_INAPP_SIGNATURE = "INAPP_DATA_SIGNATURE";
- public static final String RESPONSE_INAPP_ITEM_LIST = "INAPP_PURCHASE_ITEM_LIST";
- public static final String RESPONSE_INAPP_PURCHASE_DATA_LIST = "INAPP_PURCHASE_DATA_LIST";
- public static final String RESPONSE_INAPP_SIGNATURE_LIST = "INAPP_DATA_SIGNATURE_LIST";
- public static final String INAPP_CONTINUATION_TOKEN = "INAPP_CONTINUATION_TOKEN";
-
- // Item types
- public static final String ITEM_TYPE_INAPP = "inapp";
- public static final String ITEM_TYPE_SUBS = "subs";
-
- // some fields on the getSkuDetails response bundle
- public static final String GET_SKU_DETAILS_ITEM_LIST = "ITEM_ID_LIST";
- public static final String GET_SKU_DETAILS_ITEM_TYPE_LIST = "ITEM_TYPE_LIST";
-
- /**
- * Creates an instance. After creation, it will not yet be ready to use. You must perform
- * setup by calling {@link #startSetup} and wait for setup to complete. This constructor does not
- * block and is safe to call from a UI thread.
- *
- * @param ctx Your application or Activity context. Needed to bind to the in-app billing service.
- * @param base64PublicKey Your application's public key, encoded in base64.
- * This is used for verification of purchase signatures. You can find your app's base64-encoded
- * public key in your application's page on Google Play Developer Console. Note that this
- * is NOT your "developer public key".
- */
- public IabHelper(Context ctx, String base64PublicKey) {
- mContext = ctx.getApplicationContext();
- mSignatureBase64 = base64PublicKey;
- logDebug("IAB helper created.");
- }
-
- /**
- * Enables or disable debug logging through LogCat.
- */
- public void enableDebugLogging(boolean enable, String tag) {
- checkNotDisposed();
- mDebugLog = enable;
- mDebugTag = tag;
- }
-
- public void enableDebugLogging(boolean enable) {
- checkNotDisposed();
- mDebugLog = enable;
- }
-
- /**
- * Callback for setup process. This listener's {@link #onIabSetupFinished} method is called
- * when the setup process is complete.
- */
- public interface OnIabSetupFinishedListener {
- /**
- * Called to notify that setup is complete.
- *
- * @param result The result of the setup process.
- */
- public void onIabSetupFinished(IabResult result);
- }
-
- /**
- * Starts the setup process. This will start up the setup process asynchronously.
- * You will be notified through the listener when the setup process is complete.
- * This method is safe to call from a UI thread.
- *
- * @param listener The listener to notify when the setup process is complete.
- */
- public void startSetup(final OnIabSetupFinishedListener listener) {
- // If already set up, can't do it again.
- checkNotDisposed();
- if (mSetupDone) throw new IllegalStateException("IAB helper is already set up.");
-
- // Connection to IAB service
- logDebug("Starting in-app billing setup.");
- mServiceConn = new ServiceConnection() {
- @Override
- public void onServiceDisconnected(ComponentName name) {
- logDebug("Billing service disconnected.");
- mService = null;
- }
-
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- if (mDisposed) return;
- logDebug("Billing service connected.");
- mService = IInAppBillingService.Stub.asInterface(service);
- String packageName = mContext.getPackageName();
- try {
- logDebug("Checking for in-app billing 3 support.");
-
- // check for in-app billing v3 support
- int response = mService.isBillingSupported(3, packageName, ITEM_TYPE_INAPP);
- if (response != BILLING_RESPONSE_RESULT_OK) {
- if (listener != null) listener.onIabSetupFinished(new IabResult(response,
- "Error checking for billing v3 support."));
-
- // if in-app purchases aren't supported, neither are subscriptions.
- mSubscriptionsSupported = false;
- return;
- }
- logDebug("In-app billing version 3 supported for " + packageName);
-
- // check for v3 subscriptions support
- response = mService.isBillingSupported(3, packageName, ITEM_TYPE_SUBS);
- if (response == BILLING_RESPONSE_RESULT_OK) {
- logDebug("Subscriptions AVAILABLE.");
- mSubscriptionsSupported = true;
- }
- else {
- logDebug("Subscriptions NOT AVAILABLE. Response: " + response);
- }
-
- mSetupDone = true;
- }
- catch (RemoteException e) {
- if (listener != null) {
- listener.onIabSetupFinished(new IabResult(IABHELPER_REMOTE_EXCEPTION,
- "RemoteException while setting up in-app billing."));
- }
- e.printStackTrace();
- return;
- }
-
- if (listener != null) {
- listener.onIabSetupFinished(new IabResult(BILLING_RESPONSE_RESULT_OK, "Setup successful."));
- }
- }
- };
-
- Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
- if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) {
- // service available to handle that Intent
- mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
- }
- else {
- // no service available to handle that Intent
- if (listener != null) {
- listener.onIabSetupFinished(
- new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE,
- "Billing service unavailable on device."));
- }
- }
- }
-
- /**
- * Dispose of object, releasing resources. It's very important to call this
- * method when you are done with this object. It will release any resources
- * used by it such as service connections. Naturally, once the object is
- * disposed of, it can't be used again.
- */
- public void dispose() {
- logDebug("Disposing.");
- mSetupDone = false;
- if (mServiceConn != null) {
- logDebug("Unbinding from service.");
- if (mContext != null) mContext.unbindService(mServiceConn);
- }
- mDisposed = true;
- mContext = null;
- mServiceConn = null;
- mService = null;
- mPurchaseListener = null;
- }
-
- private void checkNotDisposed() {
- if (mDisposed) throw new IllegalStateException("IabHelper was disposed of, so it cannot be used.");
- }
-
- /** Returns whether subscriptions are supported. */
- public boolean subscriptionsSupported() {
- checkNotDisposed();
- return mSubscriptionsSupported;
- }
-
-
- /**
- * Callback that notifies when a purchase is finished.
- */
- public interface OnIabPurchaseFinishedListener {
- /**
- * Called to notify that an in-app purchase finished. If the purchase was successful,
- * then the sku parameter specifies which item was purchased. If the purchase failed,
- * the sku and extraData parameters may or may not be null, depending on how far the purchase
- * process went.
- *
- * @param result The result of the purchase.
- * @param info The purchase information (null if purchase failed)
- */
- public void onIabPurchaseFinished(IabResult result, Purchase info);
- }
-
- // The listener registered on launchPurchaseFlow, which we have to call back when
- // the purchase finishes
- OnIabPurchaseFinishedListener mPurchaseListener;
-
- public void launchPurchaseFlow(Activity act, String sku, int requestCode, OnIabPurchaseFinishedListener listener) {
- launchPurchaseFlow(act, sku, requestCode, listener, "");
- }
-
- public void launchPurchaseFlow(Activity act, String sku, int requestCode,
- OnIabPurchaseFinishedListener listener, String extraData) {
- launchPurchaseFlow(act, sku, ITEM_TYPE_INAPP, requestCode, listener, extraData);
- }
-
- public void launchSubscriptionPurchaseFlow(Activity act, String sku, int requestCode,
- OnIabPurchaseFinishedListener listener) {
- launchSubscriptionPurchaseFlow(act, sku, requestCode, listener, "");
- }
-
- public void launchSubscriptionPurchaseFlow(Activity act, String sku, int requestCode,
- OnIabPurchaseFinishedListener listener, String extraData) {
- launchPurchaseFlow(act, sku, ITEM_TYPE_SUBS, requestCode, listener, extraData);
- }
-
- /**
- * Initiate the UI flow for an in-app purchase. Call this method to initiate an in-app purchase,
- * which will involve bringing up the Google Play screen. The calling activity will be paused while
- * the user interacts with Google Play, and the result will be delivered via the activity's
- * {@link android.app.Activity#onActivityResult} method, at which point you must call
- * this object's {@link #handleActivityResult} method to continue the purchase flow. This method
- * MUST be called from the UI thread of the Activity.
- *
- * @param act The calling activity.
- * @param sku The sku of the item to purchase.
- * @param itemType indicates if it's a product or a subscription (ITEM_TYPE_INAPP or ITEM_TYPE_SUBS)
- * @param requestCode A request code (to differentiate from other responses --
- * as in {@link android.app.Activity#startActivityForResult}).
- * @param listener The listener to notify when the purchase process finishes
- * @param extraData Extra data (developer payload), which will be returned with the purchase data
- * when the purchase completes. This extra data will be permanently bound to that purchase
- * and will always be returned when the purchase is queried.
- */
- public void launchPurchaseFlow(Activity act, String sku, String itemType, int requestCode,
- OnIabPurchaseFinishedListener listener, String extraData) {
- checkNotDisposed();
- checkSetupDone("launchPurchaseFlow");
- flagStartAsync("launchPurchaseFlow");
- IabResult result;
-
- if (itemType.equals(ITEM_TYPE_SUBS) && !mSubscriptionsSupported) {
- IabResult r = new IabResult(IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE,
- "Subscriptions are not available.");
- flagEndAsync();
- if (listener != null) listener.onIabPurchaseFinished(r, null);
- return;
- }
-
- try {
- logDebug("Constructing buy intent for " + sku + ", item type: " + itemType);
- Bundle buyIntentBundle = mService.getBuyIntent(3, mContext.getPackageName(), sku, itemType, extraData);
- int response = getResponseCodeFromBundle(buyIntentBundle);
- if (response != BILLING_RESPONSE_RESULT_OK) {
- logError("Unable to buy item, Error response: " + getResponseDesc(response));
- flagEndAsync();
- result = new IabResult(response, "Unable to buy item");
- if (listener != null) listener.onIabPurchaseFinished(result, null);
- return;
- }
-
- PendingIntent pendingIntent = buyIntentBundle.getParcelable(RESPONSE_BUY_INTENT);
- logDebug("Launching buy intent for " + sku + ". Request code: " + requestCode);
- mRequestCode = requestCode;
- mPurchaseListener = listener;
- mPurchasingItemType = itemType;
- act.startIntentSenderForResult(pendingIntent.getIntentSender(),
- requestCode, new Intent(),
- Integer.valueOf(0), Integer.valueOf(0),
- Integer.valueOf(0));
- }
- catch (SendIntentException e) {
- logError("SendIntentException while launching purchase flow for sku " + sku);
- e.printStackTrace();
- flagEndAsync();
-
- result = new IabResult(IABHELPER_SEND_INTENT_FAILED, "Failed to send intent.");
- if (listener != null) listener.onIabPurchaseFinished(result, null);
- }
- catch (RemoteException e) {
- logError("RemoteException while launching purchase flow for sku " + sku);
- e.printStackTrace();
- flagEndAsync();
-
- result = new IabResult(IABHELPER_REMOTE_EXCEPTION, "Remote exception while starting purchase flow");
- if (listener != null) listener.onIabPurchaseFinished(result, null);
- }
- }
-
- /**
- * Handles an activity result that's part of the purchase flow in in-app billing. If you
- * are calling {@link #launchPurchaseFlow}, then you must call this method from your
- * Activity's {@link android.app.Activity@onActivityResult} method. This method
- * MUST be called from the UI thread of the Activity.
- *
- * @param requestCode The requestCode as you received it.
- * @param resultCode The resultCode as you received it.
- * @param data The data (Intent) as you received it.
- * @return Returns true if the result was related to a purchase flow and was handled;
- * false if the result was not related to a purchase, in which case you should
- * handle it normally.
- */
- public boolean handleActivityResult(int requestCode, int resultCode, Intent data) {
- IabResult result;
- if (requestCode != mRequestCode) return false;
-
- checkNotDisposed();
- checkSetupDone("handleActivityResult");
-
- // end of async purchase operation that started on launchPurchaseFlow
- flagEndAsync();
-
- if (data == null) {
- logError("Null data in IAB activity result.");
- result = new IabResult(IABHELPER_BAD_RESPONSE, "Null data in IAB result");
- if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
- return true;
- }
-
- int responseCode = getResponseCodeFromIntent(data);
- String purchaseData = data.getStringExtra(RESPONSE_INAPP_PURCHASE_DATA);
- String dataSignature = data.getStringExtra(RESPONSE_INAPP_SIGNATURE);
-
- if (resultCode == Activity.RESULT_OK && responseCode == BILLING_RESPONSE_RESULT_OK) {
- logDebug("Successful resultcode from purchase activity.");
- logDebug("Purchase data: " + purchaseData);
- logDebug("Data signature: " + dataSignature);
- logDebug("Extras: " + data.getExtras());
- logDebug("Expected item type: " + mPurchasingItemType);
-
- if (purchaseData == null || dataSignature == null) {
- logError("BUG: either purchaseData or dataSignature is null.");
- logDebug("Extras: " + data.getExtras().toString());
- result = new IabResult(IABHELPER_UNKNOWN_ERROR, "IAB returned null purchaseData or dataSignature");
- if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
- return true;
- }
-
- Purchase purchase = null;
- try {
- purchase = new Purchase(mPurchasingItemType, purchaseData, dataSignature);
- String sku = purchase.getSku();
-
- // Verify signature
- if (!Security.verifyPurchase(mSignatureBase64, purchaseData, dataSignature)) {
- logError("Purchase signature verification FAILED for sku " + sku);
- result = new IabResult(IABHELPER_VERIFICATION_FAILED, "Signature verification failed for sku " + sku);
- if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, purchase);
- return true;
- }
- logDebug("Purchase signature successfully verified.");
- }
- catch (JSONException e) {
- logError("Failed to parse purchase data.");
- e.printStackTrace();
- result = new IabResult(IABHELPER_BAD_RESPONSE, "Failed to parse purchase data.");
- if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
- return true;
- }
-
- if (mPurchaseListener != null) {
- mPurchaseListener.onIabPurchaseFinished(new IabResult(BILLING_RESPONSE_RESULT_OK, "Success"), purchase);
- }
- }
- else if (resultCode == Activity.RESULT_OK) {
- // result code was OK, but in-app billing response was not OK.
- logDebug("Result code was OK but in-app billing response was not OK: " + getResponseDesc(responseCode));
- if (mPurchaseListener != null) {
- result = new IabResult(responseCode, "Problem purchashing item.");
- mPurchaseListener.onIabPurchaseFinished(result, null);
- }
- }
- else if (resultCode == Activity.RESULT_CANCELED) {
- logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode));
- result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled.");
- if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
- }
- else {
- logError("Purchase failed. Result code: " + Integer.toString(resultCode)
- + ". Response: " + getResponseDesc(responseCode));
- result = new IabResult(IABHELPER_UNKNOWN_PURCHASE_RESPONSE, "Unknown purchase response.");
- if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
- }
- return true;
- }
-
- public Inventory queryInventory(boolean querySkuDetails, List moreSkus) throws IabException {
- return queryInventory(querySkuDetails, moreSkus, null);
- }
-
- /**
- * Queries the inventory. This will query all owned items from the server, as well as
- * information on additional skus, if specified. This method may block or take long to execute.
- * Do not call from a UI thread. For that, use the non-blocking version {@link #refreshInventoryAsync}.
- *
- * @param querySkuDetails if true, SKU details (price, description, etc) will be queried as well
- * as purchase information.
- * @param moreItemSkus additional PRODUCT skus to query information on, regardless of ownership.
- * Ignored if null or if querySkuDetails is false.
- * @param moreSubsSkus additional SUBSCRIPTIONS skus to query information on, regardless of ownership.
- * Ignored if null or if querySkuDetails is false.
- * @throws IabException if a problem occurs while refreshing the inventory.
- */
- public Inventory queryInventory(boolean querySkuDetails, List moreItemSkus,
- List moreSubsSkus) throws IabException {
- checkNotDisposed();
- checkSetupDone("queryInventory");
- try {
- Inventory inv = new Inventory();
- int r = queryPurchases(inv, ITEM_TYPE_INAPP);
- if (r != BILLING_RESPONSE_RESULT_OK) {
- throw new IabException(r, "Error refreshing inventory (querying owned items).");
- }
-
- if (querySkuDetails) {
- r = querySkuDetails(ITEM_TYPE_INAPP, inv, moreItemSkus);
- if (r != BILLING_RESPONSE_RESULT_OK) {
- throw new IabException(r, "Error refreshing inventory (querying prices of items).");
- }
- }
-
- // if subscriptions are supported, then also query for subscriptions
- if (mSubscriptionsSupported) {
- r = queryPurchases(inv, ITEM_TYPE_SUBS);
- if (r != BILLING_RESPONSE_RESULT_OK) {
- throw new IabException(r, "Error refreshing inventory (querying owned subscriptions).");
- }
-
- if (querySkuDetails) {
- r = querySkuDetails(ITEM_TYPE_SUBS, inv, moreItemSkus);
- if (r != BILLING_RESPONSE_RESULT_OK) {
- throw new IabException(r, "Error refreshing inventory (querying prices of subscriptions).");
- }
- }
- }
-
- return inv;
- }
- catch (RemoteException e) {
- throw new IabException(IABHELPER_REMOTE_EXCEPTION, "Remote exception while refreshing inventory.", e);
- }
- catch (JSONException e) {
- throw new IabException(IABHELPER_BAD_RESPONSE, "Error parsing JSON response while refreshing inventory.", e);
- }
- }
-
- /**
- * Listener that notifies when an inventory query operation completes.
- */
- public interface QueryInventoryFinishedListener {
- /**
- * Called to notify that an inventory query operation completed.
- *
- * @param result The result of the operation.
- * @param inv The inventory.
- */
- public void onQueryInventoryFinished(IabResult result, Inventory inv);
- }
-
-
- /**
- * Asynchronous wrapper for inventory query. This will perform an inventory
- * query as described in {@link #queryInventory}, but will do so asynchronously
- * and call back the specified listener upon completion. This method is safe to
- * call from a UI thread.
- *
- * @param querySkuDetails as in {@link #queryInventory}
- * @param moreSkus as in {@link #queryInventory}
- * @param listener The listener to notify when the refresh operation completes.
- */
- public void queryInventoryAsync(final boolean querySkuDetails,
- final List moreSkus,
- final QueryInventoryFinishedListener listener) {
- final Handler handler = new Handler();
- checkNotDisposed();
- checkSetupDone("queryInventory");
- flagStartAsync("refresh inventory");
- (new Thread(new Runnable() {
- public void run() {
- IabResult result = new IabResult(BILLING_RESPONSE_RESULT_OK, "Inventory refresh successful.");
- Inventory inv = null;
- try {
- inv = queryInventory(querySkuDetails, moreSkus);
- }
- catch (IabException ex) {
- result = ex.getResult();
- }
-
- flagEndAsync();
-
- final IabResult result_f = result;
- final Inventory inv_f = inv;
- if (!mDisposed && listener != null) {
- handler.post(new Runnable() {
- public void run() {
- listener.onQueryInventoryFinished(result_f, inv_f);
- }
- });
- }
- }
- })).start();
- }
-
- public void queryInventoryAsync(QueryInventoryFinishedListener listener) {
- queryInventoryAsync(true, null, listener);
- }
-
- public void queryInventoryAsync(boolean querySkuDetails, QueryInventoryFinishedListener listener) {
- queryInventoryAsync(querySkuDetails, null, listener);
- }
-
-
- /**
- * Consumes a given in-app product. Consuming can only be done on an item
- * that's owned, and as a result of consumption, the user will no longer own it.
- * This method may block or take long to return. Do not call from the UI thread.
- * For that, see {@link #consumeAsync}.
- *
- * @param itemInfo The PurchaseInfo that represents the item to consume.
- * @throws IabException if there is a problem during consumption.
- */
- void consume(Purchase itemInfo) throws IabException {
- checkNotDisposed();
- checkSetupDone("consume");
-
- if (!itemInfo.mItemType.equals(ITEM_TYPE_INAPP)) {
- throw new IabException(IABHELPER_INVALID_CONSUMPTION,
- "Items of type '" + itemInfo.mItemType + "' can't be consumed.");
- }
-
- try {
- String token = itemInfo.getToken();
- String sku = itemInfo.getSku();
- if (token == null || token.equals("")) {
- logError("Can't consume "+ sku + ". No token.");
- throw new IabException(IABHELPER_MISSING_TOKEN, "PurchaseInfo is missing token for sku: "
- + sku + " " + itemInfo);
- }
-
- logDebug("Consuming sku: " + sku + ", token: " + token);
- int response = mService.consumePurchase(3, mContext.getPackageName(), token);
- if (response == BILLING_RESPONSE_RESULT_OK) {
- logDebug("Successfully consumed sku: " + sku);
- }
- else {
- logDebug("Error consuming consuming sku " + sku + ". " + getResponseDesc(response));
- throw new IabException(response, "Error consuming sku " + sku);
- }
- }
- catch (RemoteException e) {
- throw new IabException(IABHELPER_REMOTE_EXCEPTION, "Remote exception while consuming. PurchaseInfo: " + itemInfo, e);
- }
- }
-
- /**
- * Callback that notifies when a consumption operation finishes.
- */
- public interface OnConsumeFinishedListener {
- /**
- * Called to notify that a consumption has finished.
- *
- * @param purchase The purchase that was (or was to be) consumed.
- * @param result The result of the consumption operation.
- */
- public void onConsumeFinished(Purchase purchase, IabResult result);
- }
-
- /**
- * Callback that notifies when a multi-item consumption operation finishes.
- */
- public interface OnConsumeMultiFinishedListener {
- /**
- * Called to notify that a consumption of multiple items has finished.
- *
- * @param purchases The purchases that were (or were to be) consumed.
- * @param results The results of each consumption operation, corresponding to each
- * sku.
- */
- public void onConsumeMultiFinished(List purchases, List results);
- }
-
- /**
- * Asynchronous wrapper to item consumption. Works like {@link #consume}, but
- * performs the consumption in the background and notifies completion through
- * the provided listener. This method is safe to call from a UI thread.
- *
- * @param purchase The purchase to be consumed.
- * @param listener The listener to notify when the consumption operation finishes.
- */
- public void consumeAsync(Purchase purchase, OnConsumeFinishedListener listener) {
- checkNotDisposed();
- checkSetupDone("consume");
- List purchases = new ArrayList();
- purchases.add(purchase);
- consumeAsyncInternal(purchases, listener, null);
- }
-
- /**
- * Same as {@link consumeAsync}, but for multiple items at once.
- * @param purchases The list of PurchaseInfo objects representing the purchases to consume.
- * @param listener The listener to notify when the consumption operation finishes.
- */
- public void consumeAsync(List purchases, OnConsumeMultiFinishedListener listener) {
- checkNotDisposed();
- checkSetupDone("consume");
- consumeAsyncInternal(purchases, null, listener);
- }
-
- /**
- * Returns a human-readable description for the given response code.
- *
- * @param code The response code
- * @return A human-readable string explaining the result code.
- * It also includes the result code numerically.
- */
- public static String getResponseDesc(int code) {
- String[] iab_msgs = ("0:OK/1:User Canceled/2:Unknown/" +
- "3:Billing Unavailable/4:Item unavailable/" +
- "5:Developer Error/6:Error/7:Item Already Owned/" +
- "8:Item not owned").split("/");
- String[] iabhelper_msgs = ("0:OK/-1001:Remote exception during initialization/" +
- "-1002:Bad response received/" +
- "-1003:Purchase signature verification failed/" +
- "-1004:Send intent failed/" +
- "-1005:User cancelled/" +
- "-1006:Unknown purchase response/" +
- "-1007:Missing token/" +
- "-1008:Unknown error/" +
- "-1009:Subscriptions not available/" +
- "-1010:Invalid consumption attempt").split("/");
-
- if (code <= IABHELPER_ERROR_BASE) {
- int index = IABHELPER_ERROR_BASE - code;
- if (index >= 0 && index < iabhelper_msgs.length) return iabhelper_msgs[index];
- else return String.valueOf(code) + ":Unknown IAB Helper Error";
- }
- else if (code < 0 || code >= iab_msgs.length)
- return String.valueOf(code) + ":Unknown";
- else
- return iab_msgs[code];
- }
-
-
- // Checks that setup was done; if not, throws an exception.
- void checkSetupDone(String operation) {
- if (!mSetupDone) {
- logError("Illegal state for operation (" + operation + "): IAB helper is not set up.");
- throw new IllegalStateException("IAB helper is not set up. Can't perform operation: " + operation);
- }
- }
-
- // Workaround to bug where sometimes response codes come as Long instead of Integer
- int getResponseCodeFromBundle(Bundle b) {
- Object o = b.get(RESPONSE_CODE);
- if (o == null) {
- logDebug("Bundle with null response code, assuming OK (known issue)");
- return BILLING_RESPONSE_RESULT_OK;
- }
- else if (o instanceof Integer) return ((Integer)o).intValue();
- else if (o instanceof Long) return (int)((Long)o).longValue();
- else {
- logError("Unexpected type for bundle response code.");
- logError(o.getClass().getName());
- throw new RuntimeException("Unexpected type for bundle response code: " + o.getClass().getName());
- }
- }
-
- // Workaround to bug where sometimes response codes come as Long instead of Integer
- int getResponseCodeFromIntent(Intent i) {
- Object o = i.getExtras().get(RESPONSE_CODE);
- if (o == null) {
- logError("Intent with no response code, assuming OK (known issue)");
- return BILLING_RESPONSE_RESULT_OK;
- }
- else if (o instanceof Integer) return ((Integer)o).intValue();
- else if (o instanceof Long) return (int)((Long)o).longValue();
- else {
- logError("Unexpected type for intent response code.");
- logError(o.getClass().getName());
- throw new RuntimeException("Unexpected type for intent response code: " + o.getClass().getName());
- }
- }
-
- void flagStartAsync(String operation) {
- if (mAsyncInProgress) throw new IllegalStateException("Can't start async operation (" +
- operation + ") because another async operation(" + mAsyncOperation + ") is in progress.");
- mAsyncOperation = operation;
- mAsyncInProgress = true;
- logDebug("Starting async operation: " + operation);
- }
-
- void flagEndAsync() {
- logDebug("Ending async operation: " + mAsyncOperation);
- mAsyncOperation = "";
- mAsyncInProgress = false;
- }
-
-
- int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException {
- // Query purchases
- logDebug("Querying owned items, item type: " + itemType);
- logDebug("Package name: " + mContext.getPackageName());
- boolean verificationFailed = false;
- String continueToken = null;
-
- do {
- logDebug("Calling getPurchases with continuation token: " + continueToken);
- Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName(),
- itemType, continueToken);
-
- int response = getResponseCodeFromBundle(ownedItems);
- logDebug("Owned items response: " + String.valueOf(response));
- if (response != BILLING_RESPONSE_RESULT_OK) {
- logDebug("getPurchases() failed: " + getResponseDesc(response));
- return response;
- }
- if (!ownedItems.containsKey(RESPONSE_INAPP_ITEM_LIST)
- || !ownedItems.containsKey(RESPONSE_INAPP_PURCHASE_DATA_LIST)
- || !ownedItems.containsKey(RESPONSE_INAPP_SIGNATURE_LIST)) {
- logError("Bundle returned from getPurchases() doesn't contain required fields.");
- return IABHELPER_BAD_RESPONSE;
- }
-
- ArrayList ownedSkus = ownedItems.getStringArrayList(
- RESPONSE_INAPP_ITEM_LIST);
- ArrayList purchaseDataList = ownedItems.getStringArrayList(
- RESPONSE_INAPP_PURCHASE_DATA_LIST);
- ArrayList signatureList = ownedItems.getStringArrayList(
- RESPONSE_INAPP_SIGNATURE_LIST);
-
- for (int i = 0; i < purchaseDataList.size(); ++i) {
- String purchaseData = purchaseDataList.get(i);
- String signature = signatureList.get(i);
- String sku = ownedSkus.get(i);
- if (Security.verifyPurchase(mSignatureBase64, purchaseData, signature)) {
- logDebug("Sku is owned: " + sku);
- Purchase purchase = new Purchase(itemType, purchaseData, signature);
-
- if (TextUtils.isEmpty(purchase.getToken())) {
- logWarn("BUG: empty/null token!");
- logDebug("Purchase data: " + purchaseData);
- }
-
- // Record ownership and token
- inv.addPurchase(purchase);
- }
- else {
- logWarn("Purchase signature verification **FAILED**. Not adding item.");
- logDebug(" Purchase data: " + purchaseData);
- logDebug(" Signature: " + signature);
- verificationFailed = true;
- }
- }
-
- continueToken = ownedItems.getString(INAPP_CONTINUATION_TOKEN);
- logDebug("Continuation token: " + continueToken);
- } while (!TextUtils.isEmpty(continueToken));
-
- return verificationFailed ? IABHELPER_VERIFICATION_FAILED : BILLING_RESPONSE_RESULT_OK;
- }
-
- int querySkuDetails(String itemType, Inventory inv, List moreSkus)
- throws RemoteException, JSONException {
- logDebug("Querying SKU details.");
- ArrayList skuList = new ArrayList();
- skuList.addAll(inv.getAllOwnedSkus(itemType));
- if (moreSkus != null) {
- for (String sku : moreSkus) {
- if (!skuList.contains(sku)) {
- skuList.add(sku);
- }
- }
- }
-
- if (skuList.size() == 0) {
- logDebug("queryPrices: nothing to do because there are no SKUs.");
- return BILLING_RESPONSE_RESULT_OK;
- }
-
- Bundle querySkus = new Bundle();
- querySkus.putStringArrayList(GET_SKU_DETAILS_ITEM_LIST, skuList);
- Bundle skuDetails = mService.getSkuDetails(3, mContext.getPackageName(),
- itemType, querySkus);
-
- if (!skuDetails.containsKey(RESPONSE_GET_SKU_DETAILS_LIST)) {
- int response = getResponseCodeFromBundle(skuDetails);
- if (response != BILLING_RESPONSE_RESULT_OK) {
- logDebug("getSkuDetails() failed: " + getResponseDesc(response));
- return response;
- }
- else {
- logError("getSkuDetails() returned a bundle with neither an error nor a detail list.");
- return IABHELPER_BAD_RESPONSE;
- }
- }
-
- ArrayList responseList = skuDetails.getStringArrayList(
- RESPONSE_GET_SKU_DETAILS_LIST);
-
- for (String thisResponse : responseList) {
- SkuDetails d = new SkuDetails(itemType, thisResponse);
- logDebug("Got sku details: " + d);
- inv.addSkuDetails(d);
- }
- return BILLING_RESPONSE_RESULT_OK;
- }
-
-
- void consumeAsyncInternal(final List purchases,
- final OnConsumeFinishedListener singleListener,
- final OnConsumeMultiFinishedListener multiListener) {
- final Handler handler = new Handler();
- flagStartAsync("consume");
- (new Thread(new Runnable() {
- public void run() {
- final List results = new ArrayList();
- for (Purchase purchase : purchases) {
- try {
- consume(purchase);
- results.add(new IabResult(BILLING_RESPONSE_RESULT_OK, "Successful consume of sku " + purchase.getSku()));
- }
- catch (IabException ex) {
- results.add(ex.getResult());
- }
- }
-
- flagEndAsync();
- if (!mDisposed && singleListener != null) {
- handler.post(new Runnable() {
- public void run() {
- singleListener.onConsumeFinished(purchases.get(0), results.get(0));
- }
- });
- }
- if (!mDisposed && multiListener != null) {
- handler.post(new Runnable() {
- public void run() {
- multiListener.onConsumeMultiFinished(purchases, results);
- }
- });
- }
- }
- })).start();
- }
-
- void logDebug(String msg) {
- if (mDebugLog) Log.d(mDebugTag, msg);
- }
-
- void logError(String msg) {
- Log.e(mDebugTag, "In-app billing error: " + msg);
- }
-
- void logWarn(String msg) {
- Log.w(mDebugTag, "In-app billing warning: " + msg);
- }
-}
diff --git a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/IabResult.java b/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/IabResult.java
deleted file mode 100644
index 37e860b..0000000
--- a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/IabResult.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (c) 2012 Google Inc.
- *
- * 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.
- */
-
-package org.sufficientlysecure.donations.google.util;
-
-/**
- * Represents the result of an in-app billing operation.
- * A result is composed of a response code (an integer) and possibly a
- * message (String). You can get those by calling
- * {@link #getResponse} and {@link #getMessage()}, respectively. You
- * can also inquire whether a result is a success or a failure by
- * calling {@link #isSuccess()} and {@link #isFailure()}.
- */
-public class IabResult {
- int mResponse;
- String mMessage;
-
- public IabResult(int response, String message) {
- mResponse = response;
- if (message == null || message.trim().length() == 0) {
- mMessage = IabHelper.getResponseDesc(response);
- }
- else {
- mMessage = message + " (response: " + IabHelper.getResponseDesc(response) + ")";
- }
- }
- public int getResponse() { return mResponse; }
- public String getMessage() { return mMessage; }
- public boolean isSuccess() { return mResponse == IabHelper.BILLING_RESPONSE_RESULT_OK; }
- public boolean isFailure() { return !isSuccess(); }
- public String toString() { return "IabResult: " + getMessage(); }
-}
-
diff --git a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Inventory.java b/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Inventory.java
deleted file mode 100644
index bf9c821..0000000
--- a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Inventory.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Copyright (c) 2012 Google Inc.
- *
- * 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.
- */
-
-package org.sufficientlysecure.donations.google.util;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Represents a block of information about in-app items.
- * An Inventory is returned by such methods as {@link IabHelper#queryInventory}.
- */
-public class Inventory {
- Map mSkuMap = new HashMap();
- Map mPurchaseMap = new HashMap();
-
- Inventory() { }
-
- /** Returns the listing details for an in-app product. */
- public SkuDetails getSkuDetails(String sku) {
- return mSkuMap.get(sku);
- }
-
- /** Returns purchase information for a given product, or null if there is no purchase. */
- public Purchase getPurchase(String sku) {
- return mPurchaseMap.get(sku);
- }
-
- /** Returns whether or not there exists a purchase of the given product. */
- public boolean hasPurchase(String sku) {
- return mPurchaseMap.containsKey(sku);
- }
-
- /** Return whether or not details about the given product are available. */
- public boolean hasDetails(String sku) {
- return mSkuMap.containsKey(sku);
- }
-
- /**
- * Erase a purchase (locally) from the inventory, given its product ID. This just
- * modifies the Inventory object locally and has no effect on the server! This is
- * useful when you have an existing Inventory object which you know to be up to date,
- * and you have just consumed an item successfully, which means that erasing its
- * purchase data from the Inventory you already have is quicker than querying for
- * a new Inventory.
- */
- public void erasePurchase(String sku) {
- if (mPurchaseMap.containsKey(sku)) mPurchaseMap.remove(sku);
- }
-
- /** Returns a list of all owned product IDs. */
- List getAllOwnedSkus() {
- return new ArrayList(mPurchaseMap.keySet());
- }
-
- /** Returns a list of all owned product IDs of a given type */
- List getAllOwnedSkus(String itemType) {
- List result = new ArrayList();
- for (Purchase p : mPurchaseMap.values()) {
- if (p.getItemType().equals(itemType)) result.add(p.getSku());
- }
- return result;
- }
-
- /** Returns a list of all purchases. */
- List getAllPurchases() {
- return new ArrayList(mPurchaseMap.values());
- }
-
- void addSkuDetails(SkuDetails d) {
- mSkuMap.put(d.getSku(), d);
- }
-
- void addPurchase(Purchase p) {
- mPurchaseMap.put(p.getSku(), p);
- }
-}
diff --git a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Purchase.java b/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Purchase.java
deleted file mode 100644
index f877a98..0000000
--- a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Purchase.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Copyright (c) 2012 Google Inc.
- *
- * 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.
- */
-
-package org.sufficientlysecure.donations.google.util;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/**
- * Represents an in-app billing purchase.
- */
-public class Purchase {
- String mItemType; // ITEM_TYPE_INAPP or ITEM_TYPE_SUBS
- String mOrderId;
- String mPackageName;
- String mSku;
- long mPurchaseTime;
- int mPurchaseState;
- String mDeveloperPayload;
- String mToken;
- String mOriginalJson;
- String mSignature;
-
- public Purchase(String itemType, String jsonPurchaseInfo, String signature) throws JSONException {
- mItemType = itemType;
- mOriginalJson = jsonPurchaseInfo;
- JSONObject o = new JSONObject(mOriginalJson);
- mOrderId = o.optString("orderId");
- mPackageName = o.optString("packageName");
- mSku = o.optString("productId");
- mPurchaseTime = o.optLong("purchaseTime");
- mPurchaseState = o.optInt("purchaseState");
- mDeveloperPayload = o.optString("developerPayload");
- mToken = o.optString("token", o.optString("purchaseToken"));
- mSignature = signature;
- }
-
- public String getItemType() { return mItemType; }
- public String getOrderId() { return mOrderId; }
- public String getPackageName() { return mPackageName; }
- public String getSku() { return mSku; }
- public long getPurchaseTime() { return mPurchaseTime; }
- public int getPurchaseState() { return mPurchaseState; }
- public String getDeveloperPayload() { return mDeveloperPayload; }
- public String getToken() { return mToken; }
- public String getOriginalJson() { return mOriginalJson; }
- public String getSignature() { return mSignature; }
-
- @Override
- public String toString() { return "PurchaseInfo(type:" + mItemType + "):" + mOriginalJson; }
-}
diff --git a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Security.java b/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Security.java
deleted file mode 100644
index 29974ca..0000000
--- a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/Security.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/* Copyright (c) 2012 Google Inc.
- *
- * 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.
- */
-
-package org.sufficientlysecure.donations.google.util;
-
-import android.text.TextUtils;
-import android.util.Log;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.X509EncodedKeySpec;
-
-/**
- * Security-related methods. For a secure implementation, all of this code
- * should be implemented on a server that communicates with the
- * application on the device. For the sake of simplicity and clarity of this
- * example, this code is included here and is executed on the device. If you
- * must verify the purchases on the phone, you should obfuscate this code to
- * make it harder for an attacker to replace the code with stubs that treat all
- * purchases as verified.
- */
-public class Security {
- private static final String TAG = "IABUtil/Security";
-
- private static final String KEY_FACTORY_ALGORITHM = "RSA";
- private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
-
- /**
- * Verifies that the data was signed with the given signature, and returns
- * the verified purchase. The data is in JSON format and signed
- * with a private key. The data also contains the {@link PurchaseState}
- * and product ID of the purchase.
- * @param base64PublicKey the base64-encoded public key to use for verifying.
- * @param signedData the signed JSON string (signed, not encrypted)
- * @param signature the signature for the data, signed with the private key
- */
- public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {
- if (signedData == null) {
- Log.e(TAG, "data is null");
- return false;
- }
-
- boolean verified = false;
- if (!TextUtils.isEmpty(signature)) {
- PublicKey key = Security.generatePublicKey(base64PublicKey);
- verified = Security.verify(key, signedData, signature);
- if (!verified) {
- Log.w(TAG, "signature does not match data.");
- return false;
- }
- }
- return true;
- }
-
- /**
- * Generates a PublicKey instance from a string containing the
- * Base64-encoded public key.
- *
- * @param encodedPublicKey Base64-encoded public key
- * @throws IllegalArgumentException if encodedPublicKey is invalid
- */
- public static PublicKey generatePublicKey(String encodedPublicKey) {
- try {
- byte[] decodedKey = Base64.decode(encodedPublicKey);
- KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
- return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException(e);
- } catch (InvalidKeySpecException e) {
- Log.e(TAG, "Invalid key specification.");
- throw new IllegalArgumentException(e);
- } catch (Base64DecoderException e) {
- Log.e(TAG, "Base64 decoding failed.");
- throw new IllegalArgumentException(e);
- }
- }
-
- /**
- * Verifies that the signature from the server matches the computed
- * signature on the data. Returns true if the data is correctly signed.
- *
- * @param publicKey public key associated with the developer account
- * @param signedData signed data from server
- * @param signature server signature
- * @return true if the data and signature match
- */
- public static boolean verify(PublicKey publicKey, String signedData, String signature) {
- Signature sig;
- try {
- sig = Signature.getInstance(SIGNATURE_ALGORITHM);
- sig.initVerify(publicKey);
- sig.update(signedData.getBytes());
- if (!sig.verify(Base64.decode(signature))) {
- Log.e(TAG, "Signature verification failed.");
- return false;
- }
- return true;
- } catch (NoSuchAlgorithmException e) {
- Log.e(TAG, "NoSuchAlgorithmException.");
- } catch (InvalidKeyException e) {
- Log.e(TAG, "Invalid key specification.");
- } catch (SignatureException e) {
- Log.e(TAG, "Signature exception.");
- } catch (Base64DecoderException e) {
- Log.e(TAG, "Base64 decoding failed.");
- }
- return false;
- }
-}
diff --git a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/SkuDetails.java b/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/SkuDetails.java
deleted file mode 100644
index 236221a..0000000
--- a/libraries/Donations/src/main/java/org/sufficientlysecure/donations/google/util/SkuDetails.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright (c) 2012 Google Inc.
- *
- * 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.
- */
-
-package org.sufficientlysecure.donations.google.util;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/**
- * Represents an in-app product's listing details.
- */
-public class SkuDetails {
- String mItemType;
- String mSku;
- String mType;
- String mPrice;
- String mTitle;
- String mDescription;
- String mJson;
-
- public SkuDetails(String jsonSkuDetails) throws JSONException {
- this(IabHelper.ITEM_TYPE_INAPP, jsonSkuDetails);
- }
-
- public SkuDetails(String itemType, String jsonSkuDetails) throws JSONException {
- mItemType = itemType;
- mJson = jsonSkuDetails;
- JSONObject o = new JSONObject(mJson);
- mSku = o.optString("productId");
- mType = o.optString("type");
- mPrice = o.optString("price");
- mTitle = o.optString("title");
- mDescription = o.optString("description");
- }
-
- public String getSku() { return mSku; }
- public String getType() { return mType; }
- public String getPrice() { return mPrice; }
- public String getTitle() { return mTitle; }
- public String getDescription() { return mDescription; }
-
- @Override
- public String toString() {
- return "SkuDetails:" + mJson;
- }
-}
diff --git a/libraries/Donations/src/main/res/layout/donations__fragment.xml b/libraries/Donations/src/main/res/layout/donations__fragment.xml
deleted file mode 100644
index a540012..0000000
--- a/libraries/Donations/src/main/res/layout/donations__fragment.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/libraries/Donations/src/main/res/layout/donations__fragment_flattr.xml b/libraries/Donations/src/main/res/layout/donations__fragment_flattr.xml
deleted file mode 100644
index cf86537..0000000
--- a/libraries/Donations/src/main/res/layout/donations__fragment_flattr.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/libraries/Donations/src/main/res/layout/donations__fragment_google.xml b/libraries/Donations/src/main/res/layout/donations__fragment_google.xml
deleted file mode 100644
index e6ef998..0000000
--- a/libraries/Donations/src/main/res/layout/donations__fragment_google.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/libraries/Donations/src/main/res/layout/donations__fragment_paypal.xml b/libraries/Donations/src/main/res/layout/donations__fragment_paypal.xml
deleted file mode 100644
index 9a60ada..0000000
--- a/libraries/Donations/src/main/res/layout/donations__fragment_paypal.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/libraries/Donations/src/main/res/values-bg/donations__strings.xml b/libraries/Donations/src/main/res/values-bg/donations__strings.xml
deleted file mode 100644
index ca85dd2..0000000
--- a/libraries/Donations/src/main/res/values-bg/donations__strings.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- Затвори
- Flattr
- Flattr взема 10% като месечна такса!
- Google Play магазин
- Дарения чрез приложението не се поддържат. Инсталиран ли е правилно магазина Google Play?
- Google взема 30% от всяко дарение!
- Дарете!
- Колко?
- PayPal
- Можете да изберете колко искате да дарите след натискане на бутона!
- Благодаря!
- Благодаря ви за дарението!\nНаистина оценявам това!
-
diff --git a/libraries/Donations/src/main/res/values-ca/donations__strings.xml b/libraries/Donations/src/main/res/values-ca/donations__strings.xml
deleted file mode 100644
index a538710..0000000
--- a/libraries/Donations/src/main/res/values-ca/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Tanca
- Flattr
- Has trobat útil aquesta aplicació?\nAjuda al seu desenvolupament enviant una donació al creador!
- Flattr té unes comissions mensuals del deu percent!
- Google Play Store
- No es poden fer donatius des de l\'aplicació. Heu instal·lat Google Play Store correctament?
- Google té unes comissions del 30 percent!
- Fer un donatiu
- Quant?
- PayPal
- Podeu escollir la quantitat del vostre donatiu tocant aquest botó.
- Gràcies!
- Gràcies per fer el donatiu!⏎ N\'estic molt agraït!
- S\'ha produït un error
- No s\'ha trobat cap navegador per obrir el lloc web!
-
diff --git a/libraries/Donations/src/main/res/values-cs/donations__strings.xml b/libraries/Donations/src/main/res/values-cs/donations__strings.xml
deleted file mode 100644
index 85519a5..0000000
--- a/libraries/Donations/src/main/res/values-cs/donations__strings.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- Zavřít
- Google Play
- Podpořte nás!
- Kolik to stojí?
- PayPal
- Díky!
- Díky za darování!\nOpravdu si toho vážím!
-
diff --git a/libraries/Donations/src/main/res/values-da-rDK/donations__strings.xml b/libraries/Donations/src/main/res/values-da-rDK/donations__strings.xml
deleted file mode 100644
index a5c54e0..0000000
--- a/libraries/Donations/src/main/res/values-da-rDK/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Luk
- Flattr
- Finder du denne app brugbar?\nSupporter dets udvikling ved at sende en donation til udvikleren!
- Flattr tager 10% i månedlig gebyr!
- Google Play Store
- In-App donationer er ikke supporteret. Er Google Play Store installeret korrekt?
- Google tager 30% fra hver donation!
- Donér!
- Hvor meget?
- PayPal
- Du kan vælge hvor meget du vil donere efter du har trykket på knappen
- Tak!
- Tak fordi du donerede!\nJeg sætter virkelig pris på dette!
- En fejl opstod
- Ingen browser blev fundet til at åbne en webside!
-
diff --git a/libraries/Donations/src/main/res/values-de-rDE/donations__strings.xml b/libraries/Donations/src/main/res/values-de-rDE/donations__strings.xml
deleted file mode 100644
index ff57433..0000000
--- a/libraries/Donations/src/main/res/values-de-rDE/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Schließen
- Flattr
- Findest die diese Anwendung nützlich?\nUnterstütze die Entwicklung indem Du sie flatterst oder spendest.
- Flattr behält 10 % als monatliche Gebühr ein!
- Google Play Store
- In-App-Spenden werden nicht unterstützt. Ist der Google Play Store korrekt installiert?
- 30 % jeder Spende geht an Google!
- Spende!
- Wie viel?
- PayPal
- Du kannst auswählen wie viel Du spenden möchtest, nachdem Du auf den Button geklickt hast!
- Danke!
- Danke für die Spende!\nIch weiß es wirklich zu schätzen!
- Fehler aufgetreten
- Kein Browser gefunden um eine Webseite zu öffnen!
-
diff --git a/libraries/Donations/src/main/res/values-el/donations__strings.xml b/libraries/Donations/src/main/res/values-el/donations__strings.xml
deleted file mode 100644
index 94d295d..0000000
--- a/libraries/Donations/src/main/res/values-el/donations__strings.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- Κλείσιμο
- Flattr
- Το Flattr παίρνει 10 % σαν μηνιαίο τέλος!
- Google Play Store
- Δεν υποστηρίζονται In-App δωρεές. Έχει εγκατασταθεί σωστά το Google Play Store;
- Το Google παίρνει το 30 % κάθε δωρεάς!
- Δωρίστε!
- Πόσο;
- PayPal
- Μπορείς να επιλέξεις πόσα θέλεις να δωρίσεις αφού πατήσεις το κουμπί!
- Ευχαριστώ!
- Ευχαριστώ για την δωρεά!\n\nΠραγματικά το εκτιμώ!
-
diff --git a/libraries/Donations/src/main/res/values-es-rES/donations__strings.xml b/libraries/Donations/src/main/res/values-es-rES/donations__strings.xml
deleted file mode 100644
index 695853e..0000000
--- a/libraries/Donations/src/main/res/values-es-rES/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Cerrar
- Flattr
- ¿Le resulta útil esta aplicación? \nApoye su desarrollo mediante el envío de una donación al desarrollador!
- ¡Flattr toma un 10% como cuota mensual!
- Google Play Store
- No se admiten Donaciones In-App. ¿Está Google Play Store instalado correctamente?
- ¡Google se queda el 30% de todas las donaciones!
- ¡Donar!
- ¿Cuánto?
- PayPal
- ¡Puedes elegir cuánto quieres donar después de pulsar el botón!
- ¡Gracias!
- ¡Gracias por donar!\n¡Te lo agradezco mucho!
- Se produjó un error
- No se encontró un navegador para abrir una página web!
-
diff --git a/libraries/Donations/src/main/res/values-es-rMX/donations__strings.xml b/libraries/Donations/src/main/res/values-es-rMX/donations__strings.xml
deleted file mode 100644
index e5ceaa9..0000000
--- a/libraries/Donations/src/main/res/values-es-rMX/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Cerrar
- Flattr
- Encuentras útil esta aplicación ?\nApoya su desarrollo enviando una donación al desarrollador!
- ¡Flattr toma 10% como cargo mensual!
- Google Play Store
- Las donaciones In-App no están soportadas. ¿Está la Tienda de Google Play instalada correctamente?
- ¡Google se queda con el 30% de cada donación!
- ¡Donar!
- ¿Cuánto?
- PayPal
- ¡Puedes escoger cuánto deseas donar después de dar clic en el botón!
- Gracias!
- Gracias por donar!\nRealmente aprecio esto!
- Ocurrió un error
- No se encontró un navegador para abrir el sitio web!
-
diff --git a/libraries/Donations/src/main/res/values-et-rEE/donations__strings.xml b/libraries/Donations/src/main/res/values-et-rEE/donations__strings.xml
deleted file mode 100644
index cf98591..0000000
--- a/libraries/Donations/src/main/res/values-et-rEE/donations__strings.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- Sulge
- Flattr
- Flattr võtab 10% igakuist tasu!
- Google Play pood
- Annetused rakenduse sees ei ole toetatud. Kas Google Play pood on korrektselt paigaldatud?
- Google võtab 30% igalt annetuselt!
- Anneta!
- Kui palju?
- PayPal
- Sellel nupul klikates saad valida kui palju soovid annetada!
- Tänan!
- Tänan annetamast! \nHindan seda väga!
-
diff --git a/libraries/Donations/src/main/res/values-fi/donations__strings.xml b/libraries/Donations/src/main/res/values-fi/donations__strings.xml
deleted file mode 100644
index 55432cd..0000000
--- a/libraries/Donations/src/main/res/values-fi/donations__strings.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- Sulje
- Flattr
- Flattr ottaa 10% kuukausipalkkiosta!
- Googlen Android Market
- Sovelluksen sisäiset lahjoitukset eivät ole tuettu. Löytyykö laitteesta Android Market?
- Gogle ottaa 30% jokaisesta lahjoituksesta!
- Lahjoita!
- Kuinka paljon?
- PayPal
- Voit valita, kuinka paljon haluat lahjoittaa painikkeen napsauttamisen jälkeen!
- Kiitos!
- Kiitos lahjoituksestasi!\nArvostan sitä suuresti!
-
diff --git a/libraries/Donations/src/main/res/values-fr/donations__strings.xml b/libraries/Donations/src/main/res/values-fr/donations__strings.xml
deleted file mode 100644
index 882a319..0000000
--- a/libraries/Donations/src/main/res/values-fr/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Fermer
- Flattr
- Cette application vous rend service ?\nParticiper à son développement en effectuant un don !
- Flattr prend 10% de frais mensuels !
- Google Play Store
- Donations In-App non-supportées. L\'application Google Play Store est-elle correctement installée ?
- Google prend 30% sur chaque don !
- Faites un don !
- Combien ?
- PayPal
- Vous pouvez faire un don du montant désiré en cliquant sur ce bouton !
- Merci !
- Merci beaucoup pour votre don !
- Une erreur est survenue
- Aucun navigateur web n\'a été trouvé pour ouvrir le site web !
-
diff --git a/libraries/Donations/src/main/res/values-he/donations__strings.xml b/libraries/Donations/src/main/res/values-he/donations__strings.xml
deleted file mode 100644
index 432356b..0000000
--- a/libraries/Donations/src/main/res/values-he/donations__strings.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- לא נמצא Busybox. כדי להתקין אותו מהמרקט לחץ על הלחצן מתחת.
- Flattr
- Flattr מספר הנחה של 10 % לתשלום החודשי!
- אנדרואיד מרקט
- תרומות לתוכנה אינם נתמכות. האם המרקט של גוגל אנדרואיד מותקן כראוי?
- גוגל מקבלת 30% מסך התרומה!
- תרומה!
- כמה?
- PayPal
- אתה יכול לבחור כמה אתה רוצה לתרום על ידי לחיצה על הכפתור!
- תודה!
- תודה על תרומתך!\nאני מאוד מעריך זאת!
-
diff --git a/libraries/Donations/src/main/res/values-hr/donations__strings.xml b/libraries/Donations/src/main/res/values-hr/donations__strings.xml
deleted file mode 100644
index 13106fc..0000000
--- a/libraries/Donations/src/main/res/values-hr/donations__strings.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- Zatvori
- Flattr
- Flatter uzima 10% iznosa donacije kao mjesečnu članarinu!
- Google Play Trgovina
- Donacije unutar aplikacije nisu podržane. Je li Google Play Trgovina ispravno instalirana?
- Google uzima 30% od svake donacije!
- Donirajte!
- Koliko?
- PayPal
- Možete izabrati koliko želite donirati nakon pritiska na gumb.
- Hvala!
- Hvala za donaciju!\n Stvarno cijenim ovo!
-
diff --git a/libraries/Donations/src/main/res/values-hu/donations__strings.xml b/libraries/Donations/src/main/res/values-hu/donations__strings.xml
deleted file mode 100644
index 51ab5e1..0000000
--- a/libraries/Donations/src/main/res/values-hu/donations__strings.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- Bezár
- Flattr
- A Flattr 10 %-ot levesz havi díjként!
- Google Android Market
- Az alkalmazáson belüli adományozás nem támogatott. A Google Android Market megfelelően van telepítve?
- A Google része 30 % minden adományból!
- Adományozok!
- Mennyi?
- PayPal
- Az adományozott összeget megválaszthatja a gombra való kattintás után.
- Köszönöm!
- Köszönjük a támogatást!\nNagyra értékeljük!
-
diff --git a/libraries/Donations/src/main/res/values-id/donations__strings.xml b/libraries/Donations/src/main/res/values-id/donations__strings.xml
deleted file mode 100644
index 9e0becd..0000000
--- a/libraries/Donations/src/main/res/values-id/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Tutup
- Flattr
- Apakah aplikasi ini berguna?\nDukung pengembangan aplikasi dengan memberikan donasi!
- Flattr mengambil 10 % sebagai biaya bulanan!
- Google Play Store
- Donasi di dalam aplikasi tidak didukung. apakah Google Play Store terpasang dengan benar?
- Google mengambil 30 % dari setiap donasi!
- Donasi!
- Berapa banyak?
- PayPal
- Anda dapat memilih berapa banyak Anda ingin sumbangkan setelah mengklik tombol!
- Terima Kasih!
- Terimkasih atas donasi anda!\n\nSaya sangat menghargai ini!
- Terjadi galat
- Tidak di temukan browser untuk membuka laman website
-
diff --git a/libraries/Donations/src/main/res/values-it/donations__strings.xml b/libraries/Donations/src/main/res/values-it/donations__strings.xml
deleted file mode 100644
index 377fb8f..0000000
--- a/libraries/Donations/src/main/res/values-it/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Chiudi
- Flattr
- Pensi che questa applicazione sia utile?\nSupporta il suo sviluppo mandando una donazione allo sviluppatore!
- Flattr riceve il 10% come canone mensile!
- Google Play Store
- Donazioni In-App non supportate. Google Play Store è installato correttamente?
- Google riceve il 30% di ogni donazione!
- Dona!
- Quanto?
- PayPal
- Puoi scegliere quanto donare dopo aver premuto il pulsante!
- Grazie!
- Grazie per la donazione!\nLo apprezzo molto!
- Si è verificato un errore
- Non è stato trovato un browser per aprire un sito internet!
-
diff --git a/libraries/Donations/src/main/res/values-iw-rIL/donations__strings.xml b/libraries/Donations/src/main/res/values-iw-rIL/donations__strings.xml
deleted file mode 100644
index 432356b..0000000
--- a/libraries/Donations/src/main/res/values-iw-rIL/donations__strings.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- לא נמצא Busybox. כדי להתקין אותו מהמרקט לחץ על הלחצן מתחת.
- Flattr
- Flattr מספר הנחה של 10 % לתשלום החודשי!
- אנדרואיד מרקט
- תרומות לתוכנה אינם נתמכות. האם המרקט של גוגל אנדרואיד מותקן כראוי?
- גוגל מקבלת 30% מסך התרומה!
- תרומה!
- כמה?
- PayPal
- אתה יכול לבחור כמה אתה רוצה לתרום על ידי לחיצה על הכפתור!
- תודה!
- תודה על תרומתך!\nאני מאוד מעריך זאת!
-
diff --git a/libraries/Donations/src/main/res/values-ja/donations__strings.xml b/libraries/Donations/src/main/res/values-ja/donations__strings.xml
deleted file mode 100644
index 59f8088..0000000
--- a/libraries/Donations/src/main/res/values-ja/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- 閉じる
- Flattr
- このアプリは役に立ちましたか?\n開発者に寄付をして開発を応援してください!
- Flattr は月額として10 %手に入れます!
- Google Playストア
- アプリ内寄付は非対応です。GooglePlayストアはインストールされていますか?
- Googleは寄付の30%を持って行きます…。
- 寄付する!
- いくら?
- PayPal
- ボタンを押した後寄付したい額を選べます!
- ありがとう!
- 寄付ありがとう!\n本当に感謝しています!
- エラーが発生しました
- サイトを開くためのブラウザが見つかりません!
-
diff --git a/libraries/Donations/src/main/res/values-km/donations__strings.xml b/libraries/Donations/src/main/res/values-km/donations__strings.xml
deleted file mode 100644
index c757504..0000000
--- a/libraries/Donations/src/main/res/values-km/donations__strings.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/libraries/Donations/src/main/res/values-ko/donations__strings.xml b/libraries/Donations/src/main/res/values-ko/donations__strings.xml
deleted file mode 100644
index c757504..0000000
--- a/libraries/Donations/src/main/res/values-ko/donations__strings.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/libraries/Donations/src/main/res/values-mn/donations__strings.xml b/libraries/Donations/src/main/res/values-mn/donations__strings.xml
deleted file mode 100644
index c7fbb1d..0000000
--- a/libraries/Donations/src/main/res/values-mn/donations__strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- Хаах
-
diff --git a/libraries/Donations/src/main/res/values-nl/donations__strings.xml b/libraries/Donations/src/main/res/values-nl/donations__strings.xml
deleted file mode 100644
index ff18224..0000000
--- a/libraries/Donations/src/main/res/values-nl/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Sluiten
- Flattr
- Vindt u dit applicatie nuttig?\nDraag bij aan de ontwikkeling ervan door een donatie te sturen aan de ontwikkelaar!
- Flattr neemt 10% als maandelijkse kosten
- Google Play Store
- Helaas, in-App donaties worden niet ondersteund. Is Google Play Store correct geïnstalleerd?
- Google houdt 30% van elke donatie in
- Doneer!
- Welke bedrag?
- Paypal
- U kunt kiezen hoeveel u wilt doneren, na het klikken van de knop
- Dank u wel
- Bedankt voor uw donatie! Ik stel het heel erg op prijs.
- Er is iets fout gegaan!
- Er is geen browser gevonden om een website te openen!
-
diff --git a/libraries/Donations/src/main/res/values-no-rNO/donations__strings.xml b/libraries/Donations/src/main/res/values-no-rNO/donations__strings.xml
deleted file mode 100644
index e434f9b..0000000
--- a/libraries/Donations/src/main/res/values-no-rNO/donations__strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- Lukk
-
diff --git a/libraries/Donations/src/main/res/values-pl/donations__strings.xml b/libraries/Donations/src/main/res/values-pl/donations__strings.xml
deleted file mode 100644
index 8bfc3a4..0000000
--- a/libraries/Donations/src/main/res/values-pl/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Zamknij
- Flattr
- Czy aplikacja jest dla Ciebie przydatna?\nWspomóż jej rozwój poprzez dotację dla autora!
- Flattr pobiera 10% jako miesięczną opłatę!
- Sklep Google Play
- Brak wsparcia dla wbudowanych płatności. Czy aplikacja Sklep Google Play jest zainstalowana prawidłowo?
- Google pobiera 30% kwoty z każdej darowizny!
- Przekaż!
- Kwota do przekazania?
- PayPal
- Wybór kwoty do przekazania nastąpi po kliknięciu przycisku \"Przekaż\"!
- Dzięki!
- Dziekuję za darowiznę!\nNaprawdę to doceniam!
- Wystąpił błąd
- Brak przeglądarki! Nie można otworzyć strony www.
-
diff --git a/libraries/Donations/src/main/res/values-pt-rBR/donations__strings.xml b/libraries/Donations/src/main/res/values-pt-rBR/donations__strings.xml
deleted file mode 100644
index c5fbcd2..0000000
--- a/libraries/Donations/src/main/res/values-pt-rBR/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Fechar
- Flattr
- Você achou esta aplicação útil?\nSuporte o seu desenvolvimento mandando uma doação programador!
- Flattr possui uma taxa mensal de 10%!
- Google Play Store
- Doações dentro do aplicativo não são suportadas. O Google Play Store foi instalado corretamente?
- Google retém 30% de cada doação!
- Doar!
- Quanto?
- PayPal
- Você pode escolher quanto deseja doar após clicar no botão!
- Obrigado!
- Obrigado pela sua doação!
- Erro ocorrido
- Nenhum navegador foi encontrado para abrir um site!
-
diff --git a/libraries/Donations/src/main/res/values-ro-rRO/donations__strings.xml b/libraries/Donations/src/main/res/values-ro-rRO/donations__strings.xml
deleted file mode 100644
index 76c552d..0000000
--- a/libraries/Donations/src/main/res/values-ro-rRO/donations__strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- Inchide
-
diff --git a/libraries/Donations/src/main/res/values-ru/donations__strings.xml b/libraries/Donations/src/main/res/values-ru/donations__strings.xml
deleted file mode 100644
index accda6a..0000000
--- a/libraries/Donations/src/main/res/values-ru/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Закрыть
- Flattr
- Считаете ли вы приложение полезным?\nПоддержите его развитие, отправив пожертвование для разработчиков!
- Flattr взимает 10% в виде ежемесячной абонентской платы!
- Google Play Store
- Пожертвования через приложение не поддерживаются. Google Play Store установлен правильно?
- Google взимает 30% с каждого пожертвования!
- Пожертвовать!
- Сколько?
- PayPal
- После нажатия на кнопку вы можете выбрать сколько хотите пожертвовать!
- Благодарю!
- Благодарю за пожертвование! Я очень это ценю!
- Произошла ошибка
- Не найден подходящий браузер для открытия этого веб-сайта!
-
diff --git a/libraries/Donations/src/main/res/values-sl-rSI/donations__strings.xml b/libraries/Donations/src/main/res/values-sl-rSI/donations__strings.xml
deleted file mode 100644
index fa91764..0000000
--- a/libraries/Donations/src/main/res/values-sl-rSI/donations__strings.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- Zapri
- Flattr
- Flattr vzame 10% kot mesečni strošek!
- Google Trgovina (Play Store)
- Donacije znotraj aplikacije niso možne. Imate nameščeno Google Trgovino (Play Store)?
- Google vzame 30% od vsake donacije!
- Doniraj!
- Koliko?
- PayPal
- O velikosti donacije boste odločili po tem ko pritisnete gumb!
- Hvala!
- Hvala za donacijo!\nRes cenim to!
-
diff --git a/libraries/Donations/src/main/res/values-sr/donations__strings.xml b/libraries/Donations/src/main/res/values-sr/donations__strings.xml
deleted file mode 100644
index 295a2e6..0000000
--- a/libraries/Donations/src/main/res/values-sr/donations__strings.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- Zatvori
- Da li vam je ovo korisna aplikacija?\nPodržite njen razvitak slanjem donacije razvijaču!
- Flattr uzima 10 % provizije mesečno!
- Google Play prodavnica
- Donacije u aplikaciji nisu dostupne. Da li je Google Play prodavnica ispravno instalirana?
- Google uzima 30 % od svae donacije!
- Doniraj!
- Koliko?
- PayPal
- Možete odabrati koliko ćete donirati posle pritiska na dugme!
- Hvala!
- Hvala za donaciju!\nZaista cenim to!
- Došlo je do greške
-
diff --git a/libraries/Donations/src/main/res/values-sv/donations__strings.xml b/libraries/Donations/src/main/res/values-sv/donations__strings.xml
deleted file mode 100644
index 5a31d2f..0000000
--- a/libraries/Donations/src/main/res/values-sv/donations__strings.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- Avsluta
- Flattr
- Flattr tar 10% som månadskostnad
- Google Play Store
- In-App-donationer stödjs inte. Är Google Play Store installerad korrekt?
- Google tar 30% av varje donation
- Donera!
- Hur mycket?
- PayPal
- Du kan välja hur mycket du vill donera efter du har tryckt på knappen!
- Tack!
- Tack för donationen!\nDet uppskattas verkligen!
-
diff --git a/libraries/Donations/src/main/res/values-tr/donations__strings.xml b/libraries/Donations/src/main/res/values-tr/donations__strings.xml
deleted file mode 100644
index ad4cad9..0000000
--- a/libraries/Donations/src/main/res/values-tr/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Kapat
- Flattr
- Bu uygulamayı kullanışlı mı buluyorsunuz?\nGeliştiriciye bağış yaparak gelişmesine yardımcı olun!
- Flattr takes 10 % as a monthly fee!
- Google Play Store
- Uygulama içi bağışlar desteklenmiyor. Google Play Store düzgünce kuruldu mu?
- Google her bağışın %30\'unu alıyor!
- Bağış Yap!
- Ne kadar?
- PayPal
- Butona bastıktan sonra ne kadar bağış yapacağınızı seçebilirsiniz!
- Teşekkürler!
- Bağış için teşekkürler!\nBunu gerçekten takdir ediyorum!
- Hata oluştu
- Website açmak için tarayıcı bulunamadı
-
diff --git a/libraries/Donations/src/main/res/values-uk/donations__strings.xml b/libraries/Donations/src/main/res/values-uk/donations__strings.xml
deleted file mode 100644
index 9eea84b..0000000
--- a/libraries/Donations/src/main/res/values-uk/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Закрити
- Flattr
- Ви вважаєте програму корисною?\n Підтримайте її розробку надіславши пожертву розробнику!
- Flattr стягує 10% у вигляді щомісячної абонентської плати!
- магазин Google Play
- Пожертвування через програму не підтримуються. Магазин Google Play встановлений правильно?
- Google стягує 30% з кожного пожертвування!
- Пожертвувати!
- Скільки?
- PayPal
- Після натискання на кнопку ви можете вибрати скільки хочете пожертвувати!
- Дякую!
- Дякую за пожертвування! Я дуже це ціную!
- Трапилася помилка
- Не знайдено жодного переглядача, щоб відкрити веб-сайт!
-
diff --git a/libraries/Donations/src/main/res/values-vi-rVN/donations__strings.xml b/libraries/Donations/src/main/res/values-vi-rVN/donations__strings.xml
deleted file mode 100644
index 6b71575..0000000
--- a/libraries/Donations/src/main/res/values-vi-rVN/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Đóng
- Đánh giá
- Bạn có thấy ứng này hữu ích?\nHãy hỗ trợ việc phát triển của phần mềm bằng cách ủng hộ tài chính!
- Đánh giá cao mất 10% như phí tháng!
- CH Google Play
- Không hỗ trợ chức năng ủng hộ trong ứng dụng. CH Google Play có hoạt động chính xác?
- Google hưởng 30% giá trị ủng hộ!
- Ủng hộ!
- Bao nhiêu?
- PayPal
- Bạn có thể bấm nút chọn số tiền cần ủng hộ!
- Xin cám ơn!
- Cám ơn bạn đã ủng hộ!\nTôi thực sự cảm kích!
- Lỗi đã xảy ra
- Không có trinnhf duyệt nào được tìm thấy để mở ra liên kết đến website!
-
diff --git a/libraries/Donations/src/main/res/values-vi/donations__strings.xml b/libraries/Donations/src/main/res/values-vi/donations__strings.xml
deleted file mode 100644
index 0c62253..0000000
--- a/libraries/Donations/src/main/res/values-vi/donations__strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- Đóng
-
diff --git a/libraries/Donations/src/main/res/values-zh-rCN/donations__strings.xml b/libraries/Donations/src/main/res/values-zh-rCN/donations__strings.xml
deleted file mode 100644
index 9eb8c7b..0000000
--- a/libraries/Donations/src/main/res/values-zh-rCN/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- 关闭
- Flattr®
- 喜欢这个应用程序?\n通过捐赠来支持我们!
- Flattr® 将从月费中提成10%!
- Google Play 商店
- 不支持 In-App 捐赠。你的 Google Play 商店是否安装正确了呢?
- Google 要从捐赠中抽取3成!\n
- 捐赠!
- 捐赠多少?
- PayPal
- 点击这个按钮之后选择你想要捐赠多少!
- 谢谢!
- 谢谢捐赠!\n非常感谢您!
- 发生错误
- 未找到浏览器来打开网页
-
diff --git a/libraries/Donations/src/main/res/values-zh-rHK/donations__strings.xml b/libraries/Donations/src/main/res/values-zh-rHK/donations__strings.xml
deleted file mode 100644
index 92236c4..0000000
--- a/libraries/Donations/src/main/res/values-zh-rHK/donations__strings.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- 關閉
- 透過 Flattr 捐款
- 這個廣告攔截程式對您有用嗎?\n您可透過以下方式進行捐款去支持本程式及其開發者!
- Flattr 會收取 10% 月費!
- 透過 Google Play 捐款
- 捐款不支援 In-App 模式。您的 Google Play 是否安裝正確?
- Google 會在每項捐款中收取 30% 手續費!
- 按此進行捐款!
- 要捐多少?
- 透過 PayPal 捐款
- 點擊按鈕您就可以選擇捐多少!
- 感謝!
- 感謝您的捐款!\n真的非常感激!
- 發生錯誤
- 沒有找到任何瀏覽器去開啟網頁!
-
diff --git a/libraries/Donations/src/main/res/values-zh-rTW/donations__strings.xml b/libraries/Donations/src/main/res/values-zh-rTW/donations__strings.xml
deleted file mode 100644
index 9034cac..0000000
--- a/libraries/Donations/src/main/res/values-zh-rTW/donations__strings.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- 關閉
- Flattr®
- Flattr®將從資助金額中扣取10%作為手續費!
- Google Play 商店
- 不支援In-App資助。你的Google Play 商店是否正確安裝?
- Google 會從每筆資助金額中抽取3成!
- 資助開發者!
- 多少?
- PayPal
- 你可以選擇你想資助多少後點擊按鈕!
- 謝謝!
- 謝謝您的資助!\n真的很感謝您!
-
diff --git a/libraries/Donations/src/main/res/values/donations__strings.xml b/libraries/Donations/src/main/res/values/donations__strings.xml
deleted file mode 100644
index 896c042..0000000
--- a/libraries/Donations/src/main/res/values/donations__strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- Close
- Flattr
- Do you find this application useful?\nSupport it\'s development by sending a donation to the developer!
- Flattr takes 10 % as a monthly fee!
- Google Play Store
- In-App Donations are not supported.
- In-App Donations are not supported. Is Google Play Store installed correctly?
- Google takes 30 % off every donation!
- Donate!
- How much?
- PayPal
- You can choose how much you want to donate after clicking the button!
- Thanks!
- Thanks for donating!\nI really appreciate this!
- Error occurred
- No browser was found to open a website!
-
-
diff --git a/libraries/HtmlTextView/.gitignore b/libraries/HtmlTextView/.gitignore
deleted file mode 100644
index afa9dfc..0000000
--- a/libraries/HtmlTextView/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-#Android specific
-bin
-gen
-obj
-libs/armeabi
-lint.xml
-local.properties
-release.properties
-ant.properties
-*.class
-*.apk
-
-#Gradle
-.gradle
-build
-gradle.properties
-gradlew
-gradlew.bat
-gradle
-
-#Maven
-target
-pom.xml.*
-
-#Eclipse
-.project
-.classpath
-.settings
-.metadata
-
-#IntelliJ IDEA
-.idea
-*.iml
diff --git a/libraries/HtmlTextView/LICENSE b/libraries/HtmlTextView/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/libraries/HtmlTextView/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/libraries/HtmlTextView/README.md b/libraries/HtmlTextView/README.md
deleted file mode 100644
index 05714f7..0000000
--- a/libraries/HtmlTextView/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# HtmlTextView for Android
-
-This HtmlTextView supports all HTML tags supported by Android's Html class (see [The CommonsBlog](http://commonsware.com/blog/Android/2010/05/26/html-tags-supported-by-textview.html) and [history of Html class](https://github.com/android/platform_frameworks_base/commits/master/core/java/android/text/Html.java) for newer additions).
-Additionally, list tags are supported (``
``, ````, ``
``) and code tags with ````.
-
-This also includes a workaround to prevent TextView crashing on [specific Android versions](http://code.google.com/p/android/issues/detail?id=35466).
-
-This library is kept very tiny with no external dependencies.
-I am using it to provide Help/About Activities in my apps.
-
-## Example
-
-```
-HtmlTextView text = new HtmlTextView(this);
-
-// loads html from string
-text.setHtmlFromString("Hello
world
cats
");
-```
-or
-```
-HtmlTextView text = new HtmlTextView(this);
-
-// loads html from raw resource, i.e., a html file in res/raw/, this allows translatable resource (e.g., res/raw-de/ for german)
-text.setHtmlFromRawResource(this, R.raw.help);
-```
-
-## Use library as Gradle dependency (Android library project)
-
-1. Copy this folder to your project and include it in ``settings.gradle`` with ``include ':html-textview'``
-2. Add dependency ``compile project(':html-textview')`` to your project's ``build.gradle``.
-
-## License
-
-Apache License v2
-
-## Authors
-- This library was hacked together by Dominik Schürmann
-- Original [TagHandler](https://gist.github.com/mlakkadshaw/5983704) developed by [Mohammed Lakkadshaw](http://blog.mohammedlakkadshaw.com/)
-- Original [UrlImageGetter](https://gist.github.com/Antarix/4167655) developed by Antarix Tandon
-- [JellyBeanSpanFixTextView](https://gist.github.com/pyricau/3424004) (with fix from comment) developed by Pierre-Yves Ricau
-
-## Contributions
-
-Feel free to fork and do pull requests. I am more than happy to merge them.
-Please do not introduce external dependencies.
\ No newline at end of file
diff --git a/libraries/HtmlTextView/build.gradle b/libraries/HtmlTextView/build.gradle
deleted file mode 100644
index 1b1b849..0000000
--- a/libraries/HtmlTextView/build.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
-apply plugin: 'android-library'
-
-android {
- compileSdkVersion 21
- buildToolsVersion "21.1.2"
-
- defaultConfig {
- minSdkVersion 16
- targetSdkVersion 21
- }
-
- // Do not abort build if lint finds errors
- lintOptions {
- abortOnError false
- }
-}
diff --git a/libraries/HtmlTextView/src/main/AndroidManifest.xml b/libraries/HtmlTextView/src/main/AndroidManifest.xml
deleted file mode 100644
index 1c747c1..0000000
--- a/libraries/HtmlTextView/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/libraries/HtmlTextView/src/main/java/org/sufficientlysecure/htmltextview/HtmlTagHandler.java b/libraries/HtmlTextView/src/main/java/org/sufficientlysecure/htmltextview/HtmlTagHandler.java
deleted file mode 100644
index c40c8de..0000000
--- a/libraries/HtmlTextView/src/main/java/org/sufficientlysecure/htmltextview/HtmlTagHandler.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2013 Mohammed Lakkadshaw
- *
- * 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.
- */
-
-package org.sufficientlysecure.htmltextview;
-
-import java.util.Vector;
-
-import org.xml.sax.XMLReader;
-
-import android.text.Editable;
-import android.text.Html;
-import android.text.Spannable;
-import android.text.style.BulletSpan;
-import android.text.style.LeadingMarginSpan;
-import android.text.style.TypefaceSpan;
-import android.util.Log;
-
-public class HtmlTagHandler implements Html.TagHandler {
- private int mListItemCount = 0;
- private Vector mListParents = new Vector();
-
- @Override
- public void handleTag(final boolean opening, final String tag, Editable output, final XMLReader xmlReader) {
-
- if (tag.equals("ul") || tag.equals("ol") || tag.equals("dd")) {
- if (opening) {
- mListParents.add(tag);
- } else mListParents.remove(tag);
-
- mListItemCount = 0;
- } else if (tag.equals("li") && !opening) {
- handleListTag(output);
- } else if (tag.equalsIgnoreCase("code")) {
- if (opening) {
- output.setSpan(new TypefaceSpan("monospace"), output.length(), output.length(), Spannable.SPAN_MARK_MARK);
- } else {
- Log.d(HtmlTextView.TAG, "Code tag encountered");
- Object obj = getLast(output, TypefaceSpan.class);
- int where = output.getSpanStart(obj);
- output.setSpan(new TypefaceSpan("monospace"), where, output.length(), 0);
- }
- }
- }
-
- private Object getLast(Editable text, Class kind) {
- Object[] objs = text.getSpans(0, text.length(), kind);
- if (objs.length == 0) {
- return null;
- } else {
- for (int i = objs.length; i > 0; i--) {
- if (text.getSpanFlags(objs[i - 1]) == Spannable.SPAN_MARK_MARK) {
- return objs[i - 1];
- }
- }
- return null;
- }
- }
-
- private void handleListTag(Editable output) {
- if (mListParents.lastElement().equals("ul")) {
- output.append("\n");
- String[] split = output.toString().split("\n");
-
- int lastIndex = split.length - 1;
- int start = output.length() - split[lastIndex].length() - 1;
- output.setSpan(new BulletSpan(15 * mListParents.size()), start, output.length(), 0);
- } else if (mListParents.lastElement().equals("ol")) {
- mListItemCount++;
-
- output.append("\n");
- String[] split = output.toString().split("\n");
-
- int lastIndex = split.length - 1;
- int start = output.length() - split[lastIndex].length() - 1;
- output.insert(start, mListItemCount + ". ");
- output.setSpan(new LeadingMarginSpan.Standard(15 * mListParents.size()), start, output.length(), 0);
- }
- }
-}
diff --git a/libraries/HtmlTextView/src/main/java/org/sufficientlysecure/htmltextview/HtmlTextView.java b/libraries/HtmlTextView/src/main/java/org/sufficientlysecure/htmltextview/HtmlTextView.java
deleted file mode 100644
index 317c25a..0000000
--- a/libraries/HtmlTextView/src/main/java/org/sufficientlysecure/htmltextview/HtmlTextView.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann
- *
- * 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.
- */
-
-package org.sufficientlysecure.htmltextview;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.method.LinkMovementMethod;
-import android.util.AttributeSet;
-
-import java.io.InputStream;
-
-public class HtmlTextView extends JellyBeanSpanFixTextView {
-
- public static final String TAG = "HtmlTextView";
-
- public HtmlTextView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- public HtmlTextView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public HtmlTextView(Context context) {
- super(context);
- }
-
- /**
- * http://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string
- *
- * @param is
- * @return
- */
- static private String convertStreamToString(java.io.InputStream is) {
- java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
- return s.hasNext() ? s.next() : "";
- }
-
- /**
- * Loads HTML from a raw resource, i.e., a HTML file in res/raw/.
- * This allows translatable resource (e.g., res/raw-de/ for german).
- * The containing HTML is parsed to Android's Spannable format and then displayed.
- *
- * @param context
- * @param id for example: R.raw.help
- */
- public void setHtmlFromRawResource(Context context, int id) {
- // load html from html file from /res/raw
- InputStream inputStreamText = context.getResources().openRawResource(id);
-
- setHtmlFromString(convertStreamToString(inputStreamText));
- }
-
- /**
- * Parses String containing HTML to Android's Spannable format and displays it in this TextView.
- *
- * @param html String containing HTML, for example: "Hello world!"
- */
- public void setHtmlFromString(String html) {
- // this uses Android's Html class for basic parsing, and HtmlTagHandler
- setText(Html.fromHtml(html, new UrlImageGetter(this, getContext()), new HtmlTagHandler()));
-
- // make links work
- setMovementMethod(LinkMovementMethod.getInstance());
-
- // no flickering when clicking textview for Android < 4
-// text.setTextColor(getResources().getColor(android.R.color.secondary_text_dark_nodisable));
- }
-}
diff --git a/libraries/HtmlTextView/src/main/java/org/sufficientlysecure/htmltextview/JellyBeanSpanFixTextView.java b/libraries/HtmlTextView/src/main/java/org/sufficientlysecure/htmltextview/JellyBeanSpanFixTextView.java
deleted file mode 100644
index 94bf458..0000000
--- a/libraries/HtmlTextView/src/main/java/org/sufficientlysecure/htmltextview/JellyBeanSpanFixTextView.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann
- * Copyright (C) 2012 Pierre-Yves Ricau
- *
- * 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.
- */
-
-package org.sufficientlysecure.htmltextview;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import android.content.Context;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.widget.TextView;
-
-/**
- *
- * A {@link android.widget.TextView} that insert spaces around its text spans where needed to prevent
- * {@link IndexOutOfBoundsException} in {@link #onMeasure(int, int)} on Jelly Bean.
- *
- * When {@link #onMeasure(int, int)} throws an exception, we try to fix the text by adding spaces
- * around spans, until it works again. We then try removing some of the added spans, to minimize the
- * insertions.
- *
- * The fix is time consuming (a few ms, it depends on the size of your text), but it should only
- * happen once per text change.
- *
- * See http://code.google.com/p/android/issues/detail?id=35466
- *
- */
-public class JellyBeanSpanFixTextView extends TextView {
-
- private static class FixingResult {
- public final boolean fixed;
- public final List