Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 138f28b6 authored by Yeabkal Wubshit's avatar Yeabkal Wubshit
Browse files

Introduce haptic vibration customization for USAGE_GESTURE_INPUT

This change introduces a logic to allow devices to customize the
VibrationEffect used for haptic feedback requests made with a specific
usage, and implements the concrete customization file/flows for
USAGE_GESTURE_INPUT.

Bug: 397602072
Bug: 408393305
Test: atest com.android.server.vibrator
Flag: android.os.vibrator.haptic_feedback_with_custom_usage
Change-Id: I72775ec4b39ee629e7da53d294cf0c3799ddf2f9
parent 6ab21e52
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5917,6 +5917,7 @@
  <java-symbol type="xml" name="haptic_feedback_customization" />
  <java-symbol type="xml" name="haptic_feedback_customization_source_rotary_encoder" />
  <java-symbol type="xml" name="haptic_feedback_customization_source_touchscreen" />
  <java-symbol type="xml" name="haptic_feedback_customization_usage_gesture_input" />

  <!-- For ActivityManager PSS profiling configurability -->
  <java-symbol type="bool" name="config_am_disablePssProfiling" />
+18 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2025 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<haptic-feedback-constants/>
+27 −3
Original line number Diff line number Diff line
@@ -16,10 +16,13 @@

package com.android.server.vibrator;

import static android.os.VibrationAttributes.USAGE_GESTURE_INPUT;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.os.VibrationAttributes;
import android.os.VibrationEffect;
import android.os.VibratorInfo;
import android.os.vibrator.Flags;
@@ -118,6 +121,9 @@ final class HapticFeedbackCustomization {
    @NonNull
    private final SparseArray<VibrationEffect> mHapticCustomizationsForSourceTouchScreen;

    @NonNull
    private final SparseArray<VibrationEffect> mHapticCustomizationsForUsageGestureInput;

    HapticFeedbackCustomization(Resources res, VibratorInfo vibratorInfo) {
        // Load base customizations.
        SparseArray<VibrationEffect> hapticCustomizations;
@@ -142,20 +148,38 @@ final class HapticFeedbackCustomization {
            mHapticCustomizationsForSourceRotary = new SparseArray<>();
            mHapticCustomizationsForSourceTouchScreen = new SparseArray<>();
        }

        // Load customizations specified for usages.
        if (android.os.vibrator.Flags.hapticFeedbackWithCustomUsage()) {
            mHapticCustomizationsForUsageGestureInput =
                    loadCustomizedFeedbackVibrationFromRes(res, vibratorInfo,
                            R.xml.haptic_feedback_customization_usage_gesture_input);
        } else {
            mHapticCustomizationsForUsageGestureInput = new SparseArray<>();
        }
    }

    @VisibleForTesting
    HapticFeedbackCustomization(@NonNull SparseArray<VibrationEffect> hapticCustomizations,
            @NonNull SparseArray<VibrationEffect> hapticCustomizationsForSourceRotary,
            @NonNull SparseArray<VibrationEffect> hapticCustomizationsForSourceTouchScreen) {
            @NonNull SparseArray<VibrationEffect> hapticCustomizationsForSourceTouchScreen,
            @NonNull SparseArray<VibrationEffect> hapticCustomizationsForUsageGestureInput) {
        mHapticCustomizations = hapticCustomizations;
        mHapticCustomizationsForSourceRotary = hapticCustomizationsForSourceRotary;
        mHapticCustomizationsForSourceTouchScreen = hapticCustomizationsForSourceTouchScreen;
        mHapticCustomizationsForUsageGestureInput = hapticCustomizationsForUsageGestureInput;
    }

    @Nullable
    VibrationEffect getEffect(int effectId) {
        return mHapticCustomizations.get(effectId);
    VibrationEffect getEffect(int effectId, @VibrationAttributes.Usage int usage) {
        VibrationEffect resultVibration = null;
        if (usage == USAGE_GESTURE_INPUT) {
            resultVibration = mHapticCustomizationsForUsageGestureInput.get(effectId);
        }
        if (resultVibration == null) {
            resultVibration = mHapticCustomizations.get(effectId);
        }
        return resultVibration;
    }

    @Nullable
+6 −3
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ public final class HapticFeedbackVibrationProvider {
        mHapticFeedbackCustomization = hapticFeedbackCustomization;

        VibrationEffect safeModeVibration = mHapticFeedbackCustomization.getEffect(
                HapticFeedbackConstants.SAFE_MODE_ENABLED);
                HapticFeedbackConstants.SAFE_MODE_ENABLED, VibrationAttributes.USAGE_UNKNOWN);
        mSafeModeEnabledVibrationEffect = safeModeVibration != null ? safeModeVibration
                : VibrationSettings.createEffectFromResource(res,
                        com.android.internal.R.array.config_safeModeEnabledVibePattern);
@@ -87,14 +87,17 @@ public final class HapticFeedbackVibrationProvider {
     * {@link HapticFeedbackConstants}).
     *
     * @param effectId the haptic feedback effect ID whose respective vibration we want to get.
     * @param usage the {@link VibrationAttributes} usage for the haptic feedback.
     * @return a {@link VibrationEffect} for the given haptic feedback effect ID, or {@code null} if
     *          the provided effect ID is not supported.
     */
    @Nullable public VibrationEffect getVibration(int effectId) {
    @Nullable public VibrationEffect getVibration(
            int effectId, @VibrationAttributes.Usage int usage) {
        if (!isFeedbackConstantEnabled(effectId)) {
            return null;
        }
        VibrationEffect customizedVibration = mHapticFeedbackCustomization.getEffect(effectId);
        VibrationEffect customizedVibration =
                mHapticFeedbackCustomization.getEffect(effectId, usage);
        if (customizedVibration != null) {
            return customizedVibration;
        }
+1 −1
Original line number Diff line number Diff line
@@ -542,7 +542,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
            return null;
        }
        return performHapticFeedbackWithEffect(uid, deviceId, opPkg, constant, reason, token,
                hapticVibrationProvider.getVibration(constant),
                hapticVibrationProvider.getVibration(constant, usage),
                hapticVibrationProvider.getVibrationAttributes(constant, usage, flags, privFlags));
    }

Loading