1 # Clock Plugins 2 3 ## Introduction 4 5 The clock appearing on the lock screen and always on display (AOD) can be 6 customized via the ClockPlugin plugin interface. 7 8 ## System Health 9 10 Clocks are high risk for battery consumption and screen burn-in because they 11 modify the UI of AOD. 12 13 To reduce battery consumption, it is recommended to 14 target a maximum on-pixel-ratio (OPR) of 5%. Clocks that are composed of 15 large blocks of color that cause the OPR to exceed 5% should be avoided. 16 17 To prevent screen burn-in, clocks should not be composed of large solid 18 blocks of color, and the clock should be moved around the screen to 19 distribute the on pixels across a large number of pixels. Software 20 burn-in testing is a good starting point to assess the pixel shifting 21 (clock movement) scheme and shape of the clock. 22 23 ### Software Burn-In Test 24 25 The goal is to look for bright spots in the luminosity average over a period of 26 time. It is difficult to define a threshold where burn-in will occur. It is, 27 therefore, recommended to compare against an element on AOD that is known not 28 to cause problems. 29 30 For clock face that contain color, it is recommended to use an all white 31 version of the face. Since white has the highest luminosity, this version of 32 the clock face represents the worst case scenario. 33 34 To start, generate a sequence of screenshots for each minute over a 12 hr interval. 35 36 ``` 37 serial = '84TY004MS' # serial number for the device 38 count = 1 39 t = datetime.datetime(2019, 1, 1) 40 stop = t + datetime.timedelta(hours=12) 41 if not os.path.exists(OUTPUT_FOLDER): 42 raise RuntimeError('output folder "%s" does not exist' % OUTPUT_FOLDER) 43 while t <= stop: 44 os.system("adb -s %s shell 'date %s ; am broadcast -a android.intent.action.TIME_SET'" % (serial, t.strftime('%m%d%H%M%Y.%S'))) 45 os.system('adb -s %s shell screencap -p > %s/screencap_%06d.png' % (serial, OUTPUT_FOLDER, count)) 46 t += datetime.timedelta(minutes=1) 47 count += 1 48 ``` 49 50 Average the luminosity of the screenshots. 51 52 ``` 53 #!python 54 import numpy 55 import scipy.ndimage 56 from imageio import imread, imwrite 57 import matplotlib.pylab as plt 58 import os 59 import os.path 60 61 def images(path): 62 return [os.path.join(path, name) for name in os.listdir(path) if name.endswith('.png')] 63 64 def average(images): 65 AVG = None 66 for name in images: 67 IM = scipy.ndimage.imread(name, mode='L') 68 A = numpy.array(IM, dtype=numpy.double) 69 if AVG is None: 70 AVG = A 71 else: 72 AVG += A 73 AVG /= len(images) 74 return numpy.array(AVG, dtype=numpy.uint8) 75 76 def main(path): 77 ims = images(path) 78 if len(ims) == 0: 79 raise ValueError("folder '%s' doesn't contain any png files" % path) 80 AVG = average(ims) 81 imwrite('average.png', AVG) 82 plt.imshow(AVG) 83 plt.show() 84 85 if __name__=='__main__': 86 import sys 87 main(sys.argv[1]) 88 ``` 89 90 Look for bright spots in the luminosity average. If bright spots are found, 91 action should be taken to change the shape of the clock face or increase the 92 amount of pixel shifting. 93