From dd17b3eaa99f761e265ff457e335b5a0ff83dafb Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 13 Dec 2010 16:49:05 -0800 Subject: [PATCH] fix [3176642] Camera preview turns completely black for multiple toggles between camera and camcorder app There was a leak of Surface tokens when a surface was detached from a UserClient. We now always detach a surface from its client before attaching to the new one, this guarantees that its token is freed. Change-Id: Icfad0b16286ed58155bdfafdf36ab161440aa485 --- services/surfaceflinger/Layer.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 80aef5fcc..2b2f557d3 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -83,8 +83,28 @@ status_t Layer::setToken(const sp& userClient, sharedClient, token, mBufferManager.getDefaultBufferCount(), getIdentity()); - status_t err = mUserClientRef.setToken(userClient, lcblk, token); + sp ourClient(mUserClientRef.getClient()); + + /* + * Here it is guaranteed that userClient != ourClient + * (see UserClient::getTokenForSurface()). + * + * We release the token used by this surface in ourClient below. + * This should be safe to do so now, since this layer won't be attached + * to this client, it should be okay to reuse that id. + * + * If this causes problems, an other solution would be to keep a list + * of all the {UserClient, token} ever used and release them when the + * Layer is destroyed. + * + */ + + if (ourClient != 0) { + ourClient->detachLayer(this); + } + + status_t err = mUserClientRef.setToken(userClient, lcblk, token); LOGE_IF(err != NO_ERROR, "ClientRef::setToken(%p, %p, %u) failed", userClient.get(), lcblk.get(), token);