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

Commit 6858a4a3 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Fix secondary user test for VirtualDevice" into tm-dev am: f5170f48

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

Change-Id: I196317d51a51fc16da0dc52fc7074c2ac88553c2
parents f330bc3f f5170f48
Loading
Loading
Loading
Loading
+28 −11
Original line number Diff line number Diff line
@@ -33,17 +33,19 @@ import com.android.internal.annotations.GuardedBy;
/**
 * Handles blocking access to the camera for apps running on virtual devices.
 */
class CameraAccessController extends CameraManager.AvailabilityCallback {
class CameraAccessController extends CameraManager.AvailabilityCallback implements AutoCloseable {
    private static final String TAG = "CameraAccessController";

    private final Object mLock = new Object();

    private final Context mContext;
    private VirtualDeviceManagerInternal mVirtualDeviceManagerInternal;
    CameraAccessBlockedCallback mBlockedCallback;
    private CameraManager mCameraManager;
    private boolean mListeningForCameraEvents;
    private PackageManager mPackageManager;
    private final VirtualDeviceManagerInternal mVirtualDeviceManagerInternal;
    private final CameraAccessBlockedCallback mBlockedCallback;
    private final CameraManager mCameraManager;
    private final PackageManager mPackageManager;

    @GuardedBy("mLock")
    private int mObserverCount = 0;

