0

I'm developing an app that implements a VPN service and I want to listen when the user clicked "Forget VPN" on my app's VPN service from android settings.

Is there a way to do it?

Tanveer Munir
  • 1,956
  • 1
  • 12
  • 27
AyTee
  • 489
  • 1
  • 8
  • 19

2 Answers2

1

When checking the source code of VpnSettings#deleteProfile() - there is nothing being broadcasted.

The only available callback seems to be VpnService#onRevoke(); as the documentation states:

Invoked when the application is revoked. At this moment, the VPN interface is already deactivated by the system. The application should close the file descriptor and shut down gracefully. The default implementation of this method is calling Service#stopSelf().

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • I suppose the source code is the answer to my question. Thank you! – AyTee Mar 28 '19 at 09:51
  • @avielt10 on a stock ROM, this seems to be out-of-reach, but these profiles are actually stored in `/misc/vpn/profiles`, where one could use a `FileObserver` to watch for `DELETE` or `DELETE_SELF` events. The `VpnSettings` is an editor for the files in this directory. – Martin Zeitler Mar 28 '19 at 10:00
  • if the VpnService is not running, we won't get a call on `onRevoke()` – Akshay Kumar S Mar 28 '19 at 10:09
  • @MartinZeitler i see...so on a non-rooted device, if my app is a device owner, can i get to this directory? – AyTee Mar 28 '19 at 10:19
  • @avielt10 You will get notified when any of the VPN is deleted from this directory, not just your own VPN. – Akshay Kumar S Mar 28 '19 at 10:40
  • @AkshayKumarS I guess it can be filtered by name. do you know if i have access to this path as a Device Owner? – AyTee Mar 28 '19 at 11:02
  • @avielt10 one can observe directories (which triggers the `DELETE` event), but also individual files (which triggers the `DELETE_SELF` event). on a custom ROM, once could even broadcast a custom event, when removing a profile. actually, the path is `/data/misc/vpn/profiles`. changing SE Linux labels might be required, even when having `root` permissions. `ls -Z /data/misc/vpn/profiles` lists the security context. – Martin Zeitler Mar 28 '19 at 11:09
  • @MartinZeitler tried on AVD and `ls -a /data/misc/vpn` output is `. ..`, seems that `/data/misc/vpn/profiles` does not exist although there are 3 VPN profiles on the device – AyTee Mar 28 '19 at 11:57
  • @avielt10 I've wrote `-Z` and not `-a` ...and that path is hard-coded in the source code, which clearly reads and writes there. when using a user account & context, which may not list the directory, it won't list the directory. only the audit log might show a denial. SE Linux is imperative and demands a matching security context, for whatever happens; at least since Android 5.0. – Martin Zeitler Mar 28 '19 at 12:23
  • `mkdir /data/misc/vpn/profiles 0770 system system` ...is part of the `init.rc` script which creates the default directory structure. which means user or group `system` may access there, independent from the security context, which may add further restrictions. a custom broadcast might be the least effort, without loosing the security measures taken... because this runs as `system:system`. – Martin Zeitler Mar 28 '19 at 12:36
  • @MartinZeitler Thank you for the detailed explanation sir. – AyTee Mar 28 '19 at 14:52
0

No, You can use Intent prepare = VpnService.prepare(this), if the intent is null, then your VPN is created in settings, else call startActivityForResult(prepare, REQUEST_VPN) to create the VPN. you can use the null check prepare == null to know whether the VPN is created or not. Hope this help you.

Akshay Kumar S
  • 333
  • 3
  • 12
  • Thanks for your answer, already using your proposal. I wanted to know if it was possible to listen to this user action. – AyTee Mar 28 '19 at 09:33