Loading services/core/java/com/android/server/vibrator/VibratorManagerService.java +3 −3 Original line number Diff line number Diff line Loading @@ -318,7 +318,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { HalListener halListener = new HalListener(this); mVibratorManager = Flags.removeHidlSupport() ? injector.createHalVibratorManager() ? injector.createHalVibratorManager(mHandler) : injector.createNativeHalVibratorManager(); mVibratorManager.init(halListener, halListener); Loading Loading @@ -1786,8 +1786,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return new VibratorFrameworkStatsLogger(handler); } HalVibratorManager createHalVibratorManager() { return VintfHalVibratorManager.createHalVibratorManager(new NativeHandler()); HalVibratorManager createHalVibratorManager(Handler handler) { return VintfHalVibratorManager.createHalVibratorManager(handler, new NativeHandler()); } HalVibratorManager createNativeHalVibratorManager() { Loading services/core/java/com/android/server/vibrator/VintfHalVibrator.java +58 −0 Original line number Diff line number Diff line Loading @@ -27,15 +27,18 @@ import android.hardware.vibrator.CompositeEffect; import android.hardware.vibrator.CompositePwleV2; import android.hardware.vibrator.FrequencyAccelerationMapEntry; import android.hardware.vibrator.IVibrator; import android.hardware.vibrator.IVibratorManager; import android.hardware.vibrator.PrimitivePwle; import android.hardware.vibrator.PwleV2Primitive; import android.hardware.vibrator.VendorEffect; import android.os.BadParcelableException; import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.os.IVibratorStateListener; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ServiceManager; import android.os.Trace; import android.os.VibrationEffect; import android.os.VibratorInfo; Loading @@ -57,6 +60,61 @@ import java.util.function.Supplier; /** Implementations for {@link HalVibrator} backed by VINTF objects. */ class VintfHalVibrator { private static final String TAG = "VintfHalVibrator"; /** {@link VintfSupplier} for {@link IVibrator} service managed by {@link IVibratorManager}. */ static final class ManagedVibratorSupplier extends VintfSupplier<IVibrator> { private final int mVibratorId; private final VintfSupplier<IVibratorManager> mManagerSupplier; ManagedVibratorSupplier(int vibratorId, VintfSupplier<IVibratorManager> managerSupplier) { mVibratorId = vibratorId; mManagerSupplier = managerSupplier; } @Nullable @Override IBinder connectToService() { try { IVibratorManager manager = mManagerSupplier.get(); if (manager == null) { Slog.e(TAG, "Error getting manager to load vibrator " + mVibratorId); return null; } IVibrator vibrator = manager.getVibrator(mVibratorId); if (vibrator == null) { Slog.e(TAG, "Null vibrator returned by manager for id " + mVibratorId); return null; } return vibrator.asBinder(); } catch (RemoteException e) { Slog.e(TAG, "Error getting vibrator " + mVibratorId + " from manager", e); } return null; } @NonNull @Override IVibrator castService(@NonNull IBinder binder) { return IVibrator.Stub.asInterface(binder); } } /** {@link VintfSupplier} for default {@link IVibrator} service. */ static final class DefaultVibratorSupplier extends VintfSupplier<IVibrator> { @Nullable @Override IBinder connectToService() { return Binder.allowBlocking(ServiceManager.waitForDeclaredService( IVibrator.DESCRIPTOR + "/default")); } @NonNull @Override IVibrator castService(@NonNull IBinder binder) { return IVibrator.Stub.asInterface(binder); } } /** Default implementation for devices with {@link IVibrator} available. */ static final class DefaultHalVibrator implements HalVibrator { Loading services/core/java/com/android/server/vibrator/VintfHalVibratorManager.java +42 −26 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.hardware.vibrator.IVibrator; import android.hardware.vibrator.IVibratorManager; import android.os.Binder; import android.os.DeadObjectException; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; Loading @@ -33,6 +34,9 @@ import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.server.vibrator.VintfHalVibrator.DefaultHalVibrator; import com.android.server.vibrator.VintfHalVibrator.DefaultVibratorSupplier; import com.android.server.vibrator.VintfHalVibrator.ManagedVibratorSupplier; import com.android.server.vibrator.VintfUtils.VintfSupplier; import java.util.ArrayList; Loading @@ -44,25 +48,30 @@ import java.util.function.IntFunction; /** Implementations for {@link HalVibratorManager} backed by VINTF objects. */ class VintfHalVibratorManager { private static final String TAG = "VintfHalVibratorManager"; private static final int DEFAULT_VIBRATOR_ID = 0; static final int DEFAULT_VIBRATOR_ID = 0; /** Create {@link HalVibratorManager} based on declared services on device. */ static HalVibratorManager createHalVibratorManager(HalNativeHandler nativeHandler) { // TODO(b/422944962): Replace this with Vintf HalVibrator IntFunction<HalVibrator> vibratorFactory = VibratorController::new; static HalVibratorManager createHalVibratorManager( Handler handler, HalNativeHandler nativeHandler) { if (ServiceManager.isDeclared(IVibratorManager.DESCRIPTOR + "/default")) { Slog.v(TAG, "Loading default IVibratorManager service."); return new DefaultHalVibratorManager(new DefaultVibratorManagerSupplier(), nativeHandler, vibratorFactory); VintfSupplier<IVibratorManager> managerSupplier = new DefaultVibratorManagerSupplier(); IntFunction<HalVibrator> vibratorFactory = vibratorId -> new DefaultHalVibrator(vibratorId, new ManagedVibratorSupplier(vibratorId, managerSupplier), handler, nativeHandler); return new DefaultHalVibratorManager(managerSupplier, nativeHandler, vibratorFactory); } if (ServiceManager.isDeclared(IVibrator.DESCRIPTOR + "/default")) { Slog.v(TAG, "Loading default IVibrator service."); return new LegacyHalVibratorManager(new int[] { DEFAULT_VIBRATOR_ID }, vibratorFactory); return new LegacyHalVibratorManager( new DefaultHalVibrator(DEFAULT_VIBRATOR_ID, new DefaultVibratorSupplier(), handler, nativeHandler), nativeHandler); } Slog.v(TAG, "No default services declared for IVibratorManager or IVibrator." + " Vibrator manager service will proceed without vibrator hardware."); return new LegacyHalVibratorManager(new int[0], vibratorFactory); return new LegacyHalVibratorManager(); } /** {@link VintfSupplier} for default {@link IVibratorManager} service. */ Loading Loading @@ -382,28 +391,35 @@ class VintfHalVibratorManager { /** Legacy implementation for devices without a declared {@link IVibratorManager} service. */ static final class LegacyHalVibratorManager implements HalVibratorManager { private final int[] mVibratorIds; private final SparseArray<HalVibrator> mVibrators; @Nullable private final HalVibrator mDefaultVibrator; @Nullable private final HalNativeHandler mNativeHandler; LegacyHalVibratorManager(@NonNull int[] vibratorIds, IntFunction<HalVibrator> vibratorFactory) { mVibratorIds = vibratorIds; mVibrators = new SparseArray<>(vibratorIds.length); for (int id : vibratorIds) { mVibrators.put(id, vibratorFactory.apply(id)); LegacyHalVibratorManager() { this(null, null); } LegacyHalVibratorManager(HalVibrator defaultVibrator, HalNativeHandler nativeHandler) { mVibratorIds = defaultVibrator == null ? new int[0] : new int[] { DEFAULT_VIBRATOR_ID }; mDefaultVibrator = defaultVibrator; mNativeHandler = nativeHandler; } @Override public void init(@NonNull Callbacks cb, @NonNull HalVibrator.Callbacks vibratorCb) { for (int i = 0; i < mVibrators.size(); i++) { mVibrators.valueAt(i).init(vibratorCb); if (mNativeHandler != null) { mNativeHandler.init(cb, vibratorCb); } if (mDefaultVibrator != null) { mDefaultVibrator.init(vibratorCb); } } @Override public void onSystemReady() { for (int i = 0; i < mVibrators.size(); i++) { mVibrators.valueAt(i).onSystemReady(); if (mDefaultVibrator != null) { mDefaultVibrator.onSystemReady(); } } Loading @@ -421,7 +437,7 @@ class VintfHalVibratorManager { @Nullable @Override public HalVibrator getVibrator(int id) { return mVibrators.get(id); return (id == DEFAULT_VIBRATOR_ID) ? mDefaultVibrator : null; } @Override Loading Loading @@ -456,11 +472,11 @@ class VintfHalVibratorManager { pw.println("vibratorIds = " + Arrays.toString(mVibratorIds)); pw.println("Vibrators:"); if (mDefaultVibrator != null) { pw.increaseIndent(); for (int i = 0; i < mVibrators.size(); i++) { mVibrators.valueAt(i).dump(pw); } mDefaultVibrator.dump(pw); pw.decreaseIndent(); } pw.decreaseIndent(); pw.println(); Loading services/core/jni/com_android_server_vibrator_VibratorManagerService.cpp +59 −22 Original line number Diff line number Diff line Loading @@ -174,6 +174,29 @@ public: return mVibratorHalProviders[vibratorId]->getHal(); } void processManagerStatus(ndk::ScopedAStatus& status, const char* logLabel) { if (!status.isOk()) { ALOGE("%s: %s", logLabel, status.getDescription().c_str()); if (status.getExceptionCode() == EX_TRANSACTION_FAILED) { ALOGE("%s: Resetting vibrator manager provider", logLabel); mManagerHalProvider->clear(); } } } void processVibratorStatus(int32_t vibratorId, ndk::ScopedAStatus& status, const char* logLabel) { if (!status.isOk()) { ALOGE("%s: %s", logLabel, status.getDescription().c_str()); if (status.getExceptionCode() == EX_TRANSACTION_FAILED) { ALOGE("%s: Resetting vibrator %d provider", logLabel, vibratorId); if (mVibratorHalProviders[vibratorId]) { mVibratorHalProviders[vibratorId]->clear(); } } } } // TODO(b/409002423): remove functions below once remove_hidl_support flag removed vibrator::ManagerHalController* hal() const { return mHal.get(); } Loading Loading @@ -255,20 +278,11 @@ vibrator::ManagerHalController* android_server_vibrator_VibratorManagerService_g return gManager; } static jboolean resultFromStatus(ndk::ScopedAStatus status, const char* logLabel) { if (status.isOk()) { return JNI_TRUE; } ALOGE("%s: %s", logLabel, status.getMessage()); return JNI_FALSE; } static jint resultFromStatus(ndk::ScopedAStatus status, int32_t successValue, jint vibrationResultFromStatus(ndk::ScopedAStatus& status, int32_t successValue, const char* logLabel) { if (status.isOk()) { return static_cast<jint>(successValue); } ALOGE("%s: %s", logLabel, status.getMessage()); if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION || status.getStatus() == STATUS_UNKNOWN_TRANSACTION) { // STATUS_UNKNOWN_TRANSACTION means the HAL implementation is an older version, so this Loading Loading @@ -337,6 +351,19 @@ static jlong nativeNewInit(JNIEnv* env, jclass /* clazz */, jobject managerCallb ALOGD("%s", __func__); auto service = std::make_unique<NativeVibratorManagerService>(env, managerCallbacks, vibratorCallbacks); auto managerHal = loadManagerHal(service.get(), __func__); if (managerHal) { // Pre-load all vibrator HALs. std::vector<int32_t> vibratorIds; if (managerHal->getVibratorIds(&vibratorIds).isOk()) { for (auto vibratorId : vibratorIds) { loadVibratorHal(service.get(), vibratorId, __func__); } } } else { // No vibrator manager, pre-load default vibrator with ID = 0. loadVibratorHal(service.get(), 0, __func__); } return reinterpret_cast<jlong>(service.release()); } Loading @@ -356,7 +383,9 @@ static jboolean nativeTriggerSyncedWithCallback(JNIEnv* env, jclass /* clazz */, auto callback = ndk::SharedRefBase::make<VibratorCallback>(sJvm, service->managerCallbacks(), sMethodIdOnSyncedVibrationComplete, vibrationId); return resultFromStatus(hal->triggerSynced(callback), __func__); auto status = hal->triggerSynced(callback); service->processManagerStatus(status, __func__); return status.isOk() ? JNI_TRUE : JNI_FALSE; } static jobject nativeStartSessionWithCallback(JNIEnv* env, jclass /* clazz */, jlong ptr, Loading @@ -376,10 +405,7 @@ static jobject nativeStartSessionWithCallback(JNIEnv* env, jclass /* clazz */, j std::vector<int32_t> ids(size); env->GetIntArrayRegion(vibratorIds, 0, size, reinterpret_cast<jint*>(ids.data())); auto status = hal->startSession(ids, config, callback, &session); if (!status.isOk()) { ALOGE("%s: %s", __func__, status.getMessage()); return nullptr; } service->processManagerStatus(status, __func__); return AIBinder_toJavaBinder(env, session->asBinder().get()); } Loading @@ -395,7 +421,9 @@ static jint nativeVibratorOnWithCallback(JNIEnv* env, jclass /* clazz */, jlong auto callback = ndk::SharedRefBase::make<VibrationCallback>(service->vibratorCallbacks(), vibratorId, vibrationId, stepId); int32_t millis = static_cast<int32_t>(durationMs); return resultFromStatus(hal->on(millis, callback), millis, __func__); auto status = hal->on(millis, callback); service->processVibratorStatus(static_cast<int32_t>(vibratorId), status, __func__); return vibrationResultFromStatus(status, millis, __func__); } static jint nativeVibratorPerformVendorEffectWithCallback(JNIEnv* env, jclass /* clazz */, Loading @@ -411,7 +439,9 @@ static jint nativeVibratorPerformVendorEffectWithCallback(JNIEnv* env, jclass /* auto effect = fromJavaParcel<VendorEffect>(env, vendorEffect); auto callback = ndk::SharedRefBase::make<VibrationCallback>(service->vibratorCallbacks(), vibratorId, vibrationId, stepId); return resultFromStatus(hal->performVendorEffect(effect, callback), INT32_MAX, __func__); auto status = hal->performVendorEffect(effect, callback); service->processVibratorStatus(static_cast<int32_t>(vibratorId), status, __func__); return vibrationResultFromStatus(status, INT32_MAX, __func__); } static jint nativeVibratorPerformEffectWithCallback(JNIEnv* env, jclass /* clazz */, jlong ptr, Loading @@ -430,7 +460,8 @@ static jint nativeVibratorPerformEffectWithCallback(JNIEnv* env, jclass /* clazz auto callback = ndk::SharedRefBase::make<VibrationCallback>(service->vibratorCallbacks(), vibratorId, vibrationId, stepId); auto status = hal->perform(effect, strength, callback, &durationMs); return resultFromStatus(std::move(status), durationMs, __func__); service->processVibratorStatus(static_cast<int32_t>(vibratorId), status, __func__); return vibrationResultFromStatus(status, durationMs, __func__); } static jint nativeVibratorComposeEffectWithCallback(JNIEnv* env, jclass /* clazz */, jlong ptr, Loading @@ -445,7 +476,9 @@ static jint nativeVibratorComposeEffectWithCallback(JNIEnv* env, jclass /* clazz auto effects = vectorFromJavaParcel<CompositeEffect>(env, compositeEffects); auto callback = ndk::SharedRefBase::make<VibrationCallback>(service->vibratorCallbacks(), vibratorId, vibrationId, stepId); return resultFromStatus(hal->compose(effects, callback), INT32_MAX, __func__); auto status = hal->compose(effects, callback); service->processVibratorStatus(static_cast<int32_t>(vibratorId), status, __func__); return vibrationResultFromStatus(status, INT32_MAX, __func__); } static jint nativeVibratorComposePwleEffectWithCallback(JNIEnv* env, jclass /* clazz */, jlong ptr, Loading @@ -460,7 +493,9 @@ static jint nativeVibratorComposePwleEffectWithCallback(JNIEnv* env, jclass /* c auto effects = vectorFromJavaParcel<PrimitivePwle>(env, pwles); auto callback = ndk::SharedRefBase::make<VibrationCallback>(service->vibratorCallbacks(), vibratorId, vibrationId, stepId); return resultFromStatus(hal->composePwle(effects, callback), INT32_MAX, __func__); auto status = hal->composePwle(effects, callback); service->processVibratorStatus(static_cast<int32_t>(vibratorId), status, __func__); return vibrationResultFromStatus(status, INT32_MAX, __func__); } static jint nativeVibratorComposePwleV2EffectWithCallback(JNIEnv* env, jclass /* clazz */, Loading @@ -476,7 +511,9 @@ static jint nativeVibratorComposePwleV2EffectWithCallback(JNIEnv* env, jclass /* auto compositePwleV2 = fromJavaParcel<CompositePwleV2>(env, composite); auto callback = ndk::SharedRefBase::make<VibrationCallback>(service->vibratorCallbacks(), vibratorId, vibrationId, stepId); return resultFromStatus(hal->composePwleV2(compositePwleV2, callback), INT32_MAX, __func__); auto status = hal->composePwleV2(compositePwleV2, callback); service->processVibratorStatus(static_cast<int32_t>(vibratorId), status, __func__); return vibrationResultFromStatus(status, INT32_MAX, __func__); } // TODO(b/409002423): remove functions below once remove_hidl_support flag removed Loading services/core/jni/com_android_server_vibrator_VibratorManagerService.h +20 −1 Original line number Diff line number Diff line Loading @@ -103,11 +103,30 @@ public: if (status.isOk()) { mIsDeathRecipientLinked = true; } else { ALOGE("%s: Error linking to HAL binder death: %s", __func__, status.getMessage()); ALOGE("%s: Error linking to HAL binder death: %s", __func__, status.getDescription().c_str()); } return mHal; } void clear() { std::lock_guard<std::mutex> lock(mMutex); if (mHal == nullptr) { return; } ALOGW("%s: clearing HAL client", __func__); auto binder = mHal->asBinder().get(); if (binder && mIsDeathRecipientLinked) { auto status = ndk::ScopedAStatus::fromStatus( AIBinder_unlinkToDeath(binder, mDeathRecipient.get(), this)); if (!status.isOk()) { ALOGE("%s: Error unlinking to HAL binder death: %s", __func__, status.getDescription().c_str()); } } mHal = nullptr; } static void onBinderDied(void* cookie) { HalProvider* provider = reinterpret_cast<HalProvider*>(cookie); if (provider) { Loading Loading
services/core/java/com/android/server/vibrator/VibratorManagerService.java +3 −3 Original line number Diff line number Diff line Loading @@ -318,7 +318,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { HalListener halListener = new HalListener(this); mVibratorManager = Flags.removeHidlSupport() ? injector.createHalVibratorManager() ? injector.createHalVibratorManager(mHandler) : injector.createNativeHalVibratorManager(); mVibratorManager.init(halListener, halListener); Loading Loading @@ -1786,8 +1786,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return new VibratorFrameworkStatsLogger(handler); } HalVibratorManager createHalVibratorManager() { return VintfHalVibratorManager.createHalVibratorManager(new NativeHandler()); HalVibratorManager createHalVibratorManager(Handler handler) { return VintfHalVibratorManager.createHalVibratorManager(handler, new NativeHandler()); } HalVibratorManager createNativeHalVibratorManager() { Loading
services/core/java/com/android/server/vibrator/VintfHalVibrator.java +58 −0 Original line number Diff line number Diff line Loading @@ -27,15 +27,18 @@ import android.hardware.vibrator.CompositeEffect; import android.hardware.vibrator.CompositePwleV2; import android.hardware.vibrator.FrequencyAccelerationMapEntry; import android.hardware.vibrator.IVibrator; import android.hardware.vibrator.IVibratorManager; import android.hardware.vibrator.PrimitivePwle; import android.hardware.vibrator.PwleV2Primitive; import android.hardware.vibrator.VendorEffect; import android.os.BadParcelableException; import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.os.IVibratorStateListener; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ServiceManager; import android.os.Trace; import android.os.VibrationEffect; import android.os.VibratorInfo; Loading @@ -57,6 +60,61 @@ import java.util.function.Supplier; /** Implementations for {@link HalVibrator} backed by VINTF objects. */ class VintfHalVibrator { private static final String TAG = "VintfHalVibrator"; /** {@link VintfSupplier} for {@link IVibrator} service managed by {@link IVibratorManager}. */ static final class ManagedVibratorSupplier extends VintfSupplier<IVibrator> { private final int mVibratorId; private final VintfSupplier<IVibratorManager> mManagerSupplier; ManagedVibratorSupplier(int vibratorId, VintfSupplier<IVibratorManager> managerSupplier) { mVibratorId = vibratorId; mManagerSupplier = managerSupplier; } @Nullable @Override IBinder connectToService() { try { IVibratorManager manager = mManagerSupplier.get(); if (manager == null) { Slog.e(TAG, "Error getting manager to load vibrator " + mVibratorId); return null; } IVibrator vibrator = manager.getVibrator(mVibratorId); if (vibrator == null) { Slog.e(TAG, "Null vibrator returned by manager for id " + mVibratorId); return null; } return vibrator.asBinder(); } catch (RemoteException e) { Slog.e(TAG, "Error getting vibrator " + mVibratorId + " from manager", e); } return null; } @NonNull @Override IVibrator castService(@NonNull IBinder binder) { return IVibrator.Stub.asInterface(binder); } } /** {@link VintfSupplier} for default {@link IVibrator} service. */ static final class DefaultVibratorSupplier extends VintfSupplier<IVibrator> { @Nullable @Override IBinder connectToService() { return Binder.allowBlocking(ServiceManager.waitForDeclaredService( IVibrator.DESCRIPTOR + "/default")); } @NonNull @Override IVibrator castService(@NonNull IBinder binder) { return IVibrator.Stub.asInterface(binder); } } /** Default implementation for devices with {@link IVibrator} available. */ static final class DefaultHalVibrator implements HalVibrator { Loading
services/core/java/com/android/server/vibrator/VintfHalVibratorManager.java +42 −26 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.hardware.vibrator.IVibrator; import android.hardware.vibrator.IVibratorManager; import android.os.Binder; import android.os.DeadObjectException; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; Loading @@ -33,6 +34,9 @@ import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.server.vibrator.VintfHalVibrator.DefaultHalVibrator; import com.android.server.vibrator.VintfHalVibrator.DefaultVibratorSupplier; import com.android.server.vibrator.VintfHalVibrator.ManagedVibratorSupplier; import com.android.server.vibrator.VintfUtils.VintfSupplier; import java.util.ArrayList; Loading @@ -44,25 +48,30 @@ import java.util.function.IntFunction; /** Implementations for {@link HalVibratorManager} backed by VINTF objects. */ class VintfHalVibratorManager { private static final String TAG = "VintfHalVibratorManager"; private static final int DEFAULT_VIBRATOR_ID = 0; static final int DEFAULT_VIBRATOR_ID = 0; /** Create {@link HalVibratorManager} based on declared services on device. */ static HalVibratorManager createHalVibratorManager(HalNativeHandler nativeHandler) { // TODO(b/422944962): Replace this with Vintf HalVibrator IntFunction<HalVibrator> vibratorFactory = VibratorController::new; static HalVibratorManager createHalVibratorManager( Handler handler, HalNativeHandler nativeHandler) { if (ServiceManager.isDeclared(IVibratorManager.DESCRIPTOR + "/default")) { Slog.v(TAG, "Loading default IVibratorManager service."); return new DefaultHalVibratorManager(new DefaultVibratorManagerSupplier(), nativeHandler, vibratorFactory); VintfSupplier<IVibratorManager> managerSupplier = new DefaultVibratorManagerSupplier(); IntFunction<HalVibrator> vibratorFactory = vibratorId -> new DefaultHalVibrator(vibratorId, new ManagedVibratorSupplier(vibratorId, managerSupplier), handler, nativeHandler); return new DefaultHalVibratorManager(managerSupplier, nativeHandler, vibratorFactory); } if (ServiceManager.isDeclared(IVibrator.DESCRIPTOR + "/default")) { Slog.v(TAG, "Loading default IVibrator service."); return new LegacyHalVibratorManager(new int[] { DEFAULT_VIBRATOR_ID }, vibratorFactory); return new LegacyHalVibratorManager( new DefaultHalVibrator(DEFAULT_VIBRATOR_ID, new DefaultVibratorSupplier(), handler, nativeHandler), nativeHandler); } Slog.v(TAG, "No default services declared for IVibratorManager or IVibrator." + " Vibrator manager service will proceed without vibrator hardware."); return new LegacyHalVibratorManager(new int[0], vibratorFactory); return new LegacyHalVibratorManager(); } /** {@link VintfSupplier} for default {@link IVibratorManager} service. */ Loading Loading @@ -382,28 +391,35 @@ class VintfHalVibratorManager { /** Legacy implementation for devices without a declared {@link IVibratorManager} service. */ static final class LegacyHalVibratorManager implements HalVibratorManager { private final int[] mVibratorIds; private final SparseArray<HalVibrator> mVibrators; @Nullable private final HalVibrator mDefaultVibrator; @Nullable private final HalNativeHandler mNativeHandler; LegacyHalVibratorManager(@NonNull int[] vibratorIds, IntFunction<HalVibrator> vibratorFactory) { mVibratorIds = vibratorIds; mVibrators = new SparseArray<>(vibratorIds.length); for (int id : vibratorIds) { mVibrators.put(id, vibratorFactory.apply(id)); LegacyHalVibratorManager() { this(null, null); } LegacyHalVibratorManager(HalVibrator defaultVibrator, HalNativeHandler nativeHandler) { mVibratorIds = defaultVibrator == null ? new int[0] : new int[] { DEFAULT_VIBRATOR_ID }; mDefaultVibrator = defaultVibrator; mNativeHandler = nativeHandler; } @Override public void init(@NonNull Callbacks cb, @NonNull HalVibrator.Callbacks vibratorCb) { for (int i = 0; i < mVibrators.size(); i++) { mVibrators.valueAt(i).init(vibratorCb); if (mNativeHandler != null) { mNativeHandler.init(cb, vibratorCb); } if (mDefaultVibrator != null) { mDefaultVibrator.init(vibratorCb); } } @Override public void onSystemReady() { for (int i = 0; i < mVibrators.size(); i++) { mVibrators.valueAt(i).onSystemReady(); if (mDefaultVibrator != null) { mDefaultVibrator.onSystemReady(); } } Loading @@ -421,7 +437,7 @@ class VintfHalVibratorManager { @Nullable @Override public HalVibrator getVibrator(int id) { return mVibrators.get(id); return (id == DEFAULT_VIBRATOR_ID) ? mDefaultVibrator : null; } @Override Loading Loading @@ -456,11 +472,11 @@ class VintfHalVibratorManager { pw.println("vibratorIds = " + Arrays.toString(mVibratorIds)); pw.println("Vibrators:"); if (mDefaultVibrator != null) { pw.increaseIndent(); for (int i = 0; i < mVibrators.size(); i++) { mVibrators.valueAt(i).dump(pw); } mDefaultVibrator.dump(pw); pw.decreaseIndent(); } pw.decreaseIndent(); pw.println(); Loading
services/core/jni/com_android_server_vibrator_VibratorManagerService.cpp +59 −22 Original line number Diff line number Diff line Loading @@ -174,6 +174,29 @@ public: return mVibratorHalProviders[vibratorId]->getHal(); } void processManagerStatus(ndk::ScopedAStatus& status, const char* logLabel) { if (!status.isOk()) { ALOGE("%s: %s", logLabel, status.getDescription().c_str()); if (status.getExceptionCode() == EX_TRANSACTION_FAILED) { ALOGE("%s: Resetting vibrator manager provider", logLabel); mManagerHalProvider->clear(); } } } void processVibratorStatus(int32_t vibratorId, ndk::ScopedAStatus& status, const char* logLabel) { if (!status.isOk()) { ALOGE("%s: %s", logLabel, status.getDescription().c_str()); if (status.getExceptionCode() == EX_TRANSACTION_FAILED) { ALOGE("%s: Resetting vibrator %d provider", logLabel, vibratorId); if (mVibratorHalProviders[vibratorId]) { mVibratorHalProviders[vibratorId]->clear(); } } } } // TODO(b/409002423): remove functions below once remove_hidl_support flag removed vibrator::ManagerHalController* hal() const { return mHal.get(); } Loading Loading @@ -255,20 +278,11 @@ vibrator::ManagerHalController* android_server_vibrator_VibratorManagerService_g return gManager; } static jboolean resultFromStatus(ndk::ScopedAStatus status, const char* logLabel) { if (status.isOk()) { return JNI_TRUE; } ALOGE("%s: %s", logLabel, status.getMessage()); return JNI_FALSE; } static jint resultFromStatus(ndk::ScopedAStatus status, int32_t successValue, jint vibrationResultFromStatus(ndk::ScopedAStatus& status, int32_t successValue, const char* logLabel) { if (status.isOk()) { return static_cast<jint>(successValue); } ALOGE("%s: %s", logLabel, status.getMessage()); if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION || status.getStatus() == STATUS_UNKNOWN_TRANSACTION) { // STATUS_UNKNOWN_TRANSACTION means the HAL implementation is an older version, so this Loading Loading @@ -337,6 +351,19 @@ static jlong nativeNewInit(JNIEnv* env, jclass /* clazz */, jobject managerCallb ALOGD("%s", __func__); auto service = std::make_unique<NativeVibratorManagerService>(env, managerCallbacks, vibratorCallbacks); auto managerHal = loadManagerHal(service.get(), __func__); if (managerHal) { // Pre-load all vibrator HALs. std::vector<int32_t> vibratorIds; if (managerHal->getVibratorIds(&vibratorIds).isOk()) { for (auto vibratorId : vibratorIds) { loadVibratorHal(service.get(), vibratorId, __func__); } } } else { // No vibrator manager, pre-load default vibrator with ID = 0. loadVibratorHal(service.get(), 0, __func__); } return reinterpret_cast<jlong>(service.release()); } Loading @@ -356,7 +383,9 @@ static jboolean nativeTriggerSyncedWithCallback(JNIEnv* env, jclass /* clazz */, auto callback = ndk::SharedRefBase::make<VibratorCallback>(sJvm, service->managerCallbacks(), sMethodIdOnSyncedVibrationComplete, vibrationId); return resultFromStatus(hal->triggerSynced(callback), __func__); auto status = hal->triggerSynced(callback); service->processManagerStatus(status, __func__); return status.isOk() ? JNI_TRUE : JNI_FALSE; } static jobject nativeStartSessionWithCallback(JNIEnv* env, jclass /* clazz */, jlong ptr, Loading @@ -376,10 +405,7 @@ static jobject nativeStartSessionWithCallback(JNIEnv* env, jclass /* clazz */, j std::vector<int32_t> ids(size); env->GetIntArrayRegion(vibratorIds, 0, size, reinterpret_cast<jint*>(ids.data())); auto status = hal->startSession(ids, config, callback, &session); if (!status.isOk()) { ALOGE("%s: %s", __func__, status.getMessage()); return nullptr; } service->processManagerStatus(status, __func__); return AIBinder_toJavaBinder(env, session->asBinder().get()); } Loading @@ -395,7 +421,9 @@ static jint nativeVibratorOnWithCallback(JNIEnv* env, jclass /* clazz */, jlong auto callback = ndk::SharedRefBase::make<VibrationCallback>(service->vibratorCallbacks(), vibratorId, vibrationId, stepId); int32_t millis = static_cast<int32_t>(durationMs); return resultFromStatus(hal->on(millis, callback), millis, __func__); auto status = hal->on(millis, callback); service->processVibratorStatus(static_cast<int32_t>(vibratorId), status, __func__); return vibrationResultFromStatus(status, millis, __func__); } static jint nativeVibratorPerformVendorEffectWithCallback(JNIEnv* env, jclass /* clazz */, Loading @@ -411,7 +439,9 @@ static jint nativeVibratorPerformVendorEffectWithCallback(JNIEnv* env, jclass /* auto effect = fromJavaParcel<VendorEffect>(env, vendorEffect); auto callback = ndk::SharedRefBase::make<VibrationCallback>(service->vibratorCallbacks(), vibratorId, vibrationId, stepId); return resultFromStatus(hal->performVendorEffect(effect, callback), INT32_MAX, __func__); auto status = hal->performVendorEffect(effect, callback); service->processVibratorStatus(static_cast<int32_t>(vibratorId), status, __func__); return vibrationResultFromStatus(status, INT32_MAX, __func__); } static jint nativeVibratorPerformEffectWithCallback(JNIEnv* env, jclass /* clazz */, jlong ptr, Loading @@ -430,7 +460,8 @@ static jint nativeVibratorPerformEffectWithCallback(JNIEnv* env, jclass /* clazz auto callback = ndk::SharedRefBase::make<VibrationCallback>(service->vibratorCallbacks(), vibratorId, vibrationId, stepId); auto status = hal->perform(effect, strength, callback, &durationMs); return resultFromStatus(std::move(status), durationMs, __func__); service->processVibratorStatus(static_cast<int32_t>(vibratorId), status, __func__); return vibrationResultFromStatus(status, durationMs, __func__); } static jint nativeVibratorComposeEffectWithCallback(JNIEnv* env, jclass /* clazz */, jlong ptr, Loading @@ -445,7 +476,9 @@ static jint nativeVibratorComposeEffectWithCallback(JNIEnv* env, jclass /* clazz auto effects = vectorFromJavaParcel<CompositeEffect>(env, compositeEffects); auto callback = ndk::SharedRefBase::make<VibrationCallback>(service->vibratorCallbacks(), vibratorId, vibrationId, stepId); return resultFromStatus(hal->compose(effects, callback), INT32_MAX, __func__); auto status = hal->compose(effects, callback); service->processVibratorStatus(static_cast<int32_t>(vibratorId), status, __func__); return vibrationResultFromStatus(status, INT32_MAX, __func__); } static jint nativeVibratorComposePwleEffectWithCallback(JNIEnv* env, jclass /* clazz */, jlong ptr, Loading @@ -460,7 +493,9 @@ static jint nativeVibratorComposePwleEffectWithCallback(JNIEnv* env, jclass /* c auto effects = vectorFromJavaParcel<PrimitivePwle>(env, pwles); auto callback = ndk::SharedRefBase::make<VibrationCallback>(service->vibratorCallbacks(), vibratorId, vibrationId, stepId); return resultFromStatus(hal->composePwle(effects, callback), INT32_MAX, __func__); auto status = hal->composePwle(effects, callback); service->processVibratorStatus(static_cast<int32_t>(vibratorId), status, __func__); return vibrationResultFromStatus(status, INT32_MAX, __func__); } static jint nativeVibratorComposePwleV2EffectWithCallback(JNIEnv* env, jclass /* clazz */, Loading @@ -476,7 +511,9 @@ static jint nativeVibratorComposePwleV2EffectWithCallback(JNIEnv* env, jclass /* auto compositePwleV2 = fromJavaParcel<CompositePwleV2>(env, composite); auto callback = ndk::SharedRefBase::make<VibrationCallback>(service->vibratorCallbacks(), vibratorId, vibrationId, stepId); return resultFromStatus(hal->composePwleV2(compositePwleV2, callback), INT32_MAX, __func__); auto status = hal->composePwleV2(compositePwleV2, callback); service->processVibratorStatus(static_cast<int32_t>(vibratorId), status, __func__); return vibrationResultFromStatus(status, INT32_MAX, __func__); } // TODO(b/409002423): remove functions below once remove_hidl_support flag removed Loading
services/core/jni/com_android_server_vibrator_VibratorManagerService.h +20 −1 Original line number Diff line number Diff line Loading @@ -103,11 +103,30 @@ public: if (status.isOk()) { mIsDeathRecipientLinked = true; } else { ALOGE("%s: Error linking to HAL binder death: %s", __func__, status.getMessage()); ALOGE("%s: Error linking to HAL binder death: %s", __func__, status.getDescription().c_str()); } return mHal; } void clear() { std::lock_guard<std::mutex> lock(mMutex); if (mHal == nullptr) { return; } ALOGW("%s: clearing HAL client", __func__); auto binder = mHal->asBinder().get(); if (binder && mIsDeathRecipientLinked) { auto status = ndk::ScopedAStatus::fromStatus( AIBinder_unlinkToDeath(binder, mDeathRecipient.get(), this)); if (!status.isOk()) { ALOGE("%s: Error unlinking to HAL binder death: %s", __func__, status.getDescription().c_str()); } } mHal = nullptr; } static void onBinderDied(void* cookie) { HalProvider* provider = reinterpret_cast<HalProvider*>(cookie); if (provider) { Loading