Skip to content

Commit

Permalink
Merge pull request #932 from getlantern/ox/ios-migrate/android
Browse files Browse the repository at this point in the history
  • Loading branch information
oxtoacart authored Oct 13, 2023
2 parents c863b52 + 4a79f87 commit 0ef55a0
Show file tree
Hide file tree
Showing 26 changed files with 388 additions and 368 deletions.
25 changes: 5 additions & 20 deletions DBModule/Sources/DBModule/Database.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ public class DatabaseManager: NSObject, MinisqlDBProtocol, MinisqlTxProtocol {
domain: "DatabasePathError", code: 1,
userInfo: [NSLocalizedDescriptionKey: "Database path cannot be blank"])
}
self.connection = try! Connection(path)
let conn = try! Connection(path)
try conn.execute("PRAGMA journal_mode=WAL")
try conn.execute("PRAGMA busy_timeout=5000")
self.connection = conn
}

self.transactional = transactional
}

Expand Down Expand Up @@ -63,7 +65,7 @@ public class DatabaseManager: NSObject, MinisqlDBProtocol, MinisqlTxProtocol {
}
}

public func exec(_ query: String?, args: MinisqlValuesProtocol?) throws -> MinisqlResultProtocol {
public func exec(_ query: String?, args: MinisqlValuesProtocol?) throws {
guard let query = query, let args = args else {
throw NSError(
domain: "ArgumentError", code: 1,
Expand All @@ -78,7 +80,6 @@ public class DatabaseManager: NSObject, MinisqlDBProtocol, MinisqlTxProtocol {
}

try runStatement(statement, bindings)
return QueryResult(changes: connection.changes)
}

public func query(_ query: String?, args: MinisqlValuesProtocol?) throws -> MinisqlRowsProtocol {
Expand Down Expand Up @@ -115,22 +116,6 @@ public class DatabaseManager: NSObject, MinisqlDBProtocol, MinisqlTxProtocol {
}
}

class QueryResult: NSObject, MinisqlResultProtocol {
let changes: Int

init(changes: Int) {
self.changes = changes
}

func lastInsertId(_ ret0_: UnsafeMutablePointer<Int64>?) throws {
ret0_?.pointee = Int64(changes)
}

func rowsAffected(_ ret0_: UnsafeMutablePointer<Int64>?) throws {
ret0_?.pointee = Int64(changes)
}
}

class RowData: NSObject, MinisqlRowsProtocol {
let rows: [Statement.Element]
var currentIndex: Int = -1
Expand Down
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ else
$(error unsupported ANDROID_ARCH "$(ANDROID_ARCH)")
endif

ANDROID_LIB_PKG := github.com/getlantern/android-lantern/internalsdk
ANDROID_LIB_BASE := liblantern

MOBILE_APPID := org.getlantern.lantern
Expand Down Expand Up @@ -275,7 +274,7 @@ $(ANDROID_LIB): $(GO_SOURCES)
-androidapi=23 \
-ldflags="$(LDFLAGS)" \
$(GOMOBILE_EXTRA_BUILD_FLAGS) \
$(ANDROID_LIB_PKG)
github.com/getlantern/android-lantern/internalsdk github.com/getlantern/pathdb/testsupport github.com/getlantern/pathdb/minisql

$(MOBILE_ANDROID_LIB): $(ANDROID_LIB)
mkdir -p $(MOBILE_LIBS) && \
Expand Down
18 changes: 9 additions & 9 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,8 @@ dependencies {
// Google Play libraries
implementation 'com.android.billingclient:billing:6.0.1'
implementation 'com.google.android.gms:play-services-base:18.2.0'
implementation 'com.google.android.gms:play-services-ads:22.4.0'


// lib that simplifies event bus communication between activities, fragments, threads, services, etc
implementation 'org.greenrobot:eventbus:3.3.1'
Expand All @@ -428,17 +430,15 @@ dependencies {

implementation 'com.stripe:stripe-android:20.17.0'

implementation 'com.datadoghq:dd-sdk-android:1.19.3'

annotationProcessor "org.androidannotations:androidannotations:$androidAnnotationsVersion"
implementation("org.androidannotations:androidannotations-api:$androidAnnotationsVersion")
kapt "org.androidannotations:androidannotations:$androidAnnotationsVersion"

androidTestImplementation 'androidx.test:rules:1.5.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'androidx.annotation:annotation:1.6.0'
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.5.1'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'

androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
Expand All @@ -452,8 +452,8 @@ dependencies {
implementation files('libs/opuslib-release.aar')
implementation 'com.github.getlantern:secrets-android:f6a7a69f3d'
implementation 'com.github.getlantern:messaging-android:1ce4613c8b'
implementation 'com.github.getlantern:db-android:573aba1458'
implementation 'com.cleveradssolutions:cas:3.2.4'
implementation 'com.github.getlantern:db-android:022779ec99'
// implementation 'com.cleveradssolutions:cas:3.3.1'
}

apply plugin: 'com.google.gms.google-services'
Expand All @@ -466,7 +466,7 @@ sentry {
// related to proguard mapping will be excluded.
// Default is enabled.
includeProguardMapping = true


// Whether the plugin should attempt to auto-upload the mapping file to Sentry or not.
// If disabled the plugin will run a dry-run and just generate a UUID.
Expand Down
4 changes: 2 additions & 2 deletions android/app/libs/liblantern-all.aar
Git LFS file not shown
20 changes: 2 additions & 18 deletions android/app/src/main/kotlin/io/lantern/model/BaseModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ abstract class BaseModel(
flutterEngine: FlutterEngine,
val db: DB,
) : EventChannel.StreamHandler, MethodChannel.MethodCallHandler {
private val activeSubscribers = ConcurrentSkipListSet<String>()
protected val activeSubscribers = ConcurrentSkipListSet<String>()
protected val mainHandler = Handler(Looper.getMainLooper())
private val asyncHandlerThread = HandlerThread("BaseModel-AsyncHandler")

Expand Down Expand Up @@ -108,14 +108,6 @@ abstract class BaseModel(
keysMigrated++
}
}
masterDB.withSchema(VpnModel.VPN_SCHEMA).mutate { tx ->
insecureDB
.withSchema(VpnModel.VPN_SCHEMA)
.listRaw<Any>("%").forEach {
tx.putRaw(it.path, it.value)
keysMigrated++
}
}
insecureDbDir.deleteRecursively()
Logger.debug(TAG, "migrated $keysMigrated keys from insecure database")
}
Expand Down Expand Up @@ -208,15 +200,10 @@ abstract class BaseModel(
}
}

private val activeSink = AtomicReference<EventChannel.EventSink?>()
protected val activeSink = AtomicReference<EventChannel.EventSink?>()

@Synchronized
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
Logger.error(
TAG,
"Session Model onListen calling with argument ${arguments} with event ${events}"
);

activeSink.set(events)
val args = arguments as Map<String, Any>
val subscriberID = args["subscriberID"] as String
Expand Down Expand Up @@ -264,9 +251,6 @@ abstract class BaseModel(
}

override fun onCancel(arguments: Any?) {
Logger.error(
TAG,
"Session Model onCancel calling with argument ${arguments} ")
if (arguments == null) {
return
}
Expand Down
107 changes: 107 additions & 0 deletions android/app/src/main/kotlin/io/lantern/model/GoModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package io.lantern.model

import internalsdk.Arguments
import internalsdk.SubscriptionRequest
import internalsdk.UpdaterModel
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.lantern.db.DB
import minisql.Value
import org.getlantern.mobilesdk.Logger

open class GoModel<M : internalsdk.Model> constructor(
val name: String,
flutterEngine: FlutterEngine,
db: DB,
protected val model: M,
) : BaseModel(name, flutterEngine, db) {
override fun doOnMethodCall(call: MethodCall, result: MethodChannel.Result) {
try {
val resultVal = model.invokeMethod(call.method, Arguments(call))
result.success(resultVal.toJava())
} catch (t: Throwable) {
result.error("unknownError", t.message, null)
}
}

override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
activeSink.set(events)
val args = arguments as Map<String, Any>
val subscriberID = args["subscriberID"] as String
val path = args["path"] as String
val details = args["details"]?.let { it as Boolean } ?: false
activeSubscribers.add(subscriberID)

val req = SubscriptionRequest()
req.receiveInitial = true
req.id = subscriberID
req.joinDetails = details
req.pathPrefixes = path
req.updater = UpdaterModel {
val updates = HashMap<String, Any>()
val deletions = ArrayList<String>()
while (it.hasUpdate()) {
val update = it.popUpdate()
updates[update.path] = update.value.toJava()
}
while (it.hasDelete()) {
deletions.add(it.popDelete())
}
Logger.debug("GoModel", "notifying $activeSink.get() on path $path updates: $updates")
mainHandler.post {
synchronized(this@GoModel) {
activeSink.get()?.success(
mapOf(
"s" to subscriberID,
"u" to updates,
"d" to deletions,
)
)
}
}
}
model.subscribe(req)
}

override fun onCancel(arguments: Any?) {
if (arguments == null) {
return
}
val args = arguments as Map<String, Any>
val subscriberID = args["subscriberID"] as String
model.unsubscribe(subscriberID)
activeSubscribers.remove(subscriberID)
}
}

private class Arguments constructor(private val call: MethodCall) : Arguments {
override fun get(key: String): Value? =
when (val arg = call.argument<Any>(key)) {
is Long -> minisql.Value(arg)
is Int -> minisql.Value(arg.toLong())
is String -> minisql.Value(arg)
is Boolean -> minisql.Value(arg)
is ByteArray -> minisql.Value(arg)
else -> null
}

override fun scalar(): Value? =
when (val arg = call.arguments) {
is Long -> minisql.Value(arg)
is Int -> minisql.Value(arg.toLong())
is String -> minisql.Value(arg)
is Boolean -> minisql.Value(arg)
is ByteArray -> minisql.Value(arg)
else -> null
}
}

fun Value.toJava(): Any = when (type) {
0L -> bytes()
1L -> string()
2L -> int_()
3L -> bool()
else -> throw RuntimeException("unknown value type $type")
}
84 changes: 20 additions & 64 deletions android/app/src/main/kotlin/io/lantern/model/VpnModel.kt
Original file line number Diff line number Diff line change
@@ -1,86 +1,42 @@
package io.lantern.model

import android.app.Activity
import internalsdk.VPNManager
import internalsdk.VPNModel
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import org.getlantern.lantern.util.castToBoolean
import org.getlantern.mobilesdk.Logger
import io.lantern.model.dbadapter.DBAdapter

class VpnModel(
activity: Activity,
flutterEngine: FlutterEngine,
private var switchLanternHandler: ((vpnOn: Boolean) -> Unit)? = null,
) : BaseModel("vpn", flutterEngine, masterDB.withSchema(VPN_SCHEMA)) {

companion object {
private const val TAG = "VpnModel"
const val VPN_SCHEMA = "vpn"

const val PATH_VPN_STATUS = "/vpn_status"
const val PATH_SERVER_INFO = "/server_info"
const val PATH_BANDWIDTH = "/bandwidth"
}
) : GoModel<VPNModel>(
"vpn",
flutterEngine,
masterDB.withSchema("vpn"),
VPNModel(DBAdapter(masterDB.db))
) {

init {
val start = System.currentTimeMillis()
db.registerType(1000, Vpn.ServerInfo::class.java)
db.registerType(1001, Vpn.Bandwidth::class.java)
db.mutate { tx ->
// initialize vpn status for fresh install
tx.put(PATH_VPN_STATUS, tx.get<String>(PATH_VPN_STATUS) ?: "disconnected")
}
Logger.debug(TAG, "db.mutate finished at ${System.currentTimeMillis() - start}")
}
model.setManager(object : VPNManager {
override fun startVPN() {
switchLanternHandler?.invoke(true)
}

override fun doMethodCall(call: MethodCall, notImplemented: () -> Unit): Any? {
return when (call.method) {
"switchVPN" -> {
val on = call.argument<Boolean>("on") ?: false
saveVpnStatus(if (on) "connecting" else "disconnecting")
switchLantern(on)
override fun stopVPN() {
switchLanternHandler?.invoke(false)
}
else -> super.doMethodCall(call, notImplemented)
}
})
}

fun isConnectedToVpn(): Boolean {
val vpnStatus = vpnStatus()
val vpnStatus = model.vpnStatus
return vpnStatus == "connected" || vpnStatus == "disconnecting"
}

private fun vpnStatus(): String {
return db.get(PATH_VPN_STATUS) ?: ""
}

private fun switchLantern(value: Boolean) {
switchLanternHandler?.invoke(value)
}

fun setVpnOn(vpnOn: Boolean) {
val vpnStatus = if (vpnOn) "connected" else "disconnected"
saveVpnStatus(vpnStatus)
}

fun saveVpnStatus(vpnStatus: String) {
db.mutate { tx ->
tx.put(PATH_VPN_STATUS, vpnStatus)
}
}

fun saveServerInfo(serverInfo: Vpn.ServerInfo) {
db.mutate { tx ->
tx.put(PATH_SERVER_INFO, serverInfo)
}
model.switchVPN(vpnOn)
}

fun saveBandwidth(bandwidth: Vpn.Bandwidth) {
Logger.d(
TAG, "Bandwidth updated to " + bandwidth.remaining + " remaining out of " +
bandwidth.allowed + " allowed"
)
db.mutate { tx ->
tx.put(PATH_BANDWIDTH, bandwidth)
}
fun updateStatus(vpnOn: Boolean) {
model.saveVPNStatus(if (vpnOn) "connected" else "disconnected")
}
}
Loading

0 comments on commit 0ef55a0

Please sign in to comment.