diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index ca5782e..54cbbdf 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -25,6 +25,8 @@
+
-
when(call.method) {
- "android.requestPermissions" -> androidPermissions(result)
"android.registerActiveSite" -> registerActiveSite(result)
"nebula.parseCerts" -> nebulaParseCerts(call, result)
@@ -242,25 +244,16 @@ class MainActivity: FlutterActivity() {
return result.error("required_argument", "id is a required argument", null)
}
- val siteContainer: SiteContainer = sites!!.getSite(id!!) ?: return result.error("unknown_site", "No site with that id exists", null)
+ startingSiteContainer = sites!!.getSite(id!!) ?: return result.error("unknown_site", "No site with that id exists", null)
+ startingSiteContainer!!.updater.setState(true, "Initializing...")
- siteContainer.updater.setState(true, "Initializing...")
-
- var intent = VpnService.prepare(this)
+ startResult = result
+ val intent = VpnService.prepare(this)
if (intent != null) {
- //TODO: ensure this boots the correct bit, I bet it doesn't and we need to go back to the active symlink
- intent.putExtra("path", siteContainer.site.path)
- intent.putExtra("id", siteContainer.site.id)
startActivityForResult(intent, VPN_START_CODE)
-
} else {
- intent = Intent(this, NebulaVpnService::class.java)
- intent.putExtra("path", siteContainer.site.path)
- intent.putExtra("id", siteContainer.site.id)
- onActivityResult(VPN_START_CODE, Activity.RESULT_OK, intent)
+ onActivityResult(VPN_START_CODE, Activity.RESULT_OK, null)
}
-
- result.success(null)
}
private fun stopSite() {
@@ -400,45 +393,38 @@ class MainActivity: FlutterActivity() {
outMessenger?.send(msg)
}
- private fun androidPermissions(result: MethodChannel.Result) {
- val intent = VpnService.prepare(this)
- if (intent != null) {
- permResult = result
- return startActivityForResult(intent, VPN_PERMISSIONS_CODE)
- }
-
- // We already have the permission
- result.success(null)
- }
-
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
// This is where activity results come back to us (startActivityForResult)
- if (requestCode == VPN_PERMISSIONS_CODE && permResult != null) {
- // We are processing a response for vpn permissions and the UI is waiting for feedback
- //TODO: unlikely we ever register multiple attempts but this could be a trouble spot if we did
- val result = permResult!!
- permResult = null
- if (resultCode == Activity.RESULT_OK) {
- return result.success(null)
+ if (requestCode == VPN_START_CODE) {
+ // If we are processing a result for VPN permissions and don't get them, let the UI know
+ val result = startResult!!
+ val siteContainer = startingSiteContainer!!
+ startResult = null
+ startingSiteContainer = null
+ if (resultCode != Activity.RESULT_OK) {
+ // The user did not grant permissions
+ siteContainer.updater.setState(false, "Disconnected")
+ return result.error("permissions", "Please grant VPN permissions to the app when requested", null)
}
- //NOTE: flutter side doesn't care about the message currently, only the code
- return result.error("PERMISSIONS", "User did not grant permission", null)
-
- } else if (requestCode == VPN_START_CODE) {
- // We are processing a response for permissions while starting the VPN
- // (or reusing code in the event we already have perms)
- startService(data)
+ // Start the VPN service
+ val intent = Intent(this, NebulaVpnService::class.java).apply {
+ putExtra("path", siteContainer.site.path)
+ putExtra("id", siteContainer.site.id)
+ }
+ startService(intent)
if (outMessenger == null) {
- bindService(data, connection, 0)
+ bindService(intent, connection, 0)
}
- return
+
+ return result.success(null)
}
// The file picker needs us to super
super.onActivityResult(requestCode, resultCode, data)
}
+
/** Defines callbacks for service binding, passed to bindService() */
private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
diff --git a/lib/screens/MainScreen.dart b/lib/screens/MainScreen.dart
index 9dfb02b..06a9cc8 100644
--- a/lib/screens/MainScreen.dart
+++ b/lib/screens/MainScreen.dart
@@ -284,43 +284,6 @@ class _MainScreenState extends State {
}
_loadSites() async {
- if (Platform.isAndroid) {
- try {
- await platform.invokeMethod("android.requestPermissions");
- } on PlatformException catch (err) {
- if (err.code == "PERMISSIONS") {
- setState(() {
- error = [
- Text("Permissions Required", style: TextStyle(fontWeight: FontWeight.bold)),
- Text(
- "VPN permissions are required for nebula to run, click the button below request and accept the appropriate permissions.",
- textAlign: TextAlign.center),
- ElevatedButton(
- onPressed: () {
- error = null;
- _loadSites();
- },
- child: Text("Request Permissions")),
- ];
- });
- } else {
- setState(() {
- error = [
- Text("Unknown Error", style: TextStyle(fontWeight: FontWeight.bold)),
- Text(err.message ?? 'An unknown error occurred', textAlign: TextAlign.center)
- ];
- });
- }
- } catch (err) {
- setState(() {
- error = [
- Text("Unknown Error", style: TextStyle(fontWeight: FontWeight.bold)),
- Text(err.toString(), textAlign: TextAlign.center)
- ];
- });
- }
- }
-
//TODO: This can throw, we need to show an error dialog
Map rawSites = jsonDecode(await platform.invokeMethod('listSites'));
bool hasErrors = false;
diff --git a/nebula/go.mod b/nebula/go.mod
index e2061c7..0b18d44 100644
--- a/nebula/go.mod
+++ b/nebula/go.mod
@@ -34,8 +34,10 @@ require (
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 // indirect
github.com/vishvananda/netlink v1.1.0 // indirect
github.com/vishvananda/netns v0.0.1 // indirect
+ golang.org/x/mobile v0.0.0-20221110043201-43a038452099 // indirect
golang.org/x/mod v0.7.0 // indirect
golang.org/x/net v0.2.0 // indirect
+ golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.2.0 // indirect
golang.org/x/term v0.2.0 // indirect
golang.org/x/tools v0.3.0 // indirect
diff --git a/nebula/go.sum b/nebula/go.sum
index 7ab9647..319d941 100644
--- a/nebula/go.sum
+++ b/nebula/go.sum
@@ -275,6 +275,8 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPI
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
+golang.org/x/mobile v0.0.0-20221110043201-43a038452099 h1:aIu0lKmfdgtn2uTj7JI2oN4TUrQvgB+wzTPO23bCKt8=
+golang.org/x/mobile v0.0.0-20221110043201-43a038452099/go.mod h1:aAjjkJNdrh3PMckS4B10TGS2nag27cbKR1y2BpUxsiY=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
@@ -340,6 +342,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=