Home | History | Annotate | Download | only in pylib
      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 
      6 class 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     sdk_version_string = device.GetProp('ro.build.version.sdk')
     16     try:
     17       sdk_version = int(sdk_version_string)
     18       assert sdk_version >= 16, (
     19           'ContentSettings supported only on SDK 16 and later')
     20     except ValueError:
     21       assert False, ('Unknown SDK version %s' % sdk_version_string)
     22     self._table = table
     23     self._device = device
     24 
     25   @staticmethod
     26   def _GetTypeBinding(value):
     27     if isinstance(value, bool):
     28       return 'b'
     29     if isinstance(value, float):
     30       return 'f'
     31     if isinstance(value, int):
     32       return 'i'
     33     if isinstance(value, long):
     34       return 'l'
     35     if isinstance(value, str):
     36       return 's'
     37     raise ValueError('Unsupported type %s' % type(value))
     38 
     39   def iteritems(self):
     40     # Example row:
     41     # 'Row: 0 _id=13, name=logging_id2, value=-1fccbaa546705b05'
     42     for row in self._device.RunShellCommand(
     43         'content query --uri content://%s' % self._table, as_root=True):
     44       fields = row.split(', ')
     45       key = None
     46       value = None
     47       for field in fields:
     48         k, _, v = field.partition('=')
     49         if k == 'name':
     50           key = v
     51         elif k == 'value':
     52           value = v
     53       if not key:
     54         continue
     55       if not value:
     56         value = ''
     57       yield key, value
     58 
     59   def __getitem__(self, key):
     60     return self._device.RunShellCommand(
     61         'content query --uri content://%s --where "name=\'%s\'" '
     62         '--projection value' % (self._table, key), as_root=True).strip()
     63 
     64   def __setitem__(self, key, value):
     65     if key in self:
     66       self._device.RunShellCommand(
     67           'content update --uri content://%s '
     68           '--bind value:%s:%s --where "name=\'%s\'"' % (
     69               self._table,
     70               self._GetTypeBinding(value), value, key),
     71           as_root=True)
     72     else:
     73       self._device.RunShellCommand(
     74           'content insert --uri content://%s '
     75           '--bind name:%s:%s --bind value:%s:%s' % (
     76               self._table,
     77               self._GetTypeBinding(key), key,
     78               self._GetTypeBinding(value), value),
     79           as_root=True)
     80 
     81   def __delitem__(self, key):
     82     self._device.RunShellCommand(
     83         'content delete --uri content://%s '
     84         '--bind name:%s:%s' % (
     85             self._table,
     86             self._GetTypeBinding(key), key),
     87         as_root=True)
     88