How to manage HTC Vive controllers power programmatically? - htc-vive

Is it possible to power off Vive controller/tracker programmatically?
I see there is an option in SteamVR under each tracked device, but I could not find any references.
The only thing I found is polling events of entering and leaving standby mode via OpenVR api.

The only workaround I've found is
Getting serial number of connected wireless dongle via OpenVR using Prop_ConnectedWirelessDongle_String property.
Calling lighthouse_console with arguments /serial %serialNumber% poweroff. This tool is provided by SteamVR and located at SteamVR\tools\lighthouse\bin\win32(64) folder.
Note that if device is connected via USB, it will not power off.

I'm currenlty using this piece of code as there is no legit way to do this. but this seems to work in my case.
void Start () {
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = "C:\\Program Files (x86)\\Steam\\steamapps\\common\\SteamVR\\tools\\lighthouse\\bin\\win64\\lighthouse_console.exe";
process.StartInfo.Arguments = "/serial 81F6B76702 poweroff";
process.StartInfo.UseShellExecute = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.Start();
}

Related

Detecting if a running application is sandboxed

Given an application's pid, is there any way, programatically, of detecting if that application is running in an OSX sandbox environment?
Ideally, I'd like to know if there's an API call somewhere, preferably in C, rather than objective-C (for a daemon, so not using Cocoa), but if not, is there any other way of checking?
#Linuxios was right partly right about there being a CoreFoundation call. In fact, there are a few that when combined, can be used to solve this and it's based on the call to SecStaticCodeCheckValidityWithErrors
For anyone that may want, or need to programmatically test for an app being sandboxed can follow this blog.
Also, the full code to the article has been added to Github here.
First you must get the path of the application from the pid, and then you can use the command codesign --display --entitlements - app_path to view all the entitlements. If the app has the entitlements com.apple.security.app-sandbox set to true then it is sandboxed.
You can take a look here.
For detecting the sandbox in Flex/AIR/AS3 you can use the following kludge. The same approach should also work in objc. The only condition under which this would not work would be if the Documents folder were entirely empty. Or you could use any other folder that is off-limits to the sandbox.
var file:File = File.userDirectory;
var a:Array = file.nativePath.split("/");
var userName:String = a[2];
var docFolder:File = new File("/Users/" + userName + "/Documents/");
var dirList:Array = docFolder.getDirectoryListing();
if (dirList.length>0) {
docDirectoryDisplay.text = "App is NOT sandboxed.";
} else {
docDirectoryDisplay.text = "App is sandboxed.";
}

Can I keep an AIR NativeProcess running after the AIR application itself exists?

My need is simple - I want to launch an external application from my AIR application, leaving the external application running while the AIR application itself exits.
The scenario is an "Install" button inside the application, that launches the 3rd party installer - the AIR application needs to close during this process.
My code to actually launch the NativeProcess object is fine, the process launches and can be used. However, if the user closes the AIR application manually, or if I attempt to close the AIR application after launching the external process via ActionScript, the external application exists almost immediately.
Some example code:
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = File.applicationDirectory.resolvePath("My Great Application");
var process:NativeProcess = new NativeProcess();
process.start(nativeProcessStartupInfo);
// Either one of the two calls following will fail with the same result
NativeApplication.nativeApplication.exit()
this.nativeWindow.close();
I have also tried another approach to keep the external application open after the AIR application exists, using a proxy of sorts. On a Mac, I'm using the /usr/bin/open command. /usr/bin/open does open the external application and leave it running after the AIR application exists, however a Terminal window is on the screen with this approach, and that's not acceptable either.
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = new File("/usr/bin/open");
var args:Vector.<String> = new Vector.<String>();
args.push(file.nativePath);
nativeProcessStartupInfo.arguments = args;
var process:NativeProcess = new NativeProcess();
process.start(nativeProcessStartupInfo);
Any thoughts on this problem? I'd love to just launch the external application directly instead of using a proxy, as that will keep complexity down between deployment platforms.
What about minimizing the application?
NativeApplication.nativeApplication.activeWindow.minimize();

