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
6class ContentSettings(dict):
7
8  """A dict interface to interact with device content settings.
9
10  System properties are key/value pairs as exposed by adb shell content.
11  """
12
13  def __init__(self, table, device):
14    super(ContentSettings, self).__init__()
15    self._table = table
16    self._device = device
17
18  @staticmethod
19  def _GetTypeBinding(value):
20    if isinstance(value, bool):
21      return 'b'
22    if isinstance(value, float):
23      return 'f'
24    if isinstance(value, int):
25      return 'i'
26    if isinstance(value, long):
27      return 'l'
28    if isinstance(value, str):
29      return 's'
30    raise ValueError('Unsupported type %s' % type(value))
31
32  def iteritems(self):
33    # Example row:
34    # 'Row: 0 _id=13, name=logging_id2, value=-1fccbaa546705b05'
35    for row in self._device.RunShellCommand(
36        'content query --uri content://%s' % self._table, as_root=True):
37      fields = row.split(', ')
38      key = None
39      value = None
40      for field in fields:
41        k, _, v = field.partition('=')
42        if k == 'name':
43          key = v
44        elif k == 'value':
45          value = v
46      if not key:
47        continue
48      if not value:
49        value = ''
50      yield key, value
51
52  def __getitem__(self, key):
53    return self._device.RunShellCommand(
54        'content query --uri content://%s --where "name=\'%s\'" '
55        '--projection value' % (self._table, key), as_root=True).strip()
56
57  def __setitem__(self, key, value):
58    if key in self:
59      self._device.RunShellCommand(
60          'content update --uri content://%s '
61          '--bind value:%s:%s --where "name=\'%s\'"' % (
62              self._table,
63              self._GetTypeBinding(value), value, key),
64          as_root=True)
65    else:
66      self._device.RunShellCommand(
67          'content insert --uri content://%s '
68          '--bind name:%s:%s --bind value:%s:%s' % (
69              self._table,
70              self._GetTypeBinding(key), key,
71              self._GetTypeBinding(value), value),
72          as_root=True)
73
74  def __delitem__(self, key):
75    self._device.RunShellCommand(
76        'content delete --uri content://%s '
77        '--bind name:%s:%s' % (
78            self._table,
79            self._GetTypeBinding(key), key),
80        as_root=True)
81