summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/SCsub4
-rw-r--r--platform/android/audio_driver_opensl.cpp3
-rw-r--r--platform/android/cpu-features.c2
-rw-r--r--platform/android/detect.py97
-rw-r--r--platform/android/export/export.cpp20
-rw-r--r--platform/android/java/res/drawable/icon.pngbin17135 -> 12574 bytes
-rw-r--r--platform/android/java/res/values-fa/strings.xml16
-rw-r--r--platform/android/java/src/com/android/godot/GodotPaymentV3.java60
-rw-r--r--platform/android/java/src/com/android/godot/payments/PaymentsManager.java127
-rw-r--r--platform/android/java/src/com/android/godot/payments/PurchaseTask.java8
-rw-r--r--platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java6
-rw-r--r--platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/R.java73
-rw-r--r--platform/android/os_android.h2
13 files changed, 247 insertions, 171 deletions
diff --git a/platform/android/SCsub b/platform/android/SCsub
index 6feeb8b365..834ee58adc 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -62,10 +62,10 @@ pp_baseout.write( manifest )
for x in env.android_source_files:
- shutil.copy(x,abspath+"/java/src/com/android/godot")
+ shutil.copy(x,abspath+"/java/src/com/android/godot")
for x in env.android_module_libraries:
- shutil.copy(x,abspath+"/java/libs")
+ shutil.copy(x,abspath+"/java/libs")
env_android.SharedLibrary("#bin/libgodot",[android_objects],SHLIBSUFFIX=env["SHLIBSUFFIX"])
diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp
index a08bc8943c..761bef27aa 100644
--- a/platform/android/audio_driver_opensl.cpp
+++ b/platform/android/audio_driver_opensl.cpp
@@ -236,13 +236,12 @@ void AudioDriverOpenSL::start(){
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
/* Initialize arrays required[] and iidArray[] */
- int i;
SLboolean required[MAX_NUMBER_INTERFACES];
SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
#if 0
- for (i=0; i<MAX_NUMBER_INTERFACES; i++)
+ for (int i=0; i<MAX_NUMBER_INTERFACES; i++)
{
required[i] = SL_BOOLEAN_FALSE;
iidArray[i] = SL_IID_NULL;
diff --git a/platform/android/cpu-features.c b/platform/android/cpu-features.c
index 156d464729..9cdadd5407 100644
--- a/platform/android/cpu-features.c
+++ b/platform/android/cpu-features.c
@@ -127,7 +127,7 @@ static __inline__ void x86_cpuid(int func, int values[4])
static int
get_file_size(const char* pathname)
{
- int fd, ret, result = 0;
+ int fd, result = 0;
char buffer[256];
fd = open(pathname, O_RDONLY);
diff --git a/platform/android/detect.py b/platform/android/detect.py
index fce1fe3ed6..9db5d02b48 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -20,15 +20,14 @@ def can_build():
def get_opts():
return [
- ('ANDROID_NDK_ROOT', 'the path to Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)),
- ('NDK_TOOLCHAIN', 'toolchain to use for the NDK',"arm-eabi-4.4.0"),
- #android 2.3
- ('ndk_platform', 'compile for platform: (2.2,2.3)',"2.2"),
- ('NDK_TARGET', 'toolchain to use for the NDK',"arm-linux-androideabi-4.8"),
- ('android_stl','enable STL support in android port (for modules)','no'),
- ('armv6','compile for older phones running arm v6 (instead of v7+neon+smp)','no'),
- ('x86','Xompile for Android-x86','no')
-
+ ('ANDROID_NDK_ROOT', 'the path to Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)),
+ ('NDK_TOOLCHAIN', 'toolchain to use for the NDK',"arm-eabi-4.4.0"),
+ ('NDK_TARGET', 'toolchain to use for the NDK',"arm-linux-androideabi-4.8"),
+ ('NDK_TARGET_X86', 'toolchain to use for the NDK x86',"x86-4.8"),
+ ('ndk_platform', 'compile for platform: (android-<api> , example: android-15)',"android-15"),
+ ('android_arch', 'select compiler architecture: (armv7/armv6/x86)',"armv7"),
+ ('android_neon','enable neon (armv7 only)',"yes"),
+ ('android_stl','enable STL support in android port (for modules)',"no")
]
def get_flags():
@@ -38,8 +37,6 @@ def get_flags():
('nedmalloc', 'no'),
('builtin_zlib', 'no'),
('openssl','builtin'), #use builtin openssl
- ('theora','no'), #use builtin openssl
-
]
@@ -94,8 +91,13 @@ def configure(env):
env['SPAWN'] = mySpawn
- if env['x86']=='yes':
- env['NDK_TARGET']='x86-4.8'
+ ndk_platform=env['ndk_platform']
+
+ if env['android_arch'] not in ['armv7','armv6','x86']:
+ env['android_arch']='armv7'
+
+ if env['android_arch']=='x86':
+ env['NDK_TARGET']=env['NDK_TARGET_X86']
if env['PLATFORM'] == 'win32':
import methods
@@ -103,22 +105,28 @@ def configure(env):
#env['SPAWN'] = methods.win32_spawn
env['SHLIBSUFFIX'] = '.so'
-# env.android_source_modules.append("../libs/apk_expansion")
+ #env.android_source_modules.append("../libs/apk_expansion")
env.android_source_modules.append("../libs/google_play_services")
env.android_source_modules.append("../libs/downloader_library")
env.android_source_modules.append("../libs/play_licensing")
-
- ndk_platform=""
-
- ndk_platform="android-15"
- print("Godot Android!!!!!")
+ neon_text=""
+ if env["android_arch"]=="armv7" and env['android_neon']=='yes':
+ neon_text=" (with neon)"
+ print("Godot Android!!!!! ("+env['android_arch']+")"+neon_text)
env.Append(CPPPATH=['#platform/android'])
- if env['x86']=='yes':
- env.extra_suffix=".x86"
-
+ if env['android_arch']=='x86':
+ env.extra_suffix=".x86"+env.extra_suffix
+ elif env['android_arch']=='armv6':
+ env.extra_suffix=".armv6"+env.extra_suffix
+ elif env["android_arch"]=="armv7":
+ if env['android_neon']=='yes':
+ env.extra_suffix=".armv7.neon"+env.extra_suffix
+ else:
+ env.extra_suffix=".armv7"+env.extra_suffix
+
gcc_path=env["ANDROID_NDK_ROOT"]+"/toolchains/"+env["NDK_TARGET"]+"/prebuilt/";
import os
@@ -136,7 +144,7 @@ def configure(env):
env['ENV']['PATH'] = gcc_path+":"+env['ENV']['PATH']
- if env['x86']=='yes':
+ if env['android_arch']=='x86':
env['CC'] = gcc_path+'/i686-linux-android-gcc'
env['CXX'] = gcc_path+'/i686-linux-android-g++'
env['AR'] = gcc_path+"/i686-linux-android-ar"
@@ -149,7 +157,7 @@ def configure(env):
env['RANLIB'] = gcc_path+"/arm-linux-androideabi-ranlib"
env['AS'] = gcc_path+"/arm-linux-androideabi-as"
- if env['x86']=='yes':
+ if env['android_arch']=='x86':
env['ARCH'] = 'arch-x86'
else:
env['ARCH'] = 'arch-arm'
@@ -163,12 +171,18 @@ def configure(env):
env.Append(CPPPATH=[gcc_include])
# env['CCFLAGS'] = string.split('-DNO_THREADS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -mthumb -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED ')
- if env['x86']=='yes':
+ env['neon_enabled']=False
+ if env['android_arch']=='x86':
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__GLIBC__ -Wno-psabi -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
- elif env["armv6"]!="no":
+ elif env["android_arch"]=="armv6":
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_6__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=vfp -mfloat-abi=softfp -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
- else:
- env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_7__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
+ elif env["android_arch"]=="armv7":
+ env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_7__ -D__ARM_ARCH_7A__ -D__GLIBC__ -Wno-psabi -march=armv7-a -mfloat-abi=softfp -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
+ if env['android_neon']=='yes':
+ env['neon_enabled']=True
+ env.Append(CCFLAGS=['-mfpu=neon','-D__ARM_NEON__'])
+ else:
+ env.Append(CCFLAGS=['-mfpu=vfpv3-d16'])
env.Append(LDPATH=[ld_path])
env.Append(LIBS=['OpenSLES'])
@@ -192,17 +206,26 @@ def configure(env):
env.Append(CCFLAGS=['-D_DEBUG', '-g1', '-Wall', '-O0', '-DDEBUG_ENABLED'])
env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC'])
- if env["armv6"] == "no" and env['x86'] != 'yes':
- env['neon_enabled']=True
-
env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL','-DMPC_FIXED_POINT'])
# env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED','-DMPC_FIXED_POINT'])
+ if(env["opus"]=="yes"):
+ env.Append(CFLAGS=["-DOPUS_ARM_OPT"])
+ env.opus_fixed_point="yes"
+
if (env['android_stl']=='yes'):
#env.Append(CCFLAGS=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/system/include"])
- env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/include"])
- env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/libs/armeabi/include"])
- env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/libs/armeabi"])
+ env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/include"])
+ if env['android_arch']=='x86':
+ env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86/include"])
+ env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86"])
+ elif env['android_arch']=='armv6':
+ env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/include"])
+ env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi"])
+ elif env["android_arch"]=="armv7":
+ env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include"])
+ env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a"])
+
env.Append(LIBS=["gnustl_static","supc++"])
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cpufeatures"])
@@ -213,10 +236,12 @@ def configure(env):
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/include"])
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cpufeatures"])
- if env['x86']=='yes':
+ if env['android_arch']=='x86':
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/x86"])
- else:
+ elif env["android_arch"]=="armv6":
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/armeabi"])
+ elif env["android_arch"]=="armv7":
+ env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/armeabi-v7a"])
env.Append(LIBS=['gabi++_static'])
env.Append(CCFLAGS=["-fno-exceptions",'-DNO_SAFE_CAST'])
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 982ef9d1cb..1deeb3457a 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -249,11 +249,11 @@ public:
virtual int get_device_count() const;
virtual String get_device_name(int p_device) const;
virtual String get_device_info(int p_device) const;
- virtual Error run(int p_device,bool p_dumb=false,bool p_remote_debug=false);
+ virtual Error run(int p_device,int p_flags=0);
virtual bool requieres_password(bool p_debug) const { return !p_debug; }
virtual String get_binary_extension() const { return "apk"; }
- virtual Error export_project(const String& p_path, bool p_debug, bool p_dumb=false, bool p_remote_debug=false);
+ virtual Error export_project(const String& p_path, bool p_debug, int p_flags=0);
virtual bool can_export(String *r_error=NULL) const;
@@ -1014,7 +1014,7 @@ Error EditorExportPlatformAndroid::save_apk_file(void *p_userdata,const String&
-Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_debug, bool p_dumb,bool p_remote_debug) {
+Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_debug, int p_flags) {
String src_apk;
@@ -1078,7 +1078,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
if (file=="AndroidManifest.xml") {
- _fix_manifest(data,p_dumb || p_remote_debug);
+ _fix_manifest(data,p_flags&(EXPORT_DUMB_CLIENT|EXPORT_REMOTE_DEBUG));
}
if (file=="resources.arsc") {
@@ -1123,6 +1123,10 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
if (file=="lib/armeabi/libgodot_android.so" && !export_arm) {
skip=true;
}
+
+ if (file.begins_with("META-INF") && _signed) {
+ skip=true;
+ }
print_line("ADDING: "+file);
@@ -1156,9 +1160,9 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
}
}
- gen_export_flags(cl,p_dumb,p_remote_debug);
+ gen_export_flags(cl,p_flags);
- if (p_dumb) {
+ if (p_flags) {
/*String host = EditorSettings::get_singleton()->get("file_server/host");
int port = EditorSettings::get_singleton()->get("file_server/post");
@@ -1485,7 +1489,7 @@ void EditorExportPlatformAndroid::_device_poll_thread(void *ud) {
}
-Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb, bool p_remote_debug) {
+Error EditorExportPlatformAndroid::run(int p_device, int p_flags) {
ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER);
device_lock->lock();
@@ -1504,7 +1508,7 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb, bool p_remote_
ep.step("Exporting APK",0);
String export_to=EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmpexport.apk";
- Error err = export_project(export_to,true,p_dumb,p_remote_debug);
+ Error err = export_project(export_to,true,p_flags);
if (err) {
device_lock->unlock();
return err;
diff --git a/platform/android/java/res/drawable/icon.png b/platform/android/java/res/drawable/icon.png
index 78757e9035..013632ddf1 100644
--- a/platform/android/java/res/drawable/icon.png
+++ b/platform/android/java/res/drawable/icon.png
Binary files differ
diff --git a/platform/android/java/res/values-fa/strings.xml b/platform/android/java/res/values-fa/strings.xml
new file mode 100644
index 0000000000..450f9fe212
--- /dev/null
+++ b/platform/android/java/res/values-fa/strings.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-fa</string>
+ <string name="testuf8">سلام</string>
+ <string name="text_paused_cellular">آیا می خواهید بر روی اتصال داده همراه دانلود را شروع کنید؟ بر اساس نوع سطح داده شما این ممکن است برای شما هزینه مالی داشته باشد.</string>
+ <string name="text_paused_cellular_2">اگر نمی خواهید بر روی اتصال داده همراه دانلود را شروع کنید ، دانلود به صورت خودکار در زمان دسترسی به وای-فای شروع می شود.</string>
+ <string name="text_button_resume_cellular">ادامه دانلود</string>
+ <string name="text_button_wifi_settings">تنظیمات وای-فای</string>
+ <string name="text_verifying_download">درحال تایید دانلود</string>
+ <string name="text_validation_complete">تایید فایل XAPK تکمیل شد. برای خروج تایید کنید.</string>
+ <string name="text_validation_failed">اعتبارسنجی فایل XAPK ناموق.</string>
+ <string name="text_button_pause">توقف دانلود</string>
+ <string name="text_button_resume">ادامه دانلود</string>
+ <string name="text_button_cancel">انصراف</string>
+ <string name="text_button_cancel_verify">انصراف از تایید شدن</string>
+</resources>
diff --git a/platform/android/java/src/com/android/godot/GodotPaymentV3.java b/platform/android/java/src/com/android/godot/GodotPaymentV3.java
index 0fd102ac55..0799e1e83d 100644
--- a/platform/android/java/src/com/android/godot/GodotPaymentV3.java
+++ b/platform/android/java/src/com/android/godot/GodotPaymentV3.java
@@ -27,7 +27,7 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
activity.getPaymentsManager().requestPurchase(sku, transactionId);
}
});
- };
+ }
/* public string requestPurchasedTicket(){
activity.getPaymentsManager()
@@ -42,7 +42,7 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
public GodotPaymentV3(Activity p_activity) {
- registerClass("GodotPayments", new String[] {"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases"});
+ registerClass("GodotPayments", new String[] {"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume"});
activity=(Godot) p_activity;
}
@@ -54,7 +54,6 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
activity.getPaymentsManager().consumeUnconsumedPurchases();
}
});
-
}
private String signature;
@@ -63,25 +62,26 @@ 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.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature});
-// Log.d(this.getClass().getName(), "POST-Send callback to purchase success");
+ public void callbackSuccess(String ticket, String signature, String sku){
+// Log.d(this.getClass().getName(), "PRE-Send callback to purchase success");
+ GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature, sku});
+// 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");
+// Log.d(this.getClass().getName(), "PRE-Send callback to consume success");
+ Log.d(this.getClass().getName(), "callbackSuccessProductMassConsumed > "+ticket+","+signature+","+sku);
+ 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[]{});
+ GodotLib.calldeferred(purchaseCallbackId, "no_validation_required", new Object[]{});
}
public void callbackFail(){
- GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[]{});
-// GodotLib.callobject(purchaseCallbackId, "purchase_fail", new Object[]{});
+ GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[]{});
+// GodotLib.callobject(purchaseCallbackId, "purchase_fail", new Object[]{});
}
public void callbackCancel(){
@@ -89,6 +89,10 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
// GodotLib.callobject(purchaseCallbackId, "purchase_cancel", new Object[]{});
}
+ public void callbackAlreadyOwned(String sku){
+ GodotLib.calldeferred(purchaseCallbackId, "purchase_owned", new Object[]{sku});
+ }
+
public int getPurchaseCallbackId() {
return purchaseCallbackId;
}
@@ -97,8 +101,6 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
this.purchaseCallbackId = purchaseCallbackId;
}
-
-
public String getPurchaseValidationUrlPrefix(){
return this.purchaseValidationUrlPrefix ;
}
@@ -107,12 +109,10 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
this.purchaseValidationUrlPrefix = url;
}
-
public String getAccessToken() {
return accessToken;
}
-
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
@@ -125,4 +125,30 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
return this.transactionId;
}
+ // request purchased items are not consumed
+ public void requestPurchased(){
+ activity.getPaymentsManager().setBaseSingleton(this);
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ activity.getPaymentsManager().requestPurchased();
+ }
+ });
+ }
+
+ // callback for requestPurchased()
+ public void callbackPurchased(String receipt, String signature, String sku){
+ GodotLib.calldeferred(purchaseCallbackId, "has_purchased", new Object[]{receipt, signature, sku});
+ }
+
+ // consume item automatically after purchase. default is true.
+ public void setAutoConsume(boolean autoConsume){
+ activity.getPaymentsManager().setAutoConsume(autoConsume);
+ }
+
+ // consume a specific item
+ public void consume(String sku){
+ activity.getPaymentsManager().consume(sku);
+ }
}
+
diff --git a/platform/android/java/src/com/android/godot/payments/PaymentsManager.java b/platform/android/java/src/com/android/godot/payments/PaymentsManager.java
index fd1a62738a..189f7108c1 100644
--- a/platform/android/java/src/com/android/godot/payments/PaymentsManager.java
+++ b/platform/android/java/src/com/android/godot/payments/PaymentsManager.java
@@ -25,10 +25,8 @@ import com.android.vending.billing.IInAppBillingService;
public class PaymentsManager {
public static final int BILLING_RESPONSE_RESULT_OK = 0;
-
-
public static final int REQUEST_CODE_FOR_PURCHASE = 0x1001;
-
+ private static boolean auto_consume = true;
private Activity activity;
IInAppBillingService mService;
@@ -47,8 +45,10 @@ public class PaymentsManager {
}
public PaymentsManager initService(){
+ Intent intent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
+ intent.setPackage("com.android.vending");
activity.bindService(
- new Intent("com.android.vending.billing.InAppBillingService.BIND"),
+ intent,
mServiceConn,
Context.BIND_AUTO_CREATE);
return this;
@@ -67,13 +67,12 @@ public class PaymentsManager {
}
@Override
- public void onServiceConnected(ComponentName name,
- IBinder service) {
- mService = IInAppBillingService.Stub.asInterface(service);
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ mService = IInAppBillingService.Stub.asInterface(service);
}
};
- public void requestPurchase(String sku, String transactionId){
+ public void requestPurchase(final String sku, String transactionId){
new PurchaseTask(mService, Godot.getInstance()) {
@Override
@@ -86,6 +85,12 @@ public class PaymentsManager {
protected void canceled() {
godotPaymentV3.callbackCancel();
}
+
+ @Override
+ protected void alreadyOwned() {
+ godotPaymentV3.callbackAlreadyOwned(sku);
+ }
+
}.purchase(sku, transactionId);
}
@@ -112,26 +117,82 @@ public class PaymentsManager {
}.consumeItAll();
}
+ public void requestPurchased(){
+ try{
+ PaymentsCache pc = new PaymentsCache(Godot.getInstance());
+
+// Log.d("godot", "requestPurchased for " + activity.getPackageName());
+ Bundle bundle = mService.getPurchases(3, activity.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!");
+ godotPaymentV3.callbackPurchased("", "", "");
+ return;
+ }
+
+// Log.d("godot", "# products are purchased:" + 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", "purchased item:" + token + "\n" + receipt);
+
+ pc.setConsumableValue("ticket_signautre", sku, signature);
+ pc.setConsumableValue("ticket", sku, receipt);
+ pc.setConsumableFlag("block", sku, true);
+ pc.setConsumableValue("token", sku, token);
+
+ godotPaymentV3.callbackPurchased(receipt, signature, sku);
+ } catch (JSONException e) {
+ }
+ }
+
+ }
+ }catch(Exception e){
+ Log.d("godot", "Error requesting purchased products:" + e.getClass().getName() + ":" + e.getMessage());
+ }
+ }
+
public void processPurchaseResponse(int resultCode, Intent data) {
new HandlePurchaseTask(activity){
@Override
protected void success(final String sku, final String signature, final String ticket) {
- godotPaymentV3.callbackSuccess(ticket, signature);
- new ConsumeTask(mService, activity) {
+ godotPaymentV3.callbackSuccess(ticket, signature, sku);
+
+ if (auto_consume){
+ new ConsumeTask(mService, activity) {
- @Override
- protected void success(String ticket) {
-// godotPaymentV3.callbackSuccess("");
- }
+ @Override
+ protected void success(String ticket) {
+// godotPaymentV3.callbackSuccess("");
+ }
- @Override
- protected void error(String message) {
- godotPaymentV3.callbackFail();
+ @Override
+ protected void error(String message) {
+ godotPaymentV3.callbackFail();
- }
- }.consume(sku);
-
+ }
+ }.consume(sku);
+ }
// godotPaymentV3.callbackSuccess(new PaymentsCache(activity).getConsumableValue("ticket", sku),signature);
// godotPaymentV3.callbackSuccess(ticket);
@@ -149,7 +210,7 @@ public class PaymentsManager {
godotPaymentV3.callbackCancel();
}
- }.handlePurchaseRequest(resultCode, data);
+ }.handlePurchaseRequest(resultCode, data);
}
public void validatePurchase(String purchaseToken, final String sku){
@@ -163,7 +224,7 @@ public class PaymentsManager {
@Override
protected void success(String ticket) {
- godotPaymentV3.callbackSuccess(ticket, null);
+ godotPaymentV3.callbackSuccess(ticket, null, sku);
}
@@ -190,11 +251,31 @@ public class PaymentsManager {
}.validatePurchase(sku);
}
+ public void setAutoConsume(boolean autoConsume){
+ auto_consume = autoConsume;
+ }
+
+ public void consume(final String sku){
+ new ConsumeTask(mService, activity) {
+
+ @Override
+ protected void success(String ticket) {
+ godotPaymentV3.callbackSuccessProductMassConsumed(ticket, "", sku);
+
+ }
+
+ @Override
+ protected void error(String message) {
+ godotPaymentV3.callbackFail();
+
+ }
+ }.consume(sku);
+ }
+
private GodotPaymentV3 godotPaymentV3;
public void setBaseSingleton(GodotPaymentV3 godotPaymentV3) {
this.godotPaymentV3 = godotPaymentV3;
-
}
}
diff --git a/platform/android/java/src/com/android/godot/payments/PurchaseTask.java b/platform/android/java/src/com/android/godot/payments/PurchaseTask.java
index 75662a442e..c1f9d164a1 100644
--- a/platform/android/java/src/com/android/godot/payments/PurchaseTask.java
+++ b/platform/android/java/src/com/android/godot/payments/PurchaseTask.java
@@ -62,7 +62,11 @@ abstract public class PurchaseTask {
// Log.d("XXX", "Buy intent response code: " + responseCode);
if(responseCode == 1 || responseCode == 3 || responseCode == 4){
canceled();
- return ;
+ return;
+ }
+ if(responseCode == 7){
+ alreadyOwned();
+ return;
}
@@ -92,6 +96,6 @@ abstract public class PurchaseTask {
abstract protected void error(String message);
abstract protected void canceled();
-
+ abstract protected void alreadyOwned();
}
diff --git a/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java b/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java
deleted file mode 100644
index da9d06e63c..0000000000
--- a/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/** Automatically generated file. DO NOT MODIFY */
-package com.android.vending.expansion.downloader;
-
-public final class BuildConfig {
- public final static boolean DEBUG = false;
-} \ No newline at end of file
diff --git a/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/R.java b/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/R.java
deleted file mode 100644
index 330aed1856..0000000000
--- a/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/R.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/* AUTO-GENERATED FILE. DO NOT MODIFY.
- *
- * This class was automatically generated by the
- * aapt tool from the resource data it found. It
- * should not be modified by hand.
- */
-
-package com.android.vending.expansion.downloader;
-
-public final class R {
- public static final class attr {
- }
- public static final class drawable {
- public static int notify_panel_notification_icon_bg=0x7f020000;
- }
- public static final class id {
- public static int appIcon=0x7f060001;
- public static int description=0x7f060007;
- public static int notificationLayout=0x7f060000;
- public static int progress_bar=0x7f060006;
- public static int progress_bar_frame=0x7f060005;
- public static int progress_text=0x7f060002;
- public static int time_remaining=0x7f060004;
- public static int title=0x7f060003;
- }
- public static final class layout {
- public static int status_bar_ongoing_event_progress_bar=0x7f030000;
- }
- public static final class string {
- public static int kilobytes_per_second=0x7f040014;
- /** When a download completes, a notification is displayed, and this
- string is used to indicate that the download successfully completed.
- Note that such a download could have been initiated by a variety of
- applications, including (but not limited to) the browser, an email
- application, a content marketplace.
- */
- public static int notification_download_complete=0x7f040000;
- /** When a download completes, a notification is displayed, and this
- string is used to indicate that the download failed.
- Note that such a download could have been initiated by a variety of
- applications, including (but not limited to) the browser, an email
- application, a content marketplace.
- */
- public static int notification_download_failed=0x7f040001;
- public static int state_completed=0x7f040007;
- public static int state_connecting=0x7f040005;
- public static int state_downloading=0x7f040006;
- public static int state_failed=0x7f040013;
- public static int state_failed_cancelled=0x7f040012;
- public static int state_failed_fetching_url=0x7f040010;
- public static int state_failed_sdcard_full=0x7f040011;
- public static int state_failed_unlicensed=0x7f04000f;
- public static int state_fetching_url=0x7f040004;
- public static int state_idle=0x7f040003;
- public static int state_paused_by_request=0x7f04000a;
- public static int state_paused_network_setup_failure=0x7f040009;
- public static int state_paused_network_unavailable=0x7f040008;
- public static int state_paused_roaming=0x7f04000d;
- public static int state_paused_sdcard_unavailable=0x7f04000e;
- public static int state_paused_wifi_disabled=0x7f04000c;
- public static int state_paused_wifi_unavailable=0x7f04000b;
- public static int state_unknown=0x7f040002;
- public static int time_remaining=0x7f040015;
- public static int time_remaining_notification=0x7f040016;
- }
- public static final class style {
- public static int ButtonBackground=0x7f050003;
- public static int NotificationText=0x7f050000;
- public static int NotificationTextSecondary=0x7f050004;
- public static int NotificationTextShadow=0x7f050001;
- public static int NotificationTitle=0x7f050002;
- }
-}
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index e9b0d00196..dcaa1db654 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -39,7 +39,7 @@
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include "servers/visual/rasterizer.h"
-
+#include "main/input_default.h"
//#ifdef USE_JAVA_FILE_ACCESS