Skip to content

OneXray/AndroidReview

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 

Repository files navigation

Get installed applications

Here, we use QUERY_ALL_PACKAGES permission to get installed applications.

class AppHostApi(
    private val context: FragmentActivity,
) : BridgeHostApi {
    override fun getInstalledApps(callback: (Result<List<AndroidAppInfo>>) -> Unit) {
        scope.launch {
            if (checkInstalledAppPermission()) {
                val packageManager = context.packageManager
                val installedApps = packageManager.getInstalledApplications(0)
                val apps = mutableListOf<AndroidAppInfo>()
                for (info in installedApps) {
                    val appInfo =
                        AndroidAppInfo(
                            packageManager.getApplicationLabel(info).toString(),
                            info.packageName
                        )
                    apps.add(appInfo)
                }
                callback(Result.success(apps))
            } else {
                callback(Result.success(listOf()))
            }
        }
    }

    private suspend fun checkInstalledAppPermission(): Boolean {
        // android 11, level 30
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            val permissions = mutableListOf<String>()
            permissions.add(Manifest.permission.QUERY_ALL_PACKAGES)

            val request = context.permissionsBuilder(permissions).build()
            val result = request.sendSuspend()
            val granted = result.allGranted()
            return granted
        } else {
            return true
        }
    }
}

Show installed applications

Here, we show installed applications to users, and let them choose which apps they want to use vpn.

class SelectedAppState extends GetxController {
  final apps = <AndroidAppInfo>[].obs;
  final _allApps = <AndroidAppInfo>[];
  final _selections = <String>{};
  Future<void> _queryApps() async {
    final androidApps = await AppHostApi().getInstalledApps();
    _allApps.clear();
    _allApps.addAll(androidApps);

    _refreshApps();
  }

  void _refreshApps() {
    final selections = <String>{};
    final selectedApps = <AndroidAppInfo>[];
    for (final app in _allApps) {
      for (final selection in _selections) {
        if (app.packageName == selection) {
          selections.add(selection);
          selectedApps.add(app);
        }
      }
    }
    _selections.clear();
    _selections.addAll(selections);

    apps.clear();
    apps.addAll(selectedApps);
  }
}

set Per-App vpn

Here, we pass the packages to vpn builder.

class TProxyService : VpnService() {
    private fun runTun(
        request: StartVpnRequest
    ) {
        if (tunnel != null) {
            return
        }
        XLog.d("tunnel = null")
        val builder = Builder()
        // Loop through the app packages in the array and confirm that the app is
        // installed before adding the app to the allowed list.
        request.perAppVPN?.let {
            if (it.isNotEmpty()) {
                for (appPackage in it) {
                    try {
                        packageManager.getPackageInfo(appPackage, 0)
                        builder.addAllowedApplication(appPackage)
                    } catch (_: PackageManager.NameNotFoundException) {
                    }
                }
            }
        }


        builder.addAddress(ipv4Address, 32)
            .addRoute("0.0.0.0", 0)
            .addAddress(ipv6Address, 128)
            .addRoute("::", 0)
            .setMtu(tunMtu)
        request.tunDnsIPv4?.let {
            builder.addDnsServer(it)
        }
        request.tunDnsIPv6?.let {
            builder.addDnsServer(it)
        }

        tunnel = builder.establish()

        XLog.d("tunnel = ${tunnel?.fd}")

        tunnel?.fd?.let { fd ->
            controller.vpn = this
            runXray(request)

            request.tunFilePath?.let { tunFilePath ->
                runTun2socks(tunFilePath, fd)
                XLog.d("tun $tunFilePath")
            }
            running = true
            updateDataStore(true)
        }
    }
}

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors