1#
2# Copyright (C) 2016 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17import logging
18
19from google.protobuf import text_format
20
21from vts.runners.host import errors
22from vts.proto import AndroidSystemControlMessage_pb2 as ASysCtrlMsg
23from vts.proto import ComponentSpecificationMessage_pb2 as CompSpecMsg
24from vts.utils.python.mirror import native_entity_mirror
25
26
27class LibMirror(native_entity_mirror.NativeEntityMirror):
28    """The class that acts as the mirror to an Android device's Lib layer.
29
30    This class holds and manages the life cycle of multiple mirror objects that
31    map to different lib components.
32
33    One can use this class to create and destroy a lib mirror object.
34    """
35
36    def InitLibDriver(self, target_type, target_version_major,
37                      target_version_minor, target_package, target_filename,
38                      target_basepaths, handler_name, bits):
39        """Initiates the driver for a lib on the target device and loads
40        the interface specification message.
41
42        Args:
43            target_type: string, the target type name (e.g., light, camera).
44            target_version_major:
45              int, the target component major version (e.g. 1.0 -> 1).
46            target_version_minor:
47              int, the target component minor version (e.g. 1.0 -> 0).
48            target_package: . separated string (e.g., a.b.c) to denote the
49                            package name of target component.
50            target_filename: string, the target file name (e.g., libm.so).
51            target_basepaths: list of strings, the paths to look for target
52                             files in.
53            handler_name: string, the name of the handler. target_type is used
54                          by default.
55            bits: integer, processor architecture indicator: 32 or 64.
56        """
57        # Get all the libs available on the target.
58        lib_list = self._client.ListHals(target_basepaths)
59        if not lib_list:
60            raise errors.ComponentLoadingError(
61                "Could not find any lib under path %s" % target_basepaths)
62        logging.debug(lib_list)
63
64        # Find the corresponding filename for Lib target type.
65        if target_filename is not None:
66            for name in lib_list:
67                if name.endswith(target_filename):
68                    target_filename = name
69                    break
70        else:
71            for name in lib_list:
72                if target_type in name:
73                    # TODO: check more exactly (e.g., multiple hits).
74                    target_filename = name
75
76        if not target_filename:
77            raise errors.ComponentLoadingError(
78                "No file found for target type %s." % target_type)
79
80        driver_id = self.LaunchMirrorDriver(
81            ASysCtrlMsg.VTS_DRIVER_TYPE_HAL_CONVENTIONAL,
82            "lib_shared",
83            target_type,
84            target_version_major,
85            target_version_minor,
86            target_package=target_package,
87            target_filename=target_filename,
88            handler_name=handler_name,
89            bits=bits)
90
91        self._driver_id = driver_id
92
93        #TODO: ListApis assumes only one lib is loaded at a time, need to
94        #      figure out a way to get the api_spec when we want to test
95        #      multiple libs together.
96        found_api_spec = self._client.ListApis()
97        if not found_api_spec:
98            raise errors.ComponentLoadingError(
99                "No API found for %s" % target_type)
100        if_spec_msg = CompSpecMsg.ComponentSpecificationMessage()
101        text_format.Merge(found_api_spec, if_spec_msg)
102
103        self._if_spec_msg = if_spec_msg
104