gfx/skia/trunk/src/views/SkEventSink.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2006 The Android Open Source Project
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8
michael@0 9
michael@0 10 #include "SkEventSink.h"
michael@0 11 #include "SkTagList.h"
michael@0 12 #include "SkThread.h"
michael@0 13
michael@0 14 #include "SkThread.h"
michael@0 15 #include "SkTime.h"
michael@0 16
michael@0 17 class SkEventSink_Globals {
michael@0 18 public:
michael@0 19 SkEventSink_Globals() {
michael@0 20 fNextSinkID = 0;
michael@0 21 fSinkHead = NULL;
michael@0 22 }
michael@0 23
michael@0 24 SkMutex fSinkMutex;
michael@0 25 SkEventSinkID fNextSinkID;
michael@0 26 SkEventSink* fSinkHead;
michael@0 27 };
michael@0 28
michael@0 29 static SkEventSink_Globals& getGlobals() {
michael@0 30 // leak this, so we don't incur any shutdown perf hit
michael@0 31 static SkEventSink_Globals* gGlobals = new SkEventSink_Globals;
michael@0 32 return *gGlobals;
michael@0 33 }
michael@0 34
michael@0 35 SkEventSink::SkEventSink() : fTagHead(NULL) {
michael@0 36 SkEventSink_Globals& globals = getGlobals();
michael@0 37
michael@0 38 globals.fSinkMutex.acquire();
michael@0 39
michael@0 40 fID = ++globals.fNextSinkID;
michael@0 41 fNextSink = globals.fSinkHead;
michael@0 42 globals.fSinkHead = this;
michael@0 43
michael@0 44 globals.fSinkMutex.release();
michael@0 45 }
michael@0 46
michael@0 47 SkEventSink::~SkEventSink() {
michael@0 48 SkEventSink_Globals& globals = getGlobals();
michael@0 49
michael@0 50 if (fTagHead)
michael@0 51 SkTagList::DeleteAll(fTagHead);
michael@0 52
michael@0 53 globals.fSinkMutex.acquire();
michael@0 54
michael@0 55 SkEventSink* sink = globals.fSinkHead;
michael@0 56 SkEventSink* prev = NULL;
michael@0 57
michael@0 58 for (;;) {
michael@0 59 SkEventSink* next = sink->fNextSink;
michael@0 60 if (sink == this) {
michael@0 61 if (prev) {
michael@0 62 prev->fNextSink = next;
michael@0 63 } else {
michael@0 64 globals.fSinkHead = next;
michael@0 65 }
michael@0 66 break;
michael@0 67 }
michael@0 68 prev = sink;
michael@0 69 sink = next;
michael@0 70 }
michael@0 71 globals.fSinkMutex.release();
michael@0 72 }
michael@0 73
michael@0 74 bool SkEventSink::doEvent(const SkEvent& evt) {
michael@0 75 return this->onEvent(evt);
michael@0 76 }
michael@0 77
michael@0 78 bool SkEventSink::doQuery(SkEvent* evt) {
michael@0 79 SkASSERT(evt);
michael@0 80 return this->onQuery(evt);
michael@0 81 }
michael@0 82
michael@0 83 bool SkEventSink::onEvent(const SkEvent&) {
michael@0 84 return false;
michael@0 85 }
michael@0 86
michael@0 87 bool SkEventSink::onQuery(SkEvent*) {
michael@0 88 return false;
michael@0 89 }
michael@0 90
michael@0 91 ///////////////////////////////////////////////////////////////////////////////
michael@0 92
michael@0 93 SkTagList* SkEventSink::findTagList(U8CPU tag) const {
michael@0 94 return fTagHead ? SkTagList::Find(fTagHead, tag) : NULL;
michael@0 95 }
michael@0 96
michael@0 97 void SkEventSink::addTagList(SkTagList* rec) {
michael@0 98 SkASSERT(rec);
michael@0 99 SkASSERT(fTagHead == NULL || SkTagList::Find(fTagHead, rec->fTag) == NULL);
michael@0 100
michael@0 101 rec->fNext = fTagHead;
michael@0 102 fTagHead = rec;
michael@0 103 }
michael@0 104
michael@0 105 void SkEventSink::removeTagList(U8CPU tag) {
michael@0 106 if (fTagHead) {
michael@0 107 SkTagList::DeleteTag(&fTagHead, tag);
michael@0 108 }
michael@0 109 }
michael@0 110
michael@0 111 ///////////////////////////////////////////////////////////////////////////////
michael@0 112
michael@0 113 struct SkListenersTagList : SkTagList {
michael@0 114 SkListenersTagList(U16CPU count) : SkTagList(kListeners_SkTagList)
michael@0 115 {
michael@0 116 fExtra16 = SkToU16(count);
michael@0 117 fIDs = (SkEventSinkID*)sk_malloc_throw(count * sizeof(SkEventSinkID));
michael@0 118 }
michael@0 119 virtual ~SkListenersTagList()
michael@0 120 {
michael@0 121 sk_free(fIDs);
michael@0 122 }
michael@0 123
michael@0 124 int countListners() const { return fExtra16; }
michael@0 125
michael@0 126 int find(SkEventSinkID id) const
michael@0 127 {
michael@0 128 const SkEventSinkID* idptr = fIDs;
michael@0 129 for (int i = fExtra16 - 1; i >= 0; --i)
michael@0 130 if (idptr[i] == id)
michael@0 131 return i;
michael@0 132 return -1;
michael@0 133 }
michael@0 134
michael@0 135 SkEventSinkID* fIDs;
michael@0 136 };
michael@0 137
michael@0 138 void SkEventSink::addListenerID(SkEventSinkID id)
michael@0 139 {
michael@0 140 if (id == 0)
michael@0 141 return;
michael@0 142
michael@0 143 SkListenersTagList* prev = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
michael@0 144 int count = 0;
michael@0 145
michael@0 146 if (prev)
michael@0 147 {
michael@0 148 if (prev->find(id) >= 0)
michael@0 149 return;
michael@0 150 count = prev->countListners();
michael@0 151 }
michael@0 152
michael@0 153 SkListenersTagList* next = SkNEW_ARGS(SkListenersTagList, (count + 1));
michael@0 154
michael@0 155 if (prev)
michael@0 156 {
michael@0 157 memcpy(next->fIDs, prev->fIDs, count * sizeof(SkEventSinkID));
michael@0 158 this->removeTagList(kListeners_SkTagList);
michael@0 159 }
michael@0 160 next->fIDs[count] = id;
michael@0 161 this->addTagList(next);
michael@0 162 }
michael@0 163
michael@0 164 void SkEventSink::copyListeners(const SkEventSink& sink)
michael@0 165 {
michael@0 166 SkListenersTagList* sinkList = (SkListenersTagList*)sink.findTagList(kListeners_SkTagList);
michael@0 167 if (sinkList == NULL)
michael@0 168 return;
michael@0 169 SkASSERT(sinkList->countListners() > 0);
michael@0 170 const SkEventSinkID* iter = sinkList->fIDs;
michael@0 171 const SkEventSinkID* stop = iter + sinkList->countListners();
michael@0 172 while (iter < stop)
michael@0 173 addListenerID(*iter++);
michael@0 174 }
michael@0 175
michael@0 176 void SkEventSink::removeListenerID(SkEventSinkID id)
michael@0 177 {
michael@0 178 if (id == 0)
michael@0 179 return;
michael@0 180
michael@0 181 SkListenersTagList* list = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
michael@0 182
michael@0 183 if (list == NULL)
michael@0 184 return;
michael@0 185
michael@0 186 int index = list->find(id);
michael@0 187 if (index >= 0)
michael@0 188 {
michael@0 189 int count = list->countListners();
michael@0 190 SkASSERT(count > 0);
michael@0 191 if (count == 1)
michael@0 192 this->removeTagList(kListeners_SkTagList);
michael@0 193 else
michael@0 194 {
michael@0 195 // overwrite without resize/reallocating our struct (for speed)
michael@0 196 list->fIDs[index] = list->fIDs[count - 1];
michael@0 197 list->fExtra16 = SkToU16(count - 1);
michael@0 198 }
michael@0 199 }
michael@0 200 }
michael@0 201
michael@0 202 bool SkEventSink::hasListeners() const
michael@0 203 {
michael@0 204 return this->findTagList(kListeners_SkTagList) != NULL;
michael@0 205 }
michael@0 206
michael@0 207 void SkEventSink::postToListeners(const SkEvent& evt, SkMSec delay) {
michael@0 208 SkListenersTagList* list = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
michael@0 209 if (list) {
michael@0 210 SkASSERT(list->countListners() > 0);
michael@0 211 const SkEventSinkID* iter = list->fIDs;
michael@0 212 const SkEventSinkID* stop = iter + list->countListners();
michael@0 213 while (iter < stop) {
michael@0 214 SkEvent* copy = SkNEW_ARGS(SkEvent, (evt));
michael@0 215 copy->setTargetID(*iter++)->postDelay(delay);
michael@0 216 }
michael@0 217 }
michael@0 218 }
michael@0 219
michael@0 220 ///////////////////////////////////////////////////////////////////////////////
michael@0 221
michael@0 222 SkEventSink::EventResult SkEventSink::DoEvent(const SkEvent& evt) {
michael@0 223 SkEvent::Proc proc = evt.getTargetProc();
michael@0 224 if (proc) {
michael@0 225 return proc(evt) ? kHandled_EventResult : kNotHandled_EventResult;
michael@0 226 }
michael@0 227
michael@0 228 SkEventSink* sink = SkEventSink::FindSink(evt.getTargetID());
michael@0 229 if (sink) {
michael@0 230 return sink->doEvent(evt) ? kHandled_EventResult : kNotHandled_EventResult;
michael@0 231 }
michael@0 232
michael@0 233 return kSinkNotFound_EventResult;
michael@0 234 }
michael@0 235
michael@0 236 SkEventSink* SkEventSink::FindSink(SkEventSinkID sinkID)
michael@0 237 {
michael@0 238 if (sinkID == 0)
michael@0 239 return 0;
michael@0 240
michael@0 241 SkEventSink_Globals& globals = getGlobals();
michael@0 242 SkAutoMutexAcquire ac(globals.fSinkMutex);
michael@0 243 SkEventSink* sink = globals.fSinkHead;
michael@0 244
michael@0 245 while (sink)
michael@0 246 {
michael@0 247 if (sink->getSinkID() == sinkID)
michael@0 248 return sink;
michael@0 249 sink = sink->fNextSink;
michael@0 250 }
michael@0 251 return NULL;
michael@0 252 }
michael@0 253
michael@0 254 ////////////////////////////////////////////////////////////////////////////////////////
michael@0 255 ////////////////////////////////////////////////////////////////////////////////////////
michael@0 256
michael@0 257 #if 0 // experimental, not tested
michael@0 258
michael@0 259 #include "SkThread.h"
michael@0 260 #include "SkTDict.h"
michael@0 261
michael@0 262 #define kMinStringBufferSize 128
michael@0 263 SK_DECLARE_STATIC_MUTEX(gNamedSinkMutex);
michael@0 264 static SkTDict<SkEventSinkID> gNamedSinkIDs(kMinStringBufferSize);
michael@0 265
michael@0 266 /** Register a name/id pair with the system. If the name already exists,
michael@0 267 replace its ID with the new id. This pair will persist until UnregisterNamedSink()
michael@0 268 is called.
michael@0 269 */
michael@0 270 void SkEventSink::RegisterNamedSinkID(const char name[], SkEventSinkID id)
michael@0 271 {
michael@0 272 if (id && name && *name)
michael@0 273 {
michael@0 274 SkAutoMutexAcquire ac(gNamedSinkMutex);
michael@0 275 gNamedSinkIDs.set(name, id);
michael@0 276 }
michael@0 277 }
michael@0 278
michael@0 279 /** Return the id that matches the specified name (from a previous call to
michael@0 280 RegisterNamedSinkID(). If no match is found, return 0
michael@0 281 */
michael@0 282 SkEventSinkID SkEventSink::FindNamedSinkID(const char name[])
michael@0 283 {
michael@0 284 SkEventSinkID id = 0;
michael@0 285
michael@0 286 if (name && *name)
michael@0 287 {
michael@0 288 SkAutoMutexAcquire ac(gNamedSinkMutex);
michael@0 289 (void)gNamedSinkIDs.find(name, &id);
michael@0 290 }
michael@0 291 return id;
michael@0 292 }
michael@0 293
michael@0 294 /** Remove all name/id pairs from the system. This is call internally
michael@0 295 on shutdown, to ensure no memory leaks. It should not be called
michael@0 296 before shutdown.
michael@0 297 */
michael@0 298 void SkEventSink::RemoveAllNamedSinkIDs()
michael@0 299 {
michael@0 300 SkAutoMutexAcquire ac(gNamedSinkMutex);
michael@0 301 (void)gNamedSinkIDs.reset();
michael@0 302 }
michael@0 303 #endif

mercurial