1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-06 12:20:30 +00:00

Small Issues & Maintenance

-=-=-=-=-=-=-=-=-=-=-=-=-=

-Begin work on Navigation Meshes (simple pathfinding for now, will improve soon)
-More doc on theme overriding
-Upgraded OpenSSL to version without bugs
-Misc bugfixes
This commit is contained in:
Juan Linietsky
2014-08-01 22:10:38 -03:00
parent 9ff6d55822
commit 678948068b
1323 changed files with 11564 additions and 39728 deletions

View File

@@ -28,16 +28,20 @@
/*************************************************************************/
package com.android.godot;
import android.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.view.ViewGroup.LayoutParams;
import android.app.*;
import android.content.*;
import android.content.SharedPreferences.Editor;
import android.view.*;
import android.view.inputmethod.InputMethodManager;
import android.os.*;
@@ -48,33 +52,82 @@ import android.text.*;
import android.media.*;
import android.hardware.*;
import android.content.*;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.media.MediaPlayer;
import java.lang.reflect.Method;
import java.util.List;
import java.util.ArrayList;
import com.android.godot.payments.PaymentsManager;
import java.io.IOException;
import android.provider.Settings.Secure;
import android.widget.FrameLayout;
import com.android.godot.input.*;
import java.io.InputStream;
import com.android.godot.input.*;
import java.io.InputStream;
import javax.microedition.khronos.opengles.GL10;
import java.security.MessageDigest;
import java.io.File;
import java.io.FileInputStream;
import java.util.LinkedList;
public class Godot extends Activity implements SensorEventListener
import com.google.android.vending.expansion.downloader.Constants;
import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;
import com.google.android.vending.expansion.downloader.DownloaderServiceMarshaller;
import com.google.android.vending.expansion.downloader.Helpers;
import com.google.android.vending.expansion.downloader.IDownloaderClient;
import com.google.android.vending.expansion.downloader.IDownloaderService;
import com.google.android.vending.expansion.downloader.IStub;
import android.os.Bundle;
import android.os.Messenger;
import android.os.SystemClock;
public class Godot extends Activity implements SensorEventListener, IDownloaderClient
{
static final int MAX_SINGLETONS = 64;
private IStub mDownloaderClientStub;
private IDownloaderService mRemoteService;
private TextView mStatusText;
private TextView mProgressFraction;
private TextView mProgressPercent;
private TextView mAverageSpeed;
private TextView mTimeRemaining;
private ProgressBar mPB;
private View mDashboard;
private View mCellMessage;
private Button mPauseButton;
private Button mWiFiSettingsButton;
private boolean mStatePaused;
private int mState;
private void setState(int newState) {
if (mState != newState) {
mState = newState;
mStatusText.setText(Helpers.getDownloaderStringResourceIDFromState(newState));
}
}
private void setButtonPausedState(boolean paused) {
mStatePaused = paused;
int stringResourceID = paused ? com.godot.game.R.string.text_button_resume :
com.godot.game.R.string.text_button_pause;
mPauseButton.setText(stringResourceID);
}
static public class SingletonBase {
protected void registerClass(String p_name, String[] p_methods) {
GodotLib.singleton(p_name,this);
@@ -83,20 +136,20 @@ public class Godot extends Activity implements SensorEventListener
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
boolean found=false;
System.out.printf("METHOD: %s\n",method.getName());
Log.d("XXX","METHOD: %s\n" + method.getName());
for (String s : p_methods) {
System.out.printf("METHOD CMP WITH: %s\n",s);
Log.d("XXX", "METHOD CMP WITH: %s\n" + s);
if (s.equals(method.getName())) {
found=true;
System.out.printf("METHOD CMP VALID");
Log.d("XXX","METHOD CMP VALID");
break;
}
}
if (!found)
continue;
System.out.printf("METHOD FOUND: %s\n",method.getName());
Log.d("XXX","METHOD FOUND: %s\n" + method.getName());
List<String> ptr = new ArrayList<String>();
@@ -230,7 +283,7 @@ public class Godot extends Activity implements SensorEventListener
byte[] len = new byte[4];
int r = is.read(len);
if (r<4) {
System.out.printf("**ERROR** Wrong cmdline length.\n");
Log.d("XXX","**ERROR** Wrong cmdline length.\n");
Log.d("GODOT", "**ERROR** Wrong cmdline length.\n");
return new String[0];
}
@@ -258,7 +311,6 @@ public class Godot extends Activity implements SensorEventListener
return cmdline;
} catch (Exception e) {
e.printStackTrace();
System.out.printf("**ERROR** No commandline.\n");
Log.d("GODOT", "**ERROR** Exception " + e.getClass().getName() + ":" + e.getMessage());
return new String[0];
}
@@ -277,12 +329,14 @@ public class Godot extends Activity implements SensorEventListener
String[] new_cmdline;
int cll=0;
if (command_line!=null) {
Log.d("GODOT", "initializeGodot: command_line: is not null" );
new_cmdline = new String[ command_line.length + 2 ];
cll=command_line.length;
for(int i=0;i<command_line.length;i++) {
new_cmdline[i]=command_line[i];
}
} else {
Log.d("GODOT", "initializeGodot: command_line: is null" );
new_cmdline = new String[ 2 ];
}
@@ -294,6 +348,13 @@ public class Godot extends Activity implements SensorEventListener
io = new GodotIO(this);
io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
GodotLib.io=io;
Log.d("GODOT", "command_line is null? " + ((command_line == null)?"yes":"no"));
if(command_line != null){
Log.d("GODOT", "Command Line:");
for(int w=0;w <command_line.length;w++){
Log.d("GODOT"," " + command_line[w]);
}
}
GodotLib.initialize(this,io.needsReloadHooks(),command_line);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
@@ -306,10 +367,16 @@ public class Godot extends Activity implements SensorEventListener
}
@Override
public void onServiceConnected(Messenger m) {
mRemoteService = DownloaderServiceMarshaller.CreateProxy(m);
mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger());
}
@Override protected void onCreate(Bundle icicle) {
@Override
protected void onCreate(Bundle icicle) {
System.out.printf("** GODOT ACTIVITY CREATED HERE ***\n");
Log.d("GODOT", "** GODOT ACTIVITY CREATED HERE ***\n");
super.onCreate(icicle);
_self = this;
@@ -319,7 +386,8 @@ public class Godot extends Activity implements SensorEventListener
//check for apk expansion API
if (!true) {
if (true) {
boolean md5mismatch = false;
command_line = getCommandLine();
boolean use_apk_expansion=false;
String main_pack_md5=null;
@@ -338,17 +406,25 @@ public class Godot extends Activity implements SensorEventListener
i++;
} else if (has_extra && command_line[i].equals("-apk_expansion_key")) {
main_pack_key=command_line[i+1];
SharedPreferences prefs = getSharedPreferences("app_data_keys", MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putString("store_public_key", main_pack_key);
editor.commit();
i++;
} else if (command_line[i].trim().length()!=0){
new_args.add(command_line[i]);
}
}
if (new_args.isEmpty())
if (new_args.isEmpty()){
Log.d("GODOT", "new_args is empty");
command_line=null;
else
}else{
Log.d("GODOT", "new_args is not empty");
command_line = new_args.toArray(new String[new_args.size()]);
Log.d("GODOT", "command line is null? " + ( (command_line == null) ? "yes":"no"));
}
if (use_apk_expansion && main_pack_md5!=null && main_pack_key!=null) {
//check that environment is ok!
if (!Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED )) {
@@ -374,49 +450,62 @@ public class Godot extends Activity implements SensorEventListener
pack_valid=false;
Log.d("GODOT","**PACK** - File does not exist");
} else {
try {
InputStream fis = new FileInputStream(expansion_pack_path);
// Create MD5 Hash
byte[] buffer = new byte[16384];
MessageDigest complete = MessageDigest.getInstance("MD5");
int numRead;
do {
numRead = fis.read(buffer);
if (numRead > 0) {
complete.update(buffer, 0, numRead);
}
} while (numRead != -1);
fis.close();
byte[] messageDigest = complete.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
for (int i=0; i<messageDigest.length; i++)
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
String md5str = hexString.toString();
Log.d("GODOT","**PACK** - My MD5: "+hexString+" - APK md5: "+main_pack_md5);
if (!hexString.equals(main_pack_md5)) {
pack_valid=false;
}
} catch (Exception e) {
e.printStackTrace();
Log.d("GODOT","**PACK FAIL**");
pack_valid=false;
} else if( obbIsCorrupted(expansion_pack_path, main_pack_md5)){
Log.d("GODOT", "**PACK** - Expansion pack (obb) is corrupted");
pack_valid = false;
try{
f.delete();
}catch(Exception e){
Log.d("GODOT", "**PACK** - Error deleting corrupted expansion pack (obb)");
}
}
if (!pack_valid) {
Log.d("GODOT", "Tengo que bajarme el apk");
Intent notifierIntent = new Intent(this, this.getClass());
notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT);
int startResult;
try {
Log.d("GODOT", "INICIANDO DOWNLOAD SERVICE");
startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(
getApplicationContext(),
pendingIntent,
GodotDownloaderService.class);
Log.d("GODOT", "DOWNLOAD SERVICE FINISHED:" + startResult);
if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
Log.d("GODOT", "DOWNLOAD REQUIRED");
// This is where you do set up to display the download
// progress (next step)
mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this,
GodotDownloaderService.class);
setContentView(com.godot.game.R.layout.downloading_expansion);
mPB = (ProgressBar) findViewById(com.godot.game.R.id.progressBar);
mStatusText = (TextView) findViewById(com.godot.game.R.id.statusText);
mProgressFraction = (TextView) findViewById(com.godot.game.R.id.progressAsFraction);
mProgressPercent = (TextView) findViewById(com.godot.game.R.id.progressAsPercentage);
mAverageSpeed = (TextView) findViewById(com.godot.game.R.id.progressAverageSpeed);
mTimeRemaining = (TextView) findViewById(com.godot.game.R.id.progressTimeRemaining);
mDashboard = findViewById(com.godot.game.R.id.downloaderDashboard);
mCellMessage = findViewById(com.godot.game.R.id.approveCellular);
mPauseButton = (Button) findViewById(com.godot.game.R.id.pauseButton);
mWiFiSettingsButton = (Button) findViewById(com.godot.game.R.id.wifiSettingsButton);
return;
} else{
Log.d("GODOT", "NO DOWNLOAD REQUIRED");
}
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
Log.d("GODOT", "Error downloading expansion package:" + e.getMessage());
}
}
@@ -431,6 +520,7 @@ public class Godot extends Activity implements SensorEventListener
}
@Override protected void onDestroy(){
if(mPaymentsManager != null ) mPaymentsManager.destroy();
@@ -442,8 +532,12 @@ public class Godot extends Activity implements SensorEventListener
@Override protected void onPause() {
super.onPause();
if (!godot_initialized)
if (!godot_initialized){
if (null != mDownloaderClientStub) {
mDownloaderClientStub.disconnect(this);
}
return;
}
mView.onPause();
mSensorManager.unregisterListener(this);
GodotLib.focusout();
@@ -455,8 +549,12 @@ public class Godot extends Activity implements SensorEventListener
@Override protected void onResume() {
super.onResume();
if (!godot_initialized)
if (!godot_initialized){
if (null != mDownloaderClientStub) {
mDownloaderClientStub.connect(this);
}
return;
}
mView.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
@@ -466,6 +564,8 @@ public class Godot extends Activity implements SensorEventListener
singletons[i].onMainResume();
}
}
@@ -508,6 +608,54 @@ public class Godot extends Activity implements SensorEventListener
}
private boolean obbIsCorrupted(String f, String main_pack_md5){
try {
InputStream fis = new FileInputStream(f);
// Create MD5 Hash
byte[] buffer = new byte[16384];
MessageDigest complete = MessageDigest.getInstance("MD5");
int numRead;
do {
numRead = fis.read(buffer);
if (numRead > 0) {
complete.update(buffer, 0, numRead);
}
} while (numRead != -1);
fis.close();
byte[] messageDigest = complete.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
for (int i=0; i<messageDigest.length; i++) {
String s = Integer.toHexString(0xFF & messageDigest[i]);
if (s.length()==1) {
s="0"+s;
}
hexString.append(s);
}
String md5str = hexString.toString();
//Log.d("GODOT","**PACK** - My MD5: "+hexString+" - APK md5: "+main_pack_md5);
if (!md5str.equals(main_pack_md5)) {
Log.d("GODOT","**PACK MD5 MISMATCH???** - MD5 Found: "+md5str+" "+Integer.toString(md5str.length())+" - MD5 Expected: "+main_pack_md5+" "+Integer.toString(main_pack_md5.length()));
return true;
}
return false;
} catch (Exception e) {
e.printStackTrace();
Log.d("GODOT","**PACK FAIL**");
return true;
}
}
//@Override public boolean dispatchTouchEvent (MotionEvent event) {
public boolean gotTouchEvent(MotionEvent event) {
@@ -602,5 +750,115 @@ public class Godot extends Activity implements SensorEventListener
// Audio
/**
* The download state should trigger changes in the UI --- it may be useful
* to show the state as being indeterminate at times. This sample can be
* considered a guideline.
*/
@Override
public void onDownloadStateChanged(int newState) {
Log.d("GODOT", "onDownloadStateChanged:" + newState);
setState(newState);
boolean showDashboard = true;
boolean showCellMessage = false;
boolean paused;
boolean indeterminate;
switch (newState) {
case IDownloaderClient.STATE_IDLE:
Log.d("GODOT", "STATE IDLE");
// STATE_IDLE means the service is listening, so it's
// safe to start making calls via mRemoteService.
paused = false;
indeterminate = true;
break;
case IDownloaderClient.STATE_CONNECTING:
case IDownloaderClient.STATE_FETCHING_URL:
Log.d("GODOT", "STATE CONNECTION / FETCHING URL");
showDashboard = true;
paused = false;
indeterminate = true;
break;
case IDownloaderClient.STATE_DOWNLOADING:
Log.d("GODOT", "STATE DOWNLOADING");
paused = false;
showDashboard = true;
indeterminate = false;
break;
case IDownloaderClient.STATE_FAILED_CANCELED:
case IDownloaderClient.STATE_FAILED:
case IDownloaderClient.STATE_FAILED_FETCHING_URL:
case IDownloaderClient.STATE_FAILED_UNLICENSED:
Log.d("GODOT", "MANY TYPES OF FAILING");
paused = true;
showDashboard = false;
indeterminate = false;
break;
case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION:
case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION:
Log.d("GODOT", "PAUSED FOR SOME STUPID REASON");
showDashboard = false;
paused = true;
indeterminate = false;
showCellMessage = true;
break;
case IDownloaderClient.STATE_PAUSED_BY_REQUEST:
Log.d("GODOT", "PAUSED BY STUPID USER");
paused = true;
indeterminate = false;
break;
case IDownloaderClient.STATE_PAUSED_ROAMING:
case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE:
Log.d("GODOT", "PAUSED BY ROAMING WTF!?");
paused = true;
indeterminate = false;
break;
case IDownloaderClient.STATE_COMPLETED:
Log.d("GODOT", "COMPLETED");
showDashboard = false;
paused = false;
indeterminate = false;
// validateXAPKZipFiles();
initializeGodot();
return;
default:
Log.d("GODOT", "DEFAULT ????");
paused = true;
indeterminate = true;
showDashboard = true;
}
int newDashboardVisibility = showDashboard ? View.VISIBLE : View.GONE;
if (mDashboard.getVisibility() != newDashboardVisibility) {
mDashboard.setVisibility(newDashboardVisibility);
}
int cellMessageVisibility = showCellMessage ? View.VISIBLE : View.GONE;
if (mCellMessage.getVisibility() != cellMessageVisibility) {
mCellMessage.setVisibility(cellMessageVisibility);
}
mPB.setIndeterminate(indeterminate);
setButtonPausedState(paused);
}
@Override
public void onDownloadProgress(DownloadProgressInfo progress) {
mAverageSpeed.setText(getString(com.godot.game.R.string.kilobytes_per_second,
Helpers.getSpeedString(progress.mCurrentSpeed)));
mTimeRemaining.setText(getString(com.godot.game.R.string.time_remaining,
Helpers.getTimeRemaining(progress.mTimeRemaining)));
progress.mOverallTotal = progress.mOverallTotal;
mPB.setMax((int) (progress.mOverallTotal >> 8));
mPB.setProgress((int) (progress.mOverallProgress >> 8));
mProgressPercent.setText(Long.toString(progress.mOverallProgress
* 100 /
progress.mOverallTotal) + "%");
mProgressFraction.setText(Helpers.getDownloadProgressString
(progress.mOverallProgress,
progress.mOverallTotal));
}
}

