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 android.view.Display; 20 21 import androidx.annotation.GuardedBy; 22 23 import com.example.android.vdmdemo.common.RemoteEventProto.RemoteEvent; 24 25 import java.util.ArrayList; 26 import java.util.List; 27 import java.util.Optional; 28 29 import javax.inject.Inject; 30 import javax.inject.Singleton; 31 32 @Singleton 33 final class DisplayRepository { 34 35 @GuardedBy("mDisplayRepository") 36 private final List<RemoteDisplay> mDisplayRepository = new ArrayList<>(); 37 38 @Inject DisplayRepository()39 DisplayRepository() {} 40 addDisplay(RemoteDisplay display)41 void addDisplay(RemoteDisplay display) { 42 synchronized (mDisplayRepository) { 43 mDisplayRepository.add(display); 44 } 45 } 46 removeDisplay(int displayId)47 void removeDisplay(int displayId) { 48 getDisplay(displayId).ifPresent(this::closeDisplay); 49 } 50 removeDisplayByRemoteId(int remoteDisplayId)51 void removeDisplayByRemoteId(int remoteDisplayId) { 52 getDisplayByRemoteId(remoteDisplayId).ifPresent(this::closeDisplay); 53 } 54 onDisplayChanged(int displayId)55 void onDisplayChanged(int displayId) { 56 getDisplay(displayId).ifPresent(RemoteDisplay::onDisplayChanged); 57 } 58 resetDisplay(RemoteEvent event)59 boolean resetDisplay(RemoteEvent event) { 60 Optional<RemoteDisplay> display = getDisplayByRemoteId(event.getDisplayId()); 61 display.ifPresent(d -> d.reset( 62 event.getDisplayCapabilities().getViewportWidth(), 63 event.getDisplayCapabilities().getViewportHeight(), 64 event.getDisplayCapabilities().getDensityDpi())); 65 return display.isPresent(); 66 } 67 clear()68 void clear() { 69 synchronized (mDisplayRepository) { 70 mDisplayRepository.forEach(RemoteDisplay::close); 71 mDisplayRepository.clear(); 72 } 73 } 74 getDisplayIds()75 int[] getDisplayIds() { 76 synchronized (mDisplayRepository) { 77 return mDisplayRepository.stream() 78 .mapToInt(RemoteDisplay::getDisplayId) 79 .toArray(); 80 } 81 } 82 getRemoteDisplayIds()83 int[] getRemoteDisplayIds() { 84 synchronized (mDisplayRepository) { 85 return mDisplayRepository.stream() 86 .mapToInt(RemoteDisplay::getRemoteDisplayId) 87 .toArray(); 88 } 89 } 90 getRemoteDisplayId(int displayId)91 int getRemoteDisplayId(int displayId) { 92 return getDisplay(displayId) 93 .map(RemoteDisplay::getRemoteDisplayId) 94 .orElse(Display.INVALID_DISPLAY); 95 } 96 getDisplayByIndex(int index)97 Optional<RemoteDisplay> getDisplayByIndex(int index) { 98 synchronized (mDisplayRepository) { 99 if (index < 0 || index >= mDisplayRepository.size()) { 100 return Optional.empty(); 101 } 102 return Optional.of(mDisplayRepository.get(index)); 103 } 104 } 105 getDisplay(int displayId)106 private Optional<RemoteDisplay> getDisplay(int displayId) { 107 synchronized (mDisplayRepository) { 108 return mDisplayRepository.stream() 109 .filter(display -> display.getDisplayId() == displayId) 110 .findFirst(); 111 } 112 } 113 getDisplayByRemoteId(int remoteDisplayId)114 Optional<RemoteDisplay> getDisplayByRemoteId(int remoteDisplayId) { 115 synchronized (mDisplayRepository) { 116 return mDisplayRepository.stream() 117 .filter(display -> display.getRemoteDisplayId() == remoteDisplayId) 118 .findFirst(); 119 } 120 } 121 closeDisplay(RemoteDisplay display)122 private void closeDisplay(RemoteDisplay display) { 123 synchronized (mDisplayRepository) { 124 mDisplayRepository.remove(display); 125 } 126 display.close(); 127 } 128 } 129