1#!/usr/bin/env python3
2#
3#   Copyright 2018 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17
18from acts.controllers.android_lib import errors
19from acts.controllers.android_lib import events as android_events
20from acts.event import event_bus
21
22
23class AndroidService(object):
24    """The base class for Android long-running services.
25
26    The _start method is registered to an AndroidStartServicesEvent, and
27    the _stop method is registered to an AndroidStopServicesEvent.
28
29    Attributes:
30        ad: The AndroidDevice instance associated with the service.
31        serial: The serial of the device.
32        _registration_ids: List of registration IDs for the event subscriptions.
33    """
34
35    def __init__(self, ad):
36        self.ad = ad
37        self._registration_ids = []
38
39    @property
40    def serial(self):
41        return self.ad.serial
42
43    def register(self):
44        """Registers the _start and _stop methods to their corresponding
45        events.
46        """
47        def check_serial(event):
48            return self.serial == event.ad.serial
49
50        self._registration_ids = [
51            event_bus.register(android_events.AndroidStartServicesEvent,
52                               self._start, filter_fn=check_serial),
53            event_bus.register(android_events.AndroidStopServicesEvent,
54                               self._stop, filter_fn=check_serial)]
55
56    def unregister(self):
57        """Unregisters all subscriptions in this service."""
58        event_bus.unregister_all(from_list=self._registration_ids)
59        self._registration_ids.clear()
60
61    def _start(self, start_event):
62        """Start the service. Called upon an AndroidStartServicesEvent.
63
64        Args:
65            start_event: The AndroidStartServicesEvent instance.
66        """
67        raise NotImplementedError
68
69    def _stop(self, stop_event):
70        """Stop the service. Called upon an AndroidStopServicesEvent.
71
72        Args:
73            stop_event: The AndroidStopServicesEvent instance.
74        """
75        raise NotImplementedError
76
77
78class AdbLogcatService(AndroidService):
79    """Service for adb logcat."""
80
81    def _start(self, _):
82        self.ad.start_adb_logcat()
83
84    def _stop(self, _):
85        self.ad.stop_adb_logcat()
86
87
88class Sl4aService(AndroidService):
89    """Service for SL4A."""
90
91    def _start(self, start_event):
92        if self.ad.skip_sl4a:
93            return
94
95        if not self.ad.is_sl4a_installed():
96            self.ad.log.error('sl4a.apk is not installed')
97            raise errors.AndroidDeviceError(
98                'The required sl4a.apk is not installed',
99                serial=self.serial)
100        if not self.ad.ensure_screen_on():
101            self.ad.log.error("User window cannot come up")
102            raise errors.AndroidDeviceError(
103                "User window cannot come up", serial=self.serial)
104
105        droid, ed = self.ad.get_droid()
106        ed.start()
107
108    def _stop(self, _):
109        self.ad.terminate_all_sessions()
110        self.ad._sl4a_manager.stop_service()
111        self.ad.stop_sl4a()
112