View File

@@ -6,6 +6,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.Log;
/**
* You should start your derived downloader class when this receiver gets the message
@@ -18,10 +19,12 @@ public class GodotDownloaderAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("GODOT", "Alarma recivida");
try {
DownloaderClientMarshaller.startDownloadServiceIfRequired(context, intent, GodotDownloaderService.class);
} catch (NameNotFoundException e) {
e.printStackTrace();
Log.d("GODOT", "Exception: " + e.getClass().getName() + ":" + e.getMessage());
}
}
}

View File

@@ -1,5 +1,9 @@
package com.android.godot;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import com.google.android.vending.expansion.downloader.impl.DownloaderService;
/**
@@ -21,7 +25,11 @@ public class GodotDownloaderService extends DownloaderService {
*/
@Override
public String getPublicKey() {
return BASE64_PUBLIC_KEY;
SharedPreferences prefs = getApplicationContext().getSharedPreferences("app_data_keys", Context.MODE_PRIVATE);
Log.d("GODOT", "getting public key:" + prefs.getString("store_public_key", null));
return prefs.getString("store_public_key", null);
// return BASE64_PUBLIC_KEY;
}
/**
@@ -41,7 +49,8 @@ public class GodotDownloaderService extends DownloaderService {
*/
@Override
public String getAlarmReceiverClassName() {
return GodotDownloaderAlarmReceiver.class.getName();
Log.d("GODOT", "getAlarmReceiverClassName()");
return GodotDownloaderAlarmReceiver.class.getName();
}
}

