1 /* 2 * Copyright (C) 2017 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.android.systemui.shared.recents.model; 18 19 import android.util.Log; 20 import android.util.SparseArray; 21 22 import com.android.systemui.shared.recents.model.Task.TaskKey; 23 24 /** 25 * Base class for both strong and LRU task key cache. 26 */ 27 public abstract class TaskKeyCache<V> { 28 29 protected static final String TAG = "TaskKeyCache"; 30 31 protected final SparseArray<TaskKey> mKeys = new SparseArray<>(); 32 33 /** 34 * Gets a specific entry in the cache with the specified key, regardless of whether the cached 35 * value is valid or not. 36 */ get(TaskKey key)37 public final synchronized V get(TaskKey key) { 38 return getCacheEntry(key.id); 39 } 40 41 /** 42 * Returns the value only if the key is valid (has not been updated since the last time it was 43 * in the cache) 44 */ getAndInvalidateIfModified(TaskKey key)45 public final synchronized V getAndInvalidateIfModified(TaskKey key) { 46 TaskKey lastKey = mKeys.get(key.id); 47 if (lastKey != null) { 48 if ((lastKey.windowingMode != key.windowingMode) || 49 (lastKey.lastActiveTime != key.lastActiveTime)) { 50 // The task has updated (been made active since the last time it was put into the 51 // LRU cache) or the stack id for the task has changed, invalidate that cache item 52 remove(key); 53 return null; 54 } 55 } 56 // Either the task does not exist in the cache, or the last active time is the same as 57 // the key specified, so return what is in the cache 58 return getCacheEntry(key.id); 59 } 60 61 /** Puts an entry in the cache for a specific key. */ put(TaskKey key, V value)62 public final synchronized void put(TaskKey key, V value) { 63 if (key == null || value == null) { 64 Log.e(TAG, "Unexpected null key or value: " + key + ", " + value); 65 return; 66 } 67 mKeys.put(key.id, key); 68 putCacheEntry(key.id, value); 69 } 70 71 72 /** Removes a cache entry for a specific key. */ remove(TaskKey key)73 public final synchronized void remove(TaskKey key) { 74 // Remove the key after the cache value because we need it to make the callback 75 removeCacheEntry(key.id); 76 mKeys.remove(key.id); 77 } 78 79 /** Removes all the entries in the cache. */ evictAll()80 public final synchronized void evictAll() { 81 evictAllCache(); 82 mKeys.clear(); 83 } 84 getCacheEntry(int id)85 protected abstract V getCacheEntry(int id); putCacheEntry(int id, V value)86 protected abstract void putCacheEntry(int id, V value); removeCacheEntry(int id)87 protected abstract void removeCacheEntry(int id); evictAllCache()88 protected abstract void evictAllCache(); 89 } 90