1#!/usr/bin/env python3
2#
3#   Copyright 2019 - 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
17import collections
18
19TYPE_TO_FLAG = collections.defaultdict(lambda: '--es')
20TYPE_TO_FLAG.update({bool: '--ez', int: '--ei', float: '--ef', str: '--es'})
21
22
23class IntentBuilder(object):
24    """Helper class to build am broadcast <INTENT> commands."""
25
26    def __init__(self, base_cmd=''):
27        """Initializes the intent command builder.
28
29        Args:
30            base_cmd: The base am command, e.g. am broadcast, am start
31        """
32        self._base_cmd = base_cmd
33        self._action = None
34        self._component = None
35        self._data_uri = None
36        self._flags = []
37        self._key_value_params = collections.OrderedDict()
38
39    def set_action(self, action):
40        """Set the intent action, as marked by the -a flag"""
41        self._action = action
42
43    def set_component(self, package, component=None):
44        """Set the package and/or component, as marked by the -n flag.
45        Only the package name will be used if no component is specified.
46        """
47        if component:
48            self._component = '%s/%s' % (package, component)
49        else:
50            self._component = package
51
52    def set_data_uri(self, data_uri):
53        """Set the data URI, as marked by the -d flag"""
54        self._data_uri = data_uri
55
56    def add_flag(self, flag):
57        """Add any additional flags to the intent argument"""
58        self._flags.append(flag)
59
60    def add_key_value_param(self, key, value=None):
61        """Add any extra data as a key-value pair"""
62        self._key_value_params[key] = value
63
64    def build(self):
65        """Returns the full intent command string."""
66        cmd = [self._base_cmd]
67        if self._action:
68            cmd.append('-a %s' % self._action)
69        if self._component:
70            cmd.append('-n %s' % self._component)
71        if self._data_uri:
72            cmd.append('-d %s' % self._data_uri)
73        cmd += self._flags
74        for key, value in self._key_value_params.items():
75            if value is None:
76                cmd.append('--esn %s' % key)
77            else:
78                str_value = str(value)
79                if isinstance(value, bool):
80                    str_value = str_value.lower()
81                cmd.append(' '.join((TYPE_TO_FLAG[type(value)], key,
82                                     str_value)))
83        return ' '.join(cmd).strip()
84