рабочий вариант, но скороть 10 МБит
This commit is contained in:
@@ -0,0 +1,400 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package go;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import go.Universe;
|
||||
|
||||
// Seq is a sequence of machine-dependent encoded values.
|
||||
// Used by automatically generated language bindings to talk to Go.
|
||||
public class Seq {
|
||||
private static Logger log = Logger.getLogger("GoSeq");
|
||||
|
||||
// also known to bind/seq/ref.go and bind/objc/seq_darwin.m
|
||||
private static final int NULL_REFNUM = 41;
|
||||
|
||||
// use single Ref for null Object
|
||||
public static final Ref nullRef = new Ref(NULL_REFNUM, null);
|
||||
|
||||
// The singleton GoRefQueue
|
||||
private static final GoRefQueue goRefQueue = new GoRefQueue();
|
||||
|
||||
static {
|
||||
System.loadLibrary("gojni");
|
||||
init();
|
||||
Universe.touch();
|
||||
}
|
||||
|
||||
// setContext sets the context in the go-library to be used in RunOnJvm.
|
||||
public static void setContext(Context context) {
|
||||
setContext((java.lang.Object)context);
|
||||
}
|
||||
|
||||
private static native void init();
|
||||
|
||||
// Empty method to run class initializer
|
||||
public static void touch() {}
|
||||
|
||||
private Seq() {
|
||||
}
|
||||
|
||||
// ctx is an android.context.Context.
|
||||
static native void setContext(java.lang.Object ctx);
|
||||
|
||||
public static void incRefnum(int refnum) {
|
||||
tracker.incRefnum(refnum);
|
||||
}
|
||||
|
||||
// incRef increments the reference count of Java objects.
|
||||
// For proxies for Go objects, it calls into the Proxy method
|
||||
// incRefnum() to make sure the Go reference count is positive
|
||||
// even if the Proxy is garbage collected and its Ref is finalized.
|
||||
public static int incRef(Object o) {
|
||||
return tracker.inc(o);
|
||||
}
|
||||
|
||||
public static int incGoObjectRef(GoObject o) {
|
||||
return o.incRefnum();
|
||||
}
|
||||
|
||||
// trackGoRef tracks a Go reference and decrements its refcount
|
||||
// when the given GoObject wrapper is garbage collected.
|
||||
//
|
||||
// TODO(crawshaw): We could cut down allocations for frequently
|
||||
// sent Go objects by maintaining a map to weak references. This
|
||||
// however, would require allocating two objects per reference
|
||||
// instead of one. It also introduces weak references, the bane
|
||||
// of any Java debugging session.
|
||||
//
|
||||
// When we have real code, examine the tradeoffs.
|
||||
public static void trackGoRef(int refnum, GoObject obj) {
|
||||
if (refnum > 0) {
|
||||
throw new RuntimeException("trackGoRef called with Java refnum " + refnum);
|
||||
}
|
||||
goRefQueue.track(refnum, obj);
|
||||
}
|
||||
|
||||
public static Ref getRef(int refnum) {
|
||||
return tracker.get(refnum);
|
||||
}
|
||||
|
||||
// Increment the Go reference count before sending over a refnum.
|
||||
// The ref parameter is only used to make sure the referenced
|
||||
// object is not garbage collected before Go increments the
|
||||
// count. It's the equivalent of Go's runtime.KeepAlive.
|
||||
public static native void incGoRef(int refnum, GoObject ref);
|
||||
|
||||
// Informs the Go ref tracker that Java is done with this refnum.
|
||||
static native void destroyRef(int refnum);
|
||||
|
||||
// decRef is called from seq.FinalizeRef
|
||||
static void decRef(int refnum) {
|
||||
tracker.dec(refnum);
|
||||
}
|
||||
|
||||
// A GoObject is a Java class implemented in Go. When a GoObject
|
||||
// is passed to Go, it is wrapped in a Go proxy, to make it behave
|
||||
// the same as passing a regular Java class.
|
||||
public interface GoObject {
|
||||
// Increment refcount and return the refnum of the proxy.
|
||||
//
|
||||
// The Go reference count need to be bumped while the
|
||||
// refnum is passed to Go, to avoid finalizing and
|
||||
// invalidating it before being translated on the Go side.
|
||||
int incRefnum();
|
||||
}
|
||||
// A Proxy is a Java object that proxies a Go object. Proxies, unlike
|
||||
// GoObjects, are unwrapped to their Go counterpart when deserialized
|
||||
// in Go.
|
||||
public interface Proxy extends GoObject {}
|
||||
|
||||
// A Ref represents an instance of a Java object passed back and forth
|
||||
// across the language boundary.
|
||||
public static final class Ref {
|
||||
public final int refnum;
|
||||
|
||||
private int refcnt; // Track how many times sent to Go.
|
||||
|
||||
public final Object obj; // The referenced Java obj.
|
||||
|
||||
Ref(int refnum, Object o) {
|
||||
if (refnum < 0) {
|
||||
throw new RuntimeException("Ref instantiated with a Go refnum " + refnum);
|
||||
}
|
||||
this.refnum = refnum;
|
||||
this.refcnt = 0;
|
||||
this.obj = o;
|
||||
}
|
||||
|
||||
void inc() {
|
||||
// Count how many times this ref's Java object is passed to Go.
|
||||
if (refcnt == Integer.MAX_VALUE) {
|
||||
throw new RuntimeException("refnum " + refnum + " overflow");
|
||||
}
|
||||
refcnt++;
|
||||
}
|
||||
}
|
||||
|
||||
static final RefTracker tracker = new RefTracker();
|
||||
|
||||
static final class RefTracker {
|
||||
private static final int REF_OFFSET = 42;
|
||||
|
||||
// Next Java object reference number.
|
||||
//
|
||||
// Reference numbers are positive for Java objects,
|
||||
// and start, arbitrarily at a different offset to Go
|
||||
// to make debugging by reading Seq hex a little easier.
|
||||
private int next = REF_OFFSET; // next Java object ref
|
||||
|
||||
// Java objects that have been passed to Go. refnum -> Ref
|
||||
// The Ref obj field is non-null.
|
||||
// This map pins Java objects so they don't get GCed while the
|
||||
// only reference to them is held by Go code.
|
||||
private final RefMap javaObjs = new RefMap();
|
||||
|
||||
// Java objects to refnum
|
||||
private final IdentityHashMap<Object, Integer> javaRefs = new IdentityHashMap<>();
|
||||
|
||||
// inc increments the reference count of a Java object when it
|
||||
// is sent to Go. inc returns the refnum for the object.
|
||||
synchronized int inc(Object o) {
|
||||
if (o == null) {
|
||||
return NULL_REFNUM;
|
||||
}
|
||||
if (o instanceof Proxy) {
|
||||
return ((Proxy)o).incRefnum();
|
||||
}
|
||||
Integer refnumObj = javaRefs.get(o);
|
||||
if (refnumObj == null) {
|
||||
if (next == Integer.MAX_VALUE) {
|
||||
throw new RuntimeException("createRef overflow for " + o);
|
||||
}
|
||||
refnumObj = next++;
|
||||
javaRefs.put(o, refnumObj);
|
||||
}
|
||||
int refnum = refnumObj;
|
||||
Ref ref = javaObjs.get(refnum);
|
||||
if (ref == null) {
|
||||
ref = new Ref(refnum, o);
|
||||
javaObjs.put(refnum, ref);
|
||||
}
|
||||
ref.inc();
|
||||
return refnum;
|
||||
}
|
||||
|
||||
synchronized void incRefnum(int refnum) {
|
||||
Ref ref = javaObjs.get(refnum);
|
||||
if (ref == null) {
|
||||
throw new RuntimeException("referenced Java object is not found: refnum="+refnum);
|
||||
}
|
||||
ref.inc();
|
||||
}
|
||||
|
||||
// dec decrements the reference count of a Java object when
|
||||
// Go signals a corresponding proxy object is finalized.
|
||||
// If the count reaches zero, the Java object is removed
|
||||
// from the javaObjs map.
|
||||
synchronized void dec(int refnum) {
|
||||
if (refnum <= 0) {
|
||||
// We don't keep track of the Go object.
|
||||
// This must not happen.
|
||||
log.severe("dec request for Go object "+ refnum);
|
||||
return;
|
||||
}
|
||||
if (refnum == Seq.nullRef.refnum) {
|
||||
return;
|
||||
}
|
||||
// Java objects are removed on request of Go.
|
||||
Ref obj = javaObjs.get(refnum);
|
||||
if (obj == null) {
|
||||
throw new RuntimeException("referenced Java object is not found: refnum="+refnum);
|
||||
}
|
||||
obj.refcnt--;
|
||||
if (obj.refcnt <= 0) {
|
||||
javaObjs.remove(refnum);
|
||||
javaRefs.remove(obj.obj);
|
||||
}
|
||||
}
|
||||
|
||||
// get returns an existing Ref to a Java object.
|
||||
synchronized Ref get(int refnum) {
|
||||
if (refnum < 0) {
|
||||
throw new RuntimeException("ref called with Go refnum " + refnum);
|
||||
}
|
||||
if (refnum == NULL_REFNUM) {
|
||||
return nullRef;
|
||||
}
|
||||
Ref ref = javaObjs.get(refnum);
|
||||
if (ref == null) {
|
||||
throw new RuntimeException("unknown java Ref: "+refnum);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
// GoRefQueue is a queue of GoRefs that are no longer live. An internal thread
|
||||
// processes the queue and decrement the reference count on the Go side.
|
||||
static class GoRefQueue extends ReferenceQueue<GoObject> {
|
||||
// The set of tracked GoRefs. If we don't hold on to the GoRef instances, the Java GC
|
||||
// will not add them to the queue when their referents are reclaimed.
|
||||
private final Collection<GoRef> refs = Collections.synchronizedCollection(new HashSet<GoRef>());
|
||||
|
||||
void track(int refnum, GoObject obj) {
|
||||
refs.add(new GoRef(refnum, obj, this));
|
||||
}
|
||||
|
||||
GoRefQueue() {
|
||||
Thread daemon = new Thread(new Runnable() {
|
||||
@Override public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
GoRef ref = (GoRef)remove();
|
||||
refs.remove(ref);
|
||||
destroyRef(ref.refnum);
|
||||
ref.clear();
|
||||
} catch (InterruptedException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
daemon.setDaemon(true);
|
||||
daemon.setName("GoRefQueue Finalizer Thread");
|
||||
daemon.start();
|
||||
}
|
||||
}
|
||||
|
||||
// A GoRef is a PhantomReference to a Java proxy for a Go object.
|
||||
// GoRefs are enqueued to the singleton GoRefQueue when no longer live,
|
||||
// so the corresponding reference count can be decremented.
|
||||
static class GoRef extends PhantomReference<GoObject> {
|
||||
final int refnum;
|
||||
|
||||
GoRef(int refnum, GoObject obj, GoRefQueue q) {
|
||||
super(obj, q);
|
||||
if (refnum > 0) {
|
||||
throw new RuntimeException("GoRef instantiated with a Java refnum " + refnum);
|
||||
}
|
||||
this.refnum = refnum;
|
||||
}
|
||||
}
|
||||
|
||||
// RefMap is a mapping of integers to Ref objects.
|
||||
//
|
||||
// The integers can be sparse. In Go this would be a map[int]*Ref.
|
||||
static final class RefMap {
|
||||
private int next = 0;
|
||||
private int live = 0;
|
||||
private int[] keys = new int[16];
|
||||
private Ref[] objs = new Ref[16];
|
||||
|
||||
RefMap() {}
|
||||
|
||||
Ref get(int key) {
|
||||
int i = Arrays.binarySearch(keys, 0, next, key);
|
||||
if (i >= 0) {
|
||||
return objs[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void remove(int key) {
|
||||
int i = Arrays.binarySearch(keys, 0, next, key);
|
||||
if (i >= 0) {
|
||||
if (objs[i] != null) {
|
||||
objs[i] = null;
|
||||
live--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void put(int key, Ref obj) {
|
||||
if (obj == null) {
|
||||
throw new RuntimeException("put a null ref (with key "+key+")");
|
||||
}
|
||||
int i = Arrays.binarySearch(keys, 0, next, key);
|
||||
if (i >= 0) {
|
||||
if (objs[i] == null) {
|
||||
objs[i] = obj;
|
||||
live++;
|
||||
}
|
||||
if (objs[i] != obj) {
|
||||
throw new RuntimeException("replacing an existing ref (with key "+key+")");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (next >= keys.length) {
|
||||
grow();
|
||||
i = Arrays.binarySearch(keys, 0, next, key);
|
||||
}
|
||||
i = ~i;
|
||||
if (i < next) {
|
||||
// Insert, shift everything afterwards down.
|
||||
System.arraycopy(keys, i, keys, i+1, next-i);
|
||||
System.arraycopy(objs, i, objs, i+1, next-i);
|
||||
}
|
||||
keys[i] = key;
|
||||
objs[i] = obj;
|
||||
live++;
|
||||
next++;
|
||||
}
|
||||
|
||||
private void grow() {
|
||||
// Compact and (if necessary) grow backing store.
|
||||
int[] newKeys;
|
||||
Ref[] newObjs;
|
||||
int len = 2*roundPow2(live);
|
||||
if (len > keys.length) {
|
||||
newKeys = new int[keys.length*2];
|
||||
newObjs = new Ref[objs.length*2];
|
||||
} else {
|
||||
newKeys = keys;
|
||||
newObjs = objs;
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
if (objs[i] != null) {
|
||||
newKeys[j] = keys[i];
|
||||
newObjs[j] = objs[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (int i = j; i < newKeys.length; i++) {
|
||||
newKeys[i] = 0;
|
||||
newObjs[i] = null;
|
||||
}
|
||||
|
||||
keys = newKeys;
|
||||
objs = newObjs;
|
||||
next = j;
|
||||
|
||||
if (live != next) {
|
||||
throw new RuntimeException("bad state: live="+live+", next="+next);
|
||||
}
|
||||
}
|
||||
|
||||
private static int roundPow2(int x) {
|
||||
int p = 1;
|
||||
while (p < x) {
|
||||
p *= 2;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// Code generated by gobind. DO NOT EDIT.
|
||||
|
||||
// Java class go.Universe is a proxy for talking to a Go program.
|
||||
//
|
||||
// autogenerated by gobind -lang=java -javapkg=su.cin.rapvpn.fabric
|
||||
package go;
|
||||
|
||||
import go.Seq;
|
||||
|
||||
public abstract class Universe {
|
||||
static {
|
||||
Seq.touch(); // for loading the native library
|
||||
_init();
|
||||
}
|
||||
|
||||
private Universe() {} // uninstantiable
|
||||
|
||||
// touch is called from other bound packages to initialize this package
|
||||
public static void touch() {}
|
||||
|
||||
private static native void _init();
|
||||
|
||||
private static final class proxyerror extends Exception implements Seq.Proxy, error {
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
Seq.incGoRef(refnum, this);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxyerror(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
@Override public String getMessage() { return error(); }
|
||||
|
||||
public native String error();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Code generated by gobind. DO NOT EDIT.
|
||||
|
||||
// Java class go.error is a proxy for talking to a Go program.
|
||||
//
|
||||
// autogenerated by gobind -lang=java -javapkg=su.cin.rapvpn.fabric
|
||||
package go;
|
||||
|
||||
import go.Seq;
|
||||
|
||||
public interface error {
|
||||
public String error();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// Code generated by gobind. DO NOT EDIT.
|
||||
|
||||
// Java class su.cin.rapvpn.fabric.fabricvpn.Fabricvpn is a proxy for talking to a Go program.
|
||||
//
|
||||
// autogenerated by gobind -lang=java -javapkg=su.cin.rapvpn.fabric github.com/example/remote-access-platform/agents/rap-node-agent/mobile/fabricvpn
|
||||
package su.cin.rapvpn.fabric.fabricvpn;
|
||||
|
||||
import go.Seq;
|
||||
|
||||
public abstract class Fabricvpn {
|
||||
static {
|
||||
Seq.touch(); // for loading the native library
|
||||
_init();
|
||||
}
|
||||
|
||||
private Fabricvpn() {} // uninstantiable
|
||||
|
||||
// touch is called from other bound packages to initialize this package
|
||||
public static void touch() {}
|
||||
|
||||
private static native void _init();
|
||||
|
||||
private static final class proxySocketProtector implements Seq.Proxy, SocketProtector {
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
Seq.incGoRef(refnum, this);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
proxySocketProtector(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native boolean protect(long fd);
|
||||
}
|
||||
|
||||
|
||||
public static native Manager newManager();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// Code generated by gobind. DO NOT EDIT.
|
||||
|
||||
// Java class su.cin.rapvpn.fabric.fabricvpn.Manager is a proxy for talking to a Go program.
|
||||
//
|
||||
// autogenerated by gobind -lang=java -javapkg=su.cin.rapvpn.fabric github.com/example/remote-access-platform/agents/rap-node-agent/mobile/fabricvpn
|
||||
package su.cin.rapvpn.fabric.fabricvpn;
|
||||
|
||||
import go.Seq;
|
||||
|
||||
public final class Manager implements Seq.Proxy {
|
||||
static { Fabricvpn.touch(); }
|
||||
|
||||
private final int refnum;
|
||||
|
||||
@Override public final int incRefnum() {
|
||||
Seq.incGoRef(refnum, this);
|
||||
return refnum;
|
||||
}
|
||||
|
||||
public Manager() {
|
||||
this.refnum = __NewManager();
|
||||
Seq.trackGoRef(refnum, this);
|
||||
}
|
||||
|
||||
private static native int __NewManager();
|
||||
|
||||
Manager(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
|
||||
|
||||
public native String controlRequest(String payloadJSON) throws Exception;
|
||||
public native byte[] receivePacket(long timeoutMillis) throws Exception;
|
||||
public native byte[] receivePacketBatchPayload(long timeoutMillis) throws Exception;
|
||||
public native void reconnect() throws Exception;
|
||||
public native void sendPacket(byte[] packet) throws Exception;
|
||||
public native void sendPacketBatchPayload(byte[] payload) throws Exception;
|
||||
public native void setSocketProtector(SocketProtector protector);
|
||||
public native String snapshotJSON();
|
||||
public native void start(String configJSON) throws Exception;
|
||||
public native void stop();
|
||||
public native void updateRuntimeConfig(String configJSON) throws Exception;
|
||||
@Override public boolean equals(Object o) {
|
||||
if (o == null || !(o instanceof Manager)) {
|
||||
return false;
|
||||
}
|
||||
Manager that = (Manager)o;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
return java.util.Arrays.hashCode(new Object[] {});
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("Manager").append("{");
|
||||
return b.append("}").toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Code generated by gobind. DO NOT EDIT.
|
||||
|
||||
// Java class su.cin.rapvpn.fabric.fabricvpn.SocketProtector is a proxy for talking to a Go program.
|
||||
//
|
||||
// autogenerated by gobind -lang=java -javapkg=su.cin.rapvpn.fabric github.com/example/remote-access-platform/agents/rap-node-agent/mobile/fabricvpn
|
||||
package su.cin.rapvpn.fabric.fabricvpn;
|
||||
|
||||
import go.Seq;
|
||||
|
||||
public interface SocketProtector {
|
||||
public boolean protect(long fd);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user