Add doc for system health guidelines for AOD clock faces.
Bug: 129775476 Test: none Change-Id: I3b5eb9524a076669cc15278f80d9fc8c81b5340a
This commit is contained in:
92
packages/SystemUI/docs/clock-plugins.md
Normal file
92
packages/SystemUI/docs/clock-plugins.md
Normal file
@@ -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.
|
||||
Reference in New Issue
Block a user