VirtualBox

source: vbox/trunk/src/VBox/Main/glue/vboxapi.py@ 47979

Last change on this file since 47979 was 47979, checked in by vboxsync, 12 years ago

vboxapi.py: Some cleaning up. New features: Documentation. ;-) Dropped the session manager class as it served no purpose I could fathom.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.2 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: vboxapi.py 47979 2013-08-21 18:44:35Z vboxsync $
3"""
4VirtualBox Python API Glue.
5"""
6
7__copyright__ = \
8"""
9Copyright (C) 2009-2013 Oracle Corporation
10
11This file is part of VirtualBox Open Source Edition (OSE), as
12available from http://www.virtualbox.org. This file is free software;
13you can redistribute it and/or modify it under the terms of the GNU
14General Public License (GPL) as published by the Free Software
15Foundation, in version 2 as it comes in the "COPYING" file of the
16VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18"""
19__version__ = "$Revision: 47979 $"
20
21
22# Note! To set Python bitness on OSX use 'export VERSIONER_PYTHON_PREFER_32_BIT=yes'
23
24
25# Standard Python imports.
26import sys, os
27import traceback
28
29
30#
31# Globals, environment and sys.path changes.
32#
33VBoxBinDir = os.environ.get("VBOX_PROGRAM_PATH", None)
34VBoxSdkDir = os.environ.get("VBOX_SDK_PATH", None)
35
36if VBoxBinDir is None:
37 # Will be set by the installer
38 VBoxBinDir = "%VBOX_INSTALL_PATH%"
39
40if VBoxSdkDir is None:
41 # Will be set by the installer
42 VBoxSdkDir = "%VBOX_SDK_PATH%"
43
44os.environ["VBOX_PROGRAM_PATH"] = VBoxBinDir
45os.environ["VBOX_SDK_PATH"] = VBoxSdkDir
46sys.path.append(VBoxBinDir)
47
48
49#
50# Import the generated VirtualBox constants.
51#
52from VirtualBox_constants import VirtualBoxReflectionInfo
53
54
55class PerfCollector(object):
56 """ This class provides a wrapper over IPerformanceCollector in order to
57 get more 'pythonic' interface.
58
59 To begin collection of metrics use setup() method.
60
61 To get collected data use query() method.
62
63 It is possible to disable metric collection without changing collection
64 parameters with disable() method. The enable() method resumes metric
65 collection.
66 """
67
68 def __init__(self, mgr, vbox):
69 """ Initializes the instance.
70
71 """
72 self.mgr = mgr
73 self.isMscom = (mgr.type == 'MSCOM')
74 self.collector = vbox.performanceCollector
75
76 def setup(self, names, objects, period, nsamples):
77 """ Discards all previously collected values for the specified
78 metrics, sets the period of collection and the number of retained
79 samples, enables collection.
80 """
81 self.collector.setupMetrics(names, objects, period, nsamples)
82
83 def enable(self, names, objects):
84 """ Resumes metric collection for the specified metrics.
85 """
86 self.collector.enableMetrics(names, objects)
87
88 def disable(self, names, objects):
89 """ Suspends metric collection for the specified metrics.
90 """
91 self.collector.disableMetrics(names, objects)
92
93 def query(self, names, objects):
94 """ Retrieves collected metric values as well as some auxiliary
95 information. Returns an array of dictionaries, one dictionary per
96 metric. Each dictionary contains the following entries:
97 'name': metric name
98 'object': managed object this metric associated with
99 'unit': unit of measurement
100 'scale': divide 'values' by this number to get float numbers
101 'values': collected data
102 'values_as_string': pre-processed values ready for 'print' statement
103 """
104 # Get around the problem with input arrays returned in output
105 # parameters (see #3953) for MSCOM.
106 if self.isMscom:
107 (values, names, objects, names_out, objects_out, units, scales, sequence_numbers,
108 indices, lengths) = self.collector.queryMetricsData(names, objects)
109 else:
110 (values, names_out, objects_out, units, scales, sequence_numbers,
111 indices, lengths) = self.collector.queryMetricsData(names, objects)
112 out = []
113 for i in xrange(0, len(names_out)):
114 scale = int(scales[i])
115 if scale != 1:
116 fmt = '%.2f%s'
117 else:
118 fmt = '%d %s'
119 out.append({
120 'name':str(names_out[i]),
121 'object':str(objects_out[i]),
122 'unit':str(units[i]),
123 'scale':scale,
124 'values':[int(values[j]) for j in xrange(int(indices[i]), int(indices[i])+int(lengths[i]))],
125 'values_as_string':'['+', '.join([fmt % (int(values[j])/scale, units[i]) for j in xrange(int(indices[i]), int(indices[i])+int(lengths[i]))])+']'
126 })
127 return out
128
129#
130# Attribute hacks.
131#
132def ComifyName(name):
133 return name[0].capitalize()+name[1:]
134
135
136## This is for saving the original DispatchBaseClass __getattr__ and __setattr__
137# method references.
138_g_dCOMForward = {
139 'getattr': None,
140 'setattr': None,
141}
142
143def CustomGetAttr(self, attr):
144 # fastpath
145 if self.__class__.__dict__.get(attr) != None:
146 return self.__class__.__dict__.get(attr)
147
148 # try case-insensitivity workaround for class attributes (COM methods)
149 for k in self.__class__.__dict__.keys():
150 if k.lower() == attr.lower():
151 self.__class__.__dict__[attr] = self.__class__.__dict__[k]
152 return getattr(self, k)
153 try:
154 return _g_dCOMForward['getattr'](self, ComifyName(attr))
155 except AttributeError:
156 return _g_dCOMForward['getattr'](self, attr)
157
158def CustomSetAttr(self, attr, value):
159 try:
160 return _g_dCOMForward['setattr'](self, ComifyName(attr), value)
161 except AttributeError:
162 return _g_dCOMForward['setattr'](self, attr, value)
163
164
165
166class PlatformBase(object):
167 """
168 Base class for the platform specific code.
169 """
170
171 def __init__(self, aoParams):
172 _ = aoParams;
173
174 def getVirtualBox(self):
175 """
176 Gets a the IVirtualBox singleton.
177 """
178 return None;
179
180 def getSessionObject(self, oIVBox):
181 """
182 Get a session object that can be used for opening machine sessions.
183
184 The oIVBox parameter is an getVirtualBox() return value, i.e. an
185 IVirtualBox reference.
186
187 See also openMachineSession.
188 """
189 _ = oIVBox;
190 return None;
191
192 def getType(self):
193 """ Returns the platform type (class name sans 'Platform'). """
194 return None;
195
196 def isRemote(self):
197 """
198 Returns True if remote (web services) and False if local (COM/XPCOM).
199 """
200 return False
201
202 def getArray(self, oInterface, sAttrib):
203 """
204 Retrives the value of the array attribute 'sAttrib' from
205 interface 'oInterface'.
206
207 This is for hiding platform specific differences in attributes
208 returning arrays.
209 """
210 _ = oInterface;
211 _ = sAttrib;
212 return None;
213
214 def initPerThread(self):
215 """
216 Does backend specific initialization for the calling thread.
217 """
218 return True;
219
220 def deinitPerThread(self):
221 """
222 Does backend specific uninitialization for the calling thread.
223 """
224 return True;
225
226 def createListener(self, oImplClass, dArgs):
227 """
228 Instantiates and wraps an active event listener class so it can be
229 passed to an event source for registration.
230
231 oImplClass is a class (type, not instance) which implements
232 IEventListener.
233
234 dArgs is a dictionary with string indexed variables. This may be
235 modified by the method to pass platform specific parameters. Can
236 be None.
237
238 This currently only works on XPCOM. COM support is not possible due to
239 shortcuts taken in the COM bridge code, which is not under our control.
240 Use passive listeners for COM and web services.
241 """
242 _ = oImplClass;
243 _ = dArgs;
244 raise Exception("No active listeners for this platform");
245 return None;
246
247 def waitForEvents(self, cMsTimeout):
248 """
249 Wait for events to arrive and process them.
250
251 The timeout (cMsTimeout) is in milliseconds for how long to wait for
252 events to arrive. A negative value means waiting for ever, while 0
253 does not wait at all.
254
255 Returns 0 if events was processed.
256 Returns 1 if timed out or interrupted in some way.
257 Returns 2 on error (like not supported for web services).
258
259 Raises an exception if the calling thread is not the main thread (the one
260 that initialized VirtualBoxManager) or if the time isn't an integer.
261 """
262 _ = cMsTimeout;
263 return 2;
264
265 def interruptWaitEvents(self):
266 """
267 Interrupt a waitForEvents call.
268 This is normally called from a worker thread to wake up the main thread.
269
270 Returns True on success, False on failure.
271 """
272 return False;
273
274 def deinit(self):
275 """
276 Unitializes the platform specific backend.
277 """
278 return None;
279
280 def queryInterface(self, oIUnknown, sClassName):
281 """
282 IUnknown::QueryInterface wrapper.
283
284 oIUnknown is who to ask.
285 sClassName is the name of the interface we're asking for.
286 """
287 return None;
288
289
290class PlatformMSCOM(PlatformBase):
291 """
292 Platform specific code for MS COM.
293 """
294
295 ## @name VirtualBox COM Typelib definitions (should be generate)
296 #
297 # @remarks Must be updated when the corresponding VirtualBox.xidl bits
298 # are changed. Fortunately this isn't very often.
299 # @{
300 VBOX_TLB_GUID = '{D7569351-1750-46F0-936E-BD127D5BC264}'
301 VBOX_TLB_LCID = 0
302 VBOX_TLB_MAJOR = 1
303 VBOX_TLB_MINOR = 3
304 ## @}
305
306
307 class ConstantFake(object):
308 """ Class to fake access to constants in style of foo.bar.boo """
309
310 def __init__(self, parent, name):
311 self.__dict__['_parent'] = parent
312 self.__dict__['_name'] = name
313 self.__dict__['_consts'] = {}
314 try:
315 self.__dict__['_depth']=parent.__dict__['_depth']+1
316 except:
317 self.__dict__['_depth']=0
318 if self.__dict__['_depth'] > 4:
319 raise AttributeError
320
321 def __getattr__(self, attr):
322 import win32com
323 from win32com.client import constants
324
325 if attr.startswith("__"):
326 raise AttributeError
327
328 consts = self.__dict__['_consts']
329
330 fake = consts.get(attr, None)
331 if fake != None:
332 return fake
333 try:
334 name = self.__dict__['_name']
335 parent = self.__dict__['_parent']
336 while parent != None:
337 if parent._name is not None:
338 name = parent._name+'_'+name
339 parent = parent._parent
340
341 if name is not None:
342 name += "_" + attr
343 else:
344 name = attr
345 return win32com.client.constants.__getattr__(name)
346 except AttributeError, e:
347 fake = PlatformMSCOM.ConstantFake(self, attr)
348 consts[attr] = fake
349 return fake
350
351
352 class InterfacesWrapper:
353 def __init__(self):
354 self.__dict__['_rootFake'] = PlatformMSCOM.ConstantFake(None, None)
355
356 def __getattr__(self, a):
357 import win32com
358 from win32com.client import constants
359 if a.startswith("__"):
360 raise AttributeError
361 try:
362 return win32com.client.constants.__getattr__(a)
363 except AttributeError, e:
364 return self.__dict__['_rootFake'].__getattr__(a)
365
366 def __init__(self, dParams):
367 PlatformBase.__init__(self, dParams);
368
369 #
370 # Since the code runs on all platforms, we have to do a lot of
371 # importing here instead of at the top of the file where it's normally located.
372 #
373 from win32com import universal
374 from win32com.client import gencache, DispatchBaseClass
375 from win32com.client import constants, getevents
376 import win32com
377 import pythoncom
378 import win32api
379 from win32con import DUPLICATE_SAME_ACCESS
380 from win32api import GetCurrentThread, GetCurrentThreadId, DuplicateHandle, GetCurrentProcess
381 import threading
382
383 pid = GetCurrentProcess()
384 self.tid = GetCurrentThreadId()
385 handle = DuplicateHandle(pid, GetCurrentThread(), pid, 0, 0, DUPLICATE_SAME_ACCESS)
386 self.handles = []
387 self.handles.append(handle)
388
389 # Hack the COM dispatcher base class so we can modify method and
390 # attribute names to match those in xpcom.
391 if _g_dCOMForward['setattr'] is None:
392 _g_dCOMForward['getattr'] = DispatchBaseClass.__dict__['__getattr__']
393 DispatchBaseClass.__dict__['__getattr__'] = CustomGetAttr
394 _g_dCOMForward['setattr'] = DispatchBaseClass.__dict__['__setattr__']
395 DispatchBaseClass.__dict__['__setattr__'] = CustomSetAttr
396
397 # Hack the exception base class so the users doesn't need to check for
398 # XPCOM or COM and do different things.
399 ## @todo
400
401
402 win32com.client.gencache.EnsureDispatch('VirtualBox.Session')
403 win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBox')
404
405 self.oIntCv = threading.Condition()
406 self.fInterrupted = False;
407
408 _ = dParams;
409
410 def getSessionObject(self, oIVBox):
411 _ = oIVBox
412 import win32com
413 from win32com.client import Dispatch
414 return win32com.client.Dispatch("VirtualBox.Session")
415
416 def getVirtualBox(self):
417 import win32com
418 from win32com.client import Dispatch
419 return win32com.client.Dispatch("VirtualBox.VirtualBox")
420
421 def getType(self):
422 return 'MSCOM'
423
424 def getArray(self, oInterface, sAttrib):
425 return oInterface.__getattr__(sAttrib)
426
427 def initPerThread(self):
428 import pythoncom
429 pythoncom.CoInitializeEx(0)
430
431 def deinitPerThread(self):
432 import pythoncom
433 pythoncom.CoUninitialize()
434
435 def createListener(self, oImplClass, dArgs):
436 if True:
437 raise Exception('no active listeners on Windows as PyGatewayBase::QueryInterface() '
438 'returns new gateway objects all the time, thus breaking EventQueue '
439 'assumptions about the listener interface pointer being constants between calls ');
440 # Did this code ever really work?
441 d = {}
442 d['BaseClass'] = oImplClass
443 d['dArgs'] = dArgs
444 d['tlb_guid'] = PlatformMSCOM.VBOX_TLB_GUID
445 d['tlb_major'] = PlatformMSCOM.VBOX_TLB_MAJOR
446 d['tlb_minor'] = PlatformMSCOM.VBOX_TLB_MINOR
447 str = ""
448 str += "import win32com.server.util\n"
449 str += "import pythoncom\n"
450
451 str += "class ListenerImpl(BaseClass):\n"
452 str += " _com_interfaces_ = ['IEventListener']\n"
453 str += " _typelib_guid_ = tlb_guid\n"
454 str += " _typelib_version_ = tlb_major, tlb_minor\n"
455 str += " _reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER\n"
456 # Maybe we'd better implement Dynamic invoke policy, to be more flexible here
457 str += " _reg_policy_spec_ = 'win32com.server.policy.EventHandlerPolicy'\n"
458
459 # capitalized version of listener method
460 str += " HandleEvent=BaseClass.handleEvent\n"
461 str += " def __init__(self): BaseClass.__init__(self, dArgs)\n"
462 str += "result = win32com.server.util.wrap(ListenerImpl())\n"
463 exec(str, d, d)
464 return d['result']
465
466 def waitForEvents(self, timeout):
467 from win32api import GetCurrentThreadId
468 from win32event import INFINITE
469 from win32event import MsgWaitForMultipleObjects, \
470 QS_ALLINPUT, WAIT_TIMEOUT, WAIT_OBJECT_0
471 from pythoncom import PumpWaitingMessages
472 import types
473
474 if not isinstance(timeout, types.IntType):
475 raise TypeError("The timeout argument is not an integer")
476 if (self.tid != GetCurrentThreadId()):
477 raise Exception("wait for events from the same thread you inited!")
478
479 if timeout < 0:
480 cMsTimeout = INFINITE
481 else:
482 cMsTimeout = timeout
483 rc = MsgWaitForMultipleObjects(self.handles, 0, cMsTimeout, QS_ALLINPUT)
484 if rc >= WAIT_OBJECT_0 and rc < WAIT_OBJECT_0+len(self.handles):
485 # is it possible?
486 rc = 2;
487 elif rc==WAIT_OBJECT_0 + len(self.handles):
488 # Waiting messages
489 PumpWaitingMessages()
490 rc = 0;
491 else:
492 # Timeout
493 rc = 1;
494
495 # check for interruption
496 self.oIntCv.acquire()
497 if self.fInterrupted:
498 self.fInterrupted = False
499 rc = 1;
500 self.oIntCv.release()
501
502 return rc;
503
504 def interruptWaitEvents(self):
505 """
506 Basically a python implementation of NativeEventQueue::postEvent().
507
508 The magic value must be in sync with the C++ implementation or this
509 won't work.
510
511 Note that because of this method we cannot easily make use of a
512 non-visible Window to handle the message like we would like to do.
513 """
514 from win32api import PostThreadMessage
515 from win32con import WM_USER
516 self.oIntCv.acquire()
517 self.fInterrupted = True
518 self.oIntCv.release()
519 try:
520 PostThreadMessage(self.tid, WM_USER, None, 0xf241b819)
521 except:
522 return False;
523 return True;
524
525 def deinit(self):
526 import pythoncom
527 from win32file import CloseHandle
528
529 for h in self.handles:
530 if h is not None:
531 CloseHandle(h)
532 self.handles = None
533 pythoncom.CoUninitialize()
534 pass
535
536 def queryInterface(self, oIUnknown, sClassName):
537 from win32com.client import CastTo
538 return CastTo(oIUnknown, sClassName)
539
540
541class PlatformXPCOM(PlatformBase):
542 """
543 Platform specific code for XPCOM.
544 """
545
546 def __init__(self, dParams):
547 PlatformBase.__init__(self, dParams);
548 sys.path.append(VBoxSdkDir+'/bindings/xpcom/python/')
549 import xpcom.vboxxpcom
550 import xpcom
551 import xpcom.components
552 _ = dParams;
553
554 def getSessionObject(self, oIVBox):
555 _ = oIVBox;
556 import xpcom.components
557 return xpcom.components.classes["@virtualbox.org/Session;1"].createInstance()
558
559 def getVirtualBox(self):
560 import xpcom.components
561 return xpcom.components.classes["@virtualbox.org/VirtualBox;1"].createInstance()
562
563 def getType(self):
564 return 'XPCOM'
565
566 def getArray(self, oInterface, sAttrib):
567 return oInterface.__getattr__('get'+ComifyName(sAttrib))()
568
569 def initPerThread(self):
570 import xpcom
571 xpcom._xpcom.AttachThread()
572
573 def deinitPerThread(self):
574 import xpcom
575 xpcom._xpcom.DetachThread()
576
577 def createListener(self, oImplClass, dArgs):
578 d = {}
579 d['BaseClass'] = oImplClass
580 d['dArgs'] = dArgs
581 str = ""
582 str += "import xpcom.components\n"
583 str += "class ListenerImpl(BaseClass):\n"
584 str += " _com_interfaces_ = xpcom.components.interfaces.IEventListener\n"
585 str += " def __init__(self): BaseClass.__init__(self, dArgs)\n"
586 str += "result = ListenerImpl()\n"
587 exec (str, d, d)
588 return d['result']
589
590 def waitForEvents(self, timeout):
591 import xpcom
592 return xpcom._xpcom.WaitForEvents(timeout)
593
594 def interruptWaitEvents(self):
595 import xpcom
596 return xpcom._xpcom.InterruptWait()
597
598 def deinit(self):
599 import xpcom
600 xpcom._xpcom.DeinitCOM()
601
602 def queryInterface(self, oIUnknown, sClassName):
603 import xpcom.components
604 return oIUnknown.queryInterface(getattr(xpcom.components.interfaces, sClassName))
605
606
607class PlatformWEBSERVICE(PlatformBase):
608 """
609 VirtualBox Web Services API specific code.
610 """
611
612 def __init__(self, dParams):
613 PlatformBase.__init__(self, dParams);
614 # Import web services stuff. Fix the sys.path the first time.
615 sWebServLib = os.path.join(VBoxSdkDir, 'bindings', 'webservice', 'python', 'lib');
616 if sWebServLib not in sys.path:
617 sys.path.append(sWebServLib);
618 import VirtualBox_wrappers
619 from VirtualBox_wrappers import IWebsessionManager2
620
621 # Initialize instance variables from parameters.
622 if dParams is not None:
623 self.user = dParams.get("user", "")
624 self.password = dParams.get("password", "")
625 self.url = dParams.get("url", "")
626 else:
627 self.user = ""
628 self.password = ""
629 self.url = None
630 self.vbox = None
631 self.wsmgr = None;
632
633 #
634 # Base class overrides.
635 #
636
637 def getSessionObject(self, oIVBox):
638 return self.wsmgr.getSessionObject(oIVBox)
639
640 def getVirtualBox(self):
641 return self.connect(self.url, self.user, self.password)
642
643 def getType(self):
644 return 'WEBSERVICE'
645
646 def isRemote(self):
647 """ Returns True if remote VBox host, False if local. """
648 return True
649
650 def getArray(self, oInterface, sAttrib):
651 return oInterface.__getattr__(sAttrib)
652
653 def waitForEvents(self, timeout):
654 # Webservices cannot do that yet
655 return 2;
656
657 def interruptWaitEvents(self, timeout):
658 # Webservices cannot do that yet
659 return False;
660
661 def deinit(self):
662 try:
663 disconnect()
664 except:
665 pass
666
667 def queryInterface(self, oIUnknown, sClassName):
668 d = {}
669 d['oIUnknown'] = oIUnknown
670 str = ""
671 str += "from VirtualBox_wrappers import "+sClassName+"\n"
672 str += "result = "+sClassName+"(oIUnknown.mgr, oIUnknown.handle)\n"
673 # wrong, need to test if class indeed implements this interface
674 exec (str, d, d)
675 return d['result']
676
677 #
678 # Web service specific methods.
679 #
680
681 def connect(self, url, user, passwd):
682 if self.vbox is not None:
683 self.disconnect()
684 from VirtualBox_wrappers import IWebsessionManager2
685 if url is None:
686 url = ""
687 self.url = url
688 if user is None:
689 user = ""
690 self.user = user
691 if passwd is None:
692 passwd = ""
693 self.password = passwd
694 self.wsmgr = IWebsessionManager2(self.url)
695 self.vbox = self.wsmgr.logon(self.user, self.password)
696 if not self.vbox.handle:
697 raise Exception("cannot connect to '"+self.url+"' as '"+self.user+"'")
698 return self.vbox
699
700 def disconnect(self):
701 if self.vbox is not None and self.wsmgr is not None:
702 self.wsmgr.logoff(self.vbox)
703 self.vbox = None
704 self.wsmgr = None
705
706
707
708class VirtualBoxManager(object):
709 """
710 VirtualBox API manager class.
711
712 The API users will have to instantiate this. If no parameters are given,
713 it will default to interface with the VirtualBox running on the local
714 machine. sStyle can be None (default), MSCOM, XPCOM or WEBSERVICES. Most
715 users will either be specifying None or WEBSERVICES.
716
717 The dPlatformParams is an optional dictionary for passing parameters to the
718 WEBSERVICE backend.
719 """
720
721 def __init__(self, sStyle = None, dPlatformParams = None):
722 if sStyle is None:
723 if sys.platform == 'win32':
724 sStyle = "MSCOM"
725 else:
726 sStyle = "XPCOM"
727 if sStyle == 'XPCOM':
728 self.platform = PlatformXPCOM(dPlatformParams);
729 elif sStyle == 'MSCOM':
730 self.platform = PlatformMSCOM(dPlatformParams);
731 elif sStyle == 'WEBSERVICE':
732 self.platform = PlatformWEBSERVICE(dPlatformParams);
733 else:
734 raise Exception('Unknown sStyle=%s' % (sStyle,));
735 self.style = sStyle
736 self.type = self.platform.getType()
737 self.remote = self.platform.isRemote()
738 # for webservices, enums are symbolic
739 self.constants = VirtualBoxReflectionInfo(sStyle == "WEBSERVICE")
740
741 try:
742 self.vbox = self.platform.getVirtualBox()
743 except NameError, ne:
744 print "Installation problem: check that appropriate libs in place"
745 traceback.print_exc()
746 raise ne
747 except Exception, e:
748 print "init exception: ", e
749 traceback.print_exc()
750 if self.remote:
751 self.vbox = None
752 else:
753 raise e
754 ## @deprecated
755 # This used to refer to a session manager class with only one method
756 # called getSessionObject. The method has moved into this call.
757 self.mgr = self;
758
759 def __del__(self):
760 self.deinit()
761
762
763 #
764 # Wrappers for self.platform methods.
765 #
766
767 def getVirtualBox(self):
768 """ See PlatformBase::getVirtualBox(). """
769 return self.platform.getVirtualBox()
770
771 def getSessionObject(self, oIVBox):
772 """ See PlatformBase::getSessionObject(). """
773 return self.platform.getSessionObject(oIVBox);
774
775 def getArray(self, oInterface, sAttrib):
776 """ See PlatformBase::getArray(). """
777 return self.platform.getArray(oInterface, sAttrib)
778
779 def createListener(self, oImplClass, dArgs = None):
780 """ See PlatformBase::createListener(). """
781 return self.platform.createListener(oImplClass, dArgs)
782
783 def waitForEvents(self, cMsTimeout):
784 """ See PlatformBase::waitForEvents(). """
785 return self.platform.waitForEvents(cMsTimeout)
786
787 def interruptWaitEvents(self):
788 """ See PlatformBase::interruptWaitEvents(). """
789 return self.platform.interruptWaitEvents()
790
791 def queryInterface(self, oIUnknown, sClassName):
792 """ See PlatformBase::queryInterface(). """
793 return self.platform.queryInterface(oIUnknown, sClassName)
794
795
796 #
797 # Init and uninit.
798 #
799
800 def initPerThread(self):
801 """ See PlatformBase::deinitPerThread(). """
802 self.platform.initPerThread()
803
804 def deinitPerThread(self):
805 """ See PlatformBase::deinitPerThread(). """
806 return self.platform.deinitPerThread()
807
808 def deinit(self):
809 """
810 For unitializing the manager.
811 Do not access it after calling this method.
812 """
813 if hasattr(self, "vbox"):
814 del self.vbox
815 self.vbox = None
816 if hasattr(self, "platform"):
817 self.platform.deinit()
818 self.platform = None
819 return True;
820
821
822 #
823 # Utility methods.
824 #
825
826 def openMachineSession(self, oIMachine, fPermitSharing = True):
827 """
828 Attemts to open the a session to the machine.
829 Returns a session object on success.
830 Raises exception on failure.
831 """
832 oSession = self.mgr.getSessionObject(self.vbox);
833 if fPermitSharing:
834 type = self.constants.LockType_Shared;
835 else:
836 type = self.constants.LockType_Write;
837 oIMachine.lockMachine(oSession, type);
838 return oSession;
839
840 def closeMachineSession(self, oSession):
841 """
842 Closes a session opened by openMachineSession.
843 Ignores None parameters.
844 """
845 if oSession is not None:
846 oSession.unlockMachine()
847 return True;
848
849 def getPerfCollector(self, oIVBox):
850 """
851 Returns a helper class (PerfCollector) for accessing performance
852 collector goodies. See PerfCollector for details.
853 """
854 return PerfCollector(self, oIVBox)
855
856 def getBinDir(self):
857 """
858 Returns the VirtualBox binary directory.
859 """
860 global VBoxBinDir
861 return VBoxBinDir
862
863 def getSdkDir(self):
864 """
865 Returns the VirtualBox SDK directory.
866 """
867 global VBoxSdkDir
868 return VBoxSdkDir
869
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette