Merge pull request #31709 from akien-mga/android-fix-thirdparty

Android: Fix another regression with Secure.ANDROID_ID, and fix formatting and documentation of thirdparty code
This commit is contained in:
Rémi Verschelde 2019-08-27 20:16:08 +02:00 committed by GitHub
commit f38c64e8b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 5156 additions and 4721 deletions

View File

@ -86,6 +86,9 @@ do
if grep -q "thirdparty" <<< $file; then
continue;
fi
if grep -q "platform/android/java/src/com" <<< $file; then
continue;
fi
# ignore file if we do check for file extensions and the file
# does not match any of the extensions specified in $FILE_EXTS

View File

@ -11,7 +11,7 @@ else
RANGE=HEAD
fi
FILES=$(git diff-tree --no-commit-id --name-only -r $RANGE | grep -v thirdparty/ | grep -E "\.(c|h|cpp|hpp|cc|hh|cxx|m|mm|inc|java|glsl)$")
FILES=$(git diff-tree --no-commit-id --name-only -r $RANGE | grep -v thirdparty/ | grep -v platform/android/java/src/com/ | grep -E "\.(c|h|cpp|hpp|cc|hh|cxx|m|mm|inc|java|glsl)$")
echo "Checking files:\n$FILES"
# create a random filename to store our generated patch

View File

@ -1,47 +0,0 @@
# Third party libraries
## Google's vending library
- Upstream: https://github.com/google/play-licensing/tree/master/lvl_library/src/main/java/com/google/android/vending
- Version: git (eb57657, 2018) with modifications
- License: Apache 2.0
Overwrite all files under `com/google/android/vending`
### Modify some files to avoid compile error and lint warning
#### com/google/android/vending/licensing/util/Base64.java
```
@@ -338,7 +338,8 @@ public class Base64 {
e += 4;
}
- assert (e == outBuff.length);
+ if (BuildConfig.DEBUG && e != outBuff.length)
+ throw new RuntimeException();
return outBuff;
}
```
#### com/google/android/vending/licensing/LicenseChecker.java
```
@@ -29,8 +29,8 @@ import android.os.RemoteException;
import android.provider.Settings.Secure;
import android.util.Log;
-import com.android.vending.licensing.ILicenseResultListener;
-import com.android.vending.licensing.ILicensingService;
+import com.google.android.vending.licensing.ILicenseResultListener;
+import com.google.android.vending.licensing.ILicensingService;
import com.google.android.vending.licensing.util.Base64;
import com.google.android.vending.licensing.util.Base64DecoderException;
```
```
@@ -287,13 +287,15 @@ public class LicenseChecker implements ServiceConnection {
if (logResponse) {
- String android_id = Secure.getString(mContext.getContentResolver(),
- Secure.ANDROID_ID);
+ String android_id = Secure.ANDROID_ID;
Date date = new Date();
```

View File

@ -0,0 +1,39 @@
# Third-party libraries
This file list third-party libraries used in the Android source folder,
with their provenance and, when relevant, modifications made to those files.
## com.android.vending.billing
- Upstream: https://github.com/googlesamples/android-play-billing/tree/master/TrivialDrive/app/src/main
- Version: git (7a94c69, 2019)
- License: Apache 2.0
Overwrite the file `aidl/com/android/vending/billing/IInAppBillingService.aidl`.
## com.google.android.vending.expansion.downloader
- Upstream: https://github.com/google/play-apk-expansion/tree/master/apkx_library
- Version: git (9ecf54e, 2017)
- License: Apache 2.0
Overwrite all files under:
- `src/com/google/android/vending/expansion/downloader`
Some files have been modified for yet unclear reasons.
See the `patches/com.google.android.vending.expansion.downloader.patch` file.
## com.google.android.vending.licensing
- Upstream: https://github.com/google/play-licensing/tree/master/lvl_library/
- Version: git (eb57657, 2018) with modifications
- License: Apache 2.0
Overwrite all files under:
- `aidl/com/android/vending/licensing`
- `src/com/google/android/vending/licensing`
Some files have been modified to silence linter errors or fix downstream issues.
See the `patches/com.google.android.vending.licensing.patch` file.

View File

