diff --git a/packages/SystemUI/docs/clock-plugins.md b/packages/SystemUI/docs/clock-plugins.md new file mode 100644 index 0000000000000..5e4f6c79f47a1 --- /dev/null +++ b/packages/SystemUI/docs/clock-plugins.md @@ -0,0 +1,92 @@ +# Clock Plugins + +## Introduction + +The clock appearing on the lock screen and always on display (AOD) can be +customized via the ClockPlugin plugin interface. + +## System Health + +Clocks are high risk for battery consumption and screen burn-in because they +modify the UI of AOD. + +To reduce battery consumption, it is recommended to +target a maximum on-pixel-ratio (OPR) of 5%. Clocks that are composed of +large blocks of color that cause the OPR to exceed 5% should be avoided. + +To prevent screen burn-in, clocks should not be composed of large solid +blocks of color, and the clock should be moved around the screen to +distribute the on pixels across a large number of pixels. Software +burn-in testing is a good starting point to assess the pixel shifting +(clock movement) scheme and shape of the clock. + +### Software Burn-In Test + +The goal is to look for bright spots in the luminosity average over a period of +time. It is difficult to define a threshold where burn-in will occur. It is, +therefore, recommended to compare against an element on AOD that is known not +to cause problems. + +For clock face that contain color, it is recommended to use an all white +version of the face. Since white has the highest luminosity, this version of +the clock face represents the worst case scenario. + +To start, generate a sequence of screenshots for each minute over a 12 hr interval. + +``` +serial = '84TY004MS' # serial number for the device +count = 1 +t = datetime.datetime(2019, 1, 1) +stop = t + datetime.timedelta(hours=12) +if not os.path.exists(OUTPUT_FOLDER): + raise RuntimeError('output folder "%s" does not exist' % OUTPUT_FOLDER) +while t <= stop: + 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'))) + os.system('adb -s %s shell screencap -p > %s/screencap_%06d.png' % (serial, OUTPUT_FOLDER, count)) + t += datetime.timedelta(minutes=1) + count += 1 +``` + +Average the luminosity of the screenshots. + +``` +#!python +import numpy +import scipy.ndimage +from imageio import imread, imwrite +import matplotlib.pylab as plt +import os +import os.path + +def images(path): + return [os.path.join(path, name) for name in os.listdir(path) if name.endswith('.png')] + +def average(images): + AVG = None + for name in images: + IM = scipy.ndimage.imread(name, mode='L') + A = numpy.array(IM, dtype=numpy.double) + if AVG is None: + AVG = A + else: + AVG += A + AVG /= len(images) + return numpy.array(AVG, dtype=numpy.uint8) + +def main(path): + ims = images(path) + if len(ims) == 0: + raise ValueError("folder '%s' doesn't contain any png files" % path) + AVG = average(ims) + imwrite('average.png', AVG) + plt.imshow(AVG) + plt.show() + +if __name__=='__main__': + import sys + main(sys.argv[1]) +``` + +Look for bright spots in the luminosity average. If bright spots are found, +action should be taken to change the shape of the clock face or increase the +amount of pixel shifting.