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

Commit 1db1eff2 authored by Sahil Sonar's avatar Sahil Sonar 💬
Browse files

Merge branch '1167devices-u-tetris_richtap' into 'v1-u'

base: Add minimal support for Richtap vibrations

See merge request e/os/android_frameworks_base!240
parents 25548043 68419b1a
Loading
Loading
Loading
Loading
+69 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 Paranoid Android
 *
 * 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;

import android.content.res.Resources;
import android.os.VibrationEffect;
import android.util.Slog;

import com.android.internal.R;

/** @hide */
public class RichTapVibrationEffect {

    private static final String TAG = "RichTapVibrationEffect";

    public static boolean isSupported() {
        return Resources.getSystem().getBoolean(R.bool.config_usesRichtapVibration);
    }

    public static int[] getInnerEffect(int id) {
        switch (id) {
            case VibrationEffect.EFFECT_CLICK:
                return new int[]{1, 4097, 0, 100, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
            case VibrationEffect.EFFECT_DOUBLE_CLICK:
                return new int[]{1, 4097, 0, 100, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4097, 70, 100, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
            case VibrationEffect.EFFECT_TICK:
                return new int[]{1, 4097, 0, 100, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
            case VibrationEffect.EFFECT_THUD:
                return new int[]{1, 4097, 0, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
            case VibrationEffect.EFFECT_POP:
                return new int[]{1, 4097, 0, 100, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
            case VibrationEffect.EFFECT_HEAVY_CLICK:
                return new int[]{1, 4097, 0, 100, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
            case VibrationEffect.EFFECT_TEXTURE_TICK:
                return new int[]{1, 4097, 0, 50, 33, 29, 0, 0, 0, 12, 59, 0, 22, 75, -21, 29, 0, 0, 4097, 30, 100, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
            default:
                Slog.d(TAG, "Exception encountered!", new IllegalStateException("Unexpected effect id: " + id));
                return null;
        }
    }

    public static int getInnerEffectStrength(int strength) {
        switch (strength) {
            case VibrationEffect.EFFECT_STRENGTH_LIGHT:
                return 150;
            case VibrationEffect.EFFECT_STRENGTH_MEDIUM:
                return 200;
            case VibrationEffect.EFFECT_STRENGTH_STRONG:
                return 250;
            default:
                Slog.e(TAG, "Wrong Effect Strength!!");
                return 0;
        }
    }
}
+4 −0
Original line number Diff line number Diff line
<resources>
    <!-- Whether to use Richtap vibration -->
    <bool name="config_usesRichtapVibration">false</bool>
</resources>
+4 −0
Original line number Diff line number Diff line
<resources>
    <!-- Whether to use Richtap vibration -->
    <java-symbol type="bool" name="config_usesRichtapVibration" />
</resources>
+1 −0
Original line number Diff line number Diff line
@@ -256,6 +256,7 @@ java_library_static {
        "net_flags_lib",
        "stats_flags_lib",
        "core_os_flags_lib",
        "vendor.aac.hardware.richtap.vibrator",
    ],
    javac_shard_size: 50,
    javacflags: [
+132 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 Paranoid Android
 *
 * 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 com.android.server.vibrator;

import android.hardware.vibrator.IVibrator;
import android.os.Binder;
import android.os.IBinder;
import android.os.ServiceManager;
import android.util.Slog;

import vendor.aac.hardware.richtap.vibrator.IRichtapCallback;
import vendor.aac.hardware.richtap.vibrator.IRichtapVibrator;

public class RichTapVibratorService {

    private static final String TAG = "RichTapVibratorService";
    private static final String VIBRATOR_DESCRIPTOR = IVibrator.DESCRIPTOR + "/default";

    private IRichtapCallback mCallback;
    private volatile IRichtapVibrator sRichtapVibratorService = null;

    private IRichtapVibrator getRichtapService() {
        synchronized (RichTapVibratorService.class) {
            if (sRichtapVibratorService == null) {
                Slog.d(TAG, "vibratorDescriptor:" + VIBRATOR_DESCRIPTOR);
                IVibrator vibratorHalService = IVibrator.Stub.asInterface(ServiceManager.getService(VIBRATOR_DESCRIPTOR));
                if (vibratorHalService == null) {
                    Slog.d(TAG, "can not get hal service");
                    return null;
                }
                Slog.d(TAG, "vibratorHalService:" + vibratorHalService);
                try {
                    Slog.d(TAG, "Capabilities:" + vibratorHalService.getCapabilities());
                } catch (Exception e) {
                    Slog.d(TAG, "getCapabilities failed", e);
                }
                try {
                    IBinder binder = vibratorHalService.asBinder().getExtension();
                    if (binder != null) {
                        sRichtapVibratorService = IRichtapVibrator.Stub.asInterface(Binder.allowBlocking(binder));
                        binder.linkToDeath(new VibHalDeathRecipient(this), 0);
                    } else {
                        sRichtapVibratorService = null;
                        Slog.e(TAG, "getExtension == null");
                    }
                } catch (Exception e) {
                    Slog.e(TAG, "getExtension fail", e);
                }
            }
            return sRichtapVibratorService;
        }
    }

    public RichTapVibratorService() { }

    public RichTapVibratorService(IRichtapCallback callback) {
        mCallback = callback;
    }

    public void richTapVibratorOn(long millis) {
        try {
            IRichtapVibrator service = getRichtapService();
            if (service != null) {
                Slog.d(TAG, "aac richtap doVibratorOn");
                service.on((int) millis, mCallback);
            }
        } catch (Exception e) {
            Slog.e(TAG, "aac richtap doVibratorOn fail.", e);
        }
    }

    public void richTapVibratorSetAmplitude(int amplitude) {
        try {
            IRichtapVibrator service = getRichtapService();
            if (service != null) {
                Slog.d(TAG, "aac richtap doVibratorSetAmplitude");
                service.setAmplitude(amplitude, mCallback);
            }
        } catch (Exception e) {
            Slog.e(TAG, "aac richtap doVibratorSetAmplitude fail.", e);
        }
    }

    public void richTapVibratorOnRawPattern(int[] pattern, int amplitude, int freq) {
        try {
            IRichtapVibrator service = getRichtapService();
            if (service != null) {
                Slog.d(TAG, "aac richtap doVibratorOnRawPattern");
                service.performHe(1, 0, amplitude, freq, pattern, mCallback);
            }
        } catch (Exception e) {
            Slog.e(TAG, "aac richtap doVibratorOnRawPattern fail.", e);
        }
    }

    void resetHalServiceProxy() {
        sRichtapVibratorService = null;
    }

    public static final class VibHalDeathRecipient implements IBinder.DeathRecipient {
        RichTapVibratorService mRichTapService;

        VibHalDeathRecipient(RichTapVibratorService richtapService) {
            mRichTapService = richtapService;
        }

        @Override
        public void binderDied() {
            Slog.d(TAG, "vibrator hal died,should reset hal proxy!!");
            synchronized (VibHalDeathRecipient.class) {
                if (mRichTapService != null) {
                    Slog.d(TAG, "vibrator hal reset hal proxy");
                    mRichTapService.resetHalServiceProxy();
                }
            }
        }
    }
}
Loading