    @GuardedBy("mLock")
    private ArrayMap<String, InjectionSessionData> mPackageToSessionData = new ArrayMap<>();
@@ -77,21 +79,36 @@ class CameraAccessController extends CameraManager.AvailabilityCallback {
     */
    public void startObservingIfNeeded() {
        synchronized (mLock) {
            if (!mListeningForCameraEvents) {
            if (mObserverCount == 0) {
                mCameraManager.registerAvailabilityCallback(mContext.getMainExecutor(), this);
                mListeningForCameraEvents = true;
            }
            mObserverCount++;
        }
    }

    /**
     * Stop watching for camera access.
     */
    public void stopObserving() {
    public void stopObservingIfNeeded() {
        synchronized (mLock) {
            mCameraManager.unregisterAvailabilityCallback(this);
            mListeningForCameraEvents = false;
            mObserverCount--;
            if (mObserverCount <= 0) {
                close();
            }
        }
    }


    @Override
    public void close() {
        synchronized (mLock) {
            if (mObserverCount < 0) {
                Slog.wtf(TAG, "Unexpected negative mObserverCount: " + mObserverCount);
            } else if (mObserverCount > 0) {
                Slog.w(TAG, "Unexpected close with observers remaining: " + mObserverCount);
            }
        }
        mCameraManager.unregisterAvailabilityCallback(this);
    }

    @Override
+11 −5
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.server.companion.virtual;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.UserHandle;
import android.util.Slog;

/**
@@ -32,13 +34,15 @@ class PermissionUtils {
     *
     * @param context the context
     * @param callingPackage the calling application package name
     * @param callingUid the calling application uid
     * @return {@code true} if the package name matches the calling app uid, {@code false} otherwise
     * @return {@code true} if the package name matches {@link Binder#getCallingUid()}, or
     *   {@code false} otherwise
     */
    public static boolean validatePackageName(Context context, String callingPackage,
            int callingUid) {
    public static boolean validateCallingPackageName(Context context, String callingPackage) {
        final int callingUid = Binder.getCallingUid();
        final long token = Binder.clearCallingIdentity();
        try {
            int packageUid = context.getPackageManager().getPackageUid(callingPackage, 0);
            int packageUid = context.getPackageManager()
                    .getPackageUidAsUser(callingPackage, UserHandle.getUserId(callingUid));
            if (packageUid != callingUid) {
                Slog.e(LOG_TAG, "validatePackageName: App with package name " + callingPackage
                        + " is UID " + packageUid + " but caller is " + callingUid);
@@ -48,6 +52,8 @@ class PermissionUtils {
            Slog.e(LOG_TAG, "validatePackageName: App with package name " + callingPackage
                    + " does not exist");
            return false;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        return true;
    }
+2 −1
Original line number Diff line number Diff line
@@ -140,7 +140,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
            int ownerUid, InputController inputController, OnDeviceCloseListener listener,
            PendingTrampolineCallback pendingTrampolineCallback,
            IVirtualDeviceActivityListener activityListener, VirtualDeviceParams params) {
        mContext = context;
        UserHandle ownerUserHandle = UserHandle.getUserHandleForUid(ownerUid);
        mContext = context.createContextAsUser(ownerUserHandle, 0);
        mAssociationInfo = associationInfo;
        mPendingTrampolineCallback = pendingTrampolineCallback;
        mActivityListener = activityListener;
+35 −10
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Parcel;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ExceptionUtils;
import android.util.Slog;
import android.util.SparseArray;
@@ -66,7 +67,12 @@ public class VirtualDeviceManagerService extends SystemService {
    private VirtualDeviceManagerInternal mLocalService;
    private final Handler mHandler = new Handler(Looper.getMainLooper());
    private final PendingTrampolineMap mPendingTrampolines = new PendingTrampolineMap(mHandler);
    private final CameraAccessController mCameraAccessController;
    /**
     * Mapping from user IDs to CameraAccessControllers.
     */
    @GuardedBy("mVirtualDeviceManagerLock")
    private final SparseArray<CameraAccessController> mCameraAccessControllers =
            new SparseArray<>();

    /**
     * Mapping from CDM association IDs to virtual devices. Only one virtual device is allowed for
@@ -94,8 +100,6 @@ public class VirtualDeviceManagerService extends SystemService {
        super(context);
        mImpl = new VirtualDeviceManagerImpl();
        mLocalService = new LocalService();
        mCameraAccessController = new CameraAccessController(getContext(), mLocalService,
                this::onCameraAccessBlocked);
    }

    private final ActivityInterceptorCallback mActivityInterceptorCallback =
@@ -144,16 +148,19 @@ public class VirtualDeviceManagerService extends SystemService {
    @Override
    public void onUserStarting(@NonNull TargetUser user) {
        super.onUserStarting(user);
        Context userContext = getContext().createContextAsUser(user.getUserHandle(), 0);
        synchronized (mVirtualDeviceManagerLock) {
            final CompanionDeviceManager cdm = getContext()
                    .createContextAsUser(user.getUserHandle(), 0)
                    .getSystemService(CompanionDeviceManager.class);
            final CompanionDeviceManager cdm =
                    userContext.getSystemService(CompanionDeviceManager.class);
            final int userId = user.getUserIdentifier();
            mAllAssociations.put(userId, cdm.getAllAssociations());
            OnAssociationsChangedListener listener =
                    associations -> mAllAssociations.put(userId, associations);
            mOnAssociationsChangedListeners.put(userId, listener);
            cdm.addOnAssociationsChangedListener(Runnable::run, listener);
            CameraAccessController cameraAccessController = new CameraAccessController(
                    userContext, mLocalService, this::onCameraAccessBlocked);
            mCameraAccessControllers.put(user.getUserIdentifier(), cameraAccessController);
        }
    }

@@ -171,6 +178,14 @@ public class VirtualDeviceManagerService extends SystemService {
                cdm.removeOnAssociationsChangedListener(listener);
                mOnAssociationsChangedListeners.remove(userId);
            }
            CameraAccessController cameraAccessController = mCameraAccessControllers.get(
                    user.getUserIdentifier());
            if (cameraAccessController != null) {
                cameraAccessController.close();
                mCameraAccessControllers.remove(user.getUserIdentifier());
            } else {
                Slog.w(TAG, "Cannot unregister cameraAccessController for user " + user);
            }
        }
    }

@@ -198,7 +213,7 @@ public class VirtualDeviceManagerService extends SystemService {
                    android.Manifest.permission.CREATE_VIRTUAL_DEVICE,
                    "createVirtualDevice");
            final int callingUid = getCallingUid();
            if (!PermissionUtils.validatePackageName(getContext(), packageName, callingUid)) {
            if (!PermissionUtils.validateCallingPackageName(getContext(), packageName)) {
                throw new SecurityException(
                        "Package name " + packageName + " does not belong to calling uid "
                                + callingUid);
@@ -213,6 +228,9 @@ public class VirtualDeviceManagerService extends SystemService {
                            "Virtual device for association ID " + associationId
                                    + " already exists");
                }
                final int userId = UserHandle.getUserId(callingUid);
                final CameraAccessController cameraAccessController =
                        mCameraAccessControllers.get(userId);
                VirtualDeviceImpl virtualDevice = new VirtualDeviceImpl(getContext(),
                        associationInfo, token, callingUid,
                        new VirtualDeviceImpl.OnDeviceCloseListener() {
@@ -220,14 +238,21 @@ public class VirtualDeviceManagerService extends SystemService {
                            public void onClose(int associationId) {
                                synchronized (mVirtualDeviceManagerLock) {
                                    mVirtualDevices.remove(associationId);
                                    if (mVirtualDevices.size() == 0) {
                                        mCameraAccessController.stopObserving();
                                    if (cameraAccessController != null) {
                                        cameraAccessController.stopObservingIfNeeded();
                                    } else {
                                        Slog.w(TAG, "cameraAccessController not found for user "
                                                + userId);
                                    }
                                }
                            }
                        },
                        this, activityListener, params);
                mCameraAccessController.startObservingIfNeeded();
                if (cameraAccessController != null) {
                    cameraAccessController.startObservingIfNeeded();
                } else {
                    Slog.w(TAG, "cameraAccessController not found for user " + userId);
                }
                mVirtualDevices.put(associationInfo.getId(), virtualDevice);
                return virtualDevice;
            }
+2 −0
Original line number Diff line number Diff line
@@ -98,6 +98,8 @@
    <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK"/>
    <uses-permission
        android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/>
    <uses-permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY" />
    <uses-permission android:name="android.permission.READ_NEARBY_STREAMING_POLICY" />

    <uses-permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT" />

Loading