# Clock Plugins

The clock appearing on the lock screen and always on display (AOD) can be customized via the
ClockProviderPlugin plugin interface. The ClockPlugin interface has been removed.

## Lock screen integration
The lockscreen code has two main components, a [clock customization library](../customization), and
the SystemUI [lockscreen host code](../src/com/android/keyguard). The customization library contains
the default clock, and some support code for managing clocks and picking the correct one to render.
It is used by both SystemUI for rendering and ThemePicker for selecting clocks. The SystemUI host is
responsible for maintaining the view within the hierarchy and propagating events to the rendered
clock controller.

### Clock Library Code
[ClockProvider and ClockController](../plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt)
serve as the interface between the lockscreen (or other host application) and the clock that is
being rendered. Implementing these interfaces is the primary integration point for rendering clocks
in SystemUI. Many of the methods have an empty default implementation and are optional for
implementations if the related event is not interesting to your use case.

[DefaultClockProvider](../customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt) and
[DefaultClockController](../customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt)
implement these interfaces for the default lockscreen clock. They handle relevant events from the
lockscreen to update and control the small and large clock view as appropriate.
[AnimatableClockView](../customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt)
is the view that DefaultClockController uses to render both the small and large clock.
AnimatableClockView has moved location within the repo, but is largely unchanged from previous
versions of android.

The [ClockRegistry](../customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt)
determines which clock should be shown, and handles creating them. It does this by maintaining a
list of [ClockProviders](../plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt) and
delegating work to them as appropriate. The DefaultClockProvider is compiled in so that it is
guaranteed to be available, and additional ClockProviders are loaded at runtime via
[PluginManager](../plugin_core/src/com/android/systemui/plugins/PluginManager.java).

[ClockPlugin](../plugin/src/com/android/systemui/plugins/clocks/ClockPlugin.java) is deprecated and no
longer used by keyguard to render clocks. The host code has been disabled but most of it is still
present in the source tree, although it will likely be removed in a later patch.

### Lockscreen Host
[ClockEventController](../src/com/android/keyguard/ClockEventController.kt) propagates events from
SystemUI event dispatchers to the clock controllers. It maintains a set of event listeners, but
otherwise attempts to do as little work as possible. It does maintain some state where necessary.

[KeyguardClockSwitchController](../src/com/android/keyguard/KeyguardClockSwitchController.java) is
the primary controller for the [KeyguardClockSwitch](../src/com/android/keyguard/KeyguardClockSwitch.java),
which serves as the view parent within SystemUI. Together they ensure the correct clock (either
large or small) is shown, handle animation between clock sizes, and control some sizing/layout
parameters for the clocks.

### Creating a custom clock
In order to create a custom clock, a partner must:
 - Write an implementation of ClockProviderPlugin and the subinterfaces relevant to your use-case.
 - Build this into a seperate plugin apk, and deploy that apk to the device.
    - Alternatively, it could be compiled directly into the customization lib like DefaultClockProvider.
 - PluginManager should automatically notify ClockRegistry of your plugin apk when it arrives on
      device. ClockRegistry will print info logs when it successfully loads a plugin.
 - Set the clock either in ThemePicker or through adb:
      `adb shell settings put secure lock_screen_custom_clock_face '''{\"clockId\":\"ID\"}'''`
 - SystemUI should immediately load and render the new clock if it is available.

### Picker integration
Picker logic for choosing between clocks is available to our partners as part of the ThemePicker.
The clock picking UI will be enabled by default if there is more than 1 clock provided, otherwise
it will be hidden from the UI.

## 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 10%.
Clocks that are composed of large blocks of color that cause the OPR to exceed 10% should be
avoided, but this target will differ depending on the device hardware.

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. SystemUI currently treats all clocks the same in this regard using
[KeyguardClockPositionAlgorithm](../src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java)

### 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.
