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

Commit 6f9d5cec authored by Vladimir Komsiyski's avatar Vladimir Komsiyski Committed by Android (Google) Code Review
Browse files

Merge "Handle lockdown in VDM" into main

parents 34a892d2 a28a3bba
Loading
Loading
Loading
Loading
+59 −24
Original line number Diff line number Diff line
@@ -215,6 +215,10 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
    @GuardedBy("mVirtualDeviceLock")
    @Nullable
    private LocaleList mLocaleList = null;
    @GuardedBy("mVirtualDeviceLock")
    private boolean mLockdownActive = false;
    @GuardedBy("mVirtualDeviceLock")
    private boolean mRequestedToBeAwake = true;

    @NonNull
    private final VirtualDevice mPublicVirtualDeviceObject;
@@ -478,6 +482,20 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
        }
    }

    void onLockdownChanged(boolean lockdownActive) {
        synchronized (mVirtualDeviceLock) {
            if (lockdownActive != mLockdownActive) {
                mLockdownActive = lockdownActive;
                if (mLockdownActive) {
                    goToSleepInternal(PowerManager.GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF);
                } else if (mRequestedToBeAwake) {
                    wakeUpInternal(PowerManager.WAKE_REASON_DISPLAY_GROUP_TURNED_ON,
                            "android.server.companion.virtual:LOCKDOWN_ENDED");
                }
            }
        }
    }

    @VisibleForTesting
    SensorController getSensorControllerForTest() {
        return mSensorController;
@@ -582,20 +600,12 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    public void goToSleep() {
        super.goToSleep_enforcePermission();
        final long now = SystemClock.uptimeMillis();
        final long ident = Binder.clearCallingIdentity();
        try {
        synchronized (mVirtualDeviceLock) {
                for (int i = 0; i < mVirtualDisplays.size(); i++) {
                    VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i);
                    if (!wrapper.isTrusted() || wrapper.isMirror()) {
                        continue;
                    }
                    int displayId = mVirtualDisplays.keyAt(i);
                    mPowerManager.goToSleep(displayId, now,
                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, /* flags= */ 0);
                }
            mRequestedToBeAwake = false;
        }
        final long ident = Binder.clearCallingIdentity();
        try {
            goToSleepInternal(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
@@ -605,20 +615,17 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    public void wakeUp() {
        super.wakeUp_enforcePermission();
        final long now = SystemClock.uptimeMillis();
        final long ident = Binder.clearCallingIdentity();
        try {
        synchronized (mVirtualDeviceLock) {
                for (int i = 0; i < mVirtualDisplays.size(); i++) {
                    VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i);
                    if (!wrapper.isTrusted() || wrapper.isMirror()) {
                        continue;
                    }
                    int displayId = mVirtualDisplays.keyAt(i);
                    mPowerManager.wakeUp(now, PowerManager.WAKE_REASON_POWER_BUTTON,
                            "android.server.companion.virtual:DEVICE_ON", displayId);
            mRequestedToBeAwake = true;
            if (mLockdownActive) {
                Slog.w(TAG, "Cannot wake up device during lockdown.");
                return;
            }
        }
        final long ident = Binder.clearCallingIdentity();
        try {
            wakeUpInternal(PowerManager.WAKE_REASON_POWER_BUTTON,
                    "android.server.companion.virtual:DEVICE_ON");
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
@@ -1622,6 +1629,34 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
        }
    }

    void goToSleepInternal(@PowerManager.GoToSleepReason int reason) {
        final long now = SystemClock.uptimeMillis();
        synchronized (mVirtualDeviceLock) {
            for (int i = 0; i < mVirtualDisplays.size(); i++) {
                VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i);
                if (!wrapper.isTrusted() || wrapper.isMirror()) {
                    continue;
                }
                int displayId = mVirtualDisplays.keyAt(i);
                mPowerManager.goToSleep(displayId, now, reason, /* flags= */ 0);
            }
        }
    }

    void wakeUpInternal(@PowerManager.WakeReason int reason, String details) {
        final long now = SystemClock.uptimeMillis();
        synchronized (mVirtualDeviceLock) {
            for (int i = 0; i < mVirtualDisplays.size(); i++) {
                VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i);
                if (!wrapper.isTrusted() || wrapper.isMirror()) {
                    continue;
                }
                int displayId = mVirtualDisplays.keyAt(i);
                mPowerManager.wakeUp(now, reason, details, displayId);
            }
        }
    }

    /**
     * Release resources tied to virtual display owned by this VirtualDevice instance.
     *
+35 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.modules.expresslog.Counter;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -127,6 +128,26 @@ public class VirtualDeviceManagerService extends SystemService {
                }
            };

    private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
        final Set<Integer> mUsersInLockdown = new ArraySet<>();

        StrongAuthTracker(Context context) {
            super(context);
        }

        @Override
        public synchronized void onStrongAuthRequiredChanged(int userId) {
            if ((getStrongAuthForUser(userId) & STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN) > 0) {
                if (mUsersInLockdown.add(userId) && mUsersInLockdown.size() == 1) {
                    onLockdownChanged(true);
                }
            } else if (mUsersInLockdown.remove(userId) && mUsersInLockdown.isEmpty()) {
                onLockdownChanged(false);
            }
        }
    }
    private StrongAuthTracker mStrongAuthTracker;

    private final RemoteCallbackList<IVirtualDeviceListener> mVirtualDeviceListeners =
            new RemoteCallbackList<>();

@@ -199,6 +220,20 @@ public class VirtualDeviceManagerService extends SystemService {
                        + " will be available.");
            }
        }
        if (android.companion.virtualdevice.flags.Flags.deviceAwareDisplayPower()) {
            mStrongAuthTracker = new StrongAuthTracker(getContext());
            new LockPatternUtils(getContext()).registerStrongAuthTracker(mStrongAuthTracker);
        }
    }

    // Called when the global lockdown state changes, i.e. lockdown is considered active if any user
    // is in lockdown mode, and inactive if no users are in lockdown mode.
    void onLockdownChanged(boolean lockdownActive) {
        synchronized (mVirtualDeviceManagerLock) {
            for (int i = 0; i < mVirtualDevices.size(); i++) {
                mVirtualDevices.valueAt(i).onLockdownChanged(lockdownActive);
            }
        }
    }

    void onCameraAccessBlocked(int appUid) {