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

Commit a0ae5c19 authored by Zixuan Qu's avatar Zixuan Qu
Browse files

Register VibrationSettings as a listener to:

1) virtual displays creation and removal.
2) App Uids running on virtual displays.
These will be used in combination to ignore vibration initiated from a virtual display.

Test: VibrationSettingsTest, VibratorManagerServiceTest

bug: 189474679

Change-Id: Ie10dbfe65bb3ab9d62ed5c7b5ed7095a51bccf24
parent cd9be246
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ interface IVibratorManagerService {
    boolean unregisterVibratorStateListener(int vibratorId, in IVibratorStateListener listener);
    boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId,
            in CombinedVibration vibration, in VibrationAttributes attributes);
    void vibrate(int uid, String opPkg, in CombinedVibration vibration,
    void vibrate(int uid, int displayId, String opPkg, in CombinedVibration vibration,
            in VibrationAttributes attributes, String reason, IBinder token);
    void cancelVibrate(int usageFilter, IBinder token);
}
+2 −1
Original line number Diff line number Diff line
@@ -137,7 +137,8 @@ public class SystemVibratorManager extends VibratorManager {
            return;
        }
        try {
            mService.vibrate(uid, opPkg, effect, attributes, reason, mToken);
            mService.vibrate(uid, mContext.getAssociatedDisplayId(), opPkg, effect, attributes,
                    reason, mToken);
        } catch (RemoteException e) {
            Log.w(TAG, "Failed to vibrate.", e);
        }
+1 −0
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@ message VibrationProto {
        IGNORED_FOR_RINGER_MODE = 23;
        IGNORED_FOR_SETTINGS = 24;
        IGNORED_SUPERSEDED = 25;
        IGNORED_FROM_VIRTUAL_DEVICE = 26;
    }
}