@ -34,10 +34,11 @@ import android.os.Bundle;
*
* 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_USER_CANCELED = 1 - User pressed back or canceled a dialog
* RESULT_SERVICE_UNAVAILABLE = 2 - The network connection is down
* 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
@ -46,11 +47,11 @@ 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 apiVersion billing API version that 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
* @param type type of the in-app item being purchased ("inapp" for one-time purchases
* and "subs" for subscriptions)
* @return RESULT_OK(0) on success and appropriate response code on failures.
*/
int isBillingSupported(int apiVersion, String packageName, String type);
@ -59,16 +60,23 @@ interface IInAppBillingService {
* 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 apiVersion billing API version that the app is using
* @param packageName the package name of the calling app
* @param type of the in-app items ("inapp" for one-time purchases
* and "subs" for subscriptions)
* @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.
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
* on failures.
* "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" }'
* '{ "productId" : "exampleSku",
* "type" : "inapp",
* "price" : "$5.00",
* "price_currency": "USD",
* "price_amount_micros": 5000000,
* "title : "Example Title",
* "description" : "This is an example description" }'
*/
Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle);
@ -78,19 +86,19 @@ interface IInAppBillingService {
* @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 type of the in-app item being purchased ("inapp" for one-time purchases
* and "subs" for subscriptions)
* @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.
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
* on failures.
* "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.
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
* codes on failures.
* "INAPP_PURCHASE_DATA" - String in JSON format similar to
* '{"orderId":"12999763169054705758.1371079406387615",
* "packageName":"com.example.app",
@ -100,7 +108,6 @@ interface IInAppBillingService {
* "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);
@ -112,15 +119,15 @@ interface IInAppBillingService {
* 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 type of the in-app items being requested ("inapp" for one-time purchases
* and "subs" for subscriptions)
* @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.
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
on failures.
* "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
@ -138,7 +145,137 @@ interface IInAppBillingService {
* @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.
* @return RESULT_OK(0) if consumption succeeded, appropriate response codes on failures.
*/
int consumePurchase(int apiVersion, String packageName, String purchaseToken);
/**
* This API is currently under development.
*/
int stub(int apiVersion, String packageName, String type);
/**
* Returns a pending intent to launch the purchase flow for upgrading or downgrading a
* subscription. The existing owned SKU(s) should be provided along with the new SKU that
* the user is upgrading or downgrading to.
* @param apiVersion billing API version that the app is using, must be 5 or later
* @param packageName package name of the calling app
* @param oldSkus the SKU(s) that the user is upgrading or downgrading from,
* if null or empty this method will behave like {@link #getBuyIntent}
* @param newSku the SKU that the user is upgrading or downgrading to
* @param type of the item being purchased, currently must be "subs"
* @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, appropriate response codes
* on failures.
* "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, appropriate response
* codes on failures.
* "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
*/
Bundle getBuyIntentToReplaceSkus(int apiVersion, String packageName,
in List<String> oldSkus, String newSku, String type, String developerPayload);
/**
* Returns a pending intent to launch the purchase flow for an in-app item. This method is
* a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams}
* parameter. This parameter is a Bundle of optional keys and values that affect the
* operation of the method.
* @param apiVersion billing API version that the app is using, must be 6 or later
* @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 of the in-app item being purchased ("inapp" for one-time purchases
* and "subs" for subscriptions)
* @param developerPayload optional argument to be sent back with the purchase information
* @extraParams a Bundle with the following optional keys:
* "skusToReplace" - List<String> - an optional list of SKUs that the user is
* upgrading or downgrading from.
* Pass this field if the purchase is upgrading or downgrading
* existing subscriptions.
* The specified SKUs are replaced with the SKUs that the user is
* purchasing. Google Play replaces the specified SKUs at the start of
* the next billing cycle.
* "replaceSkusProration" - Boolean - whether the user should be credited for any unused
* subscription time on the SKUs they are upgrading or downgrading.
* If you set this field to true, Google Play swaps out the old SKUs
* and credits the user with the unused value of their subscription
* time on a pro-rated basis.
* Google Play applies this credit to the new subscription, and does
* not begin billing the user for the new subscription until after
* the credit is used up.
* If you set this field to false, the user does not receive credit for
* any unused subscription time and the recurrence date does not
* change.
* Default value is true. Ignored if you do not pass skusToReplace.
* "accountId" - String - an optional obfuscated string that is uniquely
* associated with the user's account in your app.
* If you pass this value, Google Play can use it to detect irregular
* activity, such as many devices making purchases on the same
* account in a short period of time.
* Do not use the developer ID or the user's Google ID for this field.
* In addition, this field should not contain the user's ID in
* cleartext.
* We recommend that you use a one-way hash to generate a string from
* the user's ID, and store the hashed string in this field.
* "vr" - Boolean - an optional flag indicating whether the returned intent
* should start a VR purchase flow. The apiVersion must also be 7 or
* later to use this flag.
*/
Bundle getBuyIntentExtraParams(int apiVersion, String packageName, String sku,
String type, String developerPayload, in Bundle extraParams);
/**
* Returns the most recent purchase made by the user for each SKU, even if that purchase is
* expired, canceled, or consumed.
* @param apiVersion billing API version that the app is using, must be 6 or later
* @param packageName package name of the calling app
* @param type of the in-app items being requested ("inapp" for one-time purchases
* and "subs" for subscriptions)
* @param continuationToken to be set as null for the first call, if the number of owned
* skus is too large, 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.
* @param extraParams a Bundle with extra params that would be appended into http request
* query string. Not used at this moment. Reserved for future functionality.
* @return Bundle containing the following key-value pairs
* "RESPONSE_CODE" with int value: RESULT_OK(0) if success,
* {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures.
*
* "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs
* "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information
* "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> 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 getPurchaseHistory(int apiVersion, String packageName, String type,
String continuationToken, in Bundle extraParams);
/**
* This method is a variant of {@link #isBillingSupported}} that takes an additional
* {@code extraParams} parameter.
* @param apiVersion billing API version that the app is using, must be 7 or later
* @param packageName package name of the calling app
* @param type of the in-app item being purchased ("inapp" for one-time purchases and "subs"
* for subscriptions)
* @param extraParams a Bundle with the following optional keys:
* "vr" - Boolean - an optional flag to indicate whether {link #getBuyIntentExtraParams}
* supports returning a VR purchase flow.
* @return RESULT_OK(0) on success and appropriate response code on failures.
*/
int isBillingSupportedExtraParams(int apiVersion, String packageName, String type,
in Bundle extraParams);
}

View File

@ -16,8 +16,6 @@
package com.android.vending.licensing;
// Android library projects do not yet support AIDL, so this has been
// precompiled into the src directory.
oneway interface ILicenseResultListener {
void verifyLicense(int responseCode, String signedData, String signature);
}

View File

@ -18,8 +18,6 @@ package com.android.vending.licensing;
import com.android.vending.licensing.ILicenseResultListener;
// Android library projects do not yet support AIDL, so this has been
// precompiled into the src directory.
oneway interface ILicensingService {
void checkLicense(long nonce, String packageName, in ILicenseResultListener listener);
}

View File

@ -0,0 +1,300 @@
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java
index ad6ea0de6..452c7d148 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java
+++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java
@@ -32,6 +32,9 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
+// -- GODOT start --
+import java.lang.ref.WeakReference;
+// -- GODOT end --
/**
@@ -118,29 +121,46 @@ public class DownloaderClientMarshaller {
/**
* Target we publish for clients to send messages to IncomingHandler.
*/
- final Messenger mMessenger = new Messenger(new Handler() {
+ // -- GODOT start --
+ private final MessengerHandlerClient mMsgHandler = new MessengerHandlerClient(this);
+ final Messenger mMessenger = new Messenger(mMsgHandler);
+
+ private static class MessengerHandlerClient extends Handler {
+ private final WeakReference<Stub> mDownloader;
+ public MessengerHandlerClient(Stub downloader) {
+ mDownloader = new WeakReference<>(downloader);
+ }
+
@Override
public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_ONDOWNLOADPROGRESS:
- Bundle bun = msg.getData();
- if ( null != mContext ) {
- bun.setClassLoader(mContext.getClassLoader());
- DownloadProgressInfo dpi = (DownloadProgressInfo) msg.getData()
- .getParcelable(PARAM_PROGRESS);
- mItf.onDownloadProgress(dpi);
- }
- break;
- case MSG_ONDOWNLOADSTATE_CHANGED:
- mItf.onDownloadStateChanged(msg.getData().getInt(PARAM_NEW_STATE));
- break;
- case MSG_ONSERVICECONNECTED:
- mItf.onServiceConnected(
- (Messenger) msg.getData().getParcelable(PARAM_MESSENGER));
- break;
+ Stub downloader = mDownloader.get();
+ if (downloader != null) {
+ downloader.handleMessage(msg);
}
}
- });
+ }
+
+ private void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_ONDOWNLOADPROGRESS:
+ Bundle bun = msg.getData();
+ if (null != mContext) {
+ bun.setClassLoader(mContext.getClassLoader());
+ DownloadProgressInfo dpi = (DownloadProgressInfo)msg.getData()
+ .getParcelable(PARAM_PROGRESS);
+ mItf.onDownloadProgress(dpi);
+ }
+ break;
+ case MSG_ONDOWNLOADSTATE_CHANGED:
+ mItf.onDownloadStateChanged(msg.getData().getInt(PARAM_NEW_STATE));
+ break;
+ case MSG_ONSERVICECONNECTED:
+ mItf.onServiceConnected(
+ (Messenger)msg.getData().getParcelable(PARAM_MESSENGER));
+ break;
+ }
+ }
+ // -- GODOT end --
public Stub(IDownloaderClient itf, Class<?> downloaderService) {
mItf = itf;
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java
index 979352299..3771d19c9 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java
+++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java
@@ -25,6 +25,9 @@ import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
+// -- GODOT start --
+import java.lang.ref.WeakReference;
+// -- GODOT end --
/**
@@ -108,32 +111,49 @@ public class DownloaderServiceMarshaller {
private static class Stub implements IStub {
private IDownloaderService mItf = null;
- final Messenger mMessenger = new Messenger(new Handler() {
+ // -- GODOT start --
+ private final MessengerHandlerServer mMsgHandler = new MessengerHandlerServer(this);
+ final Messenger mMessenger = new Messenger(mMsgHandler);
+
+ private static class MessengerHandlerServer extends Handler {
+ private final WeakReference<Stub> mDownloader;
+ public MessengerHandlerServer(Stub downloader) {
+ mDownloader = new WeakReference<>(downloader);
+ }
+
@Override
public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_REQUEST_ABORT_DOWNLOAD:
- mItf.requestAbortDownload();
- break;
- case MSG_REQUEST_CONTINUE_DOWNLOAD:
- mItf.requestContinueDownload();
- break;
- case MSG_REQUEST_PAUSE_DOWNLOAD:
- mItf.requestPauseDownload();
- break;
- case MSG_SET_DOWNLOAD_FLAGS:
- mItf.setDownloadFlags(msg.getData().getInt(PARAMS_FLAGS));
- break;
- case MSG_REQUEST_DOWNLOAD_STATE:
- mItf.requestDownloadStatus();
- break;
- case MSG_REQUEST_CLIENT_UPDATE:
- mItf.onClientUpdated((Messenger) msg.getData().getParcelable(
- PARAM_MESSENGER));
- break;
+ Stub downloader = mDownloader.get();
+ if (downloader != null) {
+ downloader.handleMessage(msg);
}
}
- });
+ }
+
+ private void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_REQUEST_ABORT_DOWNLOAD:
+ mItf.requestAbortDownload();
+ break;
+ case MSG_REQUEST_CONTINUE_DOWNLOAD:
+ mItf.requestContinueDownload();
+ break;
+ case MSG_REQUEST_PAUSE_DOWNLOAD:
+ mItf.requestPauseDownload();
+ break;
+ case MSG_SET_DOWNLOAD_FLAGS:
+ mItf.setDownloadFlags(msg.getData().getInt(PARAMS_FLAGS));
+ break;
+ case MSG_REQUEST_DOWNLOAD_STATE:
+ mItf.requestDownloadStatus();
+ break;
+ case MSG_REQUEST_CLIENT_UPDATE:
+ mItf.onClientUpdated((Messenger)msg.getData().getParcelable(
+ PARAM_MESSENGER));
+ break;
+ }
+ }
+ // -- GODOT end --
public Stub(IDownloaderService itf) {
mItf = itf;
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java
index e4b1b0f1c..36cd6aacf 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java
+++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java
@@ -24,7 +24,10 @@ import android.os.StatFs;
import android.os.SystemClock;
import android.util.Log;
-import com.android.vending.expansion.downloader.R;
+// -- GODOT start --
+//import com.android.vending.expansion.downloader.R;
+import com.godot.game.R;
+// -- GODOT end --
import java.io.File;
import java.text.SimpleDateFormat;
@@ -146,12 +149,14 @@ public class Helpers {
}
return "";
}
- return String.format("%.2f",
+ // -- GODOT start --
+ return String.format(Locale.ENGLISH, "%.2f",
(float) overallProgress / (1024.0f * 1024.0f))
+ "MB /" +
- String.format("%.2f", (float) overallTotal /
+ String.format(Locale.ENGLISH, "%.2f", (float) overallTotal /
(1024.0f * 1024.0f))
+ "MB";
+ // -- GODOT end --
}
/**
@@ -184,7 +189,9 @@ public class Helpers {
}
public static String getSpeedString(float bytesPerMillisecond) {
- return String.format("%.2f", bytesPerMillisecond * 1000 / 1024);
+ // -- GODOT start --
+ return String.format(Locale.ENGLISH, "%.2f", bytesPerMillisecond * 1000 / 1024);
+ // -- GODOT end --
}
public static String getTimeRemaining(long durationInMilliseconds) {
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/SystemFacade.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/SystemFacade.java
index 12edd97ab..a0e1165cc 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/SystemFacade.java
+++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/SystemFacade.java
@@ -26,6 +26,10 @@ import android.net.NetworkInfo;
import android.telephony.TelephonyManager;
import android.util.Log;
+// -- GODOT start --
+import android.annotation.SuppressLint;
+// -- GODOT end --
+
/**
* Contains useful helper functions, typically tied to the application context.
*/
@@ -51,6 +55,7 @@ class SystemFacade {
return null;
}
+ @SuppressLint("MissingPermission")
NetworkInfo activeInfo = connectivity.getActiveNetworkInfo();
if (activeInfo == null) {
if (Constants.LOGVV) {
@@ -69,6 +74,7 @@ class SystemFacade {
return false;
}
+ @SuppressLint("MissingPermission")
NetworkInfo info = connectivity.getActiveNetworkInfo();
boolean isMobile = (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE);
TelephonyManager tm = (TelephonyManager) mContext
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
index f1536e80e..4b214b22d 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
+++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
@@ -16,7 +16,11 @@
package com.google.android.vending.expansion.downloader.impl;
-import com.android.vending.expansion.downloader.R;
+// -- GODOT start --
+//import com.android.vending.expansion.downloader.R;
+import com.godot.game.R;
+// -- GODOT end --
+
import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;
import com.google.android.vending.expansion.downloader.Helpers;
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java
index b2e0e7af0..c114b8a64 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java
+++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java
@@ -146,8 +146,12 @@ public class DownloadThread {
try {
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Constants.TAG);
- wakeLock.acquire();
+ // -- GODOT start --
+ //wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Constants.TAG);
+ //wakeLock.acquire();
+ wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "org.godot.game:wakelock");
+ wakeLock.acquire(20 * 60 * 1000L /*20 minutes*/);
+ // -- GODOT end --
if (Constants.LOGV) {
Log.v(Constants.TAG, "initiating download for " + mInfo.mFileName);
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
index 4babe476f..8d41a7690 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
+++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
@@ -50,6 +50,10 @@ import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.util.Log;
+// -- GODOT start --
+import android.annotation.SuppressLint;
+// -- GODOT end --
+
import java.io.File;
/**
@@ -578,6 +582,7 @@ public abstract class DownloaderService extends CustomIntentService implements I
Log.w(Constants.TAG,
"couldn't get connectivity manager to poll network state");
} else {
+ @SuppressLint("MissingPermission")
NetworkInfo activeInfo = mConnectivityManager
.getActiveNetworkInfo();
updateNetworkState(activeInfo);

View File

@ -0,0 +1,42 @@
diff --git a/platform/android/java/src/com/google/android/vending/licensing/PreferenceObfuscator.java b/platform/android/java/src/com/google/android/vending/licensing/PreferenceObfuscator.java
index 7c42bfc28..feb579af0 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/PreferenceObfuscator.java
+++ b/platform/android/java/src/com/google/android/vending/licensing/PreferenceObfuscator.java
@@ -45,6 +45,9 @@ public class PreferenceObfuscator {
public void putString(String key, String value) {
if (mEditor == null) {
mEditor = mPreferences.edit();
+ // -- GODOT start --
+ mEditor.apply();
+ // -- GODOT end --
}
String obfuscatedValue = mObfuscator.obfuscate(value, key);
mEditor.putString(key, obfuscatedValue);
diff --git a/platform/android/java/src/com/google/android/vending/licensing/util/Base64.java b/platform/android/java/src/com/google/android/vending/licensing/util/Base64.java
index a0d2779af..a8bf65f9c 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/util/Base64.java
+++ b/platform/android/java/src/com/google/android/vending/licensing/util/Base64.java
@@ -31,6 +31,10 @@ package com.google.android.vending.licensing.util;
* @version 1.3
*/
+// -- GODOT start --
+import com.godot.game.BuildConfig;
+// -- GODOT end --
+
/**
* Base64 converter class. This code is not a full-blown MIME encoder;
* it simply converts binary data to base64 data and back.
@@ -341,7 +345,11 @@ public class Base64 {
e += 4;
}
- assert (e == outBuff.length);
+ // -- GODOT start --
+ //assert (e == outBuff.length);
+ if (BuildConfig.DEBUG && e != outBuff.length)
+ throw new RuntimeException();
+ // -- GODOT end --
return outBuff;
}

View File

@ -18,6 +18,7 @@ package com.google.android.vending.expansion.downloader;
import java.io.File;
/**
* Contains the internal constants that are used in the download manager.
* As a general rule, modifying these constants should be done with care.
@ -29,7 +30,8 @@ public class Constants {
/**
* Expansion path where we store obb files
*/
public static final String EXP_PATH = File.separator + "Android" + File.separator + "obb" + File.separator;
public static final String EXP_PATH = File.separator + "Android"
+ File.separator + "obb" + File.separator;
/** The intent that gets sent when the service must wake up for a retry */
public static final String ACTION_RETRY = "android.intent.action.DOWNLOAD_WAKEUP";
@ -230,4 +232,5 @@ public class Constants {
* The wake duration to check to see if the process was killed.
*/
public static final long ACTIVE_THREAD_WATCHDOG = 5*1000;
}

View File

@ -19,6 +19,7 @@ package com.google.android.vending.expansion.downloader;
import android.os.Parcel;
import android.os.Parcelable;
/**
* This class contains progress information about the active download(s).
*
@ -75,4 +76,5 @@ public class DownloadProgressInfo implements Parcelable {
return new DownloadProgressInfo[i];
}
};
}

View File

@ -32,7 +32,10 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
// -- GODOT start --
import java.lang.ref.WeakReference;
// -- GODOT end --
/**
* This class binds the service API to your application client. It contains the IDownloaderClient proxy,
@ -118,6 +121,7 @@ public class DownloaderClientMarshaller {
/**
* Target we publish for clients to send messages to IncomingHandler.
*/
// -- GODOT start --
private final MessengerHandlerClient mMsgHandler = new MessengerHandlerClient(this);
final Messenger mMessenger = new Messenger(mMsgHandler);
@ -156,6 +160,7 @@ public class DownloaderClientMarshaller {
break;
}
}
// -- GODOT end --
public Stub(IDownloaderClient itf, Class<?> downloaderService) {
mItf = itf;
@ -196,6 +201,7 @@ public class DownloaderClientMarshaller {
} else {
mBound = true;
}
}
@Override
@ -287,4 +293,5 @@ public class DownloaderClientMarshaller {
return DownloaderService.startDownloadServiceIfRequired(context, notificationClient,
serviceClass);
}
}

View File

@ -25,7 +25,10 @@ import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
// -- GODOT start --
import java.lang.ref.WeakReference;
// -- GODOT end --
/**
* This class is used by the client activity to proxy requests to the Downloader
@ -108,6 +111,7 @@ public class DownloaderServiceMarshaller {
private static class Stub implements IStub {
private IDownloaderService mItf = null;
// -- GODOT start --
private final MessengerHandlerServer mMsgHandler = new MessengerHandlerServer(this);
final Messenger mMessenger = new Messenger(mMsgHandler);
@ -149,6 +153,7 @@ public class DownloaderServiceMarshaller {
break;
}
}
// -- GODOT end --
public Stub(IDownloaderService itf) {
mItf = itf;
@ -161,10 +166,12 @@ public class DownloaderServiceMarshaller {
@Override
public void connect(Context c) {
}
@Override
public void disconnect(Context c) {
}
}
@ -190,4 +197,5 @@ public class DownloaderServiceMarshaller {
public static IStub CreateStub(IDownloaderService itf) {
return new Stub(itf);
}
}

View File

@ -24,7 +24,10 @@ import android.os.StatFs;
import android.os.SystemClock;
import android.util.Log;
// -- GODOT start --
//import com.android.vending.expansion.downloader.R;
import com.godot.game.R;
// -- GODOT end --
import java.io.File;
import java.text.SimpleDateFormat;
@ -113,7 +116,8 @@ public class Helpers {
public static boolean isFilenameValid(String filename) {
filename = filename.replaceFirst("/+", "/"); // normalize leading
// slashes
return filename.startsWith(Environment.getDownloadCacheDirectory().toString()) || filename.startsWith(Environment.getExternalStorageDirectory().toString());
return filename.startsWith(Environment.getDownloadCacheDirectory().toString())
|| filename.startsWith(Environment.getExternalStorageDirectory().toString());
}
/*
@ -145,10 +149,14 @@ public class Helpers {
}
return "";
}
// -- GODOT start --
return String.format(Locale.ENGLISH, "%.2f",
(float)overallProgress / (1024.0f * 1024.0f)) +
"MB /" +
String.format(Locale.ENGLISH, "%.2f", (float)overallTotal / (1024.0f * 1024.0f)) + "MB";
(float) overallProgress / (1024.0f * 1024.0f))
+ "MB /" +
String.format(Locale.ENGLISH, "%.2f", (float) overallTotal /
(1024.0f * 1024.0f))
+ "MB";
// -- GODOT end --
}
/**
@ -181,7 +189,9 @@ public class Helpers {
}
public static String getSpeedString(float bytesPerMillisecond) {
// -- GODOT start --
return String.format(Locale.ENGLISH, "%.2f", bytesPerMillisecond * 1000 / 1024);
// -- GODOT end --
}
public static String getTimeRemaining(long durationInMilliseconds) {
@ -210,7 +220,8 @@ public class Helpers {
* Returns the filename (where the file should be saved) from info about a download
*/
static public String generateSaveFileName(Context c, String fileName) {
String path = getSaveFilePath(c) + File.separator + fileName;
String path = getSaveFilePath(c)
+ File.separator + fileName;
return path;
}
@ -352,4 +363,5 @@ public class Helpers {
return R.string.state_unknown;
}
}
}

