VirtualBox

Changeset 37617 in vbox


Ignore:
Timestamp:
Jun 23, 2011 3:57:30 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
72463
Message:

Main/USB/Linux: factor out the USBProxyService code for selecting the access method

Location:
trunk/src/VBox/Main
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/USBProxyService.h

    r37596 r37617  
    197197#  endif
    198198
     199#ifdef UNIT_TEST
     200void TestUSBSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible,
     201                      const char *pcszDevicesRoot, bool fDevicesAccessible,
     202                      int rcMethodInitResult);
     203void TestUSBSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot);
     204#endif
     205
    199206/**
    200207 * The Linux hosted USB Proxy Service.
     
    212219
    213220#  ifdef UNIT_TEST
    214     /* Functions for setting our unit test mock functions.  Not quite sure if
    215      * it is good form to mix test and production code like this, but it seems
    216      * cleaner to me than tying the unit test to implementation details of the
    217      * class. */
    218     /** Select which access methods will be available to the @a init method
    219      * during unit testing, and (hack!) what return code it will see from
    220      * the access method-specific initialisation. */
    221     void testSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible,
    222                        const char *pcszDevicesRoot, bool fDevicesAccessible,
    223                        int rcMethodInitResult)
    224     {
    225         mpcszTestUsbfsRoot = pcszUsbfsRoot;
    226         mfTestUsbfsAccessible = fUsbfsAccessible;
    227         mpcszTestDevicesRoot = pcszDevicesRoot;
    228         mfTestDevicesAccessible = fDevicesAccessible;
    229         mrcTestMethodInitResult = rcMethodInitResult;
    230     }
    231     /** Specify the environment that the @a init method will see during unit
    232      * testing. */
    233     void testSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot)
    234     {
    235         mpcszTestEnvUsb = pcszEnvUsb;
    236         mpcszTestEnvUsbRoot = pcszEnvUsbRoot;
    237     }
     221    /* Test getters for querying internal state.  This will go away. */
    238222    bool testGetUsingUsbfs(void) { return mUsingUsbfsDevices; }
    239223    const char *testGetDevicesRoot(void) { return mDevicesRoot.c_str(); }
     
    271255    VBoxMainHotplugWaiter *mpWaiter;
    272256#  endif
    273 #  ifdef UNIT_TEST
    274     /** The path we pretend the usbfs root is located at, or NULL. */
    275     const char *mpcszTestUsbfsRoot;
    276     /** Should usbfs be accessible to the current user? */
    277     bool mfTestUsbfsAccessible;
    278     /** The path we pretend the device node tree root is located at, or NULL. */
    279     const char *mpcszTestDevicesRoot;
    280     /** Should the device node tree be accessible to the current user? */
    281     bool mfTestDevicesAccessible;
    282     /** The result of the usbfs/inotify-specific init */
    283     int mrcTestMethodInitResult;
    284     /** The value of the VBOX_USB environment variable. */
    285     const char *mpcszTestEnvUsb;
    286     /** The value of the VBOX_USB_ROOT environment variable. */
    287     const char *mpcszTestEnvUsbRoot;
    288 #  endif
    289257};
    290258# endif /* RT_OS_LINUX */
  • trunk/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp

    r37599 r37617  
    6464      mhWakeupPipeW(NIL_RTPIPE), mUsingUsbfsDevices(true /* see init */),
    6565      mUdevPolls(0), mpWaiter(NULL)
     66{
     67    LogFlowThisFunc(("aHost=%p\n", aHost));
     68}
     69
    6670#ifdef UNIT_TEST
    67       , mpcszTestUsbfsRoot(NULL), mfTestUsbfsAccessible(false),
    68       mpcszTestDevicesRoot(NULL), mfTestDevicesAccessible(false),
    69       mrcTestMethodInitResult(VINF_SUCCESS), mpcszTestEnvUsb(NULL),
    70       mpcszTestEnvUsbRoot(NULL)
    71 #endif
    72 {
    73     LogFlowThisFunc(("aHost=%p\n", aHost));
    74 }
    75 
    76 #ifdef UNIT_TEST
     71#  ifdef UNIT_TEST
     72    /** The path we pretend the usbfs root is located at, or NULL. */
     73    const char *s_pcszTestUsbfsRoot;
     74    /** Should usbfs be accessible to the current user? */
     75    bool s_fTestUsbfsAccessible;
     76    /** The path we pretend the device node tree root is located at, or NULL. */
     77    const char *s_pcszTestDevicesRoot;
     78    /** Should the device node tree be accessible to the current user? */
     79    bool s_fTestDevicesAccessible;
     80    /** The result of the usbfs/inotify-specific init */
     81    int s_rcTestMethodInitResult;
     82    /** The value of the VBOX_USB environment variable. */
     83    const char *s_pcszTestEnvUsb;
     84    /** The value of the VBOX_USB_ROOT environment variable. */
     85    const char *s_pcszTestEnvUsbRoot;
     86#  endif
     87
     88/** Select which access methods will be available to the @a init method
     89 * during unit testing, and (hack!) what return code it will see from
     90 * the access method-specific initialisation. */
     91void TestUSBSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible,
     92                      const char *pcszDevicesRoot, bool fDevicesAccessible,
     93                      int rcMethodInitResult)
     94{
     95    s_pcszTestUsbfsRoot = pcszUsbfsRoot;
     96    s_fTestUsbfsAccessible = fUsbfsAccessible;
     97    s_pcszTestDevicesRoot = pcszDevicesRoot;
     98    s_fTestDevicesAccessible = fDevicesAccessible;
     99    s_rcTestMethodInitResult = rcMethodInitResult;
     100}
     101
     102/** Specify the environment that the @a init method will see during unit
     103 * testing. */
     104void TestUSBSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot)
     105{
     106    s_pcszTestEnvUsb = pcszEnvUsb;
     107    s_pcszTestEnvUsbRoot = pcszEnvUsbRoot;
     108}
     109
    77110/* For testing we redefine anything that accesses the outside world to
    78111 * return test values. */
    79112# define RTEnvGet(a) \
    80     (  !RTStrCmp(a, "VBOX_USB") ? mpcszTestEnvUsb \
    81      : !RTStrCmp(a, "VBOX_USB_ROOT") ? mpcszTestEnvUsbRoot \
     113    (  !RTStrCmp(a, "VBOX_USB") ? s_pcszTestEnvUsb \
     114     : !RTStrCmp(a, "VBOX_USB_ROOT") ? s_pcszTestEnvUsbRoot \
    82115     : NULL)
    83116# define USBProxyLinuxCheckDeviceRoot(pcszPath, fUseNodes) \
    84     (   ((fUseNodes) && mfTestDevicesAccessible \
    85                      && !RTStrCmp(pcszPath, mpcszTestDevicesRoot)) \
    86      || (!(fUseNodes) && mfTestUsbfsAccessible \
    87                       && !RTStrCmp(pcszPath, mpcszTestUsbfsRoot)))
     117    (   ((fUseNodes) && s_fTestDevicesAccessible \
     118                     && !RTStrCmp(pcszPath, s_pcszTestDevicesRoot)) \
     119     || (!(fUseNodes) && s_fTestUsbfsAccessible \
     120                      && !RTStrCmp(pcszPath, s_pcszTestUsbfsRoot)))
    88121# define RTDirExists(pcszDir) \
    89122    (   (pcszDir) \
    90      && (   !RTStrCmp(pcszDir, mpcszTestDevicesRoot) \
    91          || !RTStrCmp(pcszDir, mpcszTestUsbfsRoot)))
     123     && (   !RTStrCmp(pcszDir, s_pcszTestDevicesRoot) \
     124         || !RTStrCmp(pcszDir, s_pcszTestUsbfsRoot)))
    92125# define RTFileExists(pcszFile) \
    93126    (   (pcszFile) \
    94      && mpcszTestUsbfsRoot \
    95      && !RTStrNCmp(pcszFile, mpcszTestUsbfsRoot, strlen(mpcszTestUsbfsRoot)) \
    96      && !RTStrCmp(pcszFile + strlen(mpcszTestUsbfsRoot), "/devices"))
     127     && s_pcszTestUsbfsRoot \
     128     && !RTStrNCmp(pcszFile, s_pcszTestUsbfsRoot, strlen(s_pcszTestUsbfsRoot)) \
     129     && !RTStrCmp(pcszFile + strlen(s_pcszTestUsbfsRoot), "/devices"))
    97130#endif
    98131
    99132/**
    100  * Initializes the object (called right after construction).
    101  *
    102  * @returns S_OK on success and non-fatal failures, some COM error otherwise.
    103  */
    104 HRESULT USBProxyServiceLinux::init(void)
     133 * Selects the access method that will be used to access USB devices based on
     134 * what is available on the host and what if anything the user has specified
     135 * in the environment.
     136 * @returns iprt status value
     137 * @param  pfUsingUsbfsDevices  on success this will be set to true if
     138 *                              the prefered access method is USBFS-like and to
     139 *                              false if it is sysfs/device node-like
     140 * @param  ppcszDevicesRoot     on success the root of the tree of USBFS-like
     141 *                              device nodes will be stored here
     142 */
     143int USBProxyLinuxChooseMethod(bool *pfUsingUsbfsDevices,
     144                              const char **ppcszDevicesRoot)
    105145{
    106146    /*
     
    160200    if (pcszUsbRoot)
    161201    {
    162         mUsingUsbfsDevices = fUsbfsChosen;
    163         mDevicesRoot = pcszUsbRoot;
     202        *pfUsingUsbfsDevices = fUsbfsChosen;
     203        *ppcszDevicesRoot = pcszUsbRoot;
     204        return VINF_SUCCESS;
     205    }
     206    /* else */
     207    return   pcszUsbFromEnv ? VERR_NOT_FOUND
     208           : RTDirExists("/dev/vboxusb") ? VERR_VUSB_USB_DEVICE_PERMISSION
     209           : RTFileExists("/proc/bus/usb/devices") ? VERR_VUSB_USBFS_PERMISSION
     210           : VERR_NOT_FOUND;
     211}
     212
     213/**
     214 * Initializes the object (called right after construction).
     215 *
     216 * @returns S_OK on success and non-fatal failures, some COM error otherwise.
     217 */
     218HRESULT USBProxyServiceLinux::init(void)
     219{
     220    const char *pcszDevicesRoot;
     221    int rc = USBProxyLinuxChooseMethod(&mUsingUsbfsDevices, &pcszDevicesRoot);
     222    if (RT_SUCCESS(rc))
     223    {
     224        mDevicesRoot = pcszDevicesRoot;
    164225#ifndef UNIT_TEST /* Hack for now */
    165         int rc = mUsingUsbfsDevices ? initUsbfs() : initSysfs();
     226        rc = mUsingUsbfsDevices ? initUsbfs() : initSysfs();
    166227#else
    167         int rc = mrcTestMethodInitResult;
     228        rc = s_rcTestMethodInitResult;
    168229#endif
    169230        /* For the day when we have VBoxSVC release logging... */
     
    171232                               : "Failed to initialise host USB using %s\n",
    172233                mUsingUsbfsDevices ? "USBFS" : "sysfs"));
    173         mLastError = rc;
    174     }
    175     else
    176         mLastError =   pcszUsbFromEnv ? VERR_NOT_FOUND
    177                      : RTDirExists("/dev/vboxusb") ? VERR_VUSB_USB_DEVICE_PERMISSION
    178                      : RTFileExists("/proc/bus/usb/devices") ? VERR_VUSB_USBFS_PERMISSION
    179                      : VERR_NOT_FOUND;
     234    }
     235    mLastError = rc;
    180236    return S_OK;
    181237}
  • trunk/src/VBox/Main/testcase/tstUSBProxyLinux.cpp

    r37423 r37617  
    134134    {
    135135        USBProxyServiceLinux test(NULL);
    136         test.testSetEnv(s_testEnvironment[i].pcszEnvUsb,
     136        TestUSBSetEnv(s_testEnvironment[i].pcszEnvUsb,
    137137                        s_testEnvironment[i].pcszEnvUsbRoot);
    138         test.testSetupInit(s_testEnvironment[i].pcszUsbfsRoot,
     138        TestUSBSetupInit(s_testEnvironment[i].pcszUsbfsRoot,
    139139                           s_testEnvironment[i].fUsbfsAccessible,
    140140                           s_testEnvironment[i].pcszDevicesRoot,
Note: See TracChangeset for help on using the changeset viewer.

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