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