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

Commit 39f0cf6e authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Load vibration scale gain from system properties" into main

parents 910d0afa 96a2ccda
Loading
Loading
Loading
Loading
+63 −5
Original line number Diff line number Diff line
@@ -30,13 +30,17 @@ import static android.os.VibrationAttributes.USAGE_UNKNOWN;

import android.annotation.Nullable;
import android.content.res.Resources;
import android.os.SystemProperties;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.os.Vibrator.VibrationIntensity;
import android.util.IndentingPrintWriter;

import com.android.internal.annotations.VisibleForTesting;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.function.Function;

/**
 * List of device-specific internal vibration configuration loaded from platform config.xml.
@@ -49,6 +53,37 @@ import java.util.Arrays;
 */
public class VibrationConfig {

    /**
     * The default gain to be applied between vibration scale levels.
     *
     * <p>Scale levels are defined as the difference between the user vibration intensity setting
     * and the device default config for each usage. The intensity values are defined as one of
     * Vibrator.VIBRATION_INTENSITY_*.
     *
     * <p>A user setting HIGH set on a device with default value LOW will cause the vibration
     * intensity to be scaled up 2 levels, i.e. scale with a factor of gain^2. A system with 3
     * intensities LOW, MEDIUM and HIGH has the following 5 scale levels:
     *
     * <ol>
     *     <li>VERY_HIGH: user(HIGH) - device(LOW)
     *     <li>HIGH: user(HIGH) - device(MEDIUM) / user(MEDIUM) - device(LOW)
     *     <li>NONE: user == device
     *     <li>LOW: user(MEDIUM) - device(HIGH) / user(LOW) - device(MEDIUM)
     *     <li>VERY_LOW: user(LOW) - device(HIGH)
     * </ol>
     *
     * <p>A device will only ever apply 3 out of these 5 levels based on the default intensity
     * config set for each usage (e.g. config_default[Alarm|Ring|Notification]VibrationIntensity).
     *
     * <p>This value must be greater than 1. The {@link #DEFAULT_SCALE_LEVEL_GAIN} will be used if
     * this property is undefined or invalid.
     *
     * @hide
     */
    @VisibleForTesting
    static final String SCALE_LEVEL_GAIN_SYSTEM_PROPERTY =
            "vendor.vibrator.scale.level.gain";

    /**
     * Hardcoded default scale level gain to be applied between each scale level to define their
     * scale factor value.
@@ -69,7 +104,7 @@ public class VibrationConfig {
    private final int mRampDownDurationMs;
    private final int mRequestVibrationParamsTimeoutMs;
    private final int[] mRequestVibrationParamsForUsages;

    private final float mDefaultVibrationScaleLevelGain;
    private final boolean mIgnoreVibrationsOnWirelessCharger;

    @VibrationIntensity
@@ -89,8 +124,18 @@ public class VibrationConfig {

    /** @hide */
    public VibrationConfig(@Nullable Resources resources) {
        mDefaultVibrationAmplitude = resources.getInteger(
                com.android.internal.R.integer.config_defaultVibrationAmplitude);
        this(resources, SystemProperties::get);
    }

