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