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

Commit ff063eb6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add flag to refresh of user vibration settings before vibrating" into tm-dev

parents 697afc96 4668cc85
Loading
Loading
Loading
Loading
+34 −3
Original line number Diff line number Diff line
@@ -166,12 +166,28 @@ public final class VibrationAttributes implements Parcelable {
     */
    public static final int FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF = 0x2;

    /**
     * Flag requesting vibration effect to be played with fresh user settings values.
     *
     * <p>This flag is not protected by any permission, but vibrations that use it require an extra
     * query of user vibration intensity settings, ringer mode and other controls that affect the
     * vibration effect playback, which can increase the latency for the overall request.
     *
     * <p>This is intended to be used on scenarios where the user settings might have changed
     * recently, and needs to be applied to this vibration, like settings controllers that preview
     * newly set intensities to the user.
     *
     * @hide
     */
    public static final int FLAG_INVALIDATE_SETTINGS_CACHE = 0x3;

    /**
     * All flags supported by vibrator service, update it when adding new flag.
     * @hide
     */
    public static final int FLAG_ALL_SUPPORTED =
            FLAG_BYPASS_INTERRUPTION_POLICY | FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF;
            FLAG_BYPASS_INTERRUPTION_POLICY | FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF
                    | FLAG_INVALIDATE_SETTINGS_CACHE;

    /** Creates a new {@link VibrationAttributes} instance with given usage. */
    public static @NonNull VibrationAttributes createForUsage(@Usage int usage) {
@@ -446,8 +462,10 @@ public final class VibrationAttributes implements Parcelable {
        }

        /**
         * Set flags
         * @param flags combination of flags to be set.
         * Sets only the flags specified in the bitmask, leaving the other supported flag values
         * unchanged in the builder.
         *
         * @param flags Combination of flags to be set.
         * @param mask Bit range that should be changed.
         * @return the same Builder instance.
         */
@@ -456,5 +474,18 @@ public final class VibrationAttributes implements Parcelable {
            mFlags = (mFlags & ~mask) | (flags & mask);
            return this;
        }

        /**
         * Set all supported flags with given combination of flags, overriding any previous values
         * set to this builder.
         *
         * @param flags combination of flags to be set.
         * @return the same Builder instance.
         *
         * @hide
         */
        public @NonNull Builder setFlags(@Flag int flags) {
            return setFlags(flags, FLAG_ALL_SUPPORTED);
        }
    }
}
+1 −2
Original line number Diff line number Diff line
@@ -5446,8 +5446,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        VibrationAttributes attrs = getVibrationAttributes(effectId);
        if (always) {
            attrs = new VibrationAttributes.Builder(attrs)
                    .setFlags(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF,
                            VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)
                    .setFlags(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)
                    .build();
        }
        mVibrator.vibrate(uid, packageName, effect, reason, attrs);
