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.example.android.vdmdemo.host; 18 19 import static android.Manifest.permission.ADD_MIRROR_DISPLAY; 20 21 import android.companion.AssociationRequest; 22 import android.companion.virtual.VirtualDeviceManager.VirtualDevice; 23 import android.companion.virtualdevice.flags.Flags; 24 import android.content.Context; 25 import android.content.pm.PackageManager; 26 import android.hardware.display.VirtualDisplayConfig; 27 import android.hardware.input.InputManager; 28 import android.os.Build; 29 import android.view.InputDevice; 30 31 import androidx.core.os.BuildCompat; 32 33 public class VdmCompat { 34 35 // Hidden DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS. 36 private static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 9; 37 VdmCompat()38 private VdmCompat() {} 39 setHomeSupported( VirtualDisplayConfig.Builder builder, int flags)40 static VirtualDisplayConfig.Builder setHomeSupported( 41 VirtualDisplayConfig.Builder builder, int flags) { 42 if (BuildCompat.isAtLeastV()) { 43 return builder.setHomeSupported(true); 44 } else { 45 return builder.setFlags(flags | VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS); 46 } 47 } 48 setDisplayImePolicy(VirtualDevice virtualDevice, int displayId, int policy)49 static void setDisplayImePolicy(VirtualDevice virtualDevice, int displayId, int policy) { 50 if (BuildCompat.isAtLeastV()) { 51 virtualDevice.setDisplayImePolicy(displayId, policy); 52 } 53 } 54 canCreateVirtualMouse(Context context)55 static boolean canCreateVirtualMouse(Context context) { 56 if (BuildCompat.isAtLeastV()) { 57 return true; 58 } 59 InputManager inputManager = context.getSystemService(InputManager.class); 60 for (int inputDeviceId : inputManager.getInputDeviceIds()) { 61 InputDevice inputDevice = inputManager.getInputDevice(inputDeviceId); 62 String inputDeviceName = inputDevice.getName(); 63 if (inputDeviceName != null && inputDeviceName.startsWith("vdmdemo-mouse")) { 64 return false; 65 } 66 } 67 return true; 68 } 69 isMirrorDisplaySupported(Context context, PreferenceController preferenceController)70 static boolean isMirrorDisplaySupported(Context context, 71 PreferenceController preferenceController) { 72 if (!preferenceController.getBoolean(R.string.internal_pref_mirror_displays_supported)) { 73 return false; 74 } 75 if (preferenceController.getBoolean(R.string.pref_standalone_host_demo)) { 76 return false; 77 } 78 if (isAtLeastB() && Flags.enableLimitedVdmRole()) { 79 return context.checkCallingOrSelfPermission(ADD_MIRROR_DISPLAY) 80 == PackageManager.PERMISSION_GRANTED; 81 } 82 return preferenceController.getString(R.string.pref_device_profile) 83 .equals(AssociationRequest.DEVICE_PROFILE_APP_STREAMING); 84 } 85 86 // TODO(b/379277747): replace with BuildCompat.isAtLeastB once available. isAtLeastB()87 static boolean isAtLeastB() { 88 return Build.VERSION.CODENAME.equals("Baklava") 89 || Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA; 90 } 91 } 92