    /** @hide */
    @VisibleForTesting
    public VibrationConfig(@Nullable Resources resources,
            Function<String, String> systemPropertiesGetter) {
        mDefaultVibrationAmplitude = loadInteger(resources,
                com.android.internal.R.integer.config_defaultVibrationAmplitude,
                DEFAULT_AMPLITUDE);
        mDefaultVibrationScaleLevelGain = loadFloat(systemPropertiesGetter,
                SCALE_LEVEL_GAIN_SYSTEM_PROPERTY, DEFAULT_SCALE_LEVEL_GAIN);
        mHapticChannelMaxVibrationAmplitude = loadFloat(resources,
                com.android.internal.R.dimen.config_hapticChannelMaxVibrationAmplitude);
        mRampDownDurationMs = loadInteger(resources,
@@ -135,6 +180,15 @@ public class VibrationConfig {
        return res != null ? res.getFloat(resId) : 0f;
    }

    private static float loadFloat(Function<String, String> systemPropertiesGetter,
            String propertyKey, float defaultValue) {
        try {
            return Float.parseFloat(systemPropertiesGetter.apply(propertyKey));
        } catch (Exception e) {
            return defaultValue;
        }
    }

    private static int loadInteger(@Nullable Resources res, int resId, int defaultValue) {
        return res != null ? res.getInteger(resId) : defaultValue;
    }
@@ -176,9 +230,11 @@ public class VibrationConfig {
     * for each level.
     */
    public float getDefaultVibrationScaleLevelGain() {
        // TODO(b/356407380): add device config for this
        if (mDefaultVibrationScaleLevelGain <= 1) {
            return DEFAULT_SCALE_LEVEL_GAIN;
        }
        return mDefaultVibrationScaleLevelGain;
    }

    /**
     * The duration, in milliseconds, that should be applied to the ramp to turn off the vibrator
@@ -270,6 +326,7 @@ public class VibrationConfig {
        return "VibrationConfig{"
                + "mIgnoreVibrationsOnWirelessCharger=" + mIgnoreVibrationsOnWirelessCharger
                + ", mDefaultVibrationAmplitude=" + mDefaultVibrationAmplitude
                + ", mDefaultVibrationScaleLevelGain=" + mDefaultVibrationScaleLevelGain
                + ", mHapticChannelMaxVibrationAmplitude=" + mHapticChannelMaxVibrationAmplitude
                + ", mRampStepDurationMs=" + mRampStepDurationMs
                + ", mRampDownDurationMs=" + mRampDownDurationMs
@@ -296,6 +353,7 @@ public class VibrationConfig {
        pw.increaseIndent();
        pw.println("ignoreVibrationsOnWirelessCharger = " + mIgnoreVibrationsOnWirelessCharger);
        pw.println("defaultVibrationAmplitude = " + mDefaultVibrationAmplitude);
        pw.println("defaultVibrationScaleLevelGain = " + mDefaultVibrationScaleLevelGain);
        pw.println("hapticChannelMaxAmplitude = " + mHapticChannelMaxVibrationAmplitude);
        pw.println("rampStepDurationMs = " + mRampStepDurationMs);
        pw.println("rampDownDurationMs = " + mRampDownDurationMs);
+100 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.
 */

package android.os.vibrator;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.when;

import android.content.res.Resources;

import com.android.internal.R;

import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import java.util.HashMap;
import java.util.Map;

public class VibrationConfigTest {

    @Rule
    public MockitoRule rule = MockitoJUnit.rule();

    @Mock
    private Resources mResourcesMock;

    private final Map<String, String> mSystemProperties = new HashMap<>();

    @Test
    public void getDefaultVibrationAmplitude_returnsConfiguredAmplitude() {
        when(mResourcesMock.getInteger(R.integer.config_defaultVibrationAmplitude)).thenReturn(1);
        assertThat(createConfig().getDefaultVibrationAmplitude()).isEqualTo(1);

        when(mResourcesMock.getInteger(R.integer.config_defaultVibrationAmplitude)).thenReturn(123);
        assertThat(createConfig().getDefaultVibrationAmplitude()).isEqualTo(123);

        when(mResourcesMock.getInteger(R.integer.config_defaultVibrationAmplitude)).thenReturn(255);
        assertThat(createConfig().getDefaultVibrationAmplitude()).isEqualTo(255);
    }

    @Test
    public void getDefaultVibrationAmplitude_invalidValue_returnsMaxAmplitude() {
        when(mResourcesMock.getInteger(R.integer.config_defaultVibrationAmplitude)).thenReturn(-1);
        assertThat(createConfig().getDefaultVibrationAmplitude()).isEqualTo(255);

        when(mResourcesMock.getInteger(R.integer.config_defaultVibrationAmplitude)).thenReturn(0);
        assertThat(createConfig().getDefaultVibrationAmplitude()).isEqualTo(255);

        when(mResourcesMock.getInteger(R.integer.config_defaultVibrationAmplitude)).thenReturn(500);
        assertThat(createConfig().getDefaultVibrationAmplitude()).isEqualTo(255);
    }

    @Test
    public void getDefaultVibrationScaleLevelGain_returnsConfiguredGain() {
        mSystemProperties.put(VibrationConfig.SCALE_LEVEL_GAIN_SYSTEM_PROPERTY, "1.2");
        assertThat(createConfig().getDefaultVibrationScaleLevelGain()).isEqualTo(1.2f);

        mSystemProperties.put(VibrationConfig.SCALE_LEVEL_GAIN_SYSTEM_PROPERTY, "2");
        assertThat(createConfig().getDefaultVibrationScaleLevelGain()).isEqualTo(2f);
    }

    @Test
    public void getDefaultVibrationScaleLevelGain_invalidValue_returnsFixedScaleGain() {
        mSystemProperties.put(VibrationConfig.SCALE_LEVEL_GAIN_SYSTEM_PROPERTY, "");
        assertThat(createConfig().getDefaultVibrationScaleLevelGain()).isEqualTo(1.4f);

        mSystemProperties.put(VibrationConfig.SCALE_LEVEL_GAIN_SYSTEM_PROPERTY, "invalid");
        assertThat(createConfig().getDefaultVibrationScaleLevelGain()).isEqualTo(1.4f);

        mSystemProperties.put(VibrationConfig.SCALE_LEVEL_GAIN_SYSTEM_PROPERTY, "-1");
        assertThat(createConfig().getDefaultVibrationScaleLevelGain()).isEqualTo(1.4f);

        mSystemProperties.put(VibrationConfig.SCALE_LEVEL_GAIN_SYSTEM_PROPERTY, "0.5");
        assertThat(createConfig().getDefaultVibrationScaleLevelGain()).isEqualTo(1.4f);

        mSystemProperties.put(VibrationConfig.SCALE_LEVEL_GAIN_SYSTEM_PROPERTY, "1.0");
        assertThat(createConfig().getDefaultVibrationScaleLevelGain()).isEqualTo(1.4f);
    }

    private VibrationConfig createConfig() {
        return new VibrationConfig(mResourcesMock, mSystemProperties::get);
    }
}