Implement haptics

Device manufacturers are generally considered the owners of the private assets created for each device. As such, their engineering efforts are often focused on a per-device basis; little to no effort goes to the consistency of other devices in the ecosystem.

In direct contrast, developers strive to build apps that work on all Android phones in the ecosystem, regardless of each device's technical specifications. This difference in approach can cause a fragmentation problem, for example, the hardware capabilities of certain phones don't match expectations set by the app developers. So if the haptics APIs work on some Android phones but not others, the result is an inconsistent ecosystem. This is why hardware configuration plays a critical role in ensuring that manufacturers can implement Android haptics APIs on every device.

This page provides a step-by-step checklist to set up hardware compliance for the best use of the Android haptics APIs.

The figure below illustrates building common knowledge between device manufacturers and developers, which is a critical step in creating a cohesive ecosystem.

Diagram of haptics use cases for app developers and device manufacturers

Figure 1. Building knowledge between device manufacturers and developers

Haptics implementation checklist

  1. Implement constants

    • List of constants to implement haptics.
  2. Map constants between HAL and API

  3. Assess the hardware

    • Instructions on target haptic effects. Use these instructions to perform quick checks on your hardware.

We'll explore each of these steps in greater detail below.

Step 1: Implement constants

Perform these checks to determine if your device meets the minimum requirements to implement haptics.

Flowchart of the haptics implementation process

Figure 2. Implementing effects

Flowchart of steps for implementing primitives

Figure 3. Implementing primitives

Check the implementation status of the following haptic constants.

Haptic constants Locations and summaries
EFFECT_TICK, EFFECT_CLICK, EFFECT_HEAVY_CLICK, EFFECT_DOUBLE_CLICK VibrationEffect class
Haptic constants in VibrationEffect don't include any notion of input events, and have no UI elements. Constants include the notion of energy levels instead, such as EFFECT_CLICK and EFFECT_HEAVY_CLICK, which are called by createPredefined().
PRIMITIVE_TICK, PRIMITIVE_CLICK, PRIMITIVE_LOW_TICK>, PRIMITIVE_SLOW_RISE, PRIMITIVE_QUICK_RISE, PRIMITIVE_QUICK_FALL, PRIMITIVE_SPIN, PRIMITIVE_THUD VibrationEffect.Composition class
Haptic constants in VibrationEffect.Composition are allowed to have scalable intensity, which are called by addPrimitive(int primitiveId, float scale, int delay).

The alternative vibrations described below are performed on devices that don't implement the VibrationEffect constants. Updating these configurations to perform best on such devices is recommended.

  1. EFFECT_CLICK

    Waveform vibration created with VibrationEffect.createWaveform and the timings configured at frameworks/base/core/res/res/values/config.xml##config_virtualKeyVibePattern.

  2. EFFECT_HEAVY_CLICK

    Waveform vibration created with VibrationEffect.createWaveform and the timings configured at frameworks/base/core/res/res/values/config.xml##config_longPressVibePattern.

  3. EFFECT_DOUBLE_CLICK

    Waveform vibration created with VibrationEffect.createWaveform and the timings (0, 30, 100, 30).

  4. EFFECT_TICK

    Waveform vibration created with VibrationEffect.createWaveform and the timings configured at frameworks/base/core/res/res/values/config.xml##config_clockTickVibePattern.

Flowchart of steps for testing haptic feedback

Figure 4. Implementing feedback constants

Check the status of the following public feedback constants.

Haptic constants Locations and summaries
CLOCK_TICK, CONTEXT_CLICK, KEYBOARD_PRESS, KEYBOARD_RELEASE, KEYBOARD_TAP, LONG_PRESS, TEXT_HANDLE_MOVE, VIRTUAL_KEY, VIRTUAL_KEY_RELEASE, CONFIRM, REJECT, GESTURE_START, GESTURE_END HapticFeedbackConstants class
Haptic constants in HapticFeedbackConstants assist input events with certain UI elements, such as KEYBOARD_PRESS and KEYBOARD_RELEASE, which are called by performHapticFeedback().

Step 2: Map constants between HAL and API

Step 2 presents recommended mappings between public HAL constants and API constants. If the hardware assessed in Step 1 does not implement the HAL constants, then Step 2 should be used to update the fallback patterns described in Step 1 in order to generate similar outputs. The mapping is assisted by two different default models.

  • Discrete model (simple)

    • Amplitude is the key variable of this model. Each entity in the HAL represents a different haptic amplitude.
    • This model is a minimum requirement needed to implement the basic haptic UX.
    • A more advanced haptic UX requires advanced hardware and an advanced model (continuous model).
  • Continuous model (advanced)

    • Texture and amplitude are the key variables of this model. Each entity in the HAL represents different haptic textures. The amplitude of each HAL entity is controlled by the scale factor (S).
    • This model requires advanced hardware. If OEMs want to use advanced haptic UX with VibrationEffect.Composition (for the best use of the latest haptics APIs), implementing their hardware using this model is recommended.

Discrete model

Mapping all public constants provided in the API with appropriate HAL constants is recommended. To begin this process, find out how many haptic waveforms with discrete amplitude the device can define in the HAL. A specific question structured around that notion looks like this: How many single-impulse haptic effects with human-perceptible amplitude differences can be defined in my phone? The answer to this question determines the mapping.

