From 48439bf2409c4e6ad4b55f5e897703d05333c326 Mon Sep 17 00:00:00 2001 From: Marvin Ramin Date: Fri, 31 Mar 2023 07:27:16 +0000 Subject: [PATCH] Add additional null checks for VirtualDeviceManager APIs Explicitly throw NPEs instead of accidentally relying on exceptions to be thrown under specific conditions to clarify API behavior to developers. Bug: 268457357 Test: cts Change-Id: I3fd2f949df7a703d88f92d36fec8e7fe52370fc3 --- .../companion/virtual/VirtualDeviceManager.java | 11 +++++++++++ .../server/companion/virtual/VirtualDeviceImpl.java | 6 ++++++ .../virtual/VirtualDeviceManagerService.java | 5 +++++ 3 files changed, 22 insertions(+) diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java index da6784be44047..2ca2b79bcc080 100644 --- a/core/java/android/companion/virtual/VirtualDeviceManager.java +++ b/core/java/android/companion/virtual/VirtualDeviceManager.java @@ -64,6 +64,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.concurrent.Executor; import java.util.function.IntConsumer; @@ -171,6 +172,7 @@ public final class VirtualDeviceManager { public VirtualDevice createVirtualDevice( int associationId, @NonNull VirtualDeviceParams params) { + Objects.requireNonNull(params, "params must not be null"); try { return new VirtualDevice(mService, mContext, associationId, params); } catch (RemoteException e) { @@ -409,6 +411,9 @@ public final class VirtualDeviceManager { @NonNull PendingIntent pendingIntent, @NonNull Executor executor, @NonNull IntConsumer listener) { + Objects.requireNonNull(pendingIntent, "pendingIntent must not be null"); + Objects.requireNonNull(executor, "executor must not be null"); + Objects.requireNonNull(listener, "listener must not be null"); mVirtualDeviceInternal.launchPendingIntent( displayId, pendingIntent, executor, listener); } @@ -483,6 +488,7 @@ public final class VirtualDeviceManager { @NonNull VirtualDisplayConfig config, @Nullable @CallbackExecutor Executor executor, @Nullable VirtualDisplay.Callback callback) { + Objects.requireNonNull(config, "config must not be null"); return mVirtualDeviceInternal.createVirtualDisplay(config, executor, callback); } @@ -503,6 +509,7 @@ public final class VirtualDeviceManager { @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @NonNull public VirtualDpad createVirtualDpad(@NonNull VirtualDpadConfig config) { + Objects.requireNonNull(config, "config must not be null"); return mVirtualDeviceInternal.createVirtualDpad(config); } @@ -514,6 +521,7 @@ public final class VirtualDeviceManager { @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @NonNull public VirtualKeyboard createVirtualKeyboard(@NonNull VirtualKeyboardConfig config) { + Objects.requireNonNull(config, "config must not be null"); return mVirtualDeviceInternal.createVirtualKeyboard(config); } @@ -550,6 +558,7 @@ public final class VirtualDeviceManager { @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @NonNull public VirtualMouse createVirtualMouse(@NonNull VirtualMouseConfig config) { + Objects.requireNonNull(config, "config must not be null"); return mVirtualDeviceInternal.createVirtualMouse(config); } @@ -587,6 +596,7 @@ public final class VirtualDeviceManager { @NonNull public VirtualTouchscreen createVirtualTouchscreen( @NonNull VirtualTouchscreenConfig config) { + Objects.requireNonNull(config, "config must not be null"); return mVirtualDeviceInternal.createVirtualTouchscreen(config); } @@ -659,6 +669,7 @@ public final class VirtualDeviceManager { @NonNull VirtualDisplay display, @Nullable Executor executor, @Nullable AudioConfigurationChangeCallback callback) { + Objects.requireNonNull(display, "display must not be null"); return mVirtualDeviceInternal.createVirtualAudioDevice(display, executor, callback); } diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index d1f9109094ae9..ae88f24ab409b 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -348,6 +348,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub @Override // Binder call public void launchPendingIntent(int displayId, PendingIntent pendingIntent, ResultReceiver resultReceiver) { + Objects.requireNonNull(pendingIntent); synchronized (mVirtualDeviceLock) { if (!mVirtualDisplays.contains(displayId)) { throw new SecurityException("Display ID " + displayId @@ -498,6 +499,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void createVirtualDpad(VirtualDpadConfig config, @NonNull IBinder deviceToken) { super.createVirtualDpad_enforcePermission(); + Objects.requireNonNull(config); synchronized (mVirtualDeviceLock) { if (!mVirtualDisplays.contains(config.getAssociatedDisplayId())) { throw new SecurityException( @@ -518,6 +520,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void createVirtualKeyboard(VirtualKeyboardConfig config, @NonNull IBinder deviceToken) { super.createVirtualKeyboard_enforcePermission(); + Objects.requireNonNull(config); synchronized (mVirtualDeviceLock) { if (!mVirtualDisplays.contains(config.getAssociatedDisplayId())) { throw new SecurityException( @@ -540,6 +543,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void createVirtualMouse(VirtualMouseConfig config, @NonNull IBinder deviceToken) { super.createVirtualMouse_enforcePermission(); + Objects.requireNonNull(config); synchronized (mVirtualDeviceLock) { if (!mVirtualDisplays.contains(config.getAssociatedDisplayId())) { throw new SecurityException( @@ -561,6 +565,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub public void createVirtualTouchscreen(VirtualTouchscreenConfig config, @NonNull IBinder deviceToken) { super.createVirtualTouchscreen_enforcePermission(); + Objects.requireNonNull(config); synchronized (mVirtualDeviceLock) { if (!mVirtualDisplays.contains(config.getAssociatedDisplayId())) { throw new SecurityException( @@ -591,6 +596,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub public void createVirtualNavigationTouchpad(VirtualNavigationTouchpadConfig config, @NonNull IBinder deviceToken) { super.createVirtualNavigationTouchpad_enforcePermission(); + Objects.requireNonNull(config); synchronized (mVirtualDeviceLock) { if (!mVirtualDisplays.contains(config.getAssociatedDisplayId())) { throw new SecurityException( diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java index eec898f21800c..291c05877c173 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java @@ -68,6 +68,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; @@ -309,6 +310,9 @@ public class VirtualDeviceManagerService extends SystemService { if (associationInfo == null) { throw new IllegalArgumentException("No association with ID " + associationId); } + Objects.requireNonNull(params); + Objects.requireNonNull(activityListener); + Objects.requireNonNull(soundEffectListener); synchronized (mVirtualDeviceManagerLock) { if (mVirtualDevices.size() == 0) { @@ -340,6 +344,7 @@ public class VirtualDeviceManagerService extends SystemService { public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig, IVirtualDisplayCallback callback, IVirtualDevice virtualDevice, String packageName) throws RemoteException { + Objects.requireNonNull(virtualDisplayConfig); final int callingUid = getCallingUid(); if (!PermissionUtils.validateCallingPackageName(getContext(), packageName)) { throw new SecurityException(