View File

@@ -1,8 +1,6 @@
package com.android.godot;
import org.json.JSONObject;
import com.android.godot.Dictionary;
import android.app.Activity;
import android.util.Log;
@@ -44,10 +42,20 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
public GodotPaymentV3(Activity p_activity) {
registerClass("GodotPayments", new String[] {"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature"});
registerClass("GodotPayments", new String[] {"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases"});
activity=(Godot) p_activity;
}
public void consumeUnconsumedPurchases(){
activity.getPaymentsManager().setBaseSingleton(this);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.getPaymentsManager().consumeUnconsumedPurchases();
}
});
}
private String signature;
public String getSignature(){
@@ -56,9 +64,19 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
public void callbackSuccess(String ticket, String signature){
Log.d(this.getClass().getName(), "PRE-Send callback to purchase success");
GodotLib.calldeferred(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature});
Log.d(this.getClass().getName(), "POST-Send callback to purchase success");
Log.d(this.getClass().getName(), "PRE-Send callback to purchase success");
GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature});
Log.d(this.getClass().getName(), "POST-Send callback to purchase success");
}
public void callbackSuccessProductMassConsumed(String ticket, String signature, String sku){
Log.d(this.getClass().getName(), "PRE-Send callback to consume success");
GodotLib.calldeferred(purchaseCallbackId, "consume_success", new Object[]{ticket, signature, sku});
Log.d(this.getClass().getName(), "POST-Send callback to consume success");
}
public void callbackSuccessNoUnconsumedPurchases(){
GodotLib.calldeferred(purchaseCallbackId, "no_validation_required", new Object[]{});
}
public void callbackFail(){

View File

@@ -0,0 +1,53 @@
package com.android.godot.payments;
import com.android.vending.billing.IInAppBillingService;
import android.content.Context;
import android.os.AsyncTask;
import android.os.RemoteException;
import android.util.Log;
abstract public class GenericConsumeTask extends AsyncTask<String, String, String>{
private Context context;
private IInAppBillingService mService;
public GenericConsumeTask(Context context, IInAppBillingService mService, String sku, String receipt, String signature, String token){
this.context = context;
this.mService = mService;
this.sku = sku;
this.receipt = receipt;
this.signature = signature;
this.token = token;
}
private String sku;
private String receipt;
private String signature;
private String token;
@Override
protected String doInBackground(String... params) {
try {
Log.d("godot", "Requesting to consume an item with token ." + token);
int response = mService.consumePurchase(3, context.getPackageName(), token);
Log.d("godot", "consumePurchase response: " + response);
if(response == 0 || response == 8){
return null;
}
} catch (Exception e) {
Log.d("godot", "Error " + e.getClass().getName() + ":" + e.getMessage());
}
return null;
}
protected void onPostExecute(String sarasa){
onSuccess(sku, receipt, signature, token);
}
abstract public void onSuccess(String sku, String receipt, String signature, String token);
}

View File

@@ -64,7 +64,7 @@ abstract public class HandlePurchaseTask {
pc.setConsumableFlag("block", productId, true);
pc.setConsumableValue("token", productId, purchaseToken);
success(productId, dataSignature);
success(productId, dataSignature, purchaseData);
return;
} catch (JSONException e) {
error(e.getMessage());
@@ -74,7 +74,7 @@ abstract public class HandlePurchaseTask {
}
}
abstract protected void success(String ticket, String signature);
abstract protected void success(String sku, String signature, String ticket);
abstract protected void error(String message);
abstract protected void canceled();

View File

@@ -1,5 +1,9 @@
package com.android.godot.payments;
import java.util.ArrayList;
import java.util.List;
import android.os.RemoteException;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
@@ -7,7 +11,13 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
import android.os.Bundle;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import com.android.godot.Dictionary;
import com.android.godot.Godot;
import com.android.godot.GodotPaymentV3;
import com.android.vending.billing.IInAppBillingService;
@@ -23,7 +33,6 @@ public class PaymentsManager {
private Activity activity;
IInAppBillingService mService;
public void setActivity(Activity activity){
this.activity = activity;
}
@@ -81,18 +90,39 @@ public class PaymentsManager {
}
public void consumeUnconsumedPurchases(){
new ReleaseAllConsumablesTask(mService, activity) {
@Override
protected void success(String sku, String receipt, String signature, String token) {
godotPaymentV3.callbackSuccessProductMassConsumed(receipt, signature, sku);
}
@Override
protected void error(String message) {
godotPaymentV3.callbackFail();
}
@Override
protected void notRequired() {
godotPaymentV3.callbackSuccessNoUnconsumedPurchases();
}
}.consumeItAll();
}
public void processPurchaseResponse(int resultCode, Intent data) {
new HandlePurchaseTask(activity){
@Override
protected void success(final String sku, final String signature) {
protected void success(final String sku, final String signature, final String ticket) {
godotPaymentV3.callbackSuccess(ticket, signature);
new ConsumeTask(mService, activity) {
@Override
protected void success(String ticket) {
// godotPaymentV3.callbackSuccess("");
Log.d("XXX", "calling success:" + signature);
godotPaymentV3.callbackSuccess(ticket, signature);
}
@Override
@@ -103,7 +133,7 @@ public class PaymentsManager {
}.consume(sku);
// godotPaymentV3.callbackSuccess(new PaymentsCache(activity).getConsumableValue("ticket", sku),signature);
// godotPaymentV3.callbackSuccess(ticket);
//validatePurchase(purchaseToken, sku);
}
@@ -166,5 +196,6 @@ public class PaymentsManager {
this.godotPaymentV3 = godotPaymentV3;
}
}

View File

@@ -64,31 +64,7 @@ abstract public class PurchaseTask {
canceled();
return ;
}
if(responseCode == 7){
new ConsumeTask(mService, context) {
@Override
protected void success(String ticket) {
// Log.d("XXX", "Product was erroniously purchased!");
if(isLooping){
// Log.d("XXX", "It is looping");
error("Error while purchasing product");
return;
}
isLooping=true;
PurchaseTask.this.purchase(sku, transactionId);
}
@Override
protected void error(String message) {
PurchaseTask.this.error(message);
}
}.consume(sku);
return;
}
PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
pc.setConsumableValue("validation_hash", sku, hash);

View File

@@ -0,0 +1,87 @@
package com.android.godot.payments;
import java.util.ArrayList;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.godot.Dictionary;
import com.android.godot.Godot;
import com.android.vending.billing.IInAppBillingService;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
abstract public class ReleaseAllConsumablesTask {
private Context context;
private IInAppBillingService mService;
public ReleaseAllConsumablesTask(IInAppBillingService mService, Context context ){
this.context = context;
this.mService = mService;
}
public void consumeItAll(){
try{
Log.d("godot", "consumeItall for " + context.getPackageName());
Bundle bundle = mService.getPurchases(3, context.getPackageName(), "inapp",null);
for (String key : bundle.keySet()) {
Object value = bundle.get(key);
Log.d("godot", String.format("%s %s (%s)", key,
value.toString(), value.getClass().getName()));
}
if (bundle.getInt("RESPONSE_CODE") == 0){
final ArrayList<String> myPurchases = bundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
final ArrayList<String> mySignatures = bundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
if (myPurchases == null || myPurchases.size() == 0){
Log.d("godot", "No purchases!");
notRequired();
return;
}
Log.d("godot", "# products to be consumed:" + myPurchases.size());
for (int i=0;i<myPurchases.size();i++)
{
try{
String receipt = myPurchases.get(i);
JSONObject inappPurchaseData = new JSONObject(receipt);
String sku = inappPurchaseData.getString("productId");
String token = inappPurchaseData.getString("purchaseToken");
String signature = mySignatures.get(i);
Log.d("godot", "A punto de consumir un item con token:" + token + "\n" + receipt);
new GenericConsumeTask(context, mService, sku, receipt,signature, token) {
@Override
public void onSuccess(String sku, String receipt, String signature, String token) {
ReleaseAllConsumablesTask.this.success(sku, receipt, signature, token);
}
}.execute();
} catch (JSONException e) {
}
}
}
}catch(Exception e){
Log.d("godot", "Error releasing products:" + e.getClass().getName() + ":" + e.getMessage());
}
}
abstract protected void success(String sku, String receipt, String signature, String token);
abstract protected void error(String message);
abstract protected void notRequired();
}