Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mac-virtualcam: No easy way to uninstall system extension if app is removed without using Finder #9714

Open
niw opened this issue Oct 14, 2023 · 22 comments
Labels
UI/UX Anything to do with changes or additions to UI/UX elements.

Comments

@niw
Copy link
Contributor

niw commented Oct 14, 2023

Operating System Info

macOS 13

Other OS

No response

OBS Studio Version

30.0.0-rc1

OBS Studio Version (Other)

No response

OBS Studio Log URL

https://obsproject.com/logs/YBw0Kw8hOZbeYFav

OBS Studio Crash Log URL

No response

Expected Behavior

mac-virtualcam plugin only provides the code that installs system extension but doesn't provide any way to uninstall it.
The previous DAL plugin can be uninstalled manually by users operations, but for the system extension,
the container app should provide the interface to do so by deactivationRequestForExtension API,
otherwise users can't remove it.

The expected code is like this (there is missing static in the code, by the way.)

diff --git a/plugins/mac-virtualcam/src/obs-plugin/plugin-main.mm b/plugins/mac-virtualcam/src/obs-plugin/plugin-main.mm
index 2bea96a30..8d2b65ada 100644
--- a/plugins/mac-virtualcam/src/obs-plugin/plugin-main.mm
+++ b/plugins/mac-virtualcam/src/obs-plugin/plugin-main.mm
@@ -13,7 +13,8 @@ MODULE_EXPORT const char *obs_module_description(void)
     return "macOS virtual webcam output";
 }
 