Defining HAL constants is a hardware-dependent process. For example, an entry-level phone might have only the hardware capabilities to produce a single haptic waveform. Devices with more advanced hardware components produce a wider range of discrete amplitude levels, and can define multiple haptic waveforms in the HAL. HAL-API constant mapping takes the HAL constant (using the medium amplitude as a baseline), then arranges stronger or weaker effects from there.

Diagram of HAL constant range and feedback amplitudes

Figure 5. HAL constant range by amplitude

When the number of HAL constants with discrete amplitude is defined, it's time to map HAL and API constants by the number of HAL constants. This mapping process can segment a single impulse API constant into up to three discrete groups of amplitude levels. The way that API constants are segmented is based on UX principles for accompanying input events. For more information, see Haptics UX design.

Discrete model for HAL-API constant mapping

Figure 6. HAL-API constant mapping: Discrete model

If your device supports only two HAL constants with discrete amplitudes, consider merging Medium and High amplitude level HAL constants. An example of this notion in practice would be mapping EFFECT_CLICK and EFFECT_HEAVY_CLICK to the same HAL constant, which would be the Medium amplitude level HAL constant. If your device supports only one HAL constant with discrete amplitude, consider merging all three levels into one.

Continuous model

The continuous model with amplitude scalability can be applied to define HAL constants. A scale factor (S) can be applied to the HAL constants (for example, HAL_H0, HAL_H1) to produce the scaled HAL (HAL_H0 x S). In this case, the scaled HAL is mapped to define API constants (HAL_H0 x S1 = H0S1 = EFFECT_TICK) as shown in figure 7. By using amplitude scalability of the continuous model, a device can store a small number of HAL constants with distinctive textures and add amplitude variations by adjusting the scale factor (S). Device manufacturers can define the number of HAL constants based on how many different haptic textures they want to provide.

HAL constant range by texture and amplitude

Figure 7. HAL constant range by texture (HAL_H0) and amplitude scale (S)

Continuous model for HAL-API constant mapping

Figure 8. HAL-API constant mapping: Continuous model

In the continuous model, different HAL constants represent different haptic textures rather than different amplitudes; the scale factor (S) can configure the amplitude. However, because the perception of the texture (for example, sharpness) is related to the perception of the duration and amplitude, combining the texture and the scale factor (in the design process of HAL-API mapping) is recommended.

Figure 7 illustrates constant mapping by increasing variation from one HAL to many API constants with amplitude scalability.

Increasing Varation 1

Increasing Varation 2

Figure 9. Increasing variation with amplitude scalability

For all scalable API constants such as PRIMITIVE_TICK and PRIMITIVE_CLICK in VibrationEffect.Composition, the energy level of the API constant depends on the float scale parameter when the API constant is declared through addPrimitive(int primitiveID, float scale, int delay). PRIMITIVE_TICK and PRIMITIVE_CLICK can be designed with a clear distinction by using different HAL constants. This approach is recommended if you want to add variation to texture.

Step 3: Assess the hardware

Hardware assessment involves defining three haptic effects, labeled Effects 1, 2, and 3 for this specific assessment.

Effect 1: Predefined short haptic constants

The VibrationEffect.EFFECT_CLICK constant is the baseline effect or common denominator in the HAL-API mapping provided in Step 2. It's mapped with the most used effect, HapticFeedbackConstants.KEYBOARD_PRESS. Assessing this effect helps determine the readiness of your target device for clear haptics.

Effect 2: Short custom haptic effect

The VibrationEffect.createOneShot(20,255) constant is for custom haptic effects. For short, single custom impulses, 20 ms is the recommended maximum threshold to define duration. A single impulse longer than 20 ms isn't recommended because it's perceived as a buzzy vibration.

Waveform of short custom haptic effect

Figure 10. Short custom haptic effect

Effect 3: Long custom haptic effect with amplitude variation

The VibrationEffect.createWaveform(timings[], amplitudes[], int repeat) constant is for long custom effects with amplitude variation. The ability to produce varying amplitudes for custom haptic effects is one of the indicators to evaluate the device's capabilities for rich haptics. The recommended timings [] and amplitudes [] are {500, 500} and {128, 255}, respectively, which presents an increasing trend of amplitude from 50% to 100%, with a 500 ms sampling rate.

Haptic effect waveform with amplitude variation

Figure 11. Long custom haptic effect with amplitude variation

To check the hardware capabilities of amplitude control for Effect 3, use the Vibrator.hasAmplitudeControl() method. The result has to be true to execute VibrationEffect.createWaveform with varying amplitude as intended.

Flowchart of subjective haptic effect assessment

Figure 12. Subject assessment of haptic effect 1, 2, and 3

Perform a subjective assessment

For a quick coherence check, perform a subjective assessment first. The goal of the subjective assessment is to observe the amplitude of the haptic effects to determine whether the device can generate haptics with human-perceptible amplitudes.

A specific question structured around this notion looks like this: Can the device produce easily perceptible haptic effects to the users as expected? Answering this question helps you avoid failed haptics, including imperceptible haptics that users can't feel, or unintended haptics where waveforms don't produce patterns as intended.