1# Copyright 2014 The Chromium 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"""Manages intents and associated information.
5
6This is generally intended to be used with functions that calls Android's
7Am command.
8"""
9
10# Some common flag constants that can be used to construct intents.
11# Full list: http://developer.android.com/reference/android/content/Intent.html
12FLAG_ACTIVITY_CLEAR_TASK = 0x00008000
13FLAG_ACTIVITY_CLEAR_TOP = 0x04000000
14FLAG_ACTIVITY_NEW_TASK = 0x10000000
15FLAG_ACTIVITY_REORDER_TO_FRONT = 0x00020000
16FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 0x00200000
17
18
19def _bitwise_or(flags):
20  result = 0
21  for flag in flags:
22    result |= flag
23  return result
24
25
26class Intent(object):
27  def __init__(self,
28               action='android.intent.action.VIEW',
29               activity=None,
30               category=None,
31               component=None,
32               data=None,
33               extras=None,
34               flags=None,
35               package=None):
36    """Creates an Intent.
37
38    Args:
39      action: A string containing the action.
40      activity: A string that, with |package|, can be used to specify the
41                component.
42      category: A string or list containing any categories.
43      component: A string that specifies the component to send the intent to.
44      data: A string containing a data URI.
45      extras: A dict containing extra parameters to be passed along with the
46              intent.
47      flags: A sequence of flag constants to be passed with the intent.
48      package: A string that, with activity, can be used to specify the
49               component.
50    """
51    self._action = action
52    self._activity = activity
53    if isinstance(category, list) or category is None:
54      self._category = category
55    else:
56      self._category = [category]
57    self._component = component
58    self._data = data
59    self._extras = extras
60    self._flags = '0x%0.8x' % _bitwise_or(flags) if flags else None
61    self._package = package
62
63    if self._component and '/' in component:
64      self._package, self._activity = component.split('/', 1)
65    elif self._package and self._activity:
66      self._component = '%s/%s' % (package, activity)
67
68  @property
69  def action(self):
70    return self._action
71
72  @property
73  def activity(self):
74    return self._activity
75
76  @property
77  def category(self):
78    return self._category
79
80  @property
81  def component(self):
82    return self._component
83
84  @property
85  def data(self):
86    return self._data
87
88  @property
89  def extras(self):
90    return self._extras
91
92  @property
93  def flags(self):
94    return self._flags
95
96  @property
97  def package(self):
98    return self._package
99
100  @property
101  def am_args(self):
102    """Returns the intent as a list of arguments for the activity manager.
103
104    For details refer to the specification at:
105    - http://developer.android.com/tools/help/adb.html#IntentSpec
106    """
107    args = []
108    if self.action:
109      args.extend(['-a', self.action])
110    if self.data:
111      args.extend(['-d', self.data])
112    if self.category:
113      args.extend(arg for cat in self.category for arg in ('-c', cat))
114    if self.component:
115      args.extend(['-n', self.component])
116    if self.flags:
117      args.extend(['-f', self.flags])
118    if self.extras:
119      for key, value in self.extras.items():
120        if value is None:
121          args.extend(['--esn', key])
122        elif isinstance(value, str):
123          args.extend(['--es', key, value])
124        elif isinstance(value, bool):
125          args.extend(['--ez', key, str(value)])
126        elif isinstance(value, int):
127          args.extend(['--ei', key, str(value)])
128        elif isinstance(value, float):
129          args.extend(['--ef', key, str(value)])
130        else:
131          raise NotImplementedError(
132              'Intent does not know how to pass %s extras' % type(value))
133    return args
134