You've already forked godot
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:
@@ -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));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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(){
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user