Loading core/java/android/os/SystemVibrator.java +10 −1 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ public class SystemVibrator extends Vibrator { mRegisteredListeners = new ArrayMap<>(); private final Object mLock = new Object(); @GuardedBy("mLock") private AllVibratorsInfo mVibratorInfo; @UnsupportedAppUsage Loading @@ -73,7 +74,15 @@ public class SystemVibrator extends Vibrator { int[] vibratorIds = mVibratorManager.getVibratorIds(); VibratorInfo[] vibratorInfos = new VibratorInfo[vibratorIds.length]; for (int i = 0; i < vibratorIds.length; i++) { vibratorInfos[i] = mVibratorManager.getVibrator(vibratorIds[i]).getInfo(); Vibrator vibrator = mVibratorManager.getVibrator(vibratorIds[i]); if (vibrator instanceof NullVibrator) { Log.w(TAG, "Vibrator manager service not ready; " + "Info not yet available for vibrator: " + vibratorIds[i]); // This should never happen after the vibrator manager service is ready. // Skip caching this vibrator until then. return VibratorInfo.EMPTY_VIBRATOR_INFO; } vibratorInfos[i] = vibrator.getInfo(); } return mVibratorInfo = new AllVibratorsInfo(vibratorInfos); } Loading core/java/android/os/Vibrator.java +5 −1 Original line number Diff line number Diff line Loading @@ -165,7 +165,11 @@ public abstract class Vibrator { return ctx != null ? ctx.getResources().getFloat(resId) : defaultValue; } /** @hide */ /** * Get the info describing this vibrator. * * @hide */ protected VibratorInfo getInfo() { return VibratorInfo.EMPTY_VIBRATOR_INFO; } Loading core/java/android/os/VibratorInfo.java +2 −1 Original line number Diff line number Diff line Loading @@ -461,7 +461,8 @@ public class VibratorInfo implements Parcelable { int supportedPrimitivesCount = mSupportedPrimitives.size(); String[] names = new String[supportedPrimitivesCount]; for (int i = 0; i < supportedPrimitivesCount; i++) { names[i] = VibrationEffect.Composition.primitiveToString(mSupportedPrimitives.keyAt(i)); names[i] = VibrationEffect.Composition.primitiveToString(mSupportedPrimitives.keyAt(i)) + "(" + mSupportedPrimitives.valueAt(i) + "ms)"; } return names; } Loading services/core/java/com/android/server/vibrator/VibratorController.java +56 −25 Original line number Diff line number Diff line Loading @@ -41,12 +41,11 @@ final class VibratorController { private final Object mLock = new Object(); private final NativeWrapper mNativeWrapper; private final VibratorInfo.Builder mVibratorInfoBuilder; @GuardedBy("mLock") private VibratorInfo mVibratorInfo; @GuardedBy("mLock") private boolean mVibratorInfoLoaded; private boolean mVibratorInfoLoadSuccessful; @GuardedBy("mLock") private final RemoteCallbackList<IVibratorStateListener> mVibratorStateListeners = new RemoteCallbackList<>(); Loading @@ -73,10 +72,16 @@ final class VibratorController { NativeWrapper nativeWrapper) { mNativeWrapper = nativeWrapper; mNativeWrapper.init(vibratorId, listener); mVibratorInfoBuilder = new VibratorInfo.Builder(vibratorId); mVibratorInfoLoaded = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE, mVibratorInfoBuilder); mVibratorInfo = mVibratorInfoBuilder.build(); VibratorInfo.Builder vibratorInfoBuilder = new VibratorInfo.Builder(vibratorId); mVibratorInfoLoadSuccessful = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE, vibratorInfoBuilder); mVibratorInfo = vibratorInfoBuilder.build(); if (!mVibratorInfoLoadSuccessful) { Slog.e(TAG, "Vibrator controller initialization failed to load some HAL info for vibrator " + vibratorId); } } /** Register state listener for this vibrator. */ Loading Loading @@ -108,15 +113,33 @@ final class VibratorController { } } /** Reruns the query to the vibrator to load the {@link VibratorInfo}, if not yet successful. */ public void reloadVibratorInfoIfNeeded() { synchronized (mLock) { if (mVibratorInfoLoadSuccessful) { return; } int vibratorId = mVibratorInfo.getId(); VibratorInfo.Builder vibratorInfoBuilder = new VibratorInfo.Builder(vibratorId); mVibratorInfoLoadSuccessful = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE, vibratorInfoBuilder); mVibratorInfo = vibratorInfoBuilder.build(); if (!mVibratorInfoLoadSuccessful) { Slog.e(TAG, "Failed retry of HAL getInfo for vibrator " + vibratorId); } } } /** Checks if the {@link VibratorInfo} was loaded from the vibrator hardware successfully. */ boolean isVibratorInfoLoadSuccessful() { synchronized (mLock) { return mVibratorInfoLoadSuccessful; } } /** Return the {@link VibratorInfo} representing the vibrator controlled by this instance. */ public VibratorInfo getVibratorInfo() { synchronized (mLock) { if (!mVibratorInfoLoaded) { // Try to load the vibrator metadata that has failed in the last attempt. mVibratorInfoLoaded = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE, mVibratorInfoBuilder); mVibratorInfo = mVibratorInfoBuilder.build(); } return mVibratorInfo; } } Loading Loading @@ -164,8 +187,10 @@ final class VibratorController { * @return true if this vibrator has this capability, false otherwise */ public boolean hasCapability(long capability) { synchronized (mLock) { return mVibratorInfo.hasCapability(capability); } } /** Return {@code true} if the underlying vibrator is currently available, false otherwise. */ public boolean isAvailable() { Loading @@ -178,10 +203,10 @@ final class VibratorController { * <p>This will affect the state of {@link #isUnderExternalControl()}. */ public void setExternalControl(boolean externalControl) { synchronized (mLock) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { return; } synchronized (mLock) { mIsUnderExternalControl = externalControl; mNativeWrapper.setExternalControl(externalControl); } Loading @@ -192,10 +217,10 @@ final class VibratorController { * if given {@code effect} is {@code null}. */ public void updateAlwaysOn(int id, @Nullable PrebakedSegment prebaked) { synchronized (mLock) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) { return; } synchronized (mLock) { if (prebaked == null) { mNativeWrapper.alwaysOnDisable(id); } else { Loading Loading @@ -268,10 +293,10 @@ final class VibratorController { * do not support the input or a negative number if the operation failed. */ public long on(PrimitiveSegment[] primitives, long vibrationId) { synchronized (mLock) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { return 0; } synchronized (mLock) { long duration = mNativeWrapper.compose(primitives, vibrationId); if (duration > 0) { mCurrentAmplitude = -1; Loading @@ -290,10 +315,10 @@ final class VibratorController { * @return The duration of the effect playing, or 0 if unsupported. */ public long on(RampSegment[] primitives, long vibrationId) { synchronized (mLock) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) { return 0; } synchronized (mLock) { int braking = mVibratorInfo.getDefaultBraking(); long duration = mNativeWrapper.composePwle(primitives, braking, vibrationId); if (duration > 0) { Loading Loading @@ -327,6 +352,7 @@ final class VibratorController { synchronized (mLock) { return "VibratorController{" + "mVibratorInfo=" + mVibratorInfo + ", mVibratorInfoLoadSuccessful=" + mVibratorInfoLoadSuccessful + ", mIsVibrating=" + mIsVibrating + ", mCurrentAmplitude=" + mCurrentAmplitude + ", mIsUnderExternalControl=" + mIsUnderExternalControl Loading Loading @@ -393,10 +419,15 @@ final class VibratorController { * allocated and returned by {@link #nativeInit(int, OnVibrationCompleteListener)}. */ private static native long getNativeFinalizer(); private static native boolean isAvailable(long nativePtr); private static native long on(long nativePtr, long milliseconds, long vibrationId); private static native void off(long nativePtr); private static native void setAmplitude(long nativePtr, float amplitude); private static native long performEffect(long nativePtr, long effect, long strength, long vibrationId); Loading services/core/java/com/android/server/vibrator/VibratorManagerService.java +26 −2 Original line number Diff line number Diff line Loading @@ -128,6 +128,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { private VibrationThread mNextVibration; @GuardedBy("mLock") private ExternalVibrationHolder mCurrentExternalVibration; @GuardedBy("mLock") private boolean mServiceReady; private final VibrationSettings mVibrationSettings; private final VibrationScaler mVibrationScaler; Loading Loading @@ -201,6 +203,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*"); mWakeLock.setReferenceCounted(true); // Load vibrator hardware info. The vibrator ids and manager capabilities are loaded only // once and assumed unchanged for the lifecycle of this service. Each individual vibrator // can still retry loading each individual vibrator hardware spec once more at systemReady. mCapabilities = mNativeWrapper.getCapabilities(); int[] vibratorIds = mNativeWrapper.getVibratorIds(); if (vibratorIds == null) { Loading Loading @@ -235,6 +240,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { Slog.v(TAG, "Initializing VibratorManager service..."); Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "systemReady"); try { // Will retry to load each vibrator's info, if any request have failed. for (int i = 0; i < mVibrators.size(); i++) { mVibrators.valueAt(i).reloadVibratorInfoIfNeeded(); } mVibrationSettings.onSystemReady(); mInputDeviceDelegate.onSystemReady(); Loading @@ -243,6 +253,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { // Will update settings and input devices. updateServiceState(); } finally { synchronized (mLock) { mServiceReady = true; } Slog.v(TAG, "VibratorManager service initialized"); Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } Loading @@ -256,8 +269,19 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override // Binder call @Nullable public VibratorInfo getVibratorInfo(int vibratorId) { VibratorController controller = mVibrators.get(vibratorId); return controller == null ? null : controller.getVibratorInfo(); final VibratorController controller = mVibrators.get(vibratorId); if (controller == null) { return null; } final VibratorInfo info = controller.getVibratorInfo(); synchronized (mLock) { if (mServiceReady) { return info; } } // If the service is not ready and the load was unsuccessful then return null while waiting // for the service to be ready. It will retry to load the complete info from the HAL. return controller.isVibratorInfoLoadSuccessful() ? info : null; } @Override // Binder call Loading Loading
core/java/android/os/SystemVibrator.java +10 −1 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ public class SystemVibrator extends Vibrator { mRegisteredListeners = new ArrayMap<>(); private final Object mLock = new Object(); @GuardedBy("mLock") private AllVibratorsInfo mVibratorInfo; @UnsupportedAppUsage Loading @@ -73,7 +74,15 @@ public class SystemVibrator extends Vibrator { int[] vibratorIds = mVibratorManager.getVibratorIds(); VibratorInfo[] vibratorInfos = new VibratorInfo[vibratorIds.length]; for (int i = 0; i < vibratorIds.length; i++) { vibratorInfos[i] = mVibratorManager.getVibrator(vibratorIds[i]).getInfo(); Vibrator vibrator = mVibratorManager.getVibrator(vibratorIds[i]); if (vibrator instanceof NullVibrator) { Log.w(TAG, "Vibrator manager service not ready; " + "Info not yet available for vibrator: " + vibratorIds[i]); // This should never happen after the vibrator manager service is ready. // Skip caching this vibrator until then. return VibratorInfo.EMPTY_VIBRATOR_INFO; } vibratorInfos[i] = vibrator.getInfo(); } return mVibratorInfo = new AllVibratorsInfo(vibratorInfos); } Loading
core/java/android/os/Vibrator.java +5 −1 Original line number Diff line number Diff line Loading @@ -165,7 +165,11 @@ public abstract class Vibrator { return ctx != null ? ctx.getResources().getFloat(resId) : defaultValue; } /** @hide */ /** * Get the info describing this vibrator. * * @hide */ protected VibratorInfo getInfo() { return VibratorInfo.EMPTY_VIBRATOR_INFO; } Loading
core/java/android/os/VibratorInfo.java +2 −1 Original line number Diff line number Diff line Loading @@ -461,7 +461,8 @@ public class VibratorInfo implements Parcelable { int supportedPrimitivesCount = mSupportedPrimitives.size(); String[] names = new String[supportedPrimitivesCount]; for (int i = 0; i < supportedPrimitivesCount; i++) { names[i] = VibrationEffect.Composition.primitiveToString(mSupportedPrimitives.keyAt(i)); names[i] = VibrationEffect.Composition.primitiveToString(mSupportedPrimitives.keyAt(i)) + "(" + mSupportedPrimitives.valueAt(i) + "ms)"; } return names; } Loading
services/core/java/com/android/server/vibrator/VibratorController.java +56 −25 Original line number Diff line number Diff line Loading @@ -41,12 +41,11 @@ final class VibratorController { private final Object mLock = new Object(); private final NativeWrapper mNativeWrapper; private final VibratorInfo.Builder mVibratorInfoBuilder; @GuardedBy("mLock") private VibratorInfo mVibratorInfo; @GuardedBy("mLock") private boolean mVibratorInfoLoaded; private boolean mVibratorInfoLoadSuccessful; @GuardedBy("mLock") private final RemoteCallbackList<IVibratorStateListener> mVibratorStateListeners = new RemoteCallbackList<>(); Loading @@ -73,10 +72,16 @@ final class VibratorController { NativeWrapper nativeWrapper) { mNativeWrapper = nativeWrapper; mNativeWrapper.init(vibratorId, listener); mVibratorInfoBuilder = new VibratorInfo.Builder(vibratorId); mVibratorInfoLoaded = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE, mVibratorInfoBuilder); mVibratorInfo = mVibratorInfoBuilder.build(); VibratorInfo.Builder vibratorInfoBuilder = new VibratorInfo.Builder(vibratorId); mVibratorInfoLoadSuccessful = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE, vibratorInfoBuilder); mVibratorInfo = vibratorInfoBuilder.build(); if (!mVibratorInfoLoadSuccessful) { Slog.e(TAG, "Vibrator controller initialization failed to load some HAL info for vibrator " + vibratorId); } } /** Register state listener for this vibrator. */ Loading Loading @@ -108,15 +113,33 @@ final class VibratorController { } } /** Reruns the query to the vibrator to load the {@link VibratorInfo}, if not yet successful. */ public void reloadVibratorInfoIfNeeded() { synchronized (mLock) { if (mVibratorInfoLoadSuccessful) { return; } int vibratorId = mVibratorInfo.getId(); VibratorInfo.Builder vibratorInfoBuilder = new VibratorInfo.Builder(vibratorId); mVibratorInfoLoadSuccessful = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE, vibratorInfoBuilder); mVibratorInfo = vibratorInfoBuilder.build(); if (!mVibratorInfoLoadSuccessful) { Slog.e(TAG, "Failed retry of HAL getInfo for vibrator " + vibratorId); } } } /** Checks if the {@link VibratorInfo} was loaded from the vibrator hardware successfully. */ boolean isVibratorInfoLoadSuccessful() { synchronized (mLock) { return mVibratorInfoLoadSuccessful; } } /** Return the {@link VibratorInfo} representing the vibrator controlled by this instance. */ public VibratorInfo getVibratorInfo() { synchronized (mLock) { if (!mVibratorInfoLoaded) { // Try to load the vibrator metadata that has failed in the last attempt. mVibratorInfoLoaded = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE, mVibratorInfoBuilder); mVibratorInfo = mVibratorInfoBuilder.build(); } return mVibratorInfo; } } Loading Loading @@ -164,8 +187,10 @@ final class VibratorController { * @return true if this vibrator has this capability, false otherwise */ public boolean hasCapability(long capability) { synchronized (mLock) { return mVibratorInfo.hasCapability(capability); } } /** Return {@code true} if the underlying vibrator is currently available, false otherwise. */ public boolean isAvailable() { Loading @@ -178,10 +203,10 @@ final class VibratorController { * <p>This will affect the state of {@link #isUnderExternalControl()}. */ public void setExternalControl(boolean externalControl) { synchronized (mLock) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { return; } synchronized (mLock) { mIsUnderExternalControl = externalControl; mNativeWrapper.setExternalControl(externalControl); } Loading @@ -192,10 +217,10 @@ final class VibratorController { * if given {@code effect} is {@code null}. */ public void updateAlwaysOn(int id, @Nullable PrebakedSegment prebaked) { synchronized (mLock) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) { return; } synchronized (mLock) { if (prebaked == null) { mNativeWrapper.alwaysOnDisable(id); } else { Loading Loading @@ -268,10 +293,10 @@ final class VibratorController { * do not support the input or a negative number if the operation failed. */ public long on(PrimitiveSegment[] primitives, long vibrationId) { synchronized (mLock) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { return 0; } synchronized (mLock) { long duration = mNativeWrapper.compose(primitives, vibrationId); if (duration > 0) { mCurrentAmplitude = -1; Loading @@ -290,10 +315,10 @@ final class VibratorController { * @return The duration of the effect playing, or 0 if unsupported. */ public long on(RampSegment[] primitives, long vibrationId) { synchronized (mLock) { if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) { return 0; } synchronized (mLock) { int braking = mVibratorInfo.getDefaultBraking(); long duration = mNativeWrapper.composePwle(primitives, braking, vibrationId); if (duration > 0) { Loading Loading @@ -327,6 +352,7 @@ final class VibratorController { synchronized (mLock) { return "VibratorController{" + "mVibratorInfo=" + mVibratorInfo + ", mVibratorInfoLoadSuccessful=" + mVibratorInfoLoadSuccessful + ", mIsVibrating=" + mIsVibrating + ", mCurrentAmplitude=" + mCurrentAmplitude + ", mIsUnderExternalControl=" + mIsUnderExternalControl Loading Loading @@ -393,10 +419,15 @@ final class VibratorController { * allocated and returned by {@link #nativeInit(int, OnVibrationCompleteListener)}. */ private static native long getNativeFinalizer(); private static native boolean isAvailable(long nativePtr); private static native long on(long nativePtr, long milliseconds, long vibrationId); private static native void off(long nativePtr); private static native void setAmplitude(long nativePtr, float amplitude); private static native long performEffect(long nativePtr, long effect, long strength, long vibrationId); Loading
services/core/java/com/android/server/vibrator/VibratorManagerService.java +26 −2 Original line number Diff line number Diff line Loading @@ -128,6 +128,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { private VibrationThread mNextVibration; @GuardedBy("mLock") private ExternalVibrationHolder mCurrentExternalVibration; @GuardedBy("mLock") private boolean mServiceReady; private final VibrationSettings mVibrationSettings; private final VibrationScaler mVibrationScaler; Loading Loading @@ -201,6 +203,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*"); mWakeLock.setReferenceCounted(true); // Load vibrator hardware info. The vibrator ids and manager capabilities are loaded only // once and assumed unchanged for the lifecycle of this service. Each individual vibrator // can still retry loading each individual vibrator hardware spec once more at systemReady. mCapabilities = mNativeWrapper.getCapabilities(); int[] vibratorIds = mNativeWrapper.getVibratorIds(); if (vibratorIds == null) { Loading Loading @@ -235,6 +240,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { Slog.v(TAG, "Initializing VibratorManager service..."); Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "systemReady"); try { // Will retry to load each vibrator's info, if any request have failed. for (int i = 0; i < mVibrators.size(); i++) { mVibrators.valueAt(i).reloadVibratorInfoIfNeeded(); } mVibrationSettings.onSystemReady(); mInputDeviceDelegate.onSystemReady(); Loading @@ -243,6 +253,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { // Will update settings and input devices. updateServiceState(); } finally { synchronized (mLock) { mServiceReady = true; } Slog.v(TAG, "VibratorManager service initialized"); Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } Loading @@ -256,8 +269,19 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override // Binder call @Nullable public VibratorInfo getVibratorInfo(int vibratorId) { VibratorController controller = mVibrators.get(vibratorId); return controller == null ? null : controller.getVibratorInfo(); final VibratorController controller = mVibrators.get(vibratorId); if (controller == null) { return null; } final VibratorInfo info = controller.getVibratorInfo(); synchronized (mLock) { if (mServiceReady) { return info; } } // If the service is not ready and the load was unsuccessful then return null while waiting // for the service to be ready. It will retry to load the complete info from the HAL. return controller.isVibratorInfoLoadSuccessful() ? info : null; } @Override // Binder call Loading