Problems receiving Notifications from IOKit (CoreFoundation) for plugged Devices

I'm currently developing an application on 10.6.7 which should receive notifications when a new usb device is plugged in. I found out that there is a IOKit function which handles such stuff 'IOServiceAddMatchingNotification'. Because the return value from this specific function is 0, I think that the problem perhaps is in my matching Dictionary, which is given into this function. I declare the Dictionary that way:
CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
Because I wan't to receive a notification for each device, I don't know if this is the right way to create this particular dictionary.
My complete code look like this:
ioKitNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
notificationRunLoopSource = IONotificationPortGetRunLoopSource(ioKitNotificationPort);
CFRunLoopAddSource(CFRunLoopGetCurrent(), notificationRunLoopSource, kCFRunLoopDefaultMode);
CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
addMatchingNotificationResult = IOServiceAddMatchingNotification(ioKitNotificationPort,
kIOPublishNotification,
matchingDict,
deviceAdded,
NULL,
Does anyone has a idea why this won't work?
(Note: The Callback function is a static void c function and the rest is wrapped ins
ide a Obj-C class).
Thanks
Xcode 4, 10.6.7
Weirdly, you must empty the iterator returned by IOServiceAddMatchingNotification before the notification will be armed. I don't see that in the code provided, so that could be in the issue. That iterator is actually what you need to keep around to keep the notification running.
io_iterator_t ioNotification;
addMatchingNotificationResult = IOServiceAddMatchingNotification(ioKitNotificationPort,
kIOPublishNotification,
matchingDict,
deviceAdded,
NULL,
&ioNotification);
while ((service = IOIteratorNext(ioNotification)))
{
NSLog(#"Hey, I found a service!");
IOObjectRelease(service); // yes, you have to release this
}
In my opinion, u should download the source code form IOUSBFamily on opensource.apple.com, and then find the code for USB Prober, this application does exactly the same thing as u described, listening the USB Device attachment.(Further, USB Prober also get the general device and configuration descriptor, maybe it is also the things u need.)
Did you add the VID and PID of the device you wish to look for to your matching dictionary? For the dictionary you have, and VID= yourVid, PID= yourPid, it would be:
CFDictionaryAddValue(matchingDict, usbVendorId, yourVid);
CFDictionaryAddValue(matchingDict, usbProductId, yourPid);
Another thing - after the call to IOServiceAddMatchingNotification succeeds, you need to call your device-added handler with the iterator that was set in the call. That will arm the notification and check for existing devices.
the easiest way to do what i think you are describing is to hook into the DiskArbitration Framework. DA is relatively new to OSX and allows userland applications to examine devices as they get attached. it is what is used to open iTunes when an iPod is attached, launch iPhoto when a camera is attached, etc... if the USB device you are looking for is a storage device then this will work for you. otherwise you will need to go the matching dictionary route...

Prevent webcam light from illuminating when accessing microphone in Silverlight 4

I'm writing a small audio recorder component in Silverlight 4. It works fine, but I've noticed that when I'm recording audio, the light on my webcam turns on indicating that the camera is active.
While I know that I'm not doing anything insidious with the webcam, my users would have every right to be suspicious. Is it possible to tell Silverlight that I'm only interested in microphone access and not activate the webcam?
FWIW here's how I'm accessing the mic:
private CaptureSource _source = new CaptureSource();
private MemoryAudioSink _sink; // Inherits from AudioSink. Doesn't do much more
// than store PCM audio stream in memory
private void Record_Click(object sender, RoutedEventArgs e)
{
if (( CaptureDeviceConfiguration.AllowedDeviceAccess ||
CaptureDeviceConfiguration.RequestDeviceAccess() ) &&
_source.State == CaptureState.Stopped)
{
_sink = new MemoryAudioSink();
_sink.CaptureSource = _source;
_source.Start();
}
}
CaptureSource will frequently grab the default video input device, even if you don't tell it to. Though you aren't using the camera, Silverlight is indeed accessing it. Hopefully, MS will fix this odd behavior in a later version of Silverlight.
In the meantime, just explicitly set VideoCaptureDevice to null:
var _audioCaptureSource = new CaptureSource {VideoCaptureDevice = null};
This would depend on the webcam driver - Silverlight would have no control over this.
I'm guessing its related to your use of CaptureSource. Microsoft's web site claims that:
Silverlight 4 APIs only use
CaptureSource in a video scenario
where audio may not be relevant.
Is there a way to get audio without creating your own CaptureSource?

How to know a video source (webcam) is available or not without creating capture window?

It is quite tricky because I wanna to take the result as a sign for later process. If a window flashes, it would be weird to user.
(This is not an answer, just refreshing the question and adding some details:)
Suppose you need to open a video capture driver (webcam) with code like this (delphi, but easy understandable):
result:= SendMessage(hCapWnd, WM_CAP_DRIVER_CONNECT, FDriverNo, 0);
It works fine, except when camera/webcam is busy (opened by another application, for example moviemaker). Then the capture driver suddenly shows a "select video source" window that blocks your application (but not moviemaker, which keeps recording). SendMessage function becomes modal and will not return until undesired window is closed.
Is there a way to detect if a capture driver is busy with another application before connecting to it?
Thanks
This function return number of available webcams and scanners on your mashine(с++).
int GetNumCam()
{
int MemberIndex = 0;
HDEVINFO dev;
SP_DEVINFO_DATA DeviceInfoData;
DeviceInfoData.cbSize = sizeof(DeviceInfoData);
dev = SetupDiGetClassDevsA(&GUID_DEVINTERFACE_IMAGE, NULL,NULL,DIGCF_PRESENT);
if (dev == NULL)
{
MessageBoxA(0,"it is null..","vse propalo",0);
return -1;
}
else
{
while(SetupDiEnumDeviceInfo(dev,MemberIndex, &DeviceInfoData))
{
MemberIndex++;
}
}
return MemberIndex;
}
I wonder if sending a broadcast message could do. I mean, suppose you send a VFW info request message to all windows in system. Then, all windows actually doing VFW processing will answer their status info and you will know which of them are doing video processing; some kind of shouting "anybody here...?"
But it looks like brute force, or even hacking. May be I'll test it... may be not. I am sure there must be a smarter way to know if a video capture driver is busy with another application.
(btw... anybody here?)
I was afraid it would happen.
First I enumerated all opened windows in system, then executed this instruction for each HWND, which just asks for driver information (pascal syntax):
SendMessage(h, WM_CAP_DRIVER_GET_NAME, length(driver)*sizeof(char), LPARAM(PChar(driver))
According to Msdn help, WM_CAP_DRIVER_GET_NAME results are:
"Returns TRUE if successful or FALSE if the capture window is not connected to a capture driver"
(Bold is mine). So it appears a good way to know:
1-If the window is capturing. So it is applyable to ALL windows, don't matter if they are capturing or not.
2-And if so, it tells you which driver is using.
However, after first test round, the results were:
- Task Manager (it was running) crashed and closed
- Explorer crashed and closed (reopened again automatically)
- Belkin Wireless monitor (my pc's WiFi driver) crashed and closed
- Eset Nod32 antivirus crashed, did not closed
The first conclussion can be that this is a bad way to locate which applications are capturing video in a system. But I must ensure to dismiss the possibility of a bug.
I'll keep reporting.
This is not a good solution my any means but I found out that if you disable and enable the camera in device manager immediately before sending the WM_CAP_DRIVER_CONNECT message then for some reason the video source window does not appear and the function returns and works OK.
So for a script I was working on I had to download devcon.exe and I put "devcon disable *PID_3450*MI_00*" and "devcon enable *PID_3450*MI_00*" immediately before my WM_CAP_DRIVER_CONNECT and it seems to work consistently. Unfortunately you need to run as administrator to be able to disable/enable devices. Again not a proper fix by any means...
(Hardware ID of my cam is USB\VID_0AC8&PID_3450&MI_00)