diff --git a/android/app/build.gradle b/android/app/build.gradle index 1404ac048..e4524109d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -44,7 +44,8 @@ android { versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - manifestPlaceholders = [APP_NAME: System.getenv('APP_ANDROID_NAME')] + manifestPlaceholders = [APP_NAME: System.getenv('APP_ANDROID_NAME'), + APP_PACKAGE: System.getenv('APP_ANDROID_PACKAGE')] externalNativeBuild { cmake { diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c13986b04..81418644b 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="${APP_PACKAGE}"> diff --git a/android/app/src/main/java/com/monero/app/Application.java b/android/app/src/main/java/com/monero/app/Application.java new file mode 100644 index 000000000..b085171e5 --- /dev/null +++ b/android/app/src/main/java/com/monero/app/Application.java @@ -0,0 +1,11 @@ +package com.monero.app; + +import io.flutter.app.FlutterApplication; +import io.flutter.plugin.common.PluginRegistry; +import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class Application extends FlutterApplication implements PluginRegistrantCallback { + @Override + public void registerWith(PluginRegistry registry) {} +} \ No newline at end of file diff --git a/android/app/src/main/java/com/monero/app/MainActivity.java b/android/app/src/main/java/com/monero/app/MainActivity.java new file mode 100644 index 000000000..8a46333db --- /dev/null +++ b/android/app/src/main/java/com/monero/app/MainActivity.java @@ -0,0 +1,81 @@ +package com.monero.app; + +import androidx.annotation.NonNull; + +import io.flutter.embedding.android.FlutterFragmentActivity; +import io.flutter.embedding.engine.FlutterEngine; +import io.flutter.plugins.GeneratedPluginRegistrant; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; + +import android.os.AsyncTask; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; + +import com.unstoppabledomains.resolution.DomainResolution; +import com.unstoppabledomains.resolution.Resolution; + +import java.security.SecureRandom; + +public class MainActivity extends FlutterFragmentActivity { + final String UTILS_CHANNEL = "com.cake_wallet/native_utils"; + final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24; + + @Override + public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { + GeneratedPluginRegistrant.registerWith(flutterEngine); + + MethodChannel utilsChannel = + new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), + UTILS_CHANNEL); + + utilsChannel.setMethodCallHandler(this::handle); + } + + private void handle(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + Handler handler = new Handler(Looper.getMainLooper()); + + try { + switch (call.method) { + case "sec_random": + int count = call.argument("count"); + SecureRandom random = new SecureRandom(); + byte bytes[] = new byte[count]; + random.nextBytes(bytes); + handler.post(() -> result.success(bytes)); + break; + case "getUnstoppableDomainAddress": + int version = Build.VERSION.SDK_INT; + if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) { + getUnstoppableDomainAddress(call, result); + } else { + handler.post(() -> result.success("")); + } + break; + default: + handler.post(() -> result.notImplemented()); + } + } catch (Exception e) { + handler.post(() -> result.error("UNCAUGHT_ERROR", e.getMessage(), null)); + } + } + + private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + DomainResolution resolution = new Resolution(); + Handler handler = new Handler(Looper.getMainLooper()); + String domain = call.argument("domain"); + String ticker = call.argument("ticker"); + + AsyncTask.execute(() -> { + try { + String address = resolution.getAddress(domain, ticker); + handler.post(() -> result.success(address)); + } catch (Exception e) { + System.out.println("Expected Address, but got " + e.getMessage()); + handler.post(() -> result.success("")); + } + }); + } +} \ No newline at end of file diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index f027ef801..496bdc59f 100755 --- a/scripts/android/app_env.sh +++ b/scripts/android/app_env.sh @@ -4,6 +4,7 @@ APP_ANDROID_NAME="" APP_ANDROID_VERSION="" APP_ANDROID_BUILD_VERSION="" APP_ANDROID_ID="" +APP_ANDROID_PACKAGE="" MONERO_COM="monero.com" CAKEWALLET="cakewallet" @@ -15,11 +16,13 @@ MONERO_COM_NAME="Monero.com" MONERO_COM_VERSION="1.0.0" MONERO_COM_BUILD_NUMBER=6 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" +MONERO_COM_PACKAGE="com.monero.app" CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_VERSION="4.2.8" CAKEWALLET_BUILD_NUMBER=69 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" +CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" if ! [[ " ${TYPES[*]} " =~ " ${APP_ANDROID_TYPE} " ]]; then echo "Wrong app type." @@ -32,12 +35,14 @@ case $APP_ANDROID_TYPE in APP_ANDROID_VERSION=$MONERO_COM_VERSION APP_ANDROID_BUILD_NUMBER=$MONERO_COM_BUILD_NUMBER APP_ANDROID_BUNDLE_ID=$MONERO_COM_BUNDLE_ID + APP_ANDROID_PACKAGE=$MONERO_COM_PACKAGE ;; $CAKEWALLET) APP_ANDROID_NAME=$CAKEWALLET_NAME APP_ANDROID_VERSION=$CAKEWALLET_VERSION APP_ANDROID_BUILD_NUMBER=$CAKEWALLET_BUILD_NUMBER APP_ANDROID_BUNDLE_ID=$CAKEWALLET_BUNDLE_ID + APP_ANDROID_PACKAGE=$CAKEWALLET_PACKAGE ;; esac @@ -46,3 +51,4 @@ export APP_ANDROID_NAME export APP_ANDROID_VERSION export APP_ANDROID_BUILD_NUMBER export APP_ANDROID_BUNDLE_ID +export APP_ANDROID_PACKAGE \ No newline at end of file