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.