+11 −4
Original line number Diff line number Diff line
@@ -71,7 +71,8 @@ final class Vibration {
        IGNORED_FOR_POWER(VibrationProto.IGNORED_FOR_POWER),
        IGNORED_FOR_RINGER_MODE(VibrationProto.IGNORED_FOR_RINGER_MODE),
        IGNORED_FOR_SETTINGS(VibrationProto.IGNORED_FOR_SETTINGS),
        IGNORED_SUPERSEDED(VibrationProto.IGNORED_SUPERSEDED);
        IGNORED_SUPERSEDED(VibrationProto.IGNORED_SUPERSEDED),
        IGNORED_FROM_VIRTUAL_DEVICE(VibrationProto.IGNORED_FROM_VIRTUAL_DEVICE);

        private final int mProtoEnumValue;

@@ -87,6 +88,7 @@ final class Vibration {
    public final VibrationAttributes attrs;
    public final long id;
    public final int uid;
    public final int displayId;
    public final String opPkg;
    public final String reason;
    public final IBinder token;
@@ -113,12 +115,13 @@ final class Vibration {
    private final CountDownLatch mCompletionLatch = new CountDownLatch(1);

    Vibration(IBinder token, int id, CombinedVibration effect,
            VibrationAttributes attrs, int uid, String opPkg, String reason) {
            VibrationAttributes attrs, int uid, int displayId, String opPkg, String reason) {
        this.token = token;
        this.mEffect = effect;
        this.id = id;
        this.attrs = attrs;
        this.uid = uid;
        this.displayId = displayId;
        this.opPkg = opPkg;
        this.reason = reason;
        mStatus = Vibration.Status.RUNNING;
@@ -236,7 +239,7 @@ final class Vibration {
    /** Return {@link Vibration.DebugInfo} with read-only debug information about this vibration. */
    public Vibration.DebugInfo getDebugInfo() {
        return new Vibration.DebugInfo(mStatus, mStats, mEffect, mOriginalEffect, /* scale= */ 0,
                attrs, uid, opPkg, reason);
                attrs, uid, displayId, opPkg, reason);
    }

    /** Return {@link VibrationStats.StatsInfo} with read-only metrics about this vibration. */
@@ -304,13 +307,14 @@ final class Vibration {
        private final float mScale;
        private final VibrationAttributes mAttrs;
        private final int mUid;
        private final int mDisplayId;
        private final String mOpPkg;
        private final String mReason;
        private final Status mStatus;

        DebugInfo(Status status, VibrationStats stats, @Nullable CombinedVibration effect,
                @Nullable CombinedVibration originalEffect, float scale, VibrationAttributes attrs,
                int uid, String opPkg, String reason) {
                int uid, int displayId, String opPkg, String reason) {
            mCreateTime = stats.getCreateTimeDebug();
            mStartTime = stats.getStartTimeDebug();
            mEndTime = stats.getEndTimeDebug();
@@ -320,6 +324,7 @@ final class Vibration {
            mScale = scale;
            mAttrs = attrs;
            mUid = uid;
            mDisplayId = displayId;
            mOpPkg = opPkg;
            mReason = reason;
            mStatus = status;
@@ -349,6 +354,8 @@ final class Vibration {
                    .append(mAttrs)
                    .append(", uid: ")
                    .append(mUid)
                    .append(", displayId: ")
                    .append(mDisplayId)
                    .append(", opPkg: ")
                    .append(mOpPkg)
                    .append(", reason: ")
+81 −1
Original line number Diff line number Diff line
@@ -56,10 +56,12 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.util.proto.ProtoOutputStream;
import android.view.Display;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;

import java.util.ArrayList;
import java.util.Arrays;
@@ -157,6 +159,7 @@ final class VibrationSettings {
    final UidObserver mUidObserver;
    @VisibleForTesting
    final SettingsBroadcastReceiver mSettingChangeReceiver;
    final VirtualDeviceListener mVirtualDeviceListener;

    @GuardedBy("mLock")
    private final List<OnVibratorSettingsChanged> mListeners = new ArrayList<>();
@@ -193,6 +196,7 @@ final class VibrationSettings {
        mSettingObserver = new SettingsContentObserver(handler);
        mUidObserver = new UidObserver();
        mSettingChangeReceiver = new SettingsBroadcastReceiver();
        mVirtualDeviceListener = new VirtualDeviceListener();

        mSystemUiPackage = LocalServices.getService(PackageManagerInternal.class)
                .getSystemUiServiceComponent().getPackageName();
@@ -220,6 +224,8 @@ final class VibrationSettings {

    public void onSystemReady() {
        PowerManagerInternal pm = LocalServices.getService(PowerManagerInternal.class);
        VirtualDeviceManagerInternal vdm = LocalServices.getService(
                VirtualDeviceManagerInternal.class);
        AudioManager am = mContext.getSystemService(AudioManager.class);
        int ringerMode = am.getRingerModeInternal();

@@ -257,6 +263,9 @@ final class VibrationSettings {
                    }
                });

        vdm.registerVirtualDisplayListener(mVirtualDeviceListener);
        vdm.registerAppsOnVirtualDeviceListener(mVirtualDeviceListener);

        registerSettingsChangeReceiver(USER_SWITCHED_INTENT_FILTER);
        registerSettingsChangeReceiver(INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER);

@@ -364,13 +373,17 @@ final class VibrationSettings {
     * null otherwise.
     */
    @Nullable
    public Vibration.Status shouldIgnoreVibration(int uid, VibrationAttributes attrs) {
    public Vibration.Status shouldIgnoreVibration(int uid, int displayId,
            VibrationAttributes attrs) {
        final int usage = attrs.getUsage();
        synchronized (mLock) {
            if (!mUidObserver.isUidForeground(uid)
                    && !BACKGROUND_PROCESS_USAGE_ALLOWLIST.contains(usage)) {
                return Vibration.Status.IGNORED_BACKGROUND;
            }
            if (mVirtualDeviceListener.isAppOrDisplayOnAnyVirtualDevice(uid, displayId)) {
                return Vibration.Status.IGNORED_FROM_VIRTUAL_DEVICE;
            }

            if (mBatterySaverMode && !BATTERY_SAVER_USAGE_ALLOWLIST.contains(usage)) {
                return Vibration.Status.IGNORED_FOR_POWER;
@@ -741,4 +754,71 @@ final class VibrationSettings {
        public void onUidProcAdjChanged(int uid) {
        }
    }

    /**
     * Implementation of Virtual Device listeners for the changes of virtual displays and of apps
     * running on any virtual device.
     */
    final class VirtualDeviceListener implements
            VirtualDeviceManagerInternal.VirtualDisplayListener,
            VirtualDeviceManagerInternal.AppsOnVirtualDeviceListener {
        @GuardedBy("mLock")
        private final Set<Integer> mVirtualDisplays = new HashSet<>();
        @GuardedBy("mLock")
        private final Set<Integer> mAppsOnVirtualDevice = new HashSet<>();


        @Override
        public void onVirtualDisplayCreated(int displayId) {
            synchronized (mLock) {
                mVirtualDisplays.add(displayId);
            }
        }

        @Override
        public void onVirtualDisplayRemoved(int displayId) {
            synchronized (mLock) {
                mVirtualDisplays.remove(displayId);
            }
        }


        @Override
        public void onAppsOnAnyVirtualDeviceChanged(Set<Integer> allRunningUids) {
            synchronized (mLock) {
                mAppsOnVirtualDevice.clear();
                mAppsOnVirtualDevice.addAll(allRunningUids);
            }


        }

        /**
         * @param uid:       uid of the calling app.
         * @param displayId: the id of a Display.
         * @return Returns true if:
         * 1) the displayId is valid, and it's owned by a virtual device
         * 2) the displayId is invalid, and the calling app (uid) is running on a virtual device.
         */
        public boolean isAppOrDisplayOnAnyVirtualDevice(int uid, int displayId) {
            synchronized (mLock) {
                switch (displayId) {
                    case Display.DEFAULT_DISPLAY:
                        // The default display is the primary physical display on the phone.
                        return false;
                    case Display.INVALID_DISPLAY:
                        // There is no Display object associated with the Context of calling
                        // {@link SystemVibratorManager}, checking the calling UID instead.
                        return mAppsOnVirtualDevice.contains(uid);
                    default:
                        // Other valid display IDs representing valid logical displays will be
                        // checked
                        // against the active virtual displays set built with the registered
                        // {@link VirtualDisplayListener}.
                        return mVirtualDisplays.contains(displayId);
                }
            }
        }

    }
}
Loading