1cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi/* 2cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * Copyright (C) 2017 The Android Open Source Project 3cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * 4cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License"); 5cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * you may not use this file except in compliance with the License. 6cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * You may obtain a copy of the License at 7cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * 8cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * http://www.apache.org/licenses/LICENSE-2.0 9cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * 10cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * Unless required by applicable law or agreed to in writing, software 11cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS, 12cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * See the License for the specific language governing permissions and 14cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * limitations under the License 15cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi */ 16cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 176519c1b0fe85c5f25115539e936e4333e8537098Winson Chungpackage com.android.systemui.shared.recents.model; 18cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 19cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggiimport android.util.Log; 20cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggiimport android.util.SparseArray; 21cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 226519c1b0fe85c5f25115539e936e4333e8537098Winson Chungimport com.android.systemui.shared.recents.model.Task.TaskKey; 23cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 24cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi/** 25cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * Base class for both strong and LRU task key cache. 26cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi */ 27cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggipublic abstract class TaskKeyCache<V> { 28cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 29cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi protected static final String TAG = "TaskKeyCache"; 30cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 31cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi protected final SparseArray<TaskKey> mKeys = new SparseArray<>(); 32cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 33cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi /** 34cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * Gets a specific entry in the cache with the specified key, regardless of whether the cached 35cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * value is valid or not. 36cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi */ 376519c1b0fe85c5f25115539e936e4333e8537098Winson Chung final V get(TaskKey key) { 38cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi return getCacheEntry(key.id); 39cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi } 40cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 41cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi /** 42cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * Returns the value only if the key is valid (has not been updated since the last time it was 43cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi * in the cache) 44cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi */ 456519c1b0fe85c5f25115539e936e4333e8537098Winson Chung final V getAndInvalidateIfModified(TaskKey key) { 466519c1b0fe85c5f25115539e936e4333e8537098Winson Chung TaskKey lastKey = mKeys.get(key.id); 47cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi if (lastKey != null) { 4889be5761bcacfb27bbc63d0e94a86b666f52f294Wale Ogunwale if ((lastKey.windowingMode != key.windowingMode) || 49cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi (lastKey.lastActiveTime != key.lastActiveTime)) { 50cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi // The task has updated (been made active since the last time it was put into the 51cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi // LRU cache) or the stack id for the task has changed, invalidate that cache item 52cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi remove(key); 53cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi return null; 54cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi } 55cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi } 56cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi // Either the task does not exist in the cache, or the last active time is the same as 57cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi // the key specified, so return what is in the cache 58cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi return getCacheEntry(key.id); 59cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi } 60cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 61cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi /** Puts an entry in the cache for a specific key. */ 626519c1b0fe85c5f25115539e936e4333e8537098Winson Chung final void put(TaskKey key, V value) { 63cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi if (key == null || value == null) { 64cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi Log.e(TAG, "Unexpected null key or value: " + key + ", " + value); 65cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi return; 66cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi } 67cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi mKeys.put(key.id, key); 68cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi putCacheEntry(key.id, value); 69cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi } 70cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 71cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 72cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi /** Removes a cache entry for a specific key. */ 736519c1b0fe85c5f25115539e936e4333e8537098Winson Chung final void remove(TaskKey key) { 74cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi // Remove the key after the cache value because we need it to make the callback 75cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi removeCacheEntry(key.id); 76cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi mKeys.remove(key.id); 77cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi } 78cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 79cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi /** Removes all the entries in the cache. */ 80cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi final void evictAll() { 81cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi evictAllCache(); 82cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi mKeys.clear(); 83cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi } 84cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi 85cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi protected abstract V getCacheEntry(int id); 86cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi protected abstract void putCacheEntry(int id, V value); 87cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi protected abstract void removeCacheEntry(int id); 88cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi protected abstract void evictAllCache(); 89cdef591e52e691a6f57e367caa5670fdc4ee1a8aJorim Jaggi} 90