• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2015 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import dbus
6import dbus.service
7import logging
8import time
9
10from autotest_lib.client.cros.tendo import peerd_dbus_helper
11from autotest_lib.client.cros.tendo.n_faced_peerd import dbus_property_exposer
12from autotest_lib.client.cros.tendo.n_faced_peerd import service
13
14
15class Peer(dbus_property_exposer.DBusPropertyExposer):
16    """Represents local and remote peers."""
17
18    def __init__(self, bus, path, peer_id, object_manager, is_self=False):
19        """Construct a org.chromium.peerd.Peer DBus object.
20
21        @param bus: dbus.Bus object to export this object on.
22        @param path: string object path to export this object at.
23        @param peer_id: string peerd peer ID; a UUID.
24        @param is_self: True iff this object will servce as a self peer.
25        @param object_manager: an instance of ObjectManager.
26
27        """
28        super(Peer, self).__init__(
29                bus, path, peerd_dbus_helper.DBUS_INTERFACE_PEER)
30        # Fill in the initial values for our properties.
31        self.uuid = peer_id
32        self._is_self = is_self
33        self._update_last_seen()
34        # Register properties with the property exposer.
35        self.register_property(peerd_dbus_helper.PEER_PROPERTY_ID,
36                               self._get_dbus_id)
37        self.register_property(peerd_dbus_helper.PEER_PROPERTY_LAST_SEEN,
38                               self._get_dbus_last_seen)
39        # Claim our interace with the object manager.
40        self._object_manager = object_manager
41        self._path = path
42        self._object_manager.claim_interface(
43                path, peerd_dbus_helper.DBUS_INTERFACE_PEER,
44                self.property_getter)
45        # We need to keep a good bit of stuff around because we're responsible
46        # for creating child service objects.
47        self._bus = bus
48        self.services = dict()
49        self._services_counter = 0
50
51
52    def _get_dbus_id(self):
53        """Getter for PEER_PROPERTY_ID.
54
55        @return dbus.String containing our peer ID.
56
57        """
58        return dbus.String(self.uuid)
59
60
61    def _get_dbus_last_seen(self):
62        """Getter for PEER_PROPERTY_LAST_SEEN.
63
64        @return dbus.UInt64 containing the last time this peer was seen
65                in milliseconds since the Unix epoc.
66
67        """
68        return dbus.UInt64(int(1000 * self._last_seen_seconds))
69
70
71    def _update_last_seen(self):
72        """Updates our last seen value.
73
74        This would be a simple call to time.time(), except that peerd
75        has to report a last seen time of 0 for the peer object representing
76        itself.
77
78        """
79        if self._is_self:
80            self._last_seen_seconds = 0
81        else:
82            self._last_seen_seconds = time.time()
83
84
85    def close(self):
86        """Releases interfaces claimed over DBus."""
87        # TODO(wiley) call close on child services.
88        raise NotImplementedError('Peer.close() does not work properly')
89
90
91    def update_service(self, service_id, service_info, ip_info):
92        """Update a service associated with this peer.
93
94        @param service_id: string peerd service ID.
95        @param service_info: dictionary of string,string items comprising
96                the metadata for the service.
97        @param ip_info: an instance of IpInfo defined in service.py.
98
99        """
100        if service_id in self.services:
101            self.services[service_id].update(service_info, ip_info)
102        else:
103            self._services_counter += 1
104            service_path = '%s/services/%d' % (self._path,
105                                               self._services_counter)
106            self.services[service_id] = service.Service(
107                    self._bus, service_path, self.uuid, service_id,
108                    service_info, ip_info, self._object_manager)
109        logging.info('service=%s has info %r.', service_id, service_info)
110        self._update_last_seen()
111        self.on_property_changed(peerd_dbus_helper.PEER_PROPERTY_LAST_SEEN)
112
113
114    def remove_service(self, service_id):
115        """Remove a service associated with this peer.
116
117        @param service_id: string peerd service ID.
118
119        """
120        removed_service = self.services.pop(service_id, None)
121        if removed_service is not None:
122            removed_service.close()
123        self._update_last_seen()
124        self.on_property_changed(peerd_dbus_helper.PEER_PROPERTY_LAST_SEEN)
125