You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.9 KiB
93 lines
2.9 KiB
7 months ago
|
# 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.
|