-NSString *const OBSDalDestination = @"/Library/CoreMediaIO/Plug-Ins/DAL";
+static NSString *const OBSDalDestination = @"/Library/CoreMediaIO/Plug-Ins/DAL";
+static NSString *const SystemExtensionIdentifier = @"com.obsproject.obs-studio.mac-camera-extension";
 
 static bool cmio_extension_supported()
 {
@@ -125,13 +126,22 @@ struct virtualcam_data {
 static void install_cmio_system_extension(struct virtualcam_data *vcam)
 {
     OSSystemExtensionRequest *request = [OSSystemExtensionRequest
-        activationRequestForExtension:@"com.obsproject.obs-studio.mac-camera-extension"
+        activationRequestForExtension:SystemExtensionIdentifier
                                 queue:dispatch_get_main_queue()];
     request.delegate = vcam->extensionDelegate;
 
     [[OSSystemExtensionManager sharedManager] submitRequest:request];
 }
 
+static void uninstall_cmio_system_extension(struct virtualcam_data *vcam)
+{
+    OSSystemExtensionRequest *request = [OSSystemExtensionRequest
+        deactivationRequestForExtension:SystemExtensionIdentifier
+                                  queue:dispatch_get_main_queue()];
+
+    [[OSSystemExtensionManager sharedManager] submitRequest:request];
+}
+
 typedef enum {
     OBSDalPluginNotInstalled,
     OBSDalPluginInstalled,

This is not enough of course, because we need to add also an user interface to call this uninstall_cmio_system_extension from somewhere, such as in the menu action.

Current Behavior

Users can't uninstall system extension once the app launched.

Steps to Reproduce

  1. Place OBS.app on /Applications
  2. Launch it, which will install an system extension to the system. Approve it in Settings app.
  3. Uninstall OBS.app, by dragging it to the trash.
  4. Restart macOS, if you want.
  5. Run systemextensionsctl list

Expected behavior
OBS virtual camera system extension should not be there, or provide a way to unstall it before step 3.

Actual behavior
OBS virtual camera system extension stay there and users have no way to remove it.

Anything else we should know?

Note that systemextensionsctl uninstall doesn't work on macOS without disabling SIP, which is highly not recommended to do so and that is not what regular users can do.

$ systemextensionsctl uninstall - com.obsproject.obs-studio.mac-camera-extension
At this time, this tool cannot be used if System Integrity Protection is enabled.
This limitation will be removed in the near future.
Please remember to re-enable System Integrity Protection!
@niw
Copy link
Contributor Author

niw commented Oct 14, 2023

@gxalpha Just fyi, wondering if you have already a good idea to provide a way to uninstall the system extension.

@gxalpha
Copy link
Member

gxalpha commented Oct 14, 2023

I'm a bit torn on this one personally. In theory, step 3 ("Uninstall OBS.app, by dragging it to the trash") also uninstalls the system extension, and if it doesn’t that’s usually a system issue.
There are known ways to screw this up however (e.g. I believe by rm -rf-ing the app instead of using the finder, or by fiddling with the contents of the installed bundle) and I wouldn’t want to make users use systemextensionsctl for the reason you stated above.

Anyways @PatTheMav probably has opinions here as well.

@niw
Copy link
Contributor Author

niw commented Oct 14, 2023

@gxalpha Thank you for replying, and I tried step 3 again by copying OBS.app in /Application again, then now Finder shows a dialog about uninstalling the system extension... but it was not appering. As you mentioned, likely it was a system issue (and I am sure I was not using rm -rf before just using Finder to remove it...)

I wonder if adding deactivationRequestForExtension:queue: helps such situations (not sure how it's common,) or probably just noting about retrying trash the app with Finder (like here, this issue) would be enough.

@gxalpha
Copy link
Member

gxalpha commented Oct 14, 2023

Interesting. Did you initially only use official OBS builds or did you also build OBS yourself?

@PatTheMav
Copy link
Member

I'm not against this possibility in principle - the removal of the app and macOS' automatic extension removal are a nice convenience feature, but allowing users to explicitly uninstall/install the extension is a nice thing to have.

Code-wise it's simple enough, I think the UX/UI work might take more effort.

In an ideal world I'd like to have explicit buttons to install/uninstall either the camera extension or DAL plugin (UX-wise it makes no difference, should be the same buttons) and also a prompt asking whether a missing "thing" (either plugin or extension) should be installed.

There is one scenario that will require testing however:

  1. Install OBS Studio
  2. Install Camera Extension
  3. Remove OBS Studio manually
  4. Install OBS Studio again
  5. Attempt to uninstall Camera Extension

My hunch is that there is some internal mechanism in macOS that matches system extension installations with Application Bundle instances. I've ended up with the system extension being installed twice (because bundleVersion was different), but removing the app only ever removed one instance of the extension.

@gxalpha gxalpha added macOS Affects macOS UI/UX Anything to do with changes or additions to UI/UX elements. and removed macOS Affects macOS labels Oct 14, 2023
@niw niw changed the title mac-virtualcam: No way to uninstall system extension mac-virtualcam: No easy way to uninstall system extension if app is removed without using Finder Oct 14, 2023
@niw
Copy link
Contributor Author

niw commented Oct 14, 2023

@gxalpha I had the binary built from the source separately actually in the different path, which may be related. Thus, probably it was my specific environment issue... and rare or limited corner case. Thus, I rephased the issue title to make thing clear.

@niw
Copy link
Contributor Author

niw commented Oct 14, 2023

@PatTheMav I certainly agree if we could have such user interface, or even command line actions, that would be nice. I also wonder if deactivationRequestForExtension:queue: call can handle the all installed versions or, probably only the specific version... that may be related to this 61a4922 commit.

@PatTheMav
Copy link
Member

PatTheMav commented Oct 15, 2023

@PatTheMav I certainly agree if we could have such user interface, or even command line actions, that would be nice. I also wonder if deactivationRequestForExtension:queue: call can handle the all installed versions or, probably only the specific version... that may be related to this 61a4922 commit.

I would expect it to only handle one installed version, because there is a 1-to-1 mapping of extension to application, so if we ask to uninstall the extension it will only affect the version that is mapped to the version of the application bundle on the system.

The deactivation request only takes the identifier of the extension, because the expectation for them is to have only one variant installed in the system. Duplicates are more of a bug than a supported/expected state of the system.

@elkinjosetm
Copy link

Hi, is there a way to uninstall the camera without disabling SIP? I had to install OBS 30 to try something, but now that I removed it, I still see the camera as "available"

@PatTheMav
Copy link
Member

Hi, is there a way to uninstall the camera without disabling SIP? I had to install OBS 30 to try something, but now that I removed it, I still see the camera as "available"

The canonical way is to delete the application in Finder - it will pop up a warning that the application contains a system extension and requires your approval that it should continue with the removal.

The system extension will then be removed manually. Do note that you can only remove a specific version of the extension with the associated version of the app - so if the installed extension is 30.0.0-rc1 you have to remove the identical version of the app from the Applications directory.

@elkinjosetm
Copy link

The canonical way is to delete the application in Finder - it will pop up a warning that the application contains a system extension and requires your approval that it should continue with the removal.

The system extension will then be removed manually. Do note that you can only remove a specific version of the extension with the associated version of the app - so if the installed extension is 30.0.0-rc1 you have to remove the identical version of the app from the Applications directory.

Oh, I removed OBS using AppCleaner, I guess it did not remove the extension, cuz' when I run systemextensionsctl list it is still there:

*	*	2MMRE5MTB8	com.obsproject.obs-studio.mac-camera-extension (30.0.0/6689064803)	com.obsproject.obs-studio.mac-camera-extension	[activated enabled]

@niw
Copy link
Contributor Author

niw commented Nov 9, 2023

Yeah, if the app removed by non Finder app such as AppCleaner, the extension removal dialog will not be appearing and it sticks there, which is the concern of this issue and may we want to have some alternative solution within the app, yet it’s also related to app version matching etc, so a bit complicated. That’s current state for this, as my understanding.

Put OSB.app into /Applications again and trash it on Finder will trigger that dialog to remove it.

@elkinjosetm
Copy link

elkinjosetm commented Nov 9, 2023

Makes sense, I just installed the rc2 from github, like you said, and removed it from Finder, I did get the extension removal message, but after removing it, the extension is still there, so that makes me wonder that it was not the same version(?), how do I know which rc is 30.0.0/6689064803?

@elkinjosetm
Copy link

Actually, never mind, I had to restart the computer for it to take effect, now is gone. Thank you so much!

@tnaftali
Copy link

tnaftali commented Apr 29, 2024

This issue is still happening, I cannot remove the OBS Virtual Camera even though I already uninstalled the app and cleaned up the related files using AppCleaner. Are there plans to fix this?

@PatTheMav
Copy link
Member

This issue is still happening, I cannot remove the OBS Virtual Camera even though I already uninstalled the app and cleaned up the related files using AppCleaner. Are there plans to fix this?

Using AppCleaner is usually the best way to break everything - AppCleaner is (at least to my knowledge) not capable of detecting that an application ships an extension and if it's deleted, the extension will linger around.

Right now only deleting the application in Finder will give you a prompt to also remove the extension.

If you inadvertently deleted OBS.app by other means (using something like AppCleaner or deleting it in Terminal) what you can try is:

  • Install a different(!) version of OBS.app (either an older or newer version compared to the extension version)
  • Run OBS.app
  • Attempt to run the virtual camera at least once (which should trigger a replacement of the current extension with the one shipped by the app)
  • Quit OBS.app
  • Delete OBS.app in Finder and confirm the deletion of the extension

systemextensionsctl list will tell you which version you have installed, e.g. 30.1.0/8254614054. In that case you would have to install >=30.1.1 or <=30.0.2 to ensure the extension is replaced with a different version.

@PatTheMav
Copy link
Member

PatTheMav commented Apr 29, 2024

So here's my "lingering" extension that I cannot uninstall (OBS.app is gone):

*	*	2MMRE5MTB8	com.obsproject.obs-studio.mac-camera-extension (30.1.0/8254614054)	com.obsproject.obs-studio.mac-camera-extension	[activated enabled]

I downloaded OBS 30.1.2 and installed and ran it and even without starting the virtual camera I got this state now:

*	*	2MMRE5MTB8	com.obsproject.obs-studio.mac-camera-extension (30.1.2/8576208847)	com.obsproject.obs-studio.mac-camera-extension	[activated enabled]
		2MMRE5MTB8	com.obsproject.obs-studio.mac-camera-extension (30.1.0/8254614054)	com.obsproject.obs-studio.mac-camera-extension	[terminated waiting to uninstall on reboot]

OBS detected an existing version that was different from the one it shipped and thus removed the "lingering" variant.

@tnaftali
Copy link

@PatTheMav thank you! that worked.

@niw
Copy link
Contributor Author

niw commented Apr 29, 2024

I wonder if extension can detect if OBS.app is removed from /Applications, then probably it can do something when itself lingering there e.g. at least prompting it to the users. Haven't explored much about such as extension's sandbox etc yet tho.

@PatTheMav
Copy link
Member

I wonder if extension can detect if OBS.app is removed from /Applications, then probably it can do something when itself lingering there e.g. at least prompting it to the users. Haven't explored much about such as extension's sandbox etc yet tho.

It cannot because extensions are always sandboxed and have no access to anything outside of it (particularly the file system). Extensions are entirely managed by macOS and run as part of the specific frameworks they extend.

The host application is just the delivery method of the extension.

@niw
Copy link
Contributor Author

niw commented Apr 29, 2024

Makes sense... kinda macOS itself problem that designed extension in this way and tight coupled with Finder's operation.

@ShadowJonathan
Copy link

ShadowJonathan commented Jun 16, 2024

FWIW Homebrew is running into this, and there appears to be a way to request the system to uninstall the extension: Homebrew/homebrew-cask#175497

https://developer.apple.com/documentation/systemextensions/ossystemextensionrequest/deactivationrequest(forextensionwithidentifier:queue:)

Maybe this could be implemented as a command-line option, or something similar that management tools could access, as a pre-install step?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
UI/UX Anything to do with changes or additions to UI/UX elements.
Projects
None yet
Development

No branches or pull requests

6 participants