diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index af07624..d0268dd 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -22,22 +22,23 @@ jobs: uses: actions/setup-go@v4 with: go-version: '1.21.1' + - name: Install gomobile + run: | + go install golang.org/x/mobile/cmd/gomobile@latest - name: Set up JDK 17 uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: '17' cache: 'gradle' - - name: Build imessage.so - run: ./android/imessage.sh - name: Build AAR - run: ./android/gradlew -p android :library:assembleRelease - - name: Publish to GitHub Packages - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: ./android/gradlew -p android :library:publish + run: gomobile bind -target=android -androidapi 26 -o imessage.aar ./imessage/ffi + # - name: Publish to GitHub Packages + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # run: ./android/gradlew -p android :library:publish - name: Upload artifacts uses: actions/upload-artifact@v3 with: name: aar - path: ./android/library/build/outputs/aar/library-release.aar + path: ffi.aar diff --git a/.gitignore b/.gitignore index dd73b4c..f617fd0 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,6 @@ /.android-ipc-bin /imgo.h /imgo.so + +/imessage-sources.jar +/imessage.aar diff --git a/android/.gitignore b/android/.gitignore deleted file mode 100644 index aa724b7..0000000 --- a/android/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml -.DS_Store -/build -/captures -.externalNativeBuild -.cxx -local.properties diff --git a/android/build.gradle.kts b/android/build.gradle.kts deleted file mode 100644 index 077ff67..0000000 --- a/android/build.gradle.kts +++ /dev/null @@ -1,6 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. -plugins { - id("com.android.application") version "8.2.0-rc03" apply false - id("org.jetbrains.kotlin.android") version "1.9.10" apply false - id("com.android.library") version "8.2.0-rc03" apply false -} diff --git a/android/gradle.properties b/android/gradle.properties deleted file mode 100644 index 2cbd6d1..0000000 --- a/android/gradle.properties +++ /dev/null @@ -1,23 +0,0 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn -android.useAndroidX=true -# Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official -# Enables namespacing of each library's R class so that its R class includes only the -# resources declared in the library itself and none from the library's dependencies, -# thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index e708b1c..0000000 Binary files a/android/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 6b86d58..0000000 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Wed Sep 27 15:30:00 CDT 2023 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/android/gradlew b/android/gradlew deleted file mode 100755 index 4f906e0..0000000 --- a/android/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat deleted file mode 100644 index 107acd3..0000000 --- a/android/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/android/imessage.sh b/android/imessage.sh deleted file mode 100755 index ab308bb..0000000 --- a/android/imessage.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -set -e - -ANDROID_API=26 -NDK_VERSION=24.0.8215888 -ROOT="$(cd "$(dirname "$0")"; pwd)" - -if [ -z "$ANDROID_HOME" ]; then - echo "ANDROID_HOME not set" - exit 1 -fi - -NDK_ROOT="$ANDROID_HOME/ndk/$NDK_VERSION" -if [ ! -d "$NDK_ROOT" ]; then - echo "Missing Android NDK" - exit 1 -fi - -if [ "$(uname)" = 'Darwin' ]; then - NDK_ARCH="darwin-x86_64" -else - NDK_ARCH="linux-x86_64" -fi - -LDFLAGS="-s -w -X main.Tag=$(git describe --exact-match --tags 2>/dev/null) -X main.Commit=$(git rev-parse HEAD) -X 'main.BuildTime=$(date '+%b %_d %Y, %H:%M:%S')'" - -build_imessage() { - local ANDROID_ARCH=$1 - local NDK_TARGET=$2 - local GOARCH=$3 - local GOARM=$4 - local LIB_JNI="$ROOT/library/src/main/jniLibs/$ANDROID_ARCH" - echo - echo "Building $ANDROID_ARCH" - echo - - rm -rf "$LIB_JNI" - mkdir -p "$LIB_JNI" - - (set -x; CGO_LDFLAGS="-lm -llog" CGO_ENABLED=1 GOOS=android GOARCH=$GOARCH GOARM=$GOARM \ - CC="$NDK_ROOT/toolchains/llvm/prebuilt/$NDK_ARCH/bin/$NDK_TARGET$ANDROID_API-clang" \ - go build -ldflags "$LDFLAGS" -o "$LIB_JNI"/libima.so ./imessage/ffi) -} - -build_imessage armeabi-v7a armv7a-linux-androideabi arm 7 -build_imessage arm64-v8a aarch64-linux-android arm64 -build_imessage x86 i686-linux-android 386 -build_imessage x86_64 x86_64-linux-android amd64 diff --git a/android/library/.gitignore b/android/library/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/android/library/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/android/library/build.gradle.kts b/android/library/build.gradle.kts deleted file mode 100644 index 2f88cf6..0000000 --- a/android/library/build.gradle.kts +++ /dev/null @@ -1,97 +0,0 @@ -import java.io.BufferedReader - -plugins { - id("com.android.library") - id("org.jetbrains.kotlin.android") - id("maven-publish") -} - -val gitBranch = System.getenv("GITHUB_REF_NAME") ?: gitCommand("git branch --show-current") - -val commitHash = gitCommand("git rev-parse --short HEAD") - -fun gitCommand(command: String) = - Runtime - .getRuntime() - .exec(command) - .let { process -> - process.waitFor() - val output = process.inputStream.use { - it.bufferedReader().use(BufferedReader::readText) - } - process.destroy() - output.trim() - } - -android { - namespace = "com.beeper.imessage" - compileSdk = 34 - - defaultConfig { - minSdk = 26 - buildConfigField("String", "GIT_BRANCH", "\"$gitBranch\"") - buildConfigField("String", "GIT_HASH", "\"$commitHash\"") - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = "1.8" - } - buildFeatures { - buildConfig = true - } -} - -afterEvaluate { - publishing { - repositories { - maven { - url = uri("https://maven.pkg.github.com/beeper/imessage") - credentials { - username = System.getenv("GITHUB_ACTOR") - password = System.getenv("GITHUB_TOKEN") - } - } - } - publications { - create("github") { - from(components["release"]) - groupId = "com.beeper" - artifactId = "imessage" - version = "${gitBranch.replace("/", "-")}-$commitHash" - pom { - name.set("im-on-and") - description.set("im-on-and") - url.set("https://beeper.com") - scm { - developerConnection.set("scm:git:ssh://github.com/beeper/imessage.git") - url.set("https://github.com/beeper/imessage") - } - } - } - } - } -} - -dependencies { - implementation("androidx.core:core-ktx:1.12.0") - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("com.google.android.material:material:1.9.0") - testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") -} diff --git a/android/library/consumer-rules.pro b/android/library/consumer-rules.pro deleted file mode 100644 index e69de29..0000000 diff --git a/android/library/proguard-rules.pro b/android/library/proguard-rules.pro deleted file mode 100644 index f1b4245..0000000 --- a/android/library/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/android/library/src/main/AndroidManifest.xml b/android/library/src/main/AndroidManifest.xml deleted file mode 100644 index 8bdb7e1..0000000 --- a/android/library/src/main/AndroidManifest.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts deleted file mode 100644 index 9c2b52e..0000000 --- a/android/settings.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -pluginManagement { - repositories { - google() - mavenCentral() - gradlePluginPortal() - } -} -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) - repositories { - google() - mavenCentral() - } -} - -rootProject.name = "imessage" -include(":library") diff --git a/go.mod b/go.mod index 8ced752..d467bf9 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( golang.org/x/crypto v0.17.0 golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 golang.org/x/image v0.14.0 + golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a golang.org/x/net v0.19.0 golang.org/x/sys v0.15.0 golang.org/x/time v0.5.0 @@ -41,7 +42,9 @@ require ( github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.6.0 // indirect + golang.org/x/mod v0.14.0 // indirect golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.16.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 03e9546..e416a24 100644 --- a/go.sum +++ b/go.sum @@ -80,7 +80,11 @@ golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 h1:+iq7lrkxmFNBM7xx+Rae2W6uy golang.org/x/exp v0.0.0-20231219180239-dc181d75b848/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= +golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a h1:sYbmY3FwUWCBTodZL1S3JUuOvaW6kM2o+clDzzDNBWg= +golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a/go.mod h1:Ede7gF0KGoHlj822RtphAHK1jLdrcuRBZg0sF1Q+SPc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -89,6 +93,8 @@ golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -114,6 +120,8 @@ golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= diff --git a/imessage/ffi/bridgeinfo.go b/imessage/ffi/bridgeinfo.go index 9cc1701..d749de3 100644 --- a/imessage/ffi/bridgeinfo.go +++ b/imessage/ffi/bridgeinfo.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package main +package ffi import ( "strings" diff --git a/imessage/ffi/commands.go b/imessage/ffi/commands.go index 28d9923..55b50ae 100644 --- a/imessage/ffi/commands.go +++ b/imessage/ffi/commands.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package main +package ffi import ( "context" diff --git a/imessage/ffi/events.go b/imessage/ffi/events.go index 02e0200..f2f23ec 100644 --- a/imessage/ffi/events.go +++ b/imessage/ffi/events.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package main +package ffi import ( "context" diff --git a/imessage/ffi/filetransfer.go b/imessage/ffi/filetransfer.go index 61da231..07095d2 100644 --- a/imessage/ffi/filetransfer.go +++ b/imessage/ffi/filetransfer.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package main +package ffi import ( "context" diff --git a/imessage/ffi/global.go b/imessage/ffi/global.go index 27b1852..af7379e 100644 --- a/imessage/ffi/global.go +++ b/imessage/ffi/global.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package main +package ffi import ( "context" diff --git a/imessage/ffi/main.go b/imessage/ffi/main.go index d39f022..23076da 100644 --- a/imessage/ffi/main.go +++ b/imessage/ffi/main.go @@ -14,13 +14,11 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package main +package ffi -import "C" import ( "context" _ "embed" - "encoding/json" "fmt" "io" "os" @@ -33,7 +31,6 @@ import ( "sync/atomic" "syscall" "time" - "unsafe" "github.com/rs/zerolog" deflog "github.com/rs/zerolog/log" @@ -41,6 +38,7 @@ import ( _ "go.mau.fi/util/dbutil/litestream" "go.mau.fi/util/exzerolog" "go.mau.fi/zeroconfig" + _ "golang.org/x/mobile/bind" "github.com/beeper/imessage/analytics" "github.com/beeper/imessage/database" @@ -96,10 +94,7 @@ func analyticsTrackOverIPC(event string, properties map[string]any) error { }) } -func main() {} - -//export start -func start() { +func Start() { writer := ipc.NewLockedWriter(&FFIStdout) zeroconfig.RegisterWriter(writerTypeStdoutIPC, func(config *zeroconfig.WriterConfig) (io.Writer, error) { return writer, nil @@ -363,12 +358,7 @@ type ReqStarted struct { PendingNACURL bool `json:"pending_nac_url"` } -// init_config is called over FFI to initialize the bridge configuration. -// -//export init_config -func init_config(data *C.char, n C.int) { - must(0, json.Unmarshal(C.GoBytes(unsafe.Pointer(data), n), &global.Cfg)) - +func InitConfig(data []byte) { global.NAC = &nacserv.Client{ URL: global.Cfg.NACServURL, Token: global.Cfg.NACServToken, diff --git a/imessage/ffi/stdin.go b/imessage/ffi/stdin.go index 0b2be40..d9c3b6a 100644 --- a/imessage/ffi/stdin.go +++ b/imessage/ffi/stdin.go @@ -14,28 +14,18 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package main +package ffi -import "C" import ( "io" - "unsafe" ) var FFIStdinReader, FFIStdinWriter = io.Pipe() -// stdin_write is a function which allows C code to write to the fake "stdin" -// buffer. -// -// This function returns the number of bytes written, or -1 if an error -// occurred. -// -//export stdin_write -func stdin_write(data *C.char, n C.int) C.int { - buf := C.GoBytes(unsafe.Pointer(data), n) - written, err := FFIStdinWriter.Write(buf) +func StdinWrite(data []byte) int { + written, err := FFIStdinWriter.Write(data) if err != nil { - return C.int(-1) + return -1 } - return C.int(written) + return written } diff --git a/imessage/ffi/stdout.c b/imessage/ffi/stdout.c deleted file mode 100644 index f503c0a..0000000 --- a/imessage/ffi/stdout.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -typedef void (*stdout_callback_t)(const char *, int); - -void stdout_write(stdout_callback_t callback, const char *data, int n) { - callback(data, n); -} diff --git a/imessage/ffi/stdout.go b/imessage/ffi/stdout.go index 9a1f0ca..d73f2b0 100644 --- a/imessage/ffi/stdout.go +++ b/imessage/ffi/stdout.go @@ -14,31 +14,19 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package main - -/* -#include - -// stdout_callback is a function pointer to a function that takes a string and -// returns nothing. -typedef void (*stdout_callback_t)(const char*, int); -void stdout_write(stdout_callback_t callback, const char* data, int n); -*/ -import "C" -import "unsafe" +package ffi type ffiStdout struct { - callback C.stdout_callback_t + callback func([]byte) } func (s *ffiStdout) Write(p []byte) (n int, err error) { - C.stdout_write(s.callback, (*C.char)(unsafe.Pointer(&p[0])), C.int(len(p))) + s.callback(p) return len(p), nil } var FFIStdout = ffiStdout{} -//export set_stdout_callback -func set_stdout_callback(callback C.stdout_callback_t) { +func SetStdoutCallback(callback func([]byte)) { FFIStdout.callback = callback }