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