+55 −24
Original line number Diff line number Diff line
@@ -121,6 +121,11 @@ final class VibrationSettings {
                    USAGE_PHYSICAL_EMULATION,
                    USAGE_HARDWARE_FEEDBACK));

    private static final IntentFilter USER_SWITCHED_INTENT_FILTER =
            new IntentFilter(Intent.ACTION_USER_SWITCHED);
    private static final IntentFilter INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER =
            new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);

    /** Listener for changes on vibration settings. */
    interface OnVibratorSettingsChanged {
        /** Callback triggered when any of the vibrator settings change. */
@@ -130,11 +135,11 @@ final class VibrationSettings {
    private final Object mLock = new Object();
    private final Context mContext;
    private final String mSystemUiPackage;
    private final SettingsObserver mSettingObserver;
    private final SettingsContentObserver mSettingObserver;
    @VisibleForTesting
    final UidObserver mUidObserver;
    @VisibleForTesting
    final UserObserver mUserReceiver;
    final SettingsBroadcastReceiver mSettingChangeReceiver;

    @GuardedBy("mLock")
    private final List<OnVibratorSettingsChanged> mListeners = new ArrayList<>();
@@ -154,6 +159,8 @@ final class VibrationSettings {
    private boolean mBatterySaverMode;
    @GuardedBy("mLock")
    private boolean mVibrateOn;
    @GuardedBy("mLock")
    private int mRingerMode;

    VibrationSettings(Context context, Handler handler) {
        this(context, handler, new VibrationConfig(context.getResources()));
@@ -163,9 +170,9 @@ final class VibrationSettings {
    VibrationSettings(Context context, Handler handler, VibrationConfig config) {
        mContext = context;
        mVibrationConfig = config;
        mSettingObserver = new SettingsObserver(handler);
        mSettingObserver = new SettingsContentObserver(handler);
        mUidObserver = new UidObserver();
        mUserReceiver = new UserObserver();
        mSettingChangeReceiver = new SettingsBroadcastReceiver();

        mSystemUiPackage = LocalServices.getService(PackageManagerInternal.class)
                .getSystemUiServiceComponent().getPackageName();
@@ -188,12 +195,13 @@ final class VibrationSettings {
                VibrationEffect.get(VibrationEffect.EFFECT_TICK, false));

        // Update with current values from settings.
        updateSettings();
        update();
    }

    public void onSystemReady() {
        synchronized (mLock) {
            mAudioManager = mContext.getSystemService(AudioManager.class);
            mRingerMode = mAudioManager.getRingerModeInternal();
        }
        try {
            ActivityManager.getService().registerUidObserver(mUidObserver,
@@ -224,8 +232,8 @@ final class VibrationSettings {
                    }
                });

        IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
        mContext.registerReceiver(mUserReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
        registerSettingsChangeReceiver(USER_SWITCHED_INTENT_FILTER);
        registerSettingsChangeReceiver(INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER);

        // Listen to all settings that might affect the result of Vibrator.getVibrationIntensity.
        registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES));
@@ -248,7 +256,7 @@ final class VibrationSettings {
                Settings.System.getUriFor(Settings.System.RING_VIBRATION_INTENSITY));

        // Update with newly loaded services.
        updateSettings();
        update();
    }

    /**
@@ -396,16 +404,17 @@ final class VibrationSettings {
            // Only ringtone and notification vibrations are disabled when phone is on silent mode.
            return true;
        }
        // If audio manager was not loaded yet then assume most restrictive mode.
        int ringerMode = (mAudioManager == null)
                ? AudioManager.RINGER_MODE_SILENT
                : mAudioManager.getRingerModeInternal();
        return ringerMode != AudioManager.RINGER_MODE_SILENT;
        return mRingerMode != AudioManager.RINGER_MODE_SILENT;
    }

    /** Updates all vibration settings and triggers registered listeners. */
    @VisibleForTesting
    void updateSettings() {
    /** Update all cached settings and triggers registered listeners. */
    void update() {
        updateSettings();
        updateRingerMode();
        notifyListeners();
    }

    private void updateSettings() {
        synchronized (mLock) {
            mVibrateInputDevices = loadSystemSetting(Settings.System.VIBRATE_INPUT_DEVICES, 0) > 0;
            mVibrateOn = loadSystemSetting(Settings.System.VIBRATE_ON, 1) > 0;
@@ -435,7 +444,6 @@ final class VibrationSettings {
                    loadSystemSetting(Settings.System.RING_VIBRATION_INTENSITY, -1),
                    getDefaultIntensity(USAGE_RINGTONE));


            mCurrentVibrationIntensities.clear();
            mCurrentVibrationIntensities.put(USAGE_ALARM, alarmIntensity);
            mCurrentVibrationIntensities.put(USAGE_NOTIFICATION, notificationIntensity);
@@ -469,7 +477,16 @@ final class VibrationSettings {
            // A11y is not disabled by any haptic feedback setting.
            mCurrentVibrationIntensities.put(USAGE_ACCESSIBILITY, positiveHapticFeedbackIntensity);
        }
        notifyListeners();
    }

    private void updateRingerMode() {
        synchronized (mLock) {
            // If audio manager was not loaded yet then assume most restrictive mode.
            // This will be loaded again as soon as the audio manager is loaded in onSystemReady.
            mRingerMode = (mAudioManager == null)
                    ? AudioManager.RINGER_MODE_SILENT
                    : mAudioManager.getRingerModeInternal();
        }
    }

    @Override
@@ -586,6 +603,11 @@ final class VibrationSettings {
                UserHandle.USER_ALL);
    }

    private void registerSettingsChangeReceiver(IntentFilter intentFilter) {
        mContext.registerReceiver(mSettingChangeReceiver, intentFilter,
                Context.RECEIVER_NOT_EXPORTED);
    }

    @Nullable
    private VibrationEffect createEffectFromResource(int resId) {
        long[] timings = getLongIntArray(mContext.getResources(), resId);
@@ -616,24 +638,33 @@ final class VibrationSettings {
    }

    /** Implementation of {@link ContentObserver} to be registered to a setting {@link Uri}. */
    private final class SettingsObserver extends ContentObserver {
        SettingsObserver(Handler handler) {
    private final class SettingsContentObserver extends ContentObserver {
        SettingsContentObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            updateSettings();
            notifyListeners();
        }
    }

    /** Implementation of {@link BroadcastReceiver} to update settings on current user change. */
    /**
     * Implementation of {@link BroadcastReceiver} to update settings on current user or ringer
     * mode change.
     */
    @VisibleForTesting
    final class UserObserver extends BroadcastReceiver {
    final class SettingsBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
                updateSettings();
            String action = intent.getAction();
            if (Intent.ACTION_USER_SWITCHED.equals(action)) {
                // Reload all settings, as they are user-based.
                update();
            } else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
                updateRingerMode();
                notifyListeners();
            }
        }
    }
+17 −3
Original line number Diff line number Diff line
@@ -401,6 +401,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
                    uid, opPkg, reason);
            fillVibrationFallbacks(vib, effect);

            if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) {
                // Force update of user settings before checking if this vibration effect should
                // be ignored or scaled.
                mVibrationSettings.update();
            }

            synchronized (mLock) {
                if (DEBUG) {
                    Slog.d(TAG, "Starting vibrate for vibration  " + vib.id);
@@ -1506,12 +1512,20 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
                return IExternalVibratorService.SCALE_MUTE;
            }

            VibrationAttributes attrs = fixupVibrationAttributes(vib.getVibrationAttributes(),
                    /* effect= */ null);
            if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) {
                // Force update of user settings before checking if this vibration effect should
                // be ignored or scaled.
                mVibrationSettings.update();
            }

            boolean alreadyUnderExternalControl = false;
            boolean waitForCompletion = false;
            int scale;
            synchronized (mLock) {
                Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
                        vib.getUid(), vib.getPackage(), vib.getVibrationAttributes());
                        vib.getUid(), vib.getPackage(), attrs);
                if (ignoreStatus != null) {
                    ExternalVibrationHolder vibHolder = new ExternalVibrationHolder(vib);
                    vibHolder.scale = IExternalVibratorService.SCALE_MUTE;
@@ -1549,7 +1563,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
                mCurrentExternalVibration = new ExternalVibrationHolder(vib);
                vib.linkToDeath(mCurrentExternalVibration);
                mCurrentExternalVibration.scale = mVibrationScaler.getExternalVibrationScale(
                        vib.getVibrationAttributes().getUsage());
                        attrs.getUsage());
                scale = mCurrentExternalVibration.scale;
            }

@@ -1908,7 +1922,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
            final int flags =
                    commonOptions.force ? VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY : 0;
            return new VibrationAttributes.Builder()
                    .setFlags(flags, VibrationAttributes.FLAG_ALL_SUPPORTED)
                    .setFlags(flags)
                    // Used to apply Settings.System.HAPTIC_FEEDBACK_INTENSITY to scale effects.
                    .setUsage(VibrationAttributes.USAGE_TOUCH)
                    .build();
+1 −1
Original line number Diff line number Diff line
@@ -277,6 +277,6 @@ public class VibrationScalerTest {
        Settings.System.putIntForUser(
                mContextSpy.getContentResolver(), settingName, value, UserHandle.USER_CURRENT);
        // FakeSettingsProvider don't support testing triggering ContentObserver yet.
        mVibrationSettings.updateSettings();
        mVibrationSettings.update();
    }
}
Loading