1/*
2 * Copyright (C) 2010 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#ifndef __SESSIONMAP_H__
17#define __SESSIONMAP_H__
18
19#include <utils/KeyedVector.h>
20#include <utils/threads.h>
21
22namespace android {
23
24/**
25 * A thread safe wrapper template class for session handlings for Drm Engines. It wraps a
26 * pointer type over KeyedVector. It keeps pointer as data in the vector and free up memory
27 * allocated pointer can be of any type of structure/class meant for keeping session data.
28 * so session object here means pointer to the session data.
29 */
30template <typename TValue>
31class SessionMap {
32
33public:
34    SessionMap() {}
35
36    virtual ~SessionMap() {
37        Mutex::Autolock lock(mLock);
38        destroyMap();
39    }
40
41    /**
42     * Adds a new value in the session map table. It expects memory to be allocated already
43     * for the session object
44     *
45     * @param key - key or Session ID
46     * @param value - session object to add
47     *
48     * @return boolean result of adding value. returns false if key is already exist.
49     */
50    bool addValue(int key, TValue value) {
51        Mutex::Autolock lock(mLock);
52        if (!isCreatedInternal(key)) {
53            map.add(key, value);
54            return true;
55        }
56        return false;
57    }
58
59    /**
60     * returns the session object by the key
61     *
62     * @param key - key or Session ID
63     *
64     * @return session object as per the key
65     */
66    TValue getValue(int key) {
67        Mutex::Autolock lock(mLock);
68        return getValueInternal(key);
69    }
70
71    /**
72     * returns the number of objects in the session map table
73     *
74     * @return count of number of session objects.
75     */
76    int getSize() {
77        Mutex::Autolock lock(mLock);
78        return map.size();
79    }
80
81    /**
82     * returns the session object by the index in the session map table
83     *
84     * @param index - index of the value required
85     *
86     * @return session object as per the index
87     */
88    TValue getValueAt(unsigned int index) {
89        TValue value = NULL;
90        Mutex::Autolock lock(mLock);
91
92        if (map.size() > index) {
93            value = map.valueAt(index);
94        }
95        return value;
96    }
97
98    /**
99     * deletes the object from session map. It also frees up memory for the session object.
100     *
101     * @param key - key of the value to be deleted
102     *
103     */
104    void removeValue(int key) {
105        Mutex::Autolock lock(mLock);
106        deleteValue(getValueInternal(key));
107        map.removeItem(key);
108    }
109
110    /**
111     * decides if session is already created.
112     *
113     * @param key - key of the value for the session
114     *
115     * @return boolean result of whether session is created
116     */
117    bool isCreated(int key) {
118        Mutex::Autolock lock(mLock);
119        return isCreatedInternal(key);
120    }
121
122    SessionMap<TValue> & operator=(const SessionMap<TValue> & objectCopy) {
123        Mutex::Autolock lock(mLock);
124
125        destroyMap();
126        map = objectCopy.map;
127        return *this;
128    }
129
130private:
131    KeyedVector<int, TValue> map;
132    Mutex mLock;
133
134   /**
135    * free up the memory for the session object.
136    * Make sure if any reference to the session object anywhere, otherwise it will be a
137    * dangle pointer after this call.
138    *
139    * @param value - session object to free
140    *
141    */
142    void deleteValue(TValue value) {
143        delete value;
144    }
145
146   /**
147    * free up the memory for the entire map.
148    * free up any resources in the sessions before calling this funtion.
149    *
150    */
151    void destroyMap() {
152        int size = map.size();
153
154        for (int i = 0; i < size; i++) {
155            deleteValue(map.valueAt(i));
156        }
157        map.clear();
158    }
159
160   /**
161    * decides if session is already created.
162    *
163    * @param key - key of the value for the session
164    *
165    * @return boolean result of whether session is created
166    */
167    bool isCreatedInternal(int key) {
168        return(0 <= map.indexOfKey(key));
169    }
170
171   /**
172    * returns the session object by the key
173    *
174    * @param key - key or Session ID
175    *
176    * @return session object as per the key
177    */
178    TValue getValueInternal(int key) {
179        TValue value = NULL;
180        if (isCreatedInternal(key)) {
181            value = (TValue) map.valueFor(key);
182        }
183        return value;
184    }
185};
186
187};
188
189#endif /* __SESSIONMAP_H__ */
190