1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.companion.virtual; 18 19 import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY; 20 import static android.Manifest.permission.ADD_TRUSTED_DISPLAY; 21 import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_ENABLED; 22 import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY; 23 import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY; 24 import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM; 25 import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT; 26 import static android.companion.virtual.VirtualDeviceParams.NAVIGATION_POLICY_DEFAULT_ALLOWED; 27 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_ACTIVITY; 28 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_AUDIO; 29 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_BLOCKED_ACTIVITY; 30 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CAMERA; 31 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CLIPBOARD; 32 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS; 33 34 import android.annotation.NonNull; 35 import android.annotation.Nullable; 36 import android.annotation.RequiresPermission; 37 import android.annotation.StringRes; 38 import android.annotation.UserIdInt; 39 import android.app.Activity; 40 import android.app.ActivityOptions; 41 import android.app.PendingIntent; 42 import android.app.admin.DevicePolicyManager; 43 import android.app.compat.CompatChanges; 44 import android.companion.AssociationInfo; 45 import android.companion.AssociationRequest; 46 import android.companion.virtual.ActivityPolicyExemption; 47 import android.companion.virtual.IVirtualDevice; 48 import android.companion.virtual.IVirtualDeviceActivityListener; 49 import android.companion.virtual.IVirtualDeviceIntentInterceptor; 50 import android.companion.virtual.IVirtualDeviceSoundEffectListener; 51 import android.companion.virtual.VirtualDevice; 52 import android.companion.virtual.VirtualDeviceManager; 53 import android.companion.virtual.VirtualDeviceParams; 54 import android.companion.virtual.audio.IAudioConfigChangedCallback; 55 import android.companion.virtual.audio.IAudioRoutingCallback; 56 import android.companion.virtual.camera.VirtualCameraConfig; 57 import android.companion.virtual.sensor.VirtualSensor; 58 import android.companion.virtual.sensor.VirtualSensorAdditionalInfo; 59 import android.companion.virtual.sensor.VirtualSensorEvent; 60 import android.companion.virtualdevice.flags.Flags; 61 import android.compat.annotation.ChangeId; 62 import android.compat.annotation.EnabledAfter; 63 import android.content.AttributionSource; 64 import android.content.ComponentName; 65 import android.content.Context; 66 import android.content.Intent; 67 import android.content.IntentFilter; 68 import android.content.IntentSender; 69 import android.content.pm.ActivityInfo; 70 import android.content.pm.PackageManager; 71 import android.graphics.PointF; 72 import android.hardware.display.DisplayManager; 73 import android.hardware.display.DisplayManagerGlobal; 74 import android.hardware.display.DisplayManagerInternal; 75 import android.hardware.display.IVirtualDisplayCallback; 76 import android.hardware.display.VirtualDisplayConfig; 77 import android.hardware.input.VirtualDpadConfig; 78 import android.hardware.input.VirtualKeyEvent; 79 import android.hardware.input.VirtualKeyboardConfig; 80 import android.hardware.input.VirtualMouseButtonEvent; 81 import android.hardware.input.VirtualMouseConfig; 82 import android.hardware.input.VirtualMouseRelativeEvent; 83 import android.hardware.input.VirtualMouseScrollEvent; 84 import android.hardware.input.VirtualNavigationTouchpadConfig; 85 import android.hardware.input.VirtualRotaryEncoderConfig; 86 import android.hardware.input.VirtualRotaryEncoderScrollEvent; 87 import android.hardware.input.VirtualStylusButtonEvent; 88 import android.hardware.input.VirtualStylusConfig; 89 import android.hardware.input.VirtualStylusMotionEvent; 90 import android.hardware.input.VirtualTouchEvent; 91 import android.hardware.input.VirtualTouchscreenConfig; 92 import android.media.AudioManager; 93 import android.media.audiopolicy.AudioMix; 94 import android.os.Binder; 95 import android.os.Build; 96 import android.os.IBinder; 97 import android.os.LocaleList; 98 import android.os.Looper; 99 import android.os.PowerManager; 100 import android.os.RemoteException; 101 import android.os.ResultReceiver; 102 import android.os.SystemClock; 103 import android.os.UserHandle; 104 import android.os.UserManager; 105 import android.util.ArrayMap; 106 import android.util.ArraySet; 107 import android.util.IntArray; 108 import android.util.Slog; 109 import android.util.SparseArray; 110 import android.util.SparseIntArray; 111 import android.view.Display; 112 import android.view.WindowManager; 113 import android.widget.Toast; 114 import android.window.DisplayWindowPolicyController; 115 116 import com.android.internal.annotations.GuardedBy; 117 import com.android.internal.annotations.VisibleForTesting; 118 import com.android.internal.app.BlockedAppStreamingActivity; 119 import com.android.modules.expresslog.Counter; 120 import com.android.server.LocalServices; 121 import com.android.server.companion.virtual.GenericWindowPolicyController.RunningAppsChangedListener; 122 import com.android.server.companion.virtual.audio.VirtualAudioController; 123 import com.android.server.companion.virtual.camera.VirtualCameraController; 124 import com.android.server.inputmethod.InputMethodManagerInternal; 125 126 import dalvik.annotation.optimization.FastNative; 127 128 import java.io.FileDescriptor; 129 import java.io.PrintWriter; 130 import java.util.List; 131 import java.util.Map; 132 import java.util.Objects; 133 import java.util.Set; 134 import java.util.function.Consumer; 135 136 final class VirtualDeviceImpl extends IVirtualDevice.Stub 137 implements IBinder.DeathRecipient, RunningAppsChangedListener { 138 139 private static final String TAG = "VirtualDeviceImpl"; 140 141 /** 142 * Do not show a toast on the virtual display when a secure surface is shown after 143 * {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}. VDM clients should use 144 * {@link VirtualDeviceManager.ActivityListener#onSecureWindowShown} instead to provide 145 * a custom notification if desired. 146 */ 147 @ChangeId 148 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) 149 public static final long DO_NOT_SHOW_TOAST_WHEN_SECURE_SURFACE_SHOWN = 311101667L; 150 151 private static final int DEFAULT_VIRTUAL_DISPLAY_FLAGS = 152 DisplayManager.VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED 153 | DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL 154 | DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH 155 | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS; 156 157 private static final String PERSISTENT_ID_PREFIX_CDM_ASSOCIATION = "companion:"; 158 159 private static final List<String> DEVICE_PROFILES_ALLOWING_MIRROR_DISPLAYS = List.of( 160 AssociationRequest.DEVICE_PROFILE_APP_STREAMING); 161 162 /** 163 * Timeout until {@link #launchPendingIntent} stops waiting for an activity to be launched. 164 */ 165 private static final long PENDING_TRAMPOLINE_TIMEOUT_MS = 5000; 166 167 /** 168 * Global lock for this Virtual Device. 169 * 170 * Never call outside this class while holding this lock. A number of other system services like 171 * WindowManager, DisplayManager, etc. call into this device to get device-specific information, 172 * while holding their own global locks. 173 * 174 * Making a call to another service while holding this lock creates lock order inversion and 175 * will potentially cause a deadlock. 176 */ 177 private final Object mVirtualDeviceLock = new Object(); 178 179 private final int mBaseVirtualDisplayFlags; 180 181 private final Context mContext; 182 private final AssociationInfo mAssociationInfo; 183 private final VirtualDeviceManagerService mService; 184 private final PendingTrampolineCallback mPendingTrampolineCallback; 185 private final int mOwnerUid; 186 private final VirtualDeviceLog mVirtualDeviceLog; 187 private final String mOwnerPackageName; 188 @NonNull 189 private final AttributionSource mAttributionSource; 190 private final int mDeviceId; 191 @Nullable 192 private final String mPersistentDeviceId; 193 private final InputController mInputController; 194 private final SensorController mSensorController; 195 private final CameraAccessController mCameraAccessController; 196 @Nullable // Null if virtual camera flag is off. 197 private final VirtualCameraController mVirtualCameraController; 198 private VirtualAudioController mVirtualAudioController; 199 private final IBinder mAppToken; 200 private final VirtualDeviceParams mParams; 201 @GuardedBy("mVirtualDeviceLock") 202 private final SparseIntArray mDevicePolicies; 203 @GuardedBy("mVirtualDeviceLock") 204 private final SparseArray<VirtualDisplayWrapper> mVirtualDisplays = new SparseArray<>(); 205 private IVirtualDeviceActivityListener mActivityListener; 206 private GenericWindowPolicyController.ActivityListener mActivityListenerAdapter = null; 207 private IVirtualDeviceSoundEffectListener mSoundEffectListener; 208 private final DisplayManagerGlobal mDisplayManager; 209 private final DisplayManagerInternal mDisplayManagerInternal; 210 private final PowerManager mPowerManager; 211 @GuardedBy("mIntentInterceptors") 212 private final Map<IBinder, IntentFilter> mIntentInterceptors = new ArrayMap<>(); 213 @NonNull 214 private final Consumer<ArraySet<Integer>> mRunningAppsChangedCallback; 215 216 // The default setting for showing the pointer on new displays. 217 @GuardedBy("mVirtualDeviceLock") 218 private boolean mDefaultShowPointerIcon = true; 219 @GuardedBy("mVirtualDeviceLock") 220 @Nullable 221 private LocaleList mLocaleList = null; 222 223 // Lock for power operations for this virtual device that allow calling PowerManager. 224 private final Object mPowerLock = new Object(); 225 @GuardedBy("mPowerLock") 226 private boolean mLockdownActive = false; 227 @GuardedBy("mPowerLock") 228 private boolean mRequestedToBeAwake = true; 229 230 @NonNull 231 private final VirtualDevice mPublicVirtualDeviceObject; 232 233 @GuardedBy("mVirtualDeviceLock") 234 @NonNull 235 private final Set<ComponentName> mActivityPolicyExemptions; 236 @GuardedBy("mVirtualDeviceLock") 237 @NonNull 238 private final Set<String> mActivityPolicyPackageExemptions = new ArraySet<>(); 239 240 private class GwpcActivityListener implements GenericWindowPolicyController.ActivityListener { 241 242 @Override onTopActivityChanged(int displayId, @NonNull ComponentName topActivity, @UserIdInt int userId)243 public void onTopActivityChanged(int displayId, @NonNull ComponentName topActivity, 244 @UserIdInt int userId) { 245 try { 246 mActivityListener.onTopActivityChanged(displayId, topActivity, userId); 247 } catch (RemoteException e) { 248 Slog.w(TAG, "Unable to call mActivityListener for display: " + displayId, e); 249 } 250 } 251 252 @Override onDisplayEmpty(int displayId)253 public void onDisplayEmpty(int displayId) { 254 try { 255 mActivityListener.onDisplayEmpty(displayId); 256 } catch (RemoteException e) { 257 Slog.w(TAG, "Unable to call mActivityListener for display: " + displayId, e); 258 } 259 } 260 261 @Override onActivityLaunchBlocked(int displayId, @NonNull ActivityInfo activityInfo, @Nullable IntentSender intentSender)262 public void onActivityLaunchBlocked(int displayId, @NonNull ActivityInfo activityInfo, 263 @Nullable IntentSender intentSender) { 264 Intent intent = 265 BlockedAppStreamingActivity.createIntent(activityInfo, getDisplayName()); 266 if (shouldShowBlockedActivityDialog( 267 activityInfo.getComponentName(), intent.getComponent())) { 268 mContext.startActivityAsUser( 269 intent.addFlags( 270 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK), 271 ActivityOptions.makeBasic().setLaunchDisplayId(displayId).toBundle(), 272 UserHandle.SYSTEM); 273 } 274 275 if (Flags.activityControlApi()) { 276 try { 277 mActivityListener.onActivityLaunchBlocked( 278 displayId, 279 activityInfo.getComponentName(), 280 UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid), 281 intentSender); 282 } catch (RemoteException e) { 283 Slog.w(TAG, "Unable to call mActivityListener for display: " + displayId, e); 284 } 285 } 286 } 287 288 @Override onSecureWindowShown(int displayId, @NonNull ActivityInfo activityInfo)289 public void onSecureWindowShown(int displayId, @NonNull ActivityInfo activityInfo) { 290 if (Flags.activityControlApi()) { 291 try { 292 mActivityListener.onSecureWindowShown( 293 displayId, 294 activityInfo.getComponentName(), 295 UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid)); 296 } catch (RemoteException e) { 297 Slog.w(TAG, "Unable to call mActivityListener for display: " + displayId, e); 298 } 299 300 if (CompatChanges.isChangeEnabled(DO_NOT_SHOW_TOAST_WHEN_SECURE_SURFACE_SHOWN, 301 mOwnerPackageName, UserHandle.getUserHandleForUid(mOwnerUid))) { 302 return; 303 } 304 } 305 306 // If a virtual display isn't secure, the screen can't be captured. Show a warning toast 307 // if the secure window is shown on a non-secure virtual display. 308 DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); 309 Display display = displayManager.getDisplay(displayId); 310 if (display != null) { 311 if ((display.getFlags() & Display.FLAG_SECURE) == 0) { 312 showToastWhereUidIsRunning(activityInfo.applicationInfo.uid, 313 com.android.internal.R.string.vdm_secure_window, 314 Toast.LENGTH_LONG, mContext.getMainLooper()); 315 316 Counter.logIncrementWithUid( 317 "virtual_devices.value_secure_window_blocked_count", 318 mAttributionSource.getUid()); 319 } 320 } else { 321 Slog.e(TAG, "Calling onSecureWindowShown on a non existent/connected display: " 322 + displayId); 323 } 324 } 325 326 @Override onSecureWindowHidden(int displayId)327 public void onSecureWindowHidden(int displayId) { 328 if (Flags.activityControlApi()) { 329 try { 330 mActivityListener.onSecureWindowHidden(displayId); 331 } catch (RemoteException e) { 332 Slog.w(TAG, "Unable to call mActivityListener for display: " + displayId, e); 333 } 334 } 335 } 336 337 /** 338 * Intercepts intent when matching any of the IntentFilter of any interceptor. Returns true 339 * if the intent matches any filter notifying the DisplayPolicyController to abort the 340 * activity launch to be replaced by the interception. 341 */ 342 @Override shouldInterceptIntent(@onNull Intent intent)343 public boolean shouldInterceptIntent(@NonNull Intent intent) { 344 synchronized (mIntentInterceptors) { 345 boolean hasInterceptedIntent = false; 346 for (Map.Entry<IBinder, IntentFilter> interceptor 347 : mIntentInterceptors.entrySet()) { 348 IntentFilter intentFilter = interceptor.getValue(); 349 // Explicitly match the actions because the intent filter will match any intent 350 // without an explicit action. If the intent has no action, then require that 351 // there are no actions specified in the filter either. 352 boolean explicitActionMatch = 353 intent.getAction() != null || intentFilter.countActions() == 0; 354 if (explicitActionMatch && intentFilter.match( 355 intent.getAction(), intent.getType(), intent.getScheme(), 356 intent.getData(), intent.getCategories(), TAG) >= 0) { 357 try { 358 // For privacy reasons, only returning the intents action and data. 359 // Any other required field will require a review. 360 IVirtualDeviceIntentInterceptor.Stub.asInterface(interceptor.getKey()) 361 .onIntentIntercepted( 362 new Intent(intent.getAction(), intent.getData())); 363 hasInterceptedIntent = true; 364 } catch (RemoteException e) { 365 Slog.w(TAG, "Unable to call mActivityListener", e); 366 } 367 } 368 } 369 return hasInterceptedIntent; 370 } 371 } 372 } 373 VirtualDeviceImpl( Context context, AssociationInfo associationInfo, VirtualDeviceManagerService service, VirtualDeviceLog virtualDeviceLog, IBinder token, AttributionSource attributionSource, int deviceId, CameraAccessController cameraAccessController, PendingTrampolineCallback pendingTrampolineCallback, IVirtualDeviceActivityListener activityListener, IVirtualDeviceSoundEffectListener soundEffectListener, Consumer<ArraySet<Integer>> runningAppsChangedCallback, VirtualDeviceParams params)374 VirtualDeviceImpl( 375 Context context, 376 AssociationInfo associationInfo, 377 VirtualDeviceManagerService service, 378 VirtualDeviceLog virtualDeviceLog, 379 IBinder token, 380 AttributionSource attributionSource, 381 int deviceId, 382 CameraAccessController cameraAccessController, 383 PendingTrampolineCallback pendingTrampolineCallback, 384 IVirtualDeviceActivityListener activityListener, 385 IVirtualDeviceSoundEffectListener soundEffectListener, 386 Consumer<ArraySet<Integer>> runningAppsChangedCallback, 387 VirtualDeviceParams params) { 388 this( 389 context, 390 associationInfo, 391 service, 392 virtualDeviceLog, 393 token, 394 attributionSource, 395 deviceId, 396 /* inputController= */ null, 397 cameraAccessController, 398 pendingTrampolineCallback, 399 activityListener, 400 soundEffectListener, 401 runningAppsChangedCallback, 402 params, 403 DisplayManagerGlobal.getInstance(), 404 isVirtualCameraEnabled() 405 ? new VirtualCameraController( 406 params.getDevicePolicy(POLICY_TYPE_CAMERA), deviceId) 407 : null); 408 } 409 410 @VisibleForTesting VirtualDeviceImpl( Context context, AssociationInfo associationInfo, VirtualDeviceManagerService service, VirtualDeviceLog virtualDeviceLog, IBinder token, AttributionSource attributionSource, int deviceId, InputController inputController, CameraAccessController cameraAccessController, PendingTrampolineCallback pendingTrampolineCallback, IVirtualDeviceActivityListener activityListener, IVirtualDeviceSoundEffectListener soundEffectListener, Consumer<ArraySet<Integer>> runningAppsChangedCallback, VirtualDeviceParams params, DisplayManagerGlobal displayManager, VirtualCameraController virtualCameraController)411 VirtualDeviceImpl( 412 Context context, 413 AssociationInfo associationInfo, 414 VirtualDeviceManagerService service, 415 VirtualDeviceLog virtualDeviceLog, 416 IBinder token, 417 AttributionSource attributionSource, 418 int deviceId, 419 InputController inputController, 420 CameraAccessController cameraAccessController, 421 PendingTrampolineCallback pendingTrampolineCallback, 422 IVirtualDeviceActivityListener activityListener, 423 IVirtualDeviceSoundEffectListener soundEffectListener, 424 Consumer<ArraySet<Integer>> runningAppsChangedCallback, 425 VirtualDeviceParams params, 426 DisplayManagerGlobal displayManager, 427 VirtualCameraController virtualCameraController) { 428 mVirtualDeviceLog = virtualDeviceLog; 429 mOwnerPackageName = attributionSource.getPackageName(); 430 mAttributionSource = attributionSource; 431 UserHandle ownerUserHandle = UserHandle.getUserHandleForUid(attributionSource.getUid()); 432 mContext = context.createContextAsUser(ownerUserHandle, 0); 433 mAssociationInfo = associationInfo; 434 mPersistentDeviceId = associationInfo == null 435 ? null 436 : createPersistentDeviceId(associationInfo.getId()); 437 mService = service; 438 mPendingTrampolineCallback = pendingTrampolineCallback; 439 mActivityListener = activityListener; 440 mSoundEffectListener = soundEffectListener; 441 mRunningAppsChangedCallback = runningAppsChangedCallback; 442 mOwnerUid = attributionSource.getUid(); 443 mDeviceId = deviceId; 444 mAppToken = token; 445 mParams = params; 446 mDevicePolicies = params.getDevicePolicies(); 447 mDisplayManager = displayManager; 448 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); 449 mPowerManager = context.getSystemService(PowerManager.class); 450 451 if (mDevicePolicies.get(POLICY_TYPE_CLIPBOARD, DEVICE_POLICY_DEFAULT) 452 != DEVICE_POLICY_DEFAULT) { 453 if (mContext.checkCallingOrSelfPermission(ADD_TRUSTED_DISPLAY) 454 != PackageManager.PERMISSION_GRANTED) { 455 throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " 456 + "set a custom clipboard policy."); 457 } 458 } 459 460 int flags = DEFAULT_VIRTUAL_DISPLAY_FLAGS; 461 if (mParams.getLockState() == VirtualDeviceParams.LOCK_STATE_ALWAYS_UNLOCKED) { 462 if (mContext.checkCallingOrSelfPermission(ADD_ALWAYS_UNLOCKED_DISPLAY) 463 != PackageManager.PERMISSION_GRANTED) { 464 throw new SecurityException("Requires ADD_ALWAYS_UNLOCKED_DISPLAY permission to " 465 + "create an always unlocked virtual device."); 466 } 467 flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED; 468 } 469 mBaseVirtualDisplayFlags = flags; 470 471 if (inputController == null) { 472 mInputController = new InputController( 473 context.getMainThreadHandler(), 474 context.getSystemService(WindowManager.class), mAttributionSource); 475 } else { 476 mInputController = inputController; 477 } 478 mSensorController = new SensorController(this, mDeviceId, mAttributionSource, 479 mParams.getVirtualSensorCallback(), mParams.getVirtualSensorConfigs()); 480 mCameraAccessController = cameraAccessController; 481 if (mCameraAccessController != null) { 482 mCameraAccessController.startObservingIfNeeded(); 483 } 484 mVirtualCameraController = virtualCameraController; 485 try { 486 token.linkToDeath(this, 0); 487 } catch (RemoteException e) { 488 throw e.rethrowFromSystemServer(); 489 } 490 mVirtualDeviceLog.logCreated(deviceId, mOwnerUid); 491 492 mPublicVirtualDeviceObject = new VirtualDevice( 493 this, getDeviceId(), getPersistentDeviceId(), mParams.getName(), getDisplayName()); 494 495 mActivityPolicyExemptions = new ArraySet<>( 496 mParams.getDevicePolicy(POLICY_TYPE_ACTIVITY) == DEVICE_POLICY_DEFAULT 497 ? mParams.getBlockedActivities() 498 : mParams.getAllowedActivities()); 499 500 if (mParams.getInputMethodComponent() != null) { 501 final String imeId = mParams.getInputMethodComponent().flattenToShortString(); 502 Slog.d(TAG, "Setting custom input method " + imeId + " as default for virtual device " 503 + deviceId); 504 InputMethodManagerInternal.get().setVirtualDeviceInputMethodForAllUsers( 505 mDeviceId, imeId); 506 } 507 } 508 onLockdownChanged(boolean lockdownActive)509 void onLockdownChanged(boolean lockdownActive) { 510 synchronized (mPowerLock) { 511 if (lockdownActive != mLockdownActive) { 512 mLockdownActive = lockdownActive; 513 if (mLockdownActive) { 514 goToSleepInternal(PowerManager.GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF); 515 } else if (mRequestedToBeAwake) { 516 wakeUpInternal(PowerManager.WAKE_REASON_DISPLAY_GROUP_TURNED_ON, 517 "android.server.companion.virtual:LOCKDOWN_ENDED"); 518 } 519 } 520 } 521 } 522 523 @VisibleForTesting getSensorControllerForTest()524 SensorController getSensorControllerForTest() { 525 return mSensorController; 526 } 527 createPersistentDeviceId(int associationId)528 static String createPersistentDeviceId(int associationId) { 529 return PERSISTENT_ID_PREFIX_CDM_ASSOCIATION + associationId; 530 } 531 532 /** 533 * Returns the flags that should be added to any virtual displays created on this virtual 534 * device. 535 */ getBaseVirtualDisplayFlags()536 int getBaseVirtualDisplayFlags() { 537 return mBaseVirtualDisplayFlags; 538 } 539 540 /** Returns the camera access controller of this device. */ getCameraAccessController()541 CameraAccessController getCameraAccessController() { 542 return mCameraAccessController; 543 } 544 545 /** Returns the device display name. */ getDisplayName()546 CharSequence getDisplayName() { 547 return mAssociationInfo == null ? mParams.getName() : mAssociationInfo.getDisplayName(); 548 } 549 getDeviceProfile()550 String getDeviceProfile() { 551 return mAssociationInfo == null ? null : mAssociationInfo.getDeviceProfile(); 552 } 553 554 /** Returns the public representation of the device. */ getPublicVirtualDeviceObject()555 VirtualDevice getPublicVirtualDeviceObject() { 556 return mPublicVirtualDeviceObject; 557 } 558 559 /** Returns the locale of the device. */ getDeviceLocaleList()560 LocaleList getDeviceLocaleList() { 561 synchronized (mVirtualDeviceLock) { 562 return mLocaleList; 563 } 564 } 565 566 /** 567 * Setter for listeners that live in the client process, namely in 568 * {@link android.companion.virtual.VirtualDeviceInternal}. 569 * 570 * This is needed for virtual devices that are created by the system, as the VirtualDeviceImpl 571 * object is created before the returned VirtualDeviceInternal one. 572 */ 573 @Override // Binder call setListeners(@onNull IVirtualDeviceActivityListener activityListener, @NonNull IVirtualDeviceSoundEffectListener soundEffectListener)574 public void setListeners(@NonNull IVirtualDeviceActivityListener activityListener, 575 @NonNull IVirtualDeviceSoundEffectListener soundEffectListener) { 576 mActivityListener = Objects.requireNonNull(activityListener); 577 mSoundEffectListener = Objects.requireNonNull(soundEffectListener); 578 } 579 580 @Override // Binder call getDevicePolicy( @irtualDeviceParams.PolicyType int policyType)581 public @VirtualDeviceParams.DevicePolicy int getDevicePolicy( 582 @VirtualDeviceParams.PolicyType int policyType) { 583 synchronized (mVirtualDeviceLock) { 584 return mDevicePolicies.get(policyType, DEVICE_POLICY_DEFAULT); 585 } 586 } 587 588 /** Returns device-specific audio session id for playback. */ getAudioPlaybackSessionId()589 public int getAudioPlaybackSessionId() { 590 return mParams.getAudioPlaybackSessionId(); 591 } 592 593 /** Returns device-specific audio session id for recording. */ getAudioRecordingSessionId()594 public int getAudioRecordingSessionId() { 595 return mParams.getAudioRecordingSessionId(); 596 } 597 598 /** Returns the unique device ID of this device. */ 599 @Override // Binder call getDeviceId()600 public int getDeviceId() { 601 return mDeviceId; 602 } 603 604 /** Returns the unique device ID of this device. */ 605 @Override // Binder call getPersistentDeviceId()606 public @Nullable String getPersistentDeviceId() { 607 return mPersistentDeviceId; 608 } 609 610 @Override // Binder call getAssociationId()611 public int getAssociationId() { 612 return mAssociationInfo == null 613 ? VirtualDeviceManagerService.CDM_ASSOCIATION_ID_NONE 614 : mAssociationInfo.getId(); 615 } 616 617 @Override // Binder call goToSleep()618 public void goToSleep() { 619 checkCallerIsDeviceOwner(); 620 synchronized (mPowerLock) { 621 mRequestedToBeAwake = false; 622 } 623 final long ident = Binder.clearCallingIdentity(); 624 try { 625 goToSleepInternal(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON); 626 } finally { 627 Binder.restoreCallingIdentity(ident); 628 } 629 } 630 631 @Override // Binder call wakeUp()632 public void wakeUp() { 633 checkCallerIsDeviceOwner(); 634 synchronized (mPowerLock) { 635 mRequestedToBeAwake = true; 636 if (mLockdownActive) { 637 Slog.w(TAG, "Cannot wake up device during lockdown."); 638 return; 639 } 640 } 641 final long ident = Binder.clearCallingIdentity(); 642 try { 643 wakeUpInternal(PowerManager.WAKE_REASON_POWER_BUTTON, 644 "android.server.companion.virtual:DEVICE_ON"); 645 } finally { 646 Binder.restoreCallingIdentity(ident); 647 } 648 } 649 650 @Override // Binder call launchPendingIntent(int displayId, PendingIntent pendingIntent, ResultReceiver resultReceiver)651 public void launchPendingIntent(int displayId, PendingIntent pendingIntent, 652 ResultReceiver resultReceiver) { 653 checkCallerIsDeviceOwner(); 654 Objects.requireNonNull(pendingIntent); 655 synchronized (mVirtualDeviceLock) { 656 checkDisplayOwnedByVirtualDeviceLocked(displayId); 657 } 658 if (pendingIntent.isActivity()) { 659 try { 660 sendPendingIntent(displayId, pendingIntent); 661 resultReceiver.send(VirtualDeviceManager.LAUNCH_SUCCESS, null); 662 } catch (PendingIntent.CanceledException e) { 663 Slog.w(TAG, "Pending intent canceled", e); 664 resultReceiver.send( 665 VirtualDeviceManager.LAUNCH_FAILURE_PENDING_INTENT_CANCELED, null); 666 } 667 } else { 668 PendingTrampoline pendingTrampoline = new PendingTrampoline(pendingIntent, 669 resultReceiver, displayId); 670 mPendingTrampolineCallback.startWaitingForPendingTrampoline(pendingTrampoline); 671 mContext.getMainThreadHandler().postDelayed(() -> { 672 pendingTrampoline.mResultReceiver.send( 673 VirtualDeviceManager.LAUNCH_FAILURE_NO_ACTIVITY, null); 674 mPendingTrampolineCallback.stopWaitingForPendingTrampoline(pendingTrampoline); 675 }, PENDING_TRAMPOLINE_TIMEOUT_MS); 676 try { 677 sendPendingIntent(displayId, pendingIntent); 678 } catch (PendingIntent.CanceledException e) { 679 Slog.w(TAG, "Pending intent canceled", e); 680 resultReceiver.send( 681 VirtualDeviceManager.LAUNCH_FAILURE_PENDING_INTENT_CANCELED, null); 682 mPendingTrampolineCallback.stopWaitingForPendingTrampoline(pendingTrampoline); 683 } 684 } 685 } 686 687 @Override // Binder call addActivityPolicyExemption(@onNull ActivityPolicyExemption exemption)688 public void addActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) { 689 checkCallerIsDeviceOwner(); 690 final int displayId = exemption.getDisplayId(); 691 if (exemption.getComponentName() == null || displayId != Display.INVALID_DISPLAY) { 692 if (!Flags.activityControlApi()) { 693 return; 694 } 695 } 696 synchronized (mVirtualDeviceLock) { 697 if (displayId != Display.INVALID_DISPLAY) { 698 checkDisplayOwnedByVirtualDeviceLocked(displayId); 699 if (exemption.getComponentName() != null) { 700 mVirtualDisplays.get(displayId).getWindowPolicyController() 701 .addActivityPolicyExemption(exemption.getComponentName()); 702 } else if (exemption.getPackageName() != null) { 703 mVirtualDisplays.get(displayId).getWindowPolicyController() 704 .addActivityPolicyExemption(exemption.getPackageName()); 705 } 706 } else { 707 if (exemption.getComponentName() != null 708 && mActivityPolicyExemptions.add(exemption.getComponentName())) { 709 for (int i = 0; i < mVirtualDisplays.size(); i++) { 710 mVirtualDisplays.valueAt(i).getWindowPolicyController() 711 .addActivityPolicyExemption(exemption.getComponentName()); 712 } 713 } else if (exemption.getPackageName() != null 714 && mActivityPolicyPackageExemptions.add(exemption.getPackageName())) { 715 for (int i = 0; i < mVirtualDisplays.size(); i++) { 716 mVirtualDisplays.valueAt(i).getWindowPolicyController() 717 .addActivityPolicyExemption(exemption.getPackageName()); 718 } 719 } 720 } 721 } 722 } 723 724 @Override // Binder call removeActivityPolicyExemption(@onNull ActivityPolicyExemption exemption)725 public void removeActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) { 726 checkCallerIsDeviceOwner(); 727 final int displayId = exemption.getDisplayId(); 728 if (exemption.getComponentName() == null || displayId != Display.INVALID_DISPLAY) { 729 if (!Flags.activityControlApi()) { 730 return; 731 } 732 } 733 synchronized (mVirtualDeviceLock) { 734 if (displayId != Display.INVALID_DISPLAY) { 735 checkDisplayOwnedByVirtualDeviceLocked(displayId); 736 if (exemption.getComponentName() != null) { 737 mVirtualDisplays.get(displayId).getWindowPolicyController() 738 .removeActivityPolicyExemption(exemption.getComponentName()); 739 } else if (exemption.getPackageName() != null) { 740 mVirtualDisplays.get(displayId).getWindowPolicyController() 741 .removeActivityPolicyExemption(exemption.getPackageName()); 742 } 743 } else { 744 if (exemption.getComponentName() != null 745 && mActivityPolicyExemptions.remove(exemption.getComponentName())) { 746 for (int i = 0; i < mVirtualDisplays.size(); i++) { 747 mVirtualDisplays.valueAt(i).getWindowPolicyController() 748 .removeActivityPolicyExemption(exemption.getComponentName()); 749 } 750 } else if (exemption.getPackageName() != null 751 && mActivityPolicyPackageExemptions.remove(exemption.getPackageName())) { 752 for (int i = 0; i < mVirtualDisplays.size(); i++) { 753 mVirtualDisplays.valueAt(i).getWindowPolicyController() 754 .removeActivityPolicyExemption(exemption.getPackageName()); 755 } 756 } 757 } 758 } 759 } 760 sendPendingIntent(int displayId, PendingIntent pendingIntent)761 private void sendPendingIntent(int displayId, PendingIntent pendingIntent) 762 throws PendingIntent.CanceledException { 763 final ActivityOptions options = ActivityOptions.makeBasic().setLaunchDisplayId(displayId); 764 options.setPendingIntentBackgroundActivityStartMode( 765 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS); 766 pendingIntent.send( 767 mContext, 768 /* code= */ 0, 769 /* intent= */ null, 770 /* onFinished= */ null, 771 /* handler= */ null, 772 /* requiredPermission= */ null, 773 options.toBundle()); 774 } 775 776 @Override // Binder call close()777 public void close() { 778 // Remove about-to-be-closed virtual device from the service before butchering it. 779 if (!mService.removeVirtualDevice(mDeviceId)) { 780 // Device is already closed. 781 return; 782 } 783 784 mVirtualDeviceLog.logClosed(mDeviceId, mOwnerUid); 785 786 final long ident = Binder.clearCallingIdentity(); 787 try { 788 VirtualDisplayWrapper[] virtualDisplaysToBeReleased; 789 synchronized (mVirtualDeviceLock) { 790 if (mVirtualAudioController != null) { 791 mVirtualAudioController.stopListening(); 792 mVirtualAudioController = null; 793 } 794 mLocaleList = null; 795 virtualDisplaysToBeReleased = new VirtualDisplayWrapper[mVirtualDisplays.size()]; 796 for (int i = 0; i < mVirtualDisplays.size(); i++) { 797 virtualDisplaysToBeReleased[i] = mVirtualDisplays.valueAt(i); 798 } 799 mVirtualDisplays.clear(); 800 } 801 // Destroy the display outside locked section. 802 for (VirtualDisplayWrapper virtualDisplayWrapper : virtualDisplaysToBeReleased) { 803 mDisplayManager.releaseVirtualDisplay(virtualDisplayWrapper.getToken()); 804 // The releaseVirtualDisplay call above won't trigger 805 // VirtualDeviceImpl.onVirtualDisplayRemoved callback because we already removed the 806 // virtual device from the service - we release the other display-tied resources 807 // here with the guarantee it will be done exactly once. 808 releaseOwnedVirtualDisplayResources(virtualDisplayWrapper); 809 } 810 811 mAppToken.unlinkToDeath(this, 0); 812 if (mCameraAccessController != null) { 813 mCameraAccessController.stopObservingIfNeeded(); 814 } 815 816 // Clear any previously set custom IME components. 817 if (mParams.getInputMethodComponent() != null) { 818 InputMethodManagerInternal.get().setVirtualDeviceInputMethodForAllUsers( 819 mDeviceId, null); 820 } 821 822 mInputController.close(); 823 mSensorController.close(); 824 } finally { 825 Binder.restoreCallingIdentity(ident); 826 } 827 if (mVirtualCameraController != null) { 828 mVirtualCameraController.close(); 829 } 830 } 831 832 @Override binderDied()833 public void binderDied() { 834 close(); 835 } 836 837 @Override 838 @RequiresPermission(android.Manifest.permission.CAMERA_INJECT_EXTERNAL_CAMERA) onRunningAppsChanged(ArraySet<Integer> runningUids)839 public void onRunningAppsChanged(ArraySet<Integer> runningUids) { 840 if (mCameraAccessController != null) { 841 mCameraAccessController.blockCameraAccessIfNeeded(runningUids); 842 } 843 mRunningAppsChangedCallback.accept(runningUids); 844 } 845 846 @VisibleForTesting getVirtualAudioControllerForTesting()847 VirtualAudioController getVirtualAudioControllerForTesting() { 848 return mVirtualAudioController; 849 } 850 851 @Override // Binder call onAudioSessionStarting(int displayId, @NonNull IAudioRoutingCallback routingCallback, @Nullable IAudioConfigChangedCallback configChangedCallback)852 public void onAudioSessionStarting(int displayId, 853 @NonNull IAudioRoutingCallback routingCallback, 854 @Nullable IAudioConfigChangedCallback configChangedCallback) { 855 checkCallerIsDeviceOwner(); 856 synchronized (mVirtualDeviceLock) { 857 checkDisplayOwnedByVirtualDeviceLocked(displayId); 858 if (mVirtualAudioController == null) { 859 mVirtualAudioController = new VirtualAudioController(mContext, mAttributionSource); 860 GenericWindowPolicyController gwpc = 861 mVirtualDisplays.get(displayId).getWindowPolicyController(); 862 mVirtualAudioController.startListening(gwpc, routingCallback, 863 configChangedCallback); 864 } 865 } 866 } 867 868 @Override // Binder call onAudioSessionEnded()869 public void onAudioSessionEnded() { 870 checkCallerIsDeviceOwner(); 871 synchronized (mVirtualDeviceLock) { 872 if (mVirtualAudioController != null) { 873 mVirtualAudioController.stopListening(); 874 mVirtualAudioController = null; 875 } 876 } 877 } 878 879 @Override // Binder call setDevicePolicy(@irtualDeviceParams.DynamicPolicyType int policyType, @VirtualDeviceParams.DevicePolicy int devicePolicy)880 public void setDevicePolicy(@VirtualDeviceParams.DynamicPolicyType int policyType, 881 @VirtualDeviceParams.DevicePolicy int devicePolicy) { 882 checkCallerIsDeviceOwner(); 883 884 switch (policyType) { 885 case POLICY_TYPE_RECENTS: 886 synchronized (mVirtualDeviceLock) { 887 mDevicePolicies.put(policyType, devicePolicy); 888 for (int i = 0; i < mVirtualDisplays.size(); i++) { 889 VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); 890 if (wrapper.isTrusted()) { 891 wrapper.getWindowPolicyController() 892 .setShowInHostDeviceRecents( 893 devicePolicy == DEVICE_POLICY_DEFAULT); 894 } 895 } 896 } 897 break; 898 case POLICY_TYPE_ACTIVITY: 899 synchronized (mVirtualDeviceLock) { 900 if (getDevicePolicy(policyType) != devicePolicy) { 901 mActivityPolicyExemptions.clear(); 902 mActivityPolicyPackageExemptions.clear(); 903 } 904 mDevicePolicies.put(policyType, devicePolicy); 905 for (int i = 0; i < mVirtualDisplays.size(); i++) { 906 mVirtualDisplays.valueAt(i).getWindowPolicyController() 907 .setActivityLaunchDefaultAllowed( 908 devicePolicy == DEVICE_POLICY_DEFAULT); 909 } 910 } 911 break; 912 case POLICY_TYPE_CLIPBOARD: 913 if (devicePolicy == DEVICE_POLICY_CUSTOM 914 && mContext.checkCallingOrSelfPermission(ADD_TRUSTED_DISPLAY) 915 != PackageManager.PERMISSION_GRANTED) { 916 throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " 917 + "set a custom clipboard policy."); 918 } 919 synchronized (mVirtualDeviceLock) { 920 for (int i = 0; i < mVirtualDisplays.size(); i++) { 921 VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); 922 if (!wrapper.isTrusted() && !wrapper.isMirror()) { 923 throw new SecurityException("All displays must be trusted for " 924 + "devices with custom clipboard policy."); 925 } 926 } 927 mDevicePolicies.put(policyType, devicePolicy); 928 } 929 break; 930 case POLICY_TYPE_BLOCKED_ACTIVITY: 931 if (Flags.activityControlApi()) { 932 synchronized (mVirtualDeviceLock) { 933 mDevicePolicies.put(policyType, devicePolicy); 934 } 935 } 936 break; 937 default: 938 throw new IllegalArgumentException("Device policy " + policyType 939 + " cannot be changed at runtime. "); 940 } 941 } 942 943 @Override // Binder call setDevicePolicyForDisplay(int displayId, @VirtualDeviceParams.DynamicDisplayPolicyType int policyType, @VirtualDeviceParams.DevicePolicy int devicePolicy)944 public void setDevicePolicyForDisplay(int displayId, 945 @VirtualDeviceParams.DynamicDisplayPolicyType int policyType, 946 @VirtualDeviceParams.DevicePolicy int devicePolicy) { 947 checkCallerIsDeviceOwner(); 948 if (!Flags.activityControlApi()) { 949 return; 950 } 951 synchronized (mVirtualDeviceLock) { 952 checkDisplayOwnedByVirtualDeviceLocked(displayId); 953 switch (policyType) { 954 case POLICY_TYPE_RECENTS: 955 VirtualDisplayWrapper wrapper = mVirtualDisplays.get(displayId); 956 if (wrapper.isTrusted()) { 957 wrapper.getWindowPolicyController() 958 .setShowInHostDeviceRecents(devicePolicy == DEVICE_POLICY_DEFAULT); 959 } 960 break; 961 case POLICY_TYPE_ACTIVITY: 962 mVirtualDisplays.get(displayId).getWindowPolicyController() 963 .setActivityLaunchDefaultAllowed(devicePolicy == DEVICE_POLICY_DEFAULT); 964 break; 965 default: 966 throw new IllegalArgumentException("Device policy " + policyType 967 + " cannot be changed for a specific display. "); 968 } 969 } 970 } 971 972 @Override // Binder call createVirtualDpad(VirtualDpadConfig config, @NonNull IBinder deviceToken)973 public void createVirtualDpad(VirtualDpadConfig config, @NonNull IBinder deviceToken) { 974 checkCallerIsDeviceOwner(); 975 Objects.requireNonNull(config); 976 checkVirtualInputDeviceDisplayIdAssociation(config.getAssociatedDisplayId()); 977 final long ident = Binder.clearCallingIdentity(); 978 try { 979 mInputController.createDpad(config.getInputDeviceName(), config.getVendorId(), 980 config.getProductId(), deviceToken, 981 getTargetDisplayIdForInput(config.getAssociatedDisplayId())); 982 } catch (InputController.DeviceCreationException e) { 983 throw new IllegalArgumentException(e); 984 } finally { 985 Binder.restoreCallingIdentity(ident); 986 } 987 } 988 989 @Override // Binder call createVirtualKeyboard(VirtualKeyboardConfig config, @NonNull IBinder deviceToken)990 public void createVirtualKeyboard(VirtualKeyboardConfig config, @NonNull IBinder deviceToken) { 991 checkCallerIsDeviceOwner(); 992 Objects.requireNonNull(config); 993 checkVirtualInputDeviceDisplayIdAssociation(config.getAssociatedDisplayId()); 994 final long ident = Binder.clearCallingIdentity(); 995 try { 996 mInputController.createKeyboard(config.getInputDeviceName(), config.getVendorId(), 997 config.getProductId(), deviceToken, 998 getTargetDisplayIdForInput(config.getAssociatedDisplayId()), 999 config.getLanguageTag(), config.getLayoutType()); 1000 synchronized (mVirtualDeviceLock) { 1001 mLocaleList = LocaleList.forLanguageTags(config.getLanguageTag()); 1002 } 1003 } catch (InputController.DeviceCreationException e) { 1004 throw new IllegalArgumentException(e); 1005 } finally { 1006 Binder.restoreCallingIdentity(ident); 1007 } 1008 } 1009 1010 @Override // Binder call createVirtualMouse(VirtualMouseConfig config, @NonNull IBinder deviceToken)1011 public void createVirtualMouse(VirtualMouseConfig config, @NonNull IBinder deviceToken) { 1012 checkCallerIsDeviceOwner(); 1013 Objects.requireNonNull(config); 1014 checkVirtualInputDeviceDisplayIdAssociation(config.getAssociatedDisplayId()); 1015 final long ident = Binder.clearCallingIdentity(); 1016 try { 1017 mInputController.createMouse(config.getInputDeviceName(), config.getVendorId(), 1018 config.getProductId(), deviceToken, config.getAssociatedDisplayId()); 1019 } catch (InputController.DeviceCreationException e) { 1020 throw new IllegalArgumentException(e); 1021 } finally { 1022 Binder.restoreCallingIdentity(ident); 1023 } 1024 } 1025 1026 @Override // Binder call createVirtualTouchscreen(VirtualTouchscreenConfig config, @NonNull IBinder deviceToken)1027 public void createVirtualTouchscreen(VirtualTouchscreenConfig config, 1028 @NonNull IBinder deviceToken) { 1029 checkCallerIsDeviceOwner(); 1030 Objects.requireNonNull(config); 1031 checkVirtualInputDeviceDisplayIdAssociation(config.getAssociatedDisplayId()); 1032 final long ident = Binder.clearCallingIdentity(); 1033 try { 1034 mInputController.createTouchscreen(config.getInputDeviceName(), config.getVendorId(), 1035 config.getProductId(), deviceToken, config.getAssociatedDisplayId(), 1036 config.getHeight(), config.getWidth()); 1037 } catch (InputController.DeviceCreationException e) { 1038 throw new IllegalArgumentException(e); 1039 } finally { 1040 Binder.restoreCallingIdentity(ident); 1041 } 1042 } 1043 1044 @Override // Binder call createVirtualNavigationTouchpad(VirtualNavigationTouchpadConfig config, @NonNull IBinder deviceToken)1045 public void createVirtualNavigationTouchpad(VirtualNavigationTouchpadConfig config, 1046 @NonNull IBinder deviceToken) { 1047 checkCallerIsDeviceOwner(); 1048 Objects.requireNonNull(config); 1049 checkVirtualInputDeviceDisplayIdAssociation(config.getAssociatedDisplayId()); 1050 final long ident = Binder.clearCallingIdentity(); 1051 try { 1052 mInputController.createNavigationTouchpad( 1053 config.getInputDeviceName(), config.getVendorId(), 1054 config.getProductId(), deviceToken, 1055 getTargetDisplayIdForInput(config.getAssociatedDisplayId()), 1056 config.getHeight(), config.getWidth()); 1057 } catch (InputController.DeviceCreationException e) { 1058 throw new IllegalArgumentException(e); 1059 } finally { 1060 Binder.restoreCallingIdentity(ident); 1061 } 1062 } 1063 1064 @Override // Binder call createVirtualStylus(@onNull VirtualStylusConfig config, @NonNull IBinder deviceToken)1065 public void createVirtualStylus(@NonNull VirtualStylusConfig config, 1066 @NonNull IBinder deviceToken) { 1067 checkCallerIsDeviceOwner(); 1068 Objects.requireNonNull(config); 1069 Objects.requireNonNull(deviceToken); 1070 checkVirtualInputDeviceDisplayIdAssociation(config.getAssociatedDisplayId()); 1071 final long ident = Binder.clearCallingIdentity(); 1072 try { 1073 mInputController.createStylus(config.getInputDeviceName(), config.getVendorId(), 1074 config.getProductId(), deviceToken, config.getAssociatedDisplayId(), 1075 config.getHeight(), config.getWidth()); 1076 } catch (InputController.DeviceCreationException e) { 1077 throw new IllegalArgumentException(e); 1078 } finally { 1079 Binder.restoreCallingIdentity(ident); 1080 } 1081 } 1082 1083 @Override // Binder call createVirtualRotaryEncoder(@onNull VirtualRotaryEncoderConfig config, @NonNull IBinder deviceToken)1084 public void createVirtualRotaryEncoder(@NonNull VirtualRotaryEncoderConfig config, 1085 @NonNull IBinder deviceToken) { 1086 checkCallerIsDeviceOwner(); 1087 Objects.requireNonNull(config); 1088 Objects.requireNonNull(deviceToken); 1089 checkVirtualInputDeviceDisplayIdAssociation(config.getAssociatedDisplayId()); 1090 final long ident = Binder.clearCallingIdentity(); 1091 try { 1092 mInputController.createRotaryEncoder(config.getInputDeviceName(), config.getVendorId(), 1093 config.getProductId(), deviceToken, 1094 getTargetDisplayIdForInput(config.getAssociatedDisplayId())); 1095 } catch (InputController.DeviceCreationException e) { 1096 throw new IllegalArgumentException(e); 1097 } finally { 1098 Binder.restoreCallingIdentity(ident); 1099 } 1100 } 1101 1102 @Override // Binder call unregisterInputDevice(IBinder token)1103 public void unregisterInputDevice(IBinder token) { 1104 checkCallerIsDeviceOwner(); 1105 final long ident = Binder.clearCallingIdentity(); 1106 try { 1107 mInputController.unregisterInputDevice(token); 1108 } finally { 1109 Binder.restoreCallingIdentity(ident); 1110 } 1111 } 1112 1113 @Override // Binder call getInputDeviceId(IBinder token)1114 public int getInputDeviceId(IBinder token) { 1115 final long ident = Binder.clearCallingIdentity(); 1116 try { 1117 return mInputController.getInputDeviceId(token); 1118 } finally { 1119 Binder.restoreCallingIdentity(ident); 1120 } 1121 } 1122 1123 1124 @Override // Binder call sendDpadKeyEvent(IBinder token, VirtualKeyEvent event)1125 public boolean sendDpadKeyEvent(IBinder token, VirtualKeyEvent event) { 1126 checkCallerIsDeviceOwner(); 1127 final long ident = Binder.clearCallingIdentity(); 1128 try { 1129 return mInputController.sendDpadKeyEvent(token, event); 1130 } finally { 1131 Binder.restoreCallingIdentity(ident); 1132 } 1133 } 1134 1135 @Override // Binder call sendKeyEvent(IBinder token, VirtualKeyEvent event)1136 public boolean sendKeyEvent(IBinder token, VirtualKeyEvent event) { 1137 checkCallerIsDeviceOwner(); 1138 final long ident = Binder.clearCallingIdentity(); 1139 try { 1140 return mInputController.sendKeyEvent(token, event); 1141 } finally { 1142 Binder.restoreCallingIdentity(ident); 1143 } 1144 } 1145 1146 @Override // Binder call sendButtonEvent(IBinder token, VirtualMouseButtonEvent event)1147 public boolean sendButtonEvent(IBinder token, VirtualMouseButtonEvent event) { 1148 checkCallerIsDeviceOwner(); 1149 final long ident = Binder.clearCallingIdentity(); 1150 try { 1151 return mInputController.sendButtonEvent(token, event); 1152 } finally { 1153 Binder.restoreCallingIdentity(ident); 1154 } 1155 } 1156 1157 @Override // Binder call sendTouchEvent(IBinder token, VirtualTouchEvent event)1158 public boolean sendTouchEvent(IBinder token, VirtualTouchEvent event) { 1159 checkCallerIsDeviceOwner(); 1160 final long ident = Binder.clearCallingIdentity(); 1161 try { 1162 return mInputController.sendTouchEvent(token, event); 1163 } finally { 1164 Binder.restoreCallingIdentity(ident); 1165 } 1166 } 1167 1168 @Override // Binder call sendRelativeEvent(IBinder token, VirtualMouseRelativeEvent event)1169 public boolean sendRelativeEvent(IBinder token, VirtualMouseRelativeEvent event) { 1170 checkCallerIsDeviceOwner(); 1171 final long ident = Binder.clearCallingIdentity(); 1172 try { 1173 return mInputController.sendRelativeEvent(token, event); 1174 } finally { 1175 Binder.restoreCallingIdentity(ident); 1176 } 1177 } 1178 1179 @Override // Binder call sendScrollEvent(IBinder token, VirtualMouseScrollEvent event)1180 public boolean sendScrollEvent(IBinder token, VirtualMouseScrollEvent event) { 1181 checkCallerIsDeviceOwner(); 1182 final long ident = Binder.clearCallingIdentity(); 1183 try { 1184 return mInputController.sendScrollEvent(token, event); 1185 } finally { 1186 Binder.restoreCallingIdentity(ident); 1187 } 1188 } 1189 1190 @Override // Binder call getCursorPosition(IBinder token)1191 public PointF getCursorPosition(IBinder token) { 1192 final long ident = Binder.clearCallingIdentity(); 1193 try { 1194 return mInputController.getCursorPosition(token); 1195 } finally { 1196 Binder.restoreCallingIdentity(ident); 1197 } 1198 } 1199 1200 @Override // Binder call sendStylusMotionEvent(@onNull IBinder token, @NonNull VirtualStylusMotionEvent event)1201 public boolean sendStylusMotionEvent(@NonNull IBinder token, 1202 @NonNull VirtualStylusMotionEvent event) { 1203 checkCallerIsDeviceOwner(); 1204 Objects.requireNonNull(token); 1205 Objects.requireNonNull(event); 1206 final long ident = Binder.clearCallingIdentity(); 1207 try { 1208 return mInputController.sendStylusMotionEvent(token, event); 1209 } finally { 1210 Binder.restoreCallingIdentity(ident); 1211 } 1212 } 1213 1214 @Override // Binder call sendStylusButtonEvent(@onNull IBinder token, @NonNull VirtualStylusButtonEvent event)1215 public boolean sendStylusButtonEvent(@NonNull IBinder token, 1216 @NonNull VirtualStylusButtonEvent event) { 1217 checkCallerIsDeviceOwner(); 1218 Objects.requireNonNull(token); 1219 Objects.requireNonNull(event); 1220 final long ident = Binder.clearCallingIdentity(); 1221 try { 1222 return mInputController.sendStylusButtonEvent(token, event); 1223 } finally { 1224 Binder.restoreCallingIdentity(ident); 1225 } 1226 } 1227 1228 @Override // Binder call sendRotaryEncoderScrollEvent(@onNull IBinder token, @NonNull VirtualRotaryEncoderScrollEvent event)1229 public boolean sendRotaryEncoderScrollEvent(@NonNull IBinder token, 1230 @NonNull VirtualRotaryEncoderScrollEvent event) { 1231 checkCallerIsDeviceOwner(); 1232 final long ident = Binder.clearCallingIdentity(); 1233 try { 1234 return mInputController.sendRotaryEncoderScrollEvent(token, event); 1235 } finally { 1236 Binder.restoreCallingIdentity(ident); 1237 } 1238 } 1239 1240 @Override // Binder call setShowPointerIcon(boolean showPointerIcon)1241 public void setShowPointerIcon(boolean showPointerIcon) { 1242 checkCallerIsDeviceOwner(); 1243 final long ident = Binder.clearCallingIdentity(); 1244 try { 1245 synchronized (mVirtualDeviceLock) { 1246 mDefaultShowPointerIcon = showPointerIcon; 1247 for (int i = 0; i < mVirtualDisplays.size(); i++) { 1248 VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); 1249 if (wrapper.isTrusted() || wrapper.isMirror()) { 1250 mInputController.setShowPointerIcon( 1251 mDefaultShowPointerIcon, mVirtualDisplays.keyAt(i)); 1252 } 1253 } 1254 } 1255 } finally { 1256 Binder.restoreCallingIdentity(ident); 1257 } 1258 } 1259 1260 @Override // Binder call setDisplayImePolicy(int displayId, @WindowManager.DisplayImePolicy int policy)1261 public void setDisplayImePolicy(int displayId, @WindowManager.DisplayImePolicy int policy) { 1262 checkCallerIsDeviceOwner(); 1263 synchronized (mVirtualDeviceLock) { 1264 checkDisplayOwnedByVirtualDeviceLocked(displayId); 1265 } 1266 final long ident = Binder.clearCallingIdentity(); 1267 try { 1268 mInputController.setDisplayImePolicy(displayId, policy); 1269 } finally { 1270 Binder.restoreCallingIdentity(ident); 1271 } 1272 } 1273 1274 @Override // Binder call 1275 @Nullable getVirtualSensorList()1276 public List<VirtualSensor> getVirtualSensorList() { 1277 checkCallerIsDeviceOwner(); 1278 return mSensorController.getSensorList(); 1279 } 1280 1281 @Nullable getVirtualSensorByHandle(int handle)1282 VirtualSensor getVirtualSensorByHandle(int handle) { 1283 return mSensorController.getSensorByHandle(handle); 1284 } 1285 1286 @Override // Binder call sendSensorEvent(@onNull IBinder token, @NonNull VirtualSensorEvent event)1287 public boolean sendSensorEvent(@NonNull IBinder token, @NonNull VirtualSensorEvent event) { 1288 checkCallerIsDeviceOwner(); 1289 final long ident = Binder.clearCallingIdentity(); 1290 try { 1291 return mSensorController.sendSensorEvent(token, event); 1292 } finally { 1293 Binder.restoreCallingIdentity(ident); 1294 } 1295 } 1296 1297 @Override // Binder call sendSensorAdditionalInfo(@onNull IBinder token, @NonNull VirtualSensorAdditionalInfo info)1298 public boolean sendSensorAdditionalInfo(@NonNull IBinder token, 1299 @NonNull VirtualSensorAdditionalInfo info) { 1300 checkCallerIsDeviceOwner(); 1301 final long ident = Binder.clearCallingIdentity(); 1302 try { 1303 return mSensorController.sendSensorAdditionalInfo(token, info); 1304 } finally { 1305 Binder.restoreCallingIdentity(ident); 1306 } 1307 } 1308 1309 @Override // Binder call registerIntentInterceptor(IVirtualDeviceIntentInterceptor intentInterceptor, IntentFilter filter)1310 public void registerIntentInterceptor(IVirtualDeviceIntentInterceptor intentInterceptor, 1311 IntentFilter filter) { 1312 checkCallerIsDeviceOwner(); 1313 Objects.requireNonNull(intentInterceptor); 1314 Objects.requireNonNull(filter); 1315 synchronized (mIntentInterceptors) { 1316 mIntentInterceptors.put(intentInterceptor.asBinder(), filter); 1317 } 1318 } 1319 1320 @Override // Binder call unregisterIntentInterceptor( @onNull IVirtualDeviceIntentInterceptor intentInterceptor)1321 public void unregisterIntentInterceptor( 1322 @NonNull IVirtualDeviceIntentInterceptor intentInterceptor) { 1323 checkCallerIsDeviceOwner(); 1324 Objects.requireNonNull(intentInterceptor); 1325 synchronized (mIntentInterceptors) { 1326 mIntentInterceptors.remove(intentInterceptor.asBinder()); 1327 } 1328 } 1329 1330 @Override // Binder call registerVirtualCamera(@onNull VirtualCameraConfig cameraConfig)1331 public void registerVirtualCamera(@NonNull VirtualCameraConfig cameraConfig) 1332 throws RemoteException { 1333 checkCallerIsDeviceOwner(); 1334 Objects.requireNonNull(cameraConfig); 1335 if (mVirtualCameraController == null) { 1336 throw new UnsupportedOperationException("Virtual camera controller is not available"); 1337 } 1338 mVirtualCameraController.registerCamera(cameraConfig, mAttributionSource); 1339 } 1340 1341 @Override // Binder call unregisterVirtualCamera(@onNull VirtualCameraConfig cameraConfig)1342 public void unregisterVirtualCamera(@NonNull VirtualCameraConfig cameraConfig) 1343 throws RemoteException { 1344 checkCallerIsDeviceOwner(); 1345 Objects.requireNonNull(cameraConfig); 1346 if (mVirtualCameraController == null) { 1347 throw new UnsupportedOperationException("Virtual camera controller is not available"); 1348 } 1349 mVirtualCameraController.unregisterCamera(cameraConfig); 1350 } 1351 1352 @Override // Binder call getVirtualCameraId(@onNull VirtualCameraConfig cameraConfig)1353 public String getVirtualCameraId(@NonNull VirtualCameraConfig cameraConfig) 1354 throws RemoteException { 1355 Objects.requireNonNull(cameraConfig); 1356 if (mVirtualCameraController == null) { 1357 throw new UnsupportedOperationException("Virtual camera controller is not available"); 1358 } 1359 return mVirtualCameraController.getCameraId(cameraConfig); 1360 } 1361 1362 @Override hasCustomAudioInputSupport()1363 public boolean hasCustomAudioInputSupport() throws RemoteException { 1364 return hasCustomAudioInputSupportInternal(); 1365 } 1366 1367 @Override canCreateMirrorDisplays()1368 public boolean canCreateMirrorDisplays() { 1369 return DEVICE_PROFILES_ALLOWING_MIRROR_DISPLAYS.contains(getDeviceProfile()); 1370 } 1371 hasCustomAudioInputSupportInternal()1372 private boolean hasCustomAudioInputSupportInternal() { 1373 if (!android.media.audiopolicy.Flags.audioMixTestApi()) { 1374 return false; 1375 } 1376 if (!android.media.audiopolicy.Flags.recordAudioDeviceAwarePermission()) { 1377 return false; 1378 } 1379 1380 if (getDevicePolicy(POLICY_TYPE_AUDIO) == VirtualDeviceParams.DEVICE_POLICY_CUSTOM) { 1381 return true; 1382 } 1383 final long token = Binder.clearCallingIdentity(); 1384 try { 1385 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 1386 for (AudioMix mix : audioManager.getRegisteredPolicyMixes()) { 1387 if (mix.matchesVirtualDeviceId(getDeviceId()) 1388 && mix.getMixType() == AudioMix.MIX_TYPE_RECORDERS) { 1389 return true; 1390 } 1391 } 1392 } finally { 1393 Binder.restoreCallingIdentity(token); 1394 } 1395 return false; 1396 } 1397 1398 @Override dump(FileDescriptor fd, PrintWriter fout, String[] args)1399 protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 1400 String indent = " "; 1401 fout.println(" VirtualDevice: "); 1402 fout.println(indent + "mDeviceId: " + mDeviceId); 1403 fout.println(indent + "mAssociationId: " + getAssociationId()); 1404 fout.println(indent + "mOwnerPackageName: " + mOwnerPackageName); 1405 fout.println(indent + "mParams: "); 1406 mParams.dump(fout, indent + indent); 1407 fout.println(indent + "mVirtualDisplayIds: "); 1408 synchronized (mVirtualDeviceLock) { 1409 for (int i = 0; i < mVirtualDisplays.size(); i++) { 1410 fout.println(indent + " " + mVirtualDisplays.keyAt(i)); 1411 } 1412 fout.println(" mDevicePolicies: " + mDevicePolicies); 1413 fout.println(indent + "mDefaultShowPointerIcon: " + mDefaultShowPointerIcon); 1414 } 1415 mInputController.dump(fout); 1416 mSensorController.dump(fout); 1417 if (mVirtualCameraController != null) { 1418 mVirtualCameraController.dump(fout, indent); 1419 } 1420 fout.println( 1421 indent + "hasCustomAudioInputSupport: " + hasCustomAudioInputSupportInternal()); 1422 } 1423 1424 // For display mirroring, we want to dispatch all key events to the source (default) display, 1425 // as the virtual display doesn't have any focused windows. Hence, call this for 1426 // associating any input device to the source display if the input device emits any key events. getTargetDisplayIdForInput(int displayId)1427 private int getTargetDisplayIdForInput(int displayId) { 1428 DisplayManagerInternal displayManager = LocalServices.getService( 1429 DisplayManagerInternal.class); 1430 int mirroredDisplayId = displayManager.getDisplayIdToMirror(displayId); 1431 return mirroredDisplayId == Display.INVALID_DISPLAY ? displayId : mirroredDisplayId; 1432 } 1433 createWindowPolicyController( @onNull Set<String> displayCategories)1434 private GenericWindowPolicyController createWindowPolicyController( 1435 @NonNull Set<String> displayCategories) { 1436 final boolean activityLaunchAllowedByDefault = 1437 getDevicePolicy(POLICY_TYPE_ACTIVITY) == DEVICE_POLICY_DEFAULT; 1438 final boolean crossTaskNavigationAllowedByDefault = 1439 mParams.getDefaultNavigationPolicy() == NAVIGATION_POLICY_DEFAULT_ALLOWED; 1440 final boolean showTasksInHostDeviceRecents = 1441 getDevicePolicy(POLICY_TYPE_RECENTS) == DEVICE_POLICY_DEFAULT; 1442 1443 synchronized (mVirtualDeviceLock) { 1444 if (mActivityListenerAdapter == null) { 1445 mActivityListenerAdapter = new GwpcActivityListener(); 1446 } 1447 1448 return new GenericWindowPolicyController( 1449 WindowManager.LayoutParams.FLAG_SECURE, 1450 WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS, 1451 mAttributionSource, 1452 getAllowedUserHandles(), 1453 activityLaunchAllowedByDefault, 1454 mActivityPolicyExemptions, 1455 mActivityPolicyPackageExemptions, 1456 crossTaskNavigationAllowedByDefault, 1457 /* crossTaskNavigationExemptions= */crossTaskNavigationAllowedByDefault 1458 ? mParams.getBlockedCrossTaskNavigations() 1459 : mParams.getAllowedCrossTaskNavigations(), 1460 mActivityListenerAdapter, 1461 displayCategories, 1462 showTasksInHostDeviceRecents, 1463 mParams.getHomeComponent()); 1464 } 1465 } 1466 1467 @Override // Binder call createVirtualDisplay(@onNull VirtualDisplayConfig virtualDisplayConfig, @NonNull IVirtualDisplayCallback callback)1468 public int createVirtualDisplay(@NonNull VirtualDisplayConfig virtualDisplayConfig, 1469 @NonNull IVirtualDisplayCallback callback) { 1470 checkCallerIsDeviceOwner(); 1471 1472 final boolean isTrustedDisplay = 1473 (virtualDisplayConfig.getFlags() & DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED) 1474 == DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; 1475 if (!isTrustedDisplay && getDevicePolicy(POLICY_TYPE_CLIPBOARD) != DEVICE_POLICY_DEFAULT) { 1476 throw new SecurityException( 1477 "All displays must be trusted for devices with custom clipboard policy."); 1478 } 1479 1480 GenericWindowPolicyController gwpc = 1481 createWindowPolicyController(virtualDisplayConfig.getDisplayCategories()); 1482 1483 // Create the display outside of the lock to avoid deadlock. DisplayManagerService will 1484 // acquire the global WM lock while creating the display. At the same time, WM may query 1485 // VDM and this virtual device to get policies, display ownership, etc. 1486 int displayId = mDisplayManagerInternal.createVirtualDisplay(virtualDisplayConfig, 1487 callback, this, gwpc, mOwnerPackageName); 1488 if (displayId == Display.INVALID_DISPLAY) { 1489 return displayId; 1490 } 1491 1492 // DisplayManagerService will call onVirtualDisplayCreated() after the display is created, 1493 // while holding its own lock to ensure that this device knows about the display before any 1494 // other display listeners are notified about the display creation. 1495 VirtualDisplayWrapper displayWrapper; 1496 boolean showPointer; 1497 synchronized (mVirtualDeviceLock) { 1498 if (!mVirtualDisplays.contains(displayId)) { 1499 throw new IllegalStateException("Virtual device was not notified about the " 1500 + "creation of display with ID " + displayId); 1501 } 1502 displayWrapper = mVirtualDisplays.get(displayId); 1503 showPointer = mDefaultShowPointerIcon; 1504 } 1505 displayWrapper.acquireWakeLock(); 1506 gwpc.registerRunningAppsChangedListener(/* listener= */ this); 1507 1508 Binder.withCleanCallingIdentity(() -> { 1509 mInputController.setMouseScalingEnabled(false, displayId); 1510 mInputController.setDisplayEligibilityForPointerCapture(/* isEligible= */ false, 1511 displayId); 1512 if (displayWrapper.isTrusted()) { 1513 mInputController.setShowPointerIcon(showPointer, displayId); 1514 mInputController.setDisplayImePolicy(displayId, 1515 WindowManager.DISPLAY_IME_POLICY_LOCAL); 1516 } else { 1517 gwpc.setShowInHostDeviceRecents(true); 1518 } 1519 }); 1520 1521 Counter.logIncrementWithUid( 1522 "virtual_devices.value_virtual_display_created_count", 1523 mAttributionSource.getUid()); 1524 return displayId; 1525 } 1526 createWakeLockForDisplay(int displayId)1527 private PowerManager.WakeLock createWakeLockForDisplay(int displayId) { 1528 if (Flags.deviceAwareDisplayPower()) { 1529 return null; 1530 } 1531 final long token = Binder.clearCallingIdentity(); 1532 try { 1533 PowerManager powerManager = mContext.getSystemService(PowerManager.class); 1534 PowerManager.WakeLock wakeLock = powerManager.newWakeLock( 1535 PowerManager.SCREEN_BRIGHT_WAKE_LOCK, 1536 TAG + ":" + displayId, displayId); 1537 return wakeLock; 1538 } finally { 1539 Binder.restoreCallingIdentity(token); 1540 } 1541 } 1542 shouldShowBlockedActivityDialog(ComponentName blockedComponent, ComponentName blockedAppStreamingActivityComponent)1543 private boolean shouldShowBlockedActivityDialog(ComponentName blockedComponent, 1544 ComponentName blockedAppStreamingActivityComponent) { 1545 if (Objects.equals(blockedComponent, blockedAppStreamingActivityComponent)) { 1546 // Do not show the dialog if it was blocked for some reason already to avoid 1547 // infinite blocking loop. 1548 return false; 1549 } 1550 if (!Flags.activityControlApi()) { 1551 return true; 1552 } 1553 // Do not show the dialog if disabled by policy. 1554 return getDevicePolicy(POLICY_TYPE_BLOCKED_ACTIVITY) == DEVICE_POLICY_DEFAULT; 1555 } 1556 getAllowedUserHandles()1557 private ArraySet<UserHandle> getAllowedUserHandles() { 1558 ArraySet<UserHandle> result = new ArraySet<>(); 1559 final long token = Binder.clearCallingIdentity(); 1560 try { 1561 DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class); 1562 UserManager userManager = mContext.getSystemService(UserManager.class); 1563 for (UserHandle profile : userManager.getAllProfiles()) { 1564 int nearbyAppStreamingPolicy = dpm.getNearbyAppStreamingPolicy( 1565 profile.getIdentifier()); 1566 if (nearbyAppStreamingPolicy == NEARBY_STREAMING_ENABLED 1567 || nearbyAppStreamingPolicy == NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY) { 1568 result.add(profile); 1569 } else if (nearbyAppStreamingPolicy == NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY) { 1570 if (mParams.getUsersWithMatchingAccounts().contains(profile)) { 1571 result.add(profile); 1572 } 1573 } 1574 } 1575 } finally { 1576 Binder.restoreCallingIdentity(token); 1577 } 1578 return result; 1579 } 1580 1581 /** 1582 * DisplayManagerService is notifying this virtual device about the display creation. This 1583 * should happen before the DisplayManagerInternal#createVirtualDisplay() call above 1584 * returns. 1585 * This is called while holding the DisplayManagerService lock, so no heavy-weight work must 1586 * be done here and especially *** no calls to WindowManager! *** 1587 */ onVirtualDisplayCreated(int displayId, IVirtualDisplayCallback callback, DisplayWindowPolicyController dwpc)1588 public void onVirtualDisplayCreated(int displayId, IVirtualDisplayCallback callback, 1589 DisplayWindowPolicyController dwpc) { 1590 final boolean isMirrorDisplay = 1591 mDisplayManagerInternal.getDisplayIdToMirror(displayId) != Display.INVALID_DISPLAY; 1592 final boolean isTrustedDisplay = 1593 (mDisplayManagerInternal.getDisplayInfo(displayId).flags & Display.FLAG_TRUSTED) 1594 == Display.FLAG_TRUSTED; 1595 1596 GenericWindowPolicyController gwpc = (GenericWindowPolicyController) dwpc; 1597 gwpc.setDisplayId(displayId, isMirrorDisplay); 1598 PowerManager.WakeLock wakeLock = 1599 isTrustedDisplay ? createWakeLockForDisplay(displayId) : null; 1600 synchronized (mVirtualDeviceLock) { 1601 if (mVirtualDisplays.contains(displayId)) { 1602 Slog.wtf(TAG, "Virtual device already has a virtual display with ID " + displayId); 1603 return; 1604 } 1605 mVirtualDisplays.put(displayId, new VirtualDisplayWrapper(callback, gwpc, wakeLock, 1606 isTrustedDisplay, isMirrorDisplay)); 1607 } 1608 } 1609 1610 /** 1611 * This is callback invoked by VirtualDeviceManagerService when VirtualDisplay was released 1612 * by DisplayManager (most probably caused by someone calling VirtualDisplay.close()). 1613 * At this point, the display is already released, but we still need to release the 1614 * corresponding wakeLock and unregister the RunningAppsChangedListener from corresponding 1615 * WindowPolicyController. 1616 * 1617 * Note that when the display is destroyed during VirtualDeviceImpl.close() call, 1618 * this callback won't be invoked because the display is removed from 1619 * VirtualDeviceManagerService before any resources are released. 1620 */ onVirtualDisplayRemoved(int displayId)1621 void onVirtualDisplayRemoved(int displayId) { 1622 VirtualDisplayWrapper virtualDisplayWrapper; 1623 synchronized (mVirtualDeviceLock) { 1624 virtualDisplayWrapper = mVirtualDisplays.removeReturnOld(displayId); 1625 } 1626 1627 if (virtualDisplayWrapper == null) { 1628 Slog.w(TAG, "Virtual device " + mDeviceId + " doesn't have a virtual display with ID " 1629 + displayId); 1630 return; 1631 } 1632 1633 final long ident = Binder.clearCallingIdentity(); 1634 try { 1635 releaseOwnedVirtualDisplayResources(virtualDisplayWrapper); 1636 } finally { 1637 Binder.restoreCallingIdentity(ident); 1638 } 1639 } 1640 1641 @SuppressWarnings("AndroidFrameworkRequiresPermission") checkVirtualInputDeviceDisplayIdAssociation(int displayId)1642 private void checkVirtualInputDeviceDisplayIdAssociation(int displayId) { 1643 // The INJECT_EVENTS permission allows for injecting input to any window / display. 1644 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INJECT_EVENTS) 1645 != PackageManager.PERMISSION_GRANTED) { 1646 synchronized (mVirtualDeviceLock) { 1647 checkDisplayOwnedByVirtualDeviceLocked(displayId); 1648 VirtualDisplayWrapper wrapper = mVirtualDisplays.get(displayId); 1649 if (!wrapper.isTrusted() && !wrapper.isMirror()) { 1650 throw new SecurityException( 1651 "Cannot create input device associated with an untrusted display"); 1652 } 1653 } 1654 } 1655 } 1656 1657 @GuardedBy("mVirtualDeviceLock") checkDisplayOwnedByVirtualDeviceLocked(int displayId)1658 private void checkDisplayOwnedByVirtualDeviceLocked(int displayId) { 1659 if (!mVirtualDisplays.contains(displayId)) { 1660 throw new SecurityException( 1661 "Invalid displayId: Display " + displayId 1662 + " is not associated with this virtual device"); 1663 } 1664 } 1665 checkCallerIsDeviceOwner()1666 private void checkCallerIsDeviceOwner() { 1667 if (Binder.getCallingUid() != mOwnerUid) { 1668 throw new SecurityException( 1669 "Caller is not the owner of this virtual device"); 1670 } 1671 } 1672 goToSleepInternal(@owerManager.GoToSleepReason int reason)1673 void goToSleepInternal(@PowerManager.GoToSleepReason int reason) { 1674 final long now = SystemClock.uptimeMillis(); 1675 IntArray displayIds = new IntArray(); 1676 synchronized (mVirtualDeviceLock) { 1677 for (int i = 0; i < mVirtualDisplays.size(); i++) { 1678 VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); 1679 if (!wrapper.isTrusted() || wrapper.isMirror()) { 1680 continue; 1681 } 1682 int displayId = mVirtualDisplays.keyAt(i); 1683 displayIds.add(displayId); 1684 } 1685 } 1686 for (int i = 0; i < displayIds.size(); ++i) { 1687 mPowerManager.goToSleep(displayIds.get(i), now, reason, /* flags= */ 0); 1688 } 1689 } 1690 wakeUpInternal(@owerManager.WakeReason int reason, String details)1691 void wakeUpInternal(@PowerManager.WakeReason int reason, String details) { 1692 final long now = SystemClock.uptimeMillis(); 1693 IntArray displayIds = new IntArray(); 1694 synchronized (mVirtualDeviceLock) { 1695 for (int i = 0; i < mVirtualDisplays.size(); i++) { 1696 VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i); 1697 if (!wrapper.isTrusted() || wrapper.isMirror()) { 1698 continue; 1699 } 1700 int displayId = mVirtualDisplays.keyAt(i); 1701 displayIds.add(displayId); 1702 } 1703 } 1704 for (int i = 0; i < displayIds.size(); ++i) { 1705 mPowerManager.wakeUp(now, reason, details, displayIds.get(i)); 1706 } 1707 } 1708 1709 /** 1710 * Release resources tied to virtual display owned by this VirtualDevice instance. 1711 * 1712 * Note that this method won't release the virtual display itself. 1713 * 1714 * @param virtualDisplayWrapper - VirtualDisplayWrapper to release resources for. 1715 */ releaseOwnedVirtualDisplayResources(VirtualDisplayWrapper virtualDisplayWrapper)1716 private void releaseOwnedVirtualDisplayResources(VirtualDisplayWrapper virtualDisplayWrapper) { 1717 virtualDisplayWrapper.releaseWakeLock(); 1718 virtualDisplayWrapper.getWindowPolicyController().unregisterRunningAppsChangedListener( 1719 this); 1720 } 1721 getOwnerUid()1722 int getOwnerUid() { 1723 return mOwnerUid; 1724 } 1725 getDimDurationMillis()1726 long getDimDurationMillis() { 1727 return mParams.getDimDuration().toMillis(); 1728 } 1729 getScreenOffTimeoutMillis()1730 long getScreenOffTimeoutMillis() { 1731 return mParams.getScreenOffTimeout().toMillis(); 1732 } 1733 1734 @Override // Binder call getDisplayIds()1735 public int[] getDisplayIds() { 1736 synchronized (mVirtualDeviceLock) { 1737 final int size = mVirtualDisplays.size(); 1738 int[] displayIds = new int[size]; 1739 for (int i = 0; i < size; i++) { 1740 displayIds[i] = mVirtualDisplays.keyAt(i); 1741 } 1742 return displayIds; 1743 } 1744 } 1745 1746 @VisibleForTesting getDisplayWindowPolicyControllerForTest(int displayId)1747 GenericWindowPolicyController getDisplayWindowPolicyControllerForTest(int displayId) { 1748 VirtualDisplayWrapper virtualDisplayWrapper; 1749 synchronized (mVirtualDeviceLock) { 1750 virtualDisplayWrapper = mVirtualDisplays.get(displayId); 1751 } 1752 return virtualDisplayWrapper != null ? virtualDisplayWrapper.getWindowPolicyController() 1753 : null; 1754 } 1755 1756 /** 1757 * Returns true if an app with the given {@code uid} is currently running on this virtual 1758 * device. 1759 */ isAppRunningOnVirtualDevice(int uid)1760 boolean isAppRunningOnVirtualDevice(int uid) { 1761 synchronized (mVirtualDeviceLock) { 1762 for (int i = 0; i < mVirtualDisplays.size(); i++) { 1763 if (mVirtualDisplays.valueAt(i).getWindowPolicyController().containsUid(uid)) { 1764 return true; 1765 } 1766 } 1767 } 1768 return false; 1769 } 1770 1771 /** 1772 * Shows a toast on virtual displays owned by this device which have a given uid running. 1773 */ showToastWhereUidIsRunning(int uid, @StringRes int resId, @Toast.Duration int duration, Looper looper)1774 void showToastWhereUidIsRunning(int uid, @StringRes int resId, @Toast.Duration int duration, 1775 Looper looper) { 1776 showToastWhereUidIsRunning(uid, mContext.getString(resId), duration, looper); 1777 } 1778 1779 /** 1780 * Shows a toast on virtual displays owned by this device which have a given uid running. 1781 */ showToastWhereUidIsRunning(int uid, String text, @Toast.Duration int duration, Looper looper)1782 void showToastWhereUidIsRunning(int uid, String text, @Toast.Duration int duration, 1783 Looper looper) { 1784 IntArray displayIdsForUid = getDisplayIdsWhereUidIsRunning(uid); 1785 if (displayIdsForUid.size() == 0) { 1786 return; 1787 } 1788 DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); 1789 for (int i = 0; i < displayIdsForUid.size(); i++) { 1790 Display display = displayManager.getDisplay(displayIdsForUid.get(i)); 1791 if (display != null && display.isValid()) { 1792 Toast.makeText(mContext.createDisplayContext(display), looper, text, 1793 duration).show(); 1794 } 1795 } 1796 } 1797 getDisplayIdsWhereUidIsRunning(int uid)1798 private IntArray getDisplayIdsWhereUidIsRunning(int uid) { 1799 IntArray displayIdsForUid = new IntArray(); 1800 synchronized (mVirtualDeviceLock) { 1801 for (int i = 0; i < mVirtualDisplays.size(); i++) { 1802 if (mVirtualDisplays.valueAt(i).getWindowPolicyController().containsUid(uid)) { 1803 displayIdsForUid.add(mVirtualDisplays.keyAt(i)); 1804 } 1805 } 1806 } 1807 return displayIdsForUid; 1808 } 1809 isDisplayOwnedByVirtualDevice(int displayId)1810 boolean isDisplayOwnedByVirtualDevice(int displayId) { 1811 synchronized (mVirtualDeviceLock) { 1812 return mVirtualDisplays.contains(displayId); 1813 } 1814 } 1815 isInputDeviceOwnedByVirtualDevice(int inputDeviceId)1816 boolean isInputDeviceOwnedByVirtualDevice(int inputDeviceId) { 1817 return mInputController.getInputDeviceDescriptors().values().stream().anyMatch( 1818 inputDeviceDescriptor -> inputDeviceDescriptor.getInputDeviceId() == inputDeviceId); 1819 } 1820 playSoundEffect(int effectType)1821 void playSoundEffect(int effectType) { 1822 try { 1823 mSoundEffectListener.onPlaySoundEffect(effectType); 1824 } catch (RemoteException exception) { 1825 Slog.w(TAG, "Unable to invoke sound effect listener", exception); 1826 } 1827 } 1828 1829 interface PendingTrampolineCallback { 1830 /** 1831 * Called when the callback should start waiting for the given pending trampoline. 1832 * Implementations should try to listen for activity starts associated with the given 1833 * {@code pendingTrampoline}, and launch the activity on the display with 1834 * {@link PendingTrampoline#mDisplayId}. 1835 */ startWaitingForPendingTrampoline(PendingTrampoline pendingTrampoline)1836 void startWaitingForPendingTrampoline(PendingTrampoline pendingTrampoline); 1837 1838 /** 1839 * Called when the callback should stop waiting for the given pending trampoline. This can 1840 * happen, for example, when the pending intent failed to send. 1841 */ stopWaitingForPendingTrampoline(PendingTrampoline pendingTrampoline)1842 void stopWaitingForPendingTrampoline(PendingTrampoline pendingTrampoline); 1843 } 1844 1845 /** 1846 * A data class storing a pending trampoline this device is expecting. 1847 */ 1848 static class PendingTrampoline { 1849 1850 /** 1851 * The original pending intent sent, for which a trampoline activity launch is expected. 1852 */ 1853 final PendingIntent mPendingIntent; 1854 1855 /** 1856 * The result receiver associated with this pending call. {@link Activity#RESULT_OK} will 1857 * be sent to the receiver if the trampoline activity was captured successfully. 1858 * {@link Activity#RESULT_CANCELED} is sent otherwise. 1859 */ 1860 final ResultReceiver mResultReceiver; 1861 1862 /** 1863 * The display ID to send the captured trampoline activity launch to. 1864 */ 1865 final int mDisplayId; 1866 PendingTrampoline(PendingIntent pendingIntent, ResultReceiver resultReceiver, int displayId)1867 private PendingTrampoline(PendingIntent pendingIntent, ResultReceiver resultReceiver, 1868 int displayId) { 1869 mPendingIntent = pendingIntent; 1870 mResultReceiver = resultReceiver; 1871 mDisplayId = displayId; 1872 } 1873 1874 @Override toString()1875 public String toString() { 1876 return "PendingTrampoline{" 1877 + "pendingIntent=" + mPendingIntent 1878 + ", resultReceiver=" + mResultReceiver 1879 + ", displayId=" + mDisplayId + "}"; 1880 } 1881 } 1882 1883 /** Data class wrapping resources tied to single virtual display. */ 1884 private static final class VirtualDisplayWrapper { 1885 private final IVirtualDisplayCallback mToken; 1886 private final GenericWindowPolicyController mWindowPolicyController; 1887 private final PowerManager.WakeLock mWakeLock; 1888 private final boolean mIsTrusted; 1889 private final boolean mIsMirror; 1890 VirtualDisplayWrapper(@onNull IVirtualDisplayCallback token, @NonNull GenericWindowPolicyController windowPolicyController, @Nullable PowerManager.WakeLock wakeLock, boolean isTrusted, boolean isMirror)1891 VirtualDisplayWrapper(@NonNull IVirtualDisplayCallback token, 1892 @NonNull GenericWindowPolicyController windowPolicyController, 1893 @Nullable PowerManager.WakeLock wakeLock, boolean isTrusted, boolean isMirror) { 1894 mToken = Objects.requireNonNull(token); 1895 mWindowPolicyController = Objects.requireNonNull(windowPolicyController); 1896 mWakeLock = wakeLock; 1897 mIsTrusted = isTrusted; 1898 mIsMirror = isMirror; 1899 } 1900 getWindowPolicyController()1901 GenericWindowPolicyController getWindowPolicyController() { 1902 return mWindowPolicyController; 1903 } 1904 acquireWakeLock()1905 void acquireWakeLock() { 1906 if (mWakeLock != null && !mWakeLock.isHeld()) { 1907 mWakeLock.acquire(); 1908 } 1909 } 1910 releaseWakeLock()1911 void releaseWakeLock() { 1912 if (mWakeLock != null && mWakeLock.isHeld()) { 1913 mWakeLock.release(); 1914 } 1915 } 1916 isTrusted()1917 boolean isTrusted() { 1918 return mIsTrusted; 1919 } 1920 isMirror()1921 boolean isMirror() { 1922 return mIsMirror; 1923 } 1924 getToken()1925 IVirtualDisplayCallback getToken() { 1926 return mToken; 1927 } 1928 } 1929 isVirtualCameraEnabled()1930 private static boolean isVirtualCameraEnabled() { 1931 return nativeVirtualCameraServiceBuildFlagEnabled(); 1932 } 1933 1934 // Returns true if virtual_camera service is enabled in this build. 1935 @FastNative nativeVirtualCameraServiceBuildFlagEnabled()1936 private static native boolean nativeVirtualCameraServiceBuildFlagEnabled(); 1937 } 1938