blob: f796d5014486eb011bf39b6fc2827267a31a679c [file] [log] [blame]
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
from cros.factory.probe import function
from cros.factory.probe.lib import cached_probe_function
def _ProbePCIOrUSB(path):
path = os.path.abspath(os.path.realpath(path))
return (function.InterpretFunction({'pci': path})() or
function.InterpretFunction({'usb': os.path.join(path, '..')})())
def _RecursiveProbe(path, read_method):
"""Recursively probes in path and all the subdirectory using read_method.
Args:
path: Root path of the recursive probing.
read_method: The method used to probe device information.
This method accepts an input path and returns a string.
e.g. _ReadSysfsUsbFields, _ReadSysfsPciFields, or _ReadSysfsDeviceId.
Returns:
A list of strings which contains probed results under path and
all the subdirectory of path. Duplicated data will be omitted.
"""
def _InternalRecursiveProbe(path, visited_path, results, read_method):
"""Recursively probes in path and all the subdirectory using read_method.
Args:
path: Root path of the recursive probing.
visited_path: A set containing visited paths. These paths will not
be visited again.
results: A list of string which contains probed results.
This list will be appended through the recursive probing.
read_method: The method used to probe device information.
This method accepts an input path and returns a string.
Returns:
No return value. results in the input will be appended with probed
information. Duplicated data will be omitted.
"""
path = os.path.realpath(path)
if path in visited_path:
return
if os.path.isdir(path):
data = read_method(path)
# Only append new data
for result in data:
if result not in results:
results.append(result)
entries_list = os.listdir(path)
visited_path.add(path)
else:
return
for filename in entries_list:
# Do not search directory upward
if filename == 'subsystem':
continue
sub_path = os.path.join(path, filename)
_InternalRecursiveProbe(sub_path, visited_path, results, read_method)
return
visited_path = set()
results = []
_InternalRecursiveProbe(path, visited_path, results, read_method)
return results
class GenericBluetoothFunction(cached_probe_function.CachedProbeFunction):
"""Probe the generic Bluetooth information."""
def GetCategoryFromArgs(self):
return None
@classmethod
def ProbeAllDevices(cls):
# Probe in primary path
device_id = _ProbePCIOrUSB('/sys/class/bluetooth/hci0/device')
if device_id:
return device_id
# TODO(akahuang): Confirm if we only probe the primary path or not.
# Use information in driver if probe failed in primary path
device_id_list = _RecursiveProbe('/sys/module/bluetooth/holders',
_ProbePCIOrUSB)
return sorted([x for x in device_id_list if x])