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

Commit 30cecc85 authored by Presubmit Automerger Backend's avatar Presubmit Automerger Backend
Browse files

[automerge] Fixed that the camera will not be blocked on the virtual display...

[automerge] Fixed that the camera will not be blocked on the virtual display in special cases 2p: 3895dba9

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16973066

Bug: 210795569
Change-Id: I4a80cf1b6dedacf71eee398e525d951975863200
parents 6cc23462 3895dba9
Loading
Loading
Loading
Loading
+50 −2
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ import android.util.Slog;

import com.android.internal.annotations.GuardedBy;

import java.util.Set;

/**
 * Handles blocking access to the camera for apps running on virtual devices.
 */
@@ -50,11 +52,23 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
    @GuardedBy("mLock")
    private ArrayMap<String, InjectionSessionData> mPackageToSessionData = new ArrayMap<>();

    /**
     * Mapping from camera ID to open camera app associations. Key is the camera id, value is the
     * information of the app's uid and package name.
     */
    @GuardedBy("mLock")
    private ArrayMap<String, OpenCameraInfo> mAppsToBlockOnVirtualDevice = new ArrayMap<>();

    static class InjectionSessionData {
        public int appUid;
        public ArrayMap<String, CameraInjectionSession> cameraIdToSession = new ArrayMap<>();
    }

    static class OpenCameraInfo {
        public String packageName;
        public int packageUid;
    }

    interface CameraAccessBlockedCallback {
        /**
         * Called whenever an app was blocked from accessing a camera.
@@ -98,6 +112,33 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
        }
    }

    /**
     * Need to block camera access for applications running on virtual displays.
     * <p>
     * Apps that open the camera on the main display will need to block camera access if moved to a
     * virtual display.
     *
     * @param runningUids uids of the application running on the virtual display
     */
    public void blockCameraAccessIfNeeded(Set<Integer> runningUids) {
        synchronized (mLock) {
            for (int i = 0; i < mAppsToBlockOnVirtualDevice.size(); i++) {
                final String cameraId = mAppsToBlockOnVirtualDevice.keyAt(i);
                final OpenCameraInfo openCameraInfo = mAppsToBlockOnVirtualDevice.get(cameraId);
                int packageUid = openCameraInfo.packageUid;
                if (runningUids.contains(packageUid)) {
                    final String packageName = openCameraInfo.packageName;
                    InjectionSessionData data = mPackageToSessionData.get(packageName);
                    if (data == null) {
                        data = new InjectionSessionData();
                        data.appUid = packageUid;
                        mPackageToSessionData.put(packageName, data);
                    }
                    startBlocking(packageName, cameraId);
                }
            }
        }
    }

    @Override
    public void close() {
@@ -115,10 +156,13 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
    public void onCameraOpened(@NonNull String cameraId, @NonNull String packageName) {
        synchronized (mLock) {
            try {
                final ApplicationInfo ainfo =
                        mPackageManager.getApplicationInfo(packageName, 0);
                final ApplicationInfo ainfo = mPackageManager.getApplicationInfo(packageName, 0);
                InjectionSessionData data = mPackageToSessionData.get(packageName);
                if (!mVirtualDeviceManagerInternal.isAppRunningOnAnyVirtualDevice(ainfo.uid)) {
                    OpenCameraInfo openCameraInfo = new OpenCameraInfo();
                    openCameraInfo.packageName = packageName;
                    openCameraInfo.packageUid = ainfo.uid;
                    mAppsToBlockOnVirtualDevice.put(cameraId, openCameraInfo);
                    CameraInjectionSession existingSession =
                            (data != null) ? data.cameraIdToSession.get(cameraId) : null;
                    if (existingSession != null) {
@@ -149,6 +193,7 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
    @Override
    public void onCameraClosed(@NonNull String cameraId) {
        synchronized (mLock) {
            mAppsToBlockOnVirtualDevice.remove(cameraId);
            for (int i = mPackageToSessionData.size() - 1; i >= 0; i--) {
                InjectionSessionData data = mPackageToSessionData.valueAt(i);
                CameraInjectionSession session = data.cameraIdToSession.get(cameraId);
@@ -168,6 +213,9 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
     */
    private void startBlocking(String packageName, String cameraId) {
        try {
            Slog.d(
                    TAG,
                    "startBlocking() cameraId: " + cameraId + " packageName: " + packageName);
            mCameraManager.injectCamera(packageName, cameraId, /* externalCamId */ "",
                    mContext.getMainExecutor(),
                    new CameraInjectionSession.InjectionStatusCallback() {
+15 −9
Original line number Diff line number Diff line
@@ -93,9 +93,8 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
    final ArraySet<Integer> mRunningUids = new ArraySet<>();
    @Nullable private final ActivityListener mActivityListener;
    private final Handler mHandler = new Handler(Looper.getMainLooper());

    @Nullable
    private RunningAppsChangedListener mRunningAppsChangedListener;
    private final ArraySet<RunningAppsChangedListener> mRunningAppsChangedListener =
            new ArraySet<>();

    /**
     * Creates a window policy controller that is generic to the different use cases of virtual
@@ -142,9 +141,14 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
        mActivityListener = activityListener;
    }

    /** Sets listener for running applications change. */
    public void setRunningAppsChangedListener(@Nullable RunningAppsChangedListener listener) {
        mRunningAppsChangedListener = listener;
    /** Register a listener for running applications changes. */
    public void registerRunningAppsChangedListener(@NonNull RunningAppsChangedListener listener) {
        mRunningAppsChangedListener.add(listener);
    }

    /** Unregister a listener for running applications changes. */
    public void unregisterRunningAppsChangedListener(@NonNull RunningAppsChangedListener listener) {
        mRunningAppsChangedListener.remove(listener);
    }

    @Override
@@ -237,9 +241,11 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
                mHandler.post(() -> mActivityListener.onDisplayEmpty(Display.INVALID_DISPLAY));
            }
        }
        if (mRunningAppsChangedListener != null) {
            mRunningAppsChangedListener.onRunningAppsChanged(runningUids);
        mHandler.post(() -> {
            for (RunningAppsChangedListener listener : mRunningAppsChangedListener) {
                listener.onRunningAppsChanged(runningUids);
            }
        });
    }

    /**
+24 −6
Original line number Diff line number Diff line
@@ -68,16 +68,18 @@ import android.window.DisplayWindowPolicyController;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.BlockedAppStreamingActivity;
import com.android.server.companion.virtual.GenericWindowPolicyController.RunningAppsChangedListener;
import com.android.server.companion.virtual.audio.VirtualAudioController;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;


final class VirtualDeviceImpl extends IVirtualDevice.Stub
        implements IBinder.DeathRecipient {
        implements IBinder.DeathRecipient, RunningAppsChangedListener {

    private static final String TAG = "VirtualDeviceImpl";

@@ -101,6 +103,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
    private final VirtualDeviceParams mParams;
    private final Map<Integer, PowerManager.WakeLock> mPerDisplayWakelocks = new ArrayMap<>();
    private final IVirtualDeviceActivityListener mActivityListener;
    @NonNull
    private Consumer<ArraySet<Integer>> mRunningAppsChangedCallback;
    // The default setting for showing the pointer on new displays.
    @GuardedBy("mVirtualDeviceLock")
    private boolean mDefaultShowPointerIcon = true;
@@ -139,21 +143,25 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
            IBinder token, int ownerUid, OnDeviceCloseListener listener,
            PendingTrampolineCallback pendingTrampolineCallback,
            IVirtualDeviceActivityListener activityListener,
            Consumer<ArraySet<Integer>> runningAppsChangedCallback,
            VirtualDeviceParams params) {
        this(context, associationInfo, token, ownerUid, /* inputController= */ null, listener,
                pendingTrampolineCallback, activityListener, params);
                pendingTrampolineCallback, activityListener, runningAppsChangedCallback, params);
    }

    @VisibleForTesting
    VirtualDeviceImpl(Context context, AssociationInfo associationInfo, IBinder token,
            int ownerUid, InputController inputController, OnDeviceCloseListener listener,
            PendingTrampolineCallback pendingTrampolineCallback,
            IVirtualDeviceActivityListener activityListener, VirtualDeviceParams params) {
            IVirtualDeviceActivityListener activityListener,
            Consumer<ArraySet<Integer>> runningAppsChangedCallback,
            VirtualDeviceParams params) {
        UserHandle ownerUserHandle = UserHandle.getUserHandleForUid(ownerUid);
        mContext = context.createContextAsUser(ownerUserHandle, 0);
        mAssociationInfo = associationInfo;
        mPendingTrampolineCallback = pendingTrampolineCallback;
        mActivityListener = activityListener;
        mRunningAppsChangedCallback = runningAppsChangedCallback;
        mOwnerUid = ownerUid;
        mAppToken = token;
        mParams = params;
@@ -278,6 +286,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
        close();
    }

    @Override
    public void onRunningAppsChanged(ArraySet<Integer> runningUids) {
        mRunningAppsChangedCallback.accept(runningUids);
    }

    @VisibleForTesting
    VirtualAudioController getVirtualAudioControllerForTesting() {
        return mVirtualAudioController;
@@ -529,7 +542,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
            // reentrancy  problems.
            mContext.getMainThreadHandler().post(() -> addWakeLockForDisplay(displayId));

            final GenericWindowPolicyController dwpc =
            final GenericWindowPolicyController gwpc =
                    new GenericWindowPolicyController(FLAG_SECURE,
                            SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
                            getAllowedUserHandles(),
@@ -540,8 +553,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
                            mParams.getDefaultActivityPolicy(),
                            createListenerAdapter(displayId),
                            activityInfo -> onActivityBlocked(displayId, activityInfo));
            mWindowPolicyControllers.put(displayId, dwpc);
            return dwpc;
            gwpc.registerRunningAppsChangedListener(/* listener= */ this);
            mWindowPolicyControllers.put(displayId, gwpc);
            return gwpc;
        }
    }

@@ -599,6 +613,10 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
                wakeLock.release();
                mPerDisplayWakelocks.remove(displayId);
            }
            GenericWindowPolicyController gwpc = mWindowPolicyControllers.get(displayId);
            if (gwpc != null) {
                gwpc.unregisterRunningAppsChangedListener(/* listener= */ this);
            }
            mVirtualDisplayIds.remove(displayId);
            mWindowPolicyControllers.remove(displayId);
        }
+4 −1
Original line number Diff line number Diff line
@@ -251,7 +251,10 @@ public class VirtualDeviceManagerService extends SystemService {
                                }
                            }
                        },
                        this, activityListener, params);
                        this, activityListener,
                        runningUids -> cameraAccessController.blockCameraAccessIfNeeded(
                                runningUids),
                        params);
                if (cameraAccessController != null) {
                    cameraAccessController.startObservingIfNeeded();
                } else {
+3 −2
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ public final class VirtualAudioController implements AudioPlaybackCallback,
            @NonNull IAudioRoutingCallback routingCallback,
            @Nullable IAudioConfigChangedCallback configChangedCallback) {
        mGenericWindowPolicyController = genericWindowPolicyController;
        mGenericWindowPolicyController.setRunningAppsChangedListener(/* listener= */ this);
        mGenericWindowPolicyController.registerRunningAppsChangedListener(/* listener= */ this);
        synchronized (mCallbackLock) {
            mRoutingCallback = routingCallback;
            mConfigChangedCallback = configChangedCallback;
@@ -111,7 +111,8 @@ public final class VirtualAudioController implements AudioPlaybackCallback,
        mAudioPlaybackDetector.unregister();
        mAudioRecordingDetector.unregister();
        if (mGenericWindowPolicyController != null) {
            mGenericWindowPolicyController.setRunningAppsChangedListener(/* listener= */ null);
            mGenericWindowPolicyController.unregisterRunningAppsChangedListener(
                    /* listener= */ this);
            mGenericWindowPolicyController = null;
        }
        synchronized (mCallbackLock) {
Loading