View File

@ -16,7 +16,6 @@
package com.google.android.vending.expansion.downloader;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
@ -27,6 +26,10 @@ import android.net.NetworkInfo;
import android.telephony.TelephonyManager;
import android.util.Log;
// -- GODOT start --
import android.annotation.SuppressLint;
// -- GODOT end --
/**
* Contains useful helper functions, typically tied to the application context.
*/

View File

@ -51,7 +51,8 @@ public abstract class CustomIntentService extends Service {
@Override
public void onCreate() {
super.onCreate();
HandlerThread localHandlerThread = new HandlerThread("IntentService[" + this.mName + "]");
HandlerThread localHandlerThread = new HandlerThread("IntentService["
+ this.mName + "]");
localHandlerThread.start();
this.mServiceLooper = localHandlerThread.getLooper();
this.mServiceHandler = new ServiceHandler(this.mServiceLooper);

View File

@ -16,7 +16,11 @@
package com.google.android.vending.expansion.downloader.impl;
// -- GODOT start --
//import com.android.vending.expansion.downloader.R;
import com.godot.game.R;
// -- GODOT end --
import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;
import com.google.android.vending.expansion.downloader.Helpers;
@ -221,4 +225,5 @@ public class DownloadNotification implements IDownloaderClient {
@Override
public void onServiceConnected(Messenger m) {
}
}

View File

@ -54,7 +54,9 @@ public class DownloadThread {
mService = service;
mNotification = notification;
mDB = DownloadsDB.getDB(service);
mUserAgent = "APKXDL (Linux; U; Android " + android.os.Build.VERSION.RELEASE + ";" + Locale.getDefault().toString() + "; " + android.os.Build.DEVICE + "/" + android.os.Build.ID + ")" +
mUserAgent = "APKXDL (Linux; U; Android " + android.os.Build.VERSION.RELEASE + ";"
+ Locale.getDefault().toString() + "; " + android.os.Build.DEVICE + "/"
+ android.os.Build.ID + ")" +
service.getPackageName();
}
@ -144,8 +146,12 @@ public class DownloadThread {
try {
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
// -- GODOT start --
//wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Constants.TAG);
//wakeLock.acquire();
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "org.godot.game:wakelock");
wakeLock.acquire(20 * 60 * 1000L /*20 minutes*/);
// -- GODOT end --
if (Constants.LOGV) {
Log.v(Constants.TAG, "initiating download for " + mInfo.mFileName);
@ -386,7 +392,10 @@ public class DownloadThread {
*/
private void reportProgress(State state, InnerState innerState) {
long now = System.currentTimeMillis();
if (innerState.mBytesSoFar - innerState.mBytesNotified > Constants.MIN_PROGRESS_STEP && now - innerState.mTimeLastNotification > Constants.MIN_PROGRESS_TIME) {
if (innerState.mBytesSoFar - innerState.mBytesNotified
> Constants.MIN_PROGRESS_STEP
&& now - innerState.mTimeLastNotification
> Constants.MIN_PROGRESS_TIME) {
// we store progress updates to the database here
mInfo.mCurrentBytes = innerState.mBytesSoFar;
mDB.updateDownloadCurrentBytes(mInfo);
@ -397,8 +406,10 @@ public class DownloadThread {
long totalBytesSoFar = innerState.mBytesThisSession + mService.mBytesSoFar;
if (Constants.LOGVV) {
Log.v(Constants.TAG, "downloaded " + mInfo.mCurrentBytes + " out of " + mInfo.mTotalBytes);
Log.v(Constants.TAG, " total " + totalBytesSoFar + " out of " + mService.mTotalLength);
Log.v(Constants.TAG, "downloaded " + mInfo.mCurrentBytes + " out of "
+ mInfo.mTotalBytes);
Log.v(Constants.TAG, " total " + totalBytesSoFar + " out of "
+ mService.mTotalLength);
}
mService.notifyUpdateBytes(totalBytesSoFar);
@ -452,7 +463,8 @@ public class DownloadThread {
// }
mDB.updateDownload(mInfo);
boolean lengthMismatched = (innerState.mHeaderContentLength != null) && (innerState.mBytesSoFar != Integer.parseInt(innerState.mHeaderContentLength));
boolean lengthMismatched = (innerState.mHeaderContentLength != null)
&& (innerState.mBytesSoFar != Integer.parseInt(innerState.mHeaderContentLength));
if (lengthMismatched) {
if (cannotResume(innerState)) {
throw new StopRequest(DownloaderService.STATUS_CANNOT_RESUME,
@ -485,7 +497,8 @@ public class DownloadThread {
mInfo.mCurrentBytes = innerState.mBytesSoFar;
mDB.updateDownload(mInfo);
if (cannotResume(innerState)) {
String message = "while reading response: " + ex.toString() + ", can't resume interrupted download with no ETag";
String message = "while reading response: " + ex.toString()
+ ", can't resume interrupted download with no ETag";
throw new StopRequest(DownloaderService.STATUS_CANNOT_RESUME,
message, ex);
} else {
@ -514,7 +527,9 @@ public class DownloadThread {
private void logNetworkState() {
if (Constants.LOGX) {
Log.i(Constants.TAG,
"Net " + (mService.getNetworkAvailabilityState(mDB) == DownloaderService.NETWORK_OK ? "Up" : "Down"));
"Net "
+ (mService.getNetworkAvailabilityState(mDB) == DownloaderService.NETWORK_OK ? "Up"
: "Down"));
}
}
@ -631,7 +646,9 @@ public class DownloadThread {
Log.v(Constants.TAG, "Transfer-Encoding: " + headerTransferEncoding);
}
boolean noSizeInfo = innerState.mHeaderContentLength == null && (headerTransferEncoding == null || !headerTransferEncoding.equalsIgnoreCase("chunked"));
boolean noSizeInfo = innerState.mHeaderContentLength == null
&& (headerTransferEncoding == null
|| !headerTransferEncoding.equalsIgnoreCase("chunked"));
if (noSizeInfo) {
throw new StopRequest(DownloaderService.STATUS_HTTP_DATA_ERROR,
"can't know size of download, giving up");
@ -647,7 +664,8 @@ public class DownloadThread {
if (responseCode == 503 && mInfo.mNumFailed < Constants.MAX_RETRIES) {
handleServiceUnavailable(state, connection);
}
int expectedStatus = innerState.mContinuingDownload ? 206 : DownloaderService.STATUS_SUCCESS;
int expectedStatus = innerState.mContinuingDownload ? 206
: DownloaderService.STATUS_SUCCESS;
if (responseCode != expectedStatus) {
handleOtherStatus(state, innerState, responseCode);
} else {
@ -830,4 +848,5 @@ public class DownloadThread {
}
mDB.updateDownload(mInfo);
}
}

View File

@ -29,7 +29,6 @@ import com.google.android.vending.licensing.LicenseChecker;
import com.google.android.vending.licensing.LicenseCheckerCallback;
import com.google.android.vending.licensing.Policy;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
@ -51,6 +50,10 @@ import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.util.Log;
// -- GODOT start --
import android.annotation.SuppressLint;
// -- GODOT end --
import java.io.File;
/**
@ -185,7 +188,8 @@ public abstract class DownloaderService extends CustomIntentService implements I
* error).
*/
public static boolean isStatusCompleted(int status) {
return (status >= 200 && status < 300) || (status >= 400 && status < 600);
return (status >= 200 && status < 300)
|| (status >= 400 && status < 600);
}
/**
@ -528,7 +532,10 @@ public abstract class DownloaderService extends CustomIntentService implements I
mIsConnected = false;
updateNetworkType(-1, -1);
}
mStateChanged = (mStateChanged || isConnected != mIsConnected || isFailover != mIsFailover || isCellularConnection != mIsCellularConnection || isRoaming != mIsRoaming || isAtLeast3G != mIsAtLeast3G);
mStateChanged = (mStateChanged || isConnected != mIsConnected
|| isFailover != mIsFailover
|| isCellularConnection != mIsCellularConnection
|| isRoaming != mIsRoaming || isAtLeast3G != mIsAtLeast3G);
if (Constants.LOGVV) {
if (mStateChanged) {
Log.v(LOG_TAG, "Network state changed: ");
@ -556,6 +563,7 @@ public abstract class DownloaderService extends CustomIntentService implements I
}
}
}
}
}
}
@ -628,7 +636,8 @@ public abstract class DownloaderService extends CustomIntentService implements I
public static int startDownloadServiceIfRequired(Context context,
PendingIntent pendingIntent, Class<?> serviceClass)
throws NameNotFoundException {
throws NameNotFoundException
{
String packageName = context.getPackageName();
String className = serviceClass.getName();
@ -746,7 +755,8 @@ public abstract class DownloaderService extends CustomIntentService implements I
public void run() {
setServiceRunning(true);
mNotification.onDownloadStateChanged(IDownloaderClient.STATE_FETCHING_URL);
String deviceId = Secure.ANDROID_ID;
String deviceId = Secure.getString(mContext.getContentResolver(),
Secure.ANDROID_ID);
final APKExpansionPolicy aep = new APKExpansionPolicy(mContext,
new AESObfuscator(getSALT(), mContext.getPackageName(), deviceId));
@ -761,6 +771,7 @@ public abstract class DownloaderService extends CustomIntentService implements I
getPublicKey() // Your public licensing key.
);
checker.checkAccess(new LicenseCheckerCallback() {
@Override
public void allow(int reason) {
try {
@ -798,7 +809,8 @@ public abstract class DownloaderService extends CustomIntentService implements I
// was delivered by Market or
// through
// another mechanism
Log.d(LOG_TAG, "file " + di.mFileName + " found. Not downloading.");
Log.d(LOG_TAG, "file " + di.mFileName
+ " found. Not downloading.");
di.mStatus = STATUS_SUCCESS;
di.mTotalBytes = fileSize;
di.mCurrentBytes = fileSize;
@ -854,7 +866,8 @@ public abstract class DownloaderService extends CustomIntentService implements I
@Override
public void dontAllow(int reason) {
try {
try
{
switch (reason) {
case Policy.NOT_LICENSED:
mNotification
@ -868,6 +881,7 @@ public abstract class DownloaderService extends CustomIntentService implements I
} finally {
setServiceRunning(false);
}
}
@Override
@ -879,8 +893,11 @@ public abstract class DownloaderService extends CustomIntentService implements I
setServiceRunning(false);
}
}
});
}
};
/**
@ -947,7 +964,8 @@ public abstract class DownloaderService extends CustomIntentService implements I
PendingIntent.FLAG_ONE_SHOT);
alarms.set(
AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + wakeUp, mAlarmIntent);
System.currentTimeMillis() + wakeUp, mAlarmIntent
);
}
private void cancelAlarms() {
@ -976,7 +994,8 @@ public abstract class DownloaderService extends CustomIntentService implements I
@Override
public void onReceive(Context context, Intent intent) {
pollNetworkState();
if (mStateChanged && !isServiceRunning()) {
if (mStateChanged
&& !isServiceRunning()) {
Log.d(Constants.TAG, "InnerBroadcastReceiver Called");
Intent fileIntent = new Intent(context, mService.getClass());
fileIntent.putExtra(EXTRA_PENDING_INTENT, mPendingIntent);
@ -1000,7 +1019,8 @@ public abstract class DownloaderService extends CustomIntentService implements I
final PendingIntent pendingIntent = (PendingIntent) intent
.getParcelableExtra(EXTRA_PENDING_INTENT);
if (null != pendingIntent) {
if (null != pendingIntent)
{
mNotification.setClientIntent(pendingIntent);
mPendingIntent = pendingIntent;
} else if (null != mPendingIntent) {
@ -1201,7 +1221,8 @@ public abstract class DownloaderService extends CustomIntentService implements I
* download
*/
public String generateTempSaveFileName(String fileName) {
String path = Helpers.getSaveFilePath(this) + File.separator + fileName + TEMP_EXT;
String path = Helpers.getSaveFilePath(this)
+ File.separator + fileName + TEMP_EXT;
return path;
}
@ -1217,6 +1238,7 @@ public abstract class DownloaderService extends CustomIntentService implements I
Log.d(Constants.TAG, "External media not mounted: " + path);
throw new GenerateSaveFileError(STATUS_DEVICE_NOT_FOUND_ERROR,
"external media is not yet mounted");
}
if (expPath.exists()) {
Log.d(Constants.TAG, "File already exists: " + path);
@ -1279,7 +1301,8 @@ public abstract class DownloaderService extends CustomIntentService implements I
long bytesInSample = totalBytesSoFar - mBytesAtSample;
float currentSpeedSample = (float) bytesInSample / (float) timePassed;
if (0 != mAverageDownloadSpeed) {
mAverageDownloadSpeed = SMOOTHING_FACTOR * currentSpeedSample + (1 - SMOOTHING_FACTOR) * mAverageDownloadSpeed;
mAverageDownloadSpeed = SMOOTHING_FACTOR * currentSpeedSample
+ (1 - SMOOTHING_FACTOR) * mAverageDownloadSpeed;
} else {
mAverageDownloadSpeed = currentSpeedSample;
}
@ -1293,7 +1316,9 @@ public abstract class DownloaderService extends CustomIntentService implements I
new DownloadProgressInfo(mTotalLength,
totalBytesSoFar,
timeRemaining,
mAverageDownloadSpeed));
mAverageDownloadSpeed)
);
}
@Override
@ -1317,4 +1342,5 @@ public abstract class DownloaderService extends CustomIntentService implements I
this.mClientMessenger = clientMessenger;
mNotification.setMessenger(mClientMessenger);
}
}

View File

@ -49,7 +49,9 @@ public class DownloadsDB {
private SQLiteStatement getDownloadByIndexStatement() {
if (null == mGetDownloadByIndex) {
mGetDownloadByIndex = mHelper.getReadableDatabase().compileStatement(
"SELECT " + BaseColumns._ID + " FROM " + DownloadColumns.TABLE_NAME + " WHERE " + DownloadColumns.INDEX + " = ?");
"SELECT " + BaseColumns._ID + " FROM "
+ DownloadColumns.TABLE_NAME + " WHERE "
+ DownloadColumns.INDEX + " = ?");
}
return mGetDownloadByIndex;
}
@ -57,8 +59,8 @@ public class DownloadsDB {
private SQLiteStatement getUpdateCurrentBytesStatement() {
if (null == mUpdateCurrentBytes) {
mUpdateCurrentBytes = mHelper.getReadableDatabase().compileStatement(
"UPDATE " + DownloadColumns.TABLE_NAME + " SET " + DownloadColumns.CURRENTBYTES + " = ?"
+
"UPDATE " + DownloadColumns.TABLE_NAME + " SET " + DownloadColumns.CURRENTBYTES
+ " = ?" +
" WHERE " + DownloadColumns.INDEX + " = ?");
}
return mUpdateCurrentBytes;
@ -74,8 +76,8 @@ public class DownloadsDB {
BaseColumns._ID + "," +
MetadataColumns.DOWNLOAD_STATUS + "," +
MetadataColumns.FLAGS +
" FROM " + MetadataColumns.TABLE_NAME + " LIMIT 1",
null);
" FROM "
+ MetadataColumns.TABLE_NAME + " LIMIT 1", null);
if (null != cur && cur.moveToFirst()) {
mVersionCode = cur.getInt(0);
mMetadataRowID = cur.getLong(1);
@ -93,8 +95,8 @@ public class DownloadsDB {
itemcur = sqldb.query(DownloadColumns.TABLE_NAME, DC_PROJECTION,
DownloadColumns.FILENAME + " = ?",
new String[] {
fileName },
null, null, null);
fileName
}, null, null, null);
if (null != itemcur && itemcur.moveToFirst()) {
return getDownloadInfoFromCursor(itemcur);
}
@ -208,7 +210,8 @@ public class DownloadsDB {
public void onUpgrade(SQLiteDatabase paramSQLiteDatabase,
int paramInt1, int paramInt2) {
Log.w(DownloadsContentDBHelper.class.getName(),
"Upgrading database from version " + paramInt1 + " to " + paramInt2 + ", which will destroy all old data");
"Upgrading database from version " + paramInt1 + " to "
+ paramInt2 + ", which will destroy all old data");
dropTables(paramSQLiteDatabase);
onCreate(paramSQLiteDatabase);
}
@ -220,9 +223,17 @@ public class DownloadsDB {
public static final String FLAGS = "DOWNLOADFLAGS";
public static final String[][] SCHEMA = {
{ BaseColumns._ID, "INTEGER PRIMARY KEY" },
{ APKVERSION, "INTEGER" }, { DOWNLOAD_STATUS, "INTEGER" },
{ FLAGS, "INTEGER" }
{
BaseColumns._ID, "INTEGER PRIMARY KEY"
},
{
APKVERSION, "INTEGER"
}, {
DOWNLOAD_STATUS, "INTEGER"
},
{
FLAGS, "INTEGER"
}
};
public static final String TABLE_NAME = "MetadataColumns";
public static final String _ID = "MetadataColumns._id";
@ -245,13 +256,39 @@ public class DownloadsDB {
public static final String REDIRECT_COUNT = "REDIRECTCOUNT";
public static final String[][] SCHEMA = {
{ BaseColumns._ID, "INTEGER PRIMARY KEY" },
{ INDEX, "INTEGER UNIQUE" }, { URI, "TEXT" },
{ FILENAME, "TEXT UNIQUE" }, { ETAG, "TEXT" },
{ TOTALBYTES, "INTEGER" }, { CURRENTBYTES, "INTEGER" },
{ LASTMOD, "INTEGER" }, { STATUS, "INTEGER" },
{ CONTROL, "INTEGER" }, { NUM_FAILED, "INTEGER" },
{ RETRY_AFTER, "INTEGER" }, { REDIRECT_COUNT, "INTEGER" }
{
BaseColumns._ID, "INTEGER PRIMARY KEY"
},
{
INDEX, "INTEGER UNIQUE"
}, {
URI, "TEXT"
},
{
FILENAME, "TEXT UNIQUE"
}, {
ETAG, "TEXT"
},
{
TOTALBYTES, "INTEGER"
}, {
CURRENTBYTES, "INTEGER"
},
{
LASTMOD, "INTEGER"
}, {
STATUS, "INTEGER"
},
{
CONTROL, "INTEGER"
}, {
NUM_FAILED, "INTEGER"
},
{
RETRY_AFTER, "INTEGER"
}, {
REDIRECT_COUNT, "INTEGER"
}
};
public static final String TABLE_NAME = "DownloadColumns";
public static final String _ID = "DownloadColumns._id";
@ -328,7 +365,9 @@ public class DownloadsDB {
public boolean isDownloadRequired() {
final SQLiteDatabase sqldb = mHelper.getReadableDatabase();
Cursor cur = sqldb.rawQuery("SELECT Count(*) FROM " + DownloadColumns.TABLE_NAME + " WHERE " + DownloadColumns.STATUS + " <> 0", null);
Cursor cur = sqldb.rawQuery("SELECT Count(*) FROM "
+ DownloadColumns.TABLE_NAME + " WHERE "
+ DownloadColumns.STATUS + " <> 0", null);
try {
if (null != cur && cur.moveToFirst()) {
return 0 == cur.getInt(0);
@ -410,8 +449,8 @@ public class DownloadsDB {
cur = sqldb.query(DownloadColumns.TABLE_NAME, DC_PROJECTION,
DownloadColumns.FILENAME + "= ?",
new String[] {
di.mFileName },
null, null, null);
di.mFileName
}, null, null, null);
if (null != cur && cur.moveToFirst()) {
setDownloadInfoFromCursor(di, cur);
return true;
@ -439,7 +478,8 @@ public class DownloadsDB {
public DownloadInfo getDownloadInfoFromCursor(Cursor cur) {
DownloadInfo di = new DownloadInfo(cur.getInt(INDEX_IDX),
cur.getString(FILENAME_IDX), this.getClass().getPackage().getName());
cur.getString(FILENAME_IDX), this.getClass().getPackage()
.getName());
setDownloadInfoFromCursor(di, cur);
return di;
}
@ -466,4 +506,5 @@ public class DownloadsDB {
}
}
}
}

View File

@ -106,7 +106,8 @@ public final class HttpDateTime {
private static int getDate(String dateString) {
if (dateString.length() == 2) {
return (dateString.charAt(0) - '0') * 10 + (dateString.charAt(1) - '0');
return (dateString.charAt(0) - '0') * 10
+ (dateString.charAt(1) - '0');
} else {
return (dateString.charAt(0) - '0');
}
@ -154,7 +155,8 @@ public final class HttpDateTime {
private static int getYear(String yearString) {
if (yearString.length() == 2) {
int year = (yearString.charAt(0) - '0') * 10 + (yearString.charAt(1) - '0');
int year = (yearString.charAt(0) - '0') * 10
+ (yearString.charAt(1) - '0');
if (year >= 70) {
return year + 1900;
} else {
@ -162,10 +164,15 @@ public final class HttpDateTime {
}
} else if (yearString.length() == 3) {
// According to RFC 2822, three digit years should be added to 1900.
int year = (yearString.charAt(0) - '0') * 100 + (yearString.charAt(1) - '0') * 10 + (yearString.charAt(2) - '0');
int year = (yearString.charAt(0) - '0') * 100
+ (yearString.charAt(1) - '0') * 10
+ (yearString.charAt(2) - '0');
return year + 1900;
} else if (yearString.length() == 4) {
return (yearString.charAt(0) - '0') * 1000 + (yearString.charAt(1) - '0') * 100 + (yearString.charAt(2) - '0') * 10 + (yearString.charAt(3) - '0');
return (yearString.charAt(0) - '0') * 1000
+ (yearString.charAt(1) - '0') * 100
+ (yearString.charAt(2) - '0') * 10
+ (yearString.charAt(3) - '0');
} else {
return 1970;
}
@ -180,11 +187,13 @@ public final class HttpDateTime {
// Skip ':'
i++;
int minute = (timeString.charAt(i++) - '0') * 10 + (timeString.charAt(i++) - '0');
int minute = (timeString.charAt(i++) - '0') * 10
+ (timeString.charAt(i++) - '0');
// Skip ':'
i++;
int second = (timeString.charAt(i++) - '0') * 10 + (timeString.charAt(i++) - '0');
int second = (timeString.charAt(i++) - '0') * 10
+ (timeString.charAt(i++) - '0');
return new TimeOfDay(hour, minute, second);
}

View File

@ -39,7 +39,8 @@ public class AESObfuscator implements Obfuscator {
private static final String UTF8 = "UTF-8";
private static final String KEYGEN_ALGORITHM = "PBEWITHSHAAND256BITAES-CBC-BC";
private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
private static final byte[] IV = { 16, 74, 71, -80, 32, 101, -47, 72, 117, -14, 0, -29, 70, 65, -12, 74 };
private static final byte[] IV =
{ 16, 74, 71, -80, 32, 101, -47, 72, 117, -14, 0, -29, 70, 65, -12, 74 };
private static final String header = "com.google.android.vending.licensing.AESObfuscator-1|";
private Cipher mEncryptor;
@ -92,8 +93,7 @@ public class AESObfuscator implements Obfuscator {
// where the block size is correct during decryption.
int headerIndex = result.indexOf(header+key);
if (headerIndex != 0) {
throw new ValidationException("Header not found (invalid data or key)"
+ ":" +
throw new ValidationException("Header not found (invalid data or key)" + ":" +
obfuscated);
}
return result.substring(header.length()+key.length(), result.length());

View File

@ -410,4 +410,5 @@ public class APKExpansionPolicy implements Policy {
}
return results;
}
}

View File

@ -1,100 +0,0 @@
/*
* Copyright (C) 2010 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.
*/
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: aidl/ILicenseResultListener.aidl
*/
package com.google.android.vending.licensing;
import java.lang.String;
import android.os.RemoteException;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Binder;
import android.os.Parcel;
public interface ILicenseResultListener extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.google.android.vending.licensing.ILicenseResultListener {
private static final java.lang.String DESCRIPTOR = "com.android.vending.licensing.ILicenseResultListener";
/** Construct the stub at attach it to the interface. */
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an ILicenseResultListener interface,
* generating a proxy if needed.
*/
public static com.google.android.vending.licensing.ILicenseResultListener asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.google.android.vending.licensing.ILicenseResultListener))) {
return ((com.google.android.vending.licensing.ILicenseResultListener)iin);
}
return new com.google.android.vending.licensing.ILicenseResultListener.Stub.Proxy(obj);
}
public android.os.IBinder asBinder() {
return this;
}
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_verifyLicense: {
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
java.lang.String _arg1;
_arg1 = data.readString();
java.lang.String _arg2;
_arg2 = data.readString();
this.verifyLicense(_arg0, _arg1, _arg2);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.google.android.vending.licensing.ILicenseResultListener {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
public void verifyLicense(int responseCode, java.lang.String signedData, java.lang.String signature) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(responseCode);
_data.writeString(signedData);
_data.writeString(signature);
mRemote.transact(Stub.TRANSACTION_verifyLicense, _data, null, IBinder.FLAG_ONEWAY);
} finally {
_data.recycle();
}
}
}
static final int TRANSACTION_verifyLicense = (IBinder.FIRST_CALL_TRANSACTION + 0);
}
public void verifyLicense(int responseCode, java.lang.String signedData, java.lang.String signature) throws android.os.RemoteException;
}

View File

@ -1,100 +0,0 @@
/*
* Copyright (C) 2010 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.
*/
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: aidl/ILicensingService.aidl
*/
package com.google.android.vending.licensing;
import java.lang.String;
import android.os.RemoteException;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Binder;
import android.os.Parcel;
public interface ILicensingService extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.google.android.vending.licensing.ILicensingService {
private static final java.lang.String DESCRIPTOR = "com.android.vending.licensing.ILicensingService";
/** Construct the stub at attach it to the interface. */
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an ILicensingService interface,
* generating a proxy if needed.
*/
public static com.google.android.vending.licensing.ILicensingService asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.google.android.vending.licensing.ILicensingService))) {
return ((com.google.android.vending.licensing.ILicensingService)iin);
}
return new com.google.android.vending.licensing.ILicensingService.Stub.Proxy(obj);
}
public android.os.IBinder asBinder() {
return this;
}
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_checkLicense: {
data.enforceInterface(DESCRIPTOR);
long _arg0;
_arg0 = data.readLong();
java.lang.String _arg1;
_arg1 = data.readString();
com.google.android.vending.licensing.ILicenseResultListener _arg2;
_arg2 = com.google.android.vending.licensing.ILicenseResultListener.Stub.asInterface(data.readStrongBinder());
this.checkLicense(_arg0, _arg1, _arg2);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.google.android.vending.licensing.ILicensingService {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
public void checkLicense(long nonce, java.lang.String packageName, com.google.android.vending.licensing.ILicenseResultListener listener) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeLong(nonce);
_data.writeString(packageName);
_data.writeStrongBinder((((listener != null)) ? (listener.asBinder()) : (null)));
mRemote.transact(Stub.TRANSACTION_checkLicense, _data, null, IBinder.FLAG_ONEWAY);
} finally {
_data.recycle();
}
}
}
static final int TRANSACTION_checkLicense = (IBinder.FIRST_CALL_TRANSACTION + 0);
}
public void checkLicense(long nonce, java.lang.String packageName, com.google.android.vending.licensing.ILicenseResultListener listener) throws android.os.RemoteException;
}

View File

@ -29,8 +29,8 @@ import android.os.RemoteException;
import android.provider.Settings.Secure;
import android.util.Log;
import com.google.android.vending.licensing.ILicenseResultListener;
import com.google.android.vending.licensing.ILicensingService;
import com.android.vending.licensing.ILicenseResultListener;
import com.android.vending.licensing.ILicensingService;
import com.google.android.vending.licensing.util.Base64;
import com.google.android.vending.licensing.util.Base64DecoderException;
@ -287,13 +287,15 @@ public class LicenseChecker implements ServiceConnection {
}
if (logResponse) {
String android_id = Secure.ANDROID_ID;
String android_id = Secure.getString(mContext.getContentResolver(),
Secure.ANDROID_ID);
Date date = new Date();
Log.d(TAG, "Server Failure: " + stringError);
Log.d(TAG, "Android ID: " + android_id);
Log.d(TAG, "Time: " + date.toGMTString());
}
}
}
});
}

View File

@ -95,8 +95,7 @@ class LicenseValidator {
// Verify signature.
try {
if (TextUtils.isEmpty(signedData)) {
Log.e(TAG, "Signature verification failed: signedData is empty. "
+
Log.e(TAG, "Signature verification failed: signedData is empty. " +
"(Device not signed-in to any Google accounts?)");
handleInvalidResponse();
return;

View File

@ -45,7 +45,9 @@ public class PreferenceObfuscator {
public void putString(String key, String value) {
if (mEditor == null) {
mEditor = mPreferences.edit();
// -- GODOT start --
mEditor.apply();
// -- GODOT end --
}
String obfuscatedValue = mObfuscator.obfuscate(value, key);
mEditor.putString(key, obfuscatedValue);

View File

@ -75,6 +75,7 @@ public class ResponseData {
public String toString() {
return TextUtils.join("|", new Object[] {
responseCode, nonce, packageName, versionCode,
userId, timestamp });
userId, timestamp
});
}
}

View File

@ -296,4 +296,5 @@ public class ServerManagedPolicy implements Policy {
}
return results;
}
}

View File

@ -96,4 +96,5 @@ public class StrictPolicy implements Policy {
}
return results;
}
}

View File

@ -31,7 +31,9 @@ package com.google.android.vending.licensing.util;
* @version 1.3
*/
// -- GODOT start --
import com.godot.game.BuildConfig;
// -- GODOT end --
/**
* Base64 converter class. This code is not a full-blown MIME encoder;
@ -56,7 +58,8 @@ public class Base64 {
/**
* The 64 valid Base64 values.
*/
private final static byte[] ALPHABET = { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F',
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',
@ -73,7 +76,8 @@ public class Base64 {
/**
* 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',
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',
@ -91,8 +95,7 @@ public class Base64 {
* 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
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
@ -126,8 +129,8 @@ public class Base64 {
};
/** The web safe decodabet */
private final static byte[] WEBSAFE_DECODABET = {
-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
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
@ -208,7 +211,9 @@ public class Base64 {
// 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);
(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:
@ -312,7 +317,9 @@ public class Base64 {
// 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);
((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];
@ -338,13 +345,18 @@ public class Base64 {
e += 4;
}
// -- GODOT start --
//assert (e == outBuff.length);
if (BuildConfig.DEBUG && e != outBuff.length)
throw new RuntimeException();
// -- GODOT end --
return outBuff;
}
/* ******** D E C O D I N G M E T H O D S ******** */
/**
* Decodes four bytes from array <var>source</var>
* and writes the resulting bytes (up to three of them)
@ -373,14 +385,17 @@ public class Base64 {
// Example: Dk==
if (source[srcOffset + 2] == EQUALS_SIGN) {
int outBuff =
((decodabet[source[srcOffset]] << 24) >>> 6) | ((decodabet[source[srcOffset + 1]] << 24) >>> 12);
((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);
((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);
@ -388,7 +403,10 @@ public class Base64 {
} 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);
((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);
@ -397,6 +415,7 @@ public class Base64 {
}
} // end decodeToBytes
/**
* Decodes data from Base64 notation.
*
@ -513,7 +532,8 @@ public class Base64 {
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)) {
} else if ((b4Posn == 3 && bytesLeft > 2)
|| (b4Posn == 4 && bytesLeft > 1)) {
throw new Base64DecoderException(
"padding byte '=' falsely signals end of encoded value "
+ "at offset " + i);
@ -531,7 +551,8 @@ public class Base64 {
}
}
} else {
throw new Base64DecoderException("Bad Base64 input character at " + i + ": " + source[i + off] + "(decimal)");
throw new Base64DecoderException("Bad Base64 input character at " + i
+ ": " + source[i + off] + "(decimal)");
}
}
@ -543,7 +564,8 @@ public class Base64 {
// padded with EQUALS_SIGN
if (b4Posn != 0) {
if (b4Posn == 1) {
throw new Base64DecoderException("single trailing character at offset " + (len - 1));
throw new Base64DecoderException("single trailing character at offset "
+ (len - 1));
}
b4[b4Posn++] = EQUALS_SIGN;
outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);