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

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

Merge "Fixed that the camera will not be blocked on the virtual display in...

Merge "Fixed that the camera will not be blocked on the virtual display in special cases" into tm-dev
parents 885af3d5 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