All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.statsig.StatsigJNI Maven / Gradle / Ivy

There is a newer version: 0.28.0
Show newest version
package com.statsig;

import java.io.*;
import java.net.URL;
import java.util.Map;

import static com.statsig.internal.Constants.LOG_PREFIX;

public class StatsigJNI {
    private static boolean libraryLoaded;

    public static boolean isLibraryLoaded() {
        return libraryLoaded;
    }

    static {
        String osName = System.getProperty("os.name").toLowerCase();
        String osArch = System.getProperty("os.arch").toLowerCase();

        System.out.println(LOG_PREFIX + "Detected OS: " + osName + " Arch: " + osArch);
        try {
            URL resource = findLibraryResource(osName, osArch);
            if (resource == null) {
                System.err.println(LOG_PREFIX + "Unable to find native library resource for OS: " + osName + " Arch: " + osArch);
                throw new UnsatisfiedLinkError();
            }

            System.out.println(LOG_PREFIX + "Loaded native library resource: " + resource + " for OS: " + osName + " Arch: " + osArch);
            String libPath = writeLibToTempFile(resource);

            if (libPath == null) {
                throw new UnsatisfiedLinkError();
            }

            System.out.println(LOG_PREFIX + "Loaded library path: " + libPath);
            System.load(libPath);
            libraryLoaded = true;
        } catch (UnsatisfiedLinkError e) {
            System.err.println("Failed to load libstatsig_ffi: " + e.getMessage());
            libraryLoaded = false;
        }
    }

    private static String writeLibToTempFile(URL resource) {
        try {
            InputStream stream = resource.openStream();

            if (stream == null) {
                System.err.println(LOG_PREFIX + "Unable to open stream for resource: " + resource);
                throw new RuntimeException();
            }

            File temp = File.createTempFile("statsig_ffi_lib", null);
            temp.deleteOnExit();

            try (stream; OutputStream out = new FileOutputStream(temp)) {
                byte[] buffer = new byte[1024];
                int length = 0;
                while ((length = stream.read(buffer)) != -1) {
                    out.write(buffer, 0, length);
                }
            }

            System.out.println(LOG_PREFIX + "Created temporary file at: " + temp.getAbsolutePath());
            return temp.getAbsolutePath();
        } catch (IOException e) {
            System.err.println(e);
            throw new RuntimeException(e);
        }
    }

    private static URL findLibraryResource(String osName, String osArch) {
        ClassLoader cl = StatsigJNI.class.getClassLoader();
        URL resource = null;

        if (osName.contains("win")) {
            resource = cl.getResource("libstatsig_ffi.dll");
        } else if (osName.contains("mac")) {
            if (osArch.equals("x86_64") || osArch.equals("amd64")) {
                resource = cl.getResource("libstatsig_ffi.dylib");
            } else if (osArch.equals("aarch64")) {
                resource = cl.getResource("native/libstatsig_ffi.dylib"); // TODO confirm
            }
        } else if (osName.contains("linux")) {
            resource = cl.getResource("libstatsig_ffi.so");
        }

        return resource;
    }

    /**
     * Statsig
     */
    public static native int statsigCreate(String sdkKey, int optionsRef);
    public static native void statsigRelease(int statsigRef);
    public static native void statsigInitialize(int statsigRef, Runnable callback);
    public static native void statsigShutdown(int statsigRef, Runnable callback);
    public static native boolean statsigCheckGate(int statsigRef, int userRef, String gateName);
    public static native String statsigGetFeatureGate(int statsigRef, int userRef, String gateName);
    public static native String statsigGetLayer(int statsigRef, int userRef, String layerName);
    public static native String statsigGetExperiment(int statsigRef, int userRef, String experimentName);
    public static native String statsigGetDynamicConfig(int statsigRef, int userRef, String configName);
    public static native String statsigGetClientInitResponse(int statsigRef, int userRef);
    public static native void statsigLogEvent(int statsigRef, int userRef, String eventName, String value, Map metadata);
    public static native void statsigFlushEvents(int statsigRef, Runnable callback);

    /**
     * StatsigUser
     */
    public static native int statsigUserCreate(
            String userId,
            String customIdsJson,
            String email,
            String ip,
            String userAgent,
            String country,
            String locale,
            String appVersion,
            String customJson,
            String privateAttributesJson
    );
    public static native void statsigUserRelease(int userRef);

    /**
     * StatsigOptions
     */
    public static native int statsigOptionsCreate(
            String specsUrl,
            String logEventUrl,
            long specsSyncIntervalMs,
            long eventLoggingFlushIntervalMs,
            long eventLoggingMaxQueueSize,
            String environment
    );
    public static native void statsigOptionsRelease(int optionsRef);
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy