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(event.getDisplayCapabilities())); 62 return display.isPresent(); 63 } 64 clear()65 void clear() { 66 synchronized (mDisplayRepository) { 67 mDisplayRepository.forEach(RemoteDisplay::close); 68 mDisplayRepository.clear(); 69 } 70 } 71 getDisplayIds()72 int[] getDisplayIds() { 73 synchronized (mDisplayRepository) { 74 return mDisplayRepository.stream() 75 .mapToInt(RemoteDisplay::getDisplayId) 76 .toArray(); 77 } 78 } 79 getRemoteDisplayIds()80 int[] getRemoteDisplayIds() { 81 synchronized (mDisplayRepository) { 82 return mDisplayRepository.stream() 83 .mapToInt(RemoteDisplay::getRemoteDisplayId) 84 .toArray(); 85 } 86 } 87 getRemoteDisplayId(int displayId)88 int getRemoteDisplayId(int displayId) { 89 return getDisplay(displayId) 90 .map(RemoteDisplay::getRemoteDisplayId) 91 .orElse(Display.INVALID_DISPLAY); 92 } 93 getDisplayByIndex(int index)94 Optional<RemoteDisplay> getDisplayByIndex(int index) { 95 synchronized (mDisplayRepository) { 96 if (index < 0 || index >= mDisplayRepository.size()) { 97 return Optional.empty(); 98 } 99 return Optional.of(mDisplayRepository.get(index)); 100 } 101 } 102 getDisplay(int displayId)103 private Optional<RemoteDisplay> getDisplay(int displayId) { 104 synchronized (mDisplayRepository) { 105 return mDisplayRepository.stream() 106 .filter(display -> display.getDisplayId() == displayId) 107 .findFirst(); 108 } 109 } 110 getDisplayByRemoteId(int remoteDisplayId)111 Optional<RemoteDisplay> getDisplayByRemoteId(int remoteDisplayId) { 112 synchronized (mDisplayRepository) { 113 return mDisplayRepository.stream() 114 .filter(display -> display.getRemoteDisplayId() == remoteDisplayId) 115 .findFirst(); 116 } 117 } 118 closeDisplay(RemoteDisplay display)119 private void closeDisplay(RemoteDisplay display) { 120 synchronized (mDisplayRepository) { 121 mDisplayRepository.remove(display); 122 } 123 display.close(); 124 } 125 } 126