1e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang/* 2e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * Copyright (C) 2014 The Android Open Source Project 3e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * 4e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * Licensed under the Apache License, Version 2.0 (the "License"); 5e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * you may not use this file except in compliance with the License. 6e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * You may obtain a copy of the License at 7e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * 8e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * http://www.apache.org/licenses/LICENSE-2.0 9e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * 10e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * Unless required by applicable law or agreed to in writing, software 11e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * distributed under the License is distributed on an "AS IS" BASIS, 12e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * See the License for the specific language governing permissions and 14e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * limitations under the License. 15e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang */ 16e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang 17e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jangpackage com.android.server.hdmi; 18e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang 19e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jangimport android.util.FastImmutableArraySet; 20e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jangimport android.util.SparseArray; 21e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang 22e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang/** 23e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * Cache for incoming message. It caches {@link HdmiCecMessage} with source address and opcode 24e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * as a key. 25e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * 26e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * <p>Note that whenever a device is removed it should call {@link #flushMessagesFrom(int)} 27e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * to clean up messages come from the device. 28e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang */ 29e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jangfinal class HdmiCecMessageCache { 30c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim private static final FastImmutableArraySet<Integer> CACHEABLE_OPCODES = 31c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim new FastImmutableArraySet<>(new Integer[] { 32c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim Constants.MESSAGE_SET_OSD_NAME, 33c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS, 34c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim Constants.MESSAGE_DEVICE_VENDOR_ID, 35c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim Constants.MESSAGE_CEC_VERSION, 36e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang }); 37e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang 38e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang // It's like [Source Logical Address, [Opcode, HdmiCecMessage]]. 39e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang private final SparseArray<SparseArray<HdmiCecMessage>> mCache = new SparseArray<>(); 40e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang 41e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang HdmiCecMessageCache() { 42e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang } 43e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang 44e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang /** 45e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * Return a {@link HdmiCecMessage} corresponding to the given {@code address} and 46e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * {@code opcode}. 47e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * 48e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * @param address a logical address of source device 49e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * @param opcode opcode of message 50e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * @return null if has no {@link HdmiCecMessage} matched to the given {@code address} and {code 51e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * opcode} 52e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang */ 53e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang public HdmiCecMessage getMessage(int address, int opcode) { 54e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang SparseArray<HdmiCecMessage> messages = mCache.get(address); 55e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang if (messages == null) { 56e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang return null; 57e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang } 58e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang 59e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang return messages.get(opcode); 60e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang } 61e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang 62e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang /** 63e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * Flush all {@link HdmiCecMessage}s sent from the given {@code address}. 64e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * 65e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * @param address a logical address of source device 66e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang */ 67e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang public void flushMessagesFrom(int address) { 68e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang mCache.remove(address); 69e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang } 70e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang 71e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang /** 72e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * Flush all cached {@link HdmiCecMessage}s. 73e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang */ 74e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang public void flushAll() { 75e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang mCache.clear(); 76e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang } 77e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang 78e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang /** 79e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * Cache incoming {@link HdmiCecMessage}. If opcode of message is not listed on 80e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * cacheable opcodes list, just ignore it. 81e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * 82e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang * @param message a {@link HdmiCecMessage} to be cached 83e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang */ 84e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang public void cacheMessage(HdmiCecMessage message) { 85e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang int opcode = message.getOpcode(); 86e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang if (!isCacheable(opcode)) { 87e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang return; 88e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang } 89e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang 90e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang int source = message.getSource(); 91e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang SparseArray<HdmiCecMessage> messages = mCache.get(source); 92e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang if (messages == null) { 93e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang messages = new SparseArray<>(); 94e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang mCache.put(source, messages); 95e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang } 96e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang messages.put(opcode, message); 97e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang } 98e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang 99e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang private boolean isCacheable(int opcode) { 100e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang return CACHEABLE_OPCODES.contains(opcode); 101e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang } 102e81e108c4035ea8933525baa8108cb392f8abf5dJungshik Jang} 103