summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2013-02-11 16:40:36 -0800
committerMathias Agopian <mathias@google.com>2013-02-13 15:27:08 -0800
commitac9fa427d4a86745e60a5f7fd8e3ea340c4db907 (patch)
tree657e6ec979339bc0e291247310af356e6a19ef7e /libs
parentb997f6ef0f3fa7cf67fd7487b88e5d6ac0bb15e9 (diff)
downloadframeworks_native-ac9fa427d4a86745e60a5f7fd8e3ea340c4db907.zip
frameworks_native-ac9fa427d4a86745e60a5f7fd8e3ea340c4db907.tar.gz
frameworks_native-ac9fa427d4a86745e60a5f7fd8e3ea340c4db907.tar.bz2
get rid of Surface identity and token
we use the IBinder instead. Change-Id: I4aa0b58869ba43f19980013620051e5a261b062d
Diffstat (limited to 'libs')
-rw-r--r--libs/gui/ISurfaceComposerClient.cpp31
-rw-r--r--libs/gui/LayerState.cpp50
-rw-r--r--libs/gui/Surface.cpp70
-rw-r--r--libs/gui/SurfaceComposerClient.cpp70
4 files changed, 99 insertions, 122 deletions
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 8f7bc05..101292d 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -50,8 +50,7 @@ public:
{
}
- virtual sp<ISurface> createSurface( surface_data_t* params,
- const String8& name,
+ virtual sp<ISurface> createSurface( const String8& name,
uint32_t w,
uint32_t h,
PixelFormat format,
@@ -65,15 +64,14 @@ public:
data.writeInt32(format);
data.writeInt32(flags);
remote()->transact(CREATE_SURFACE, data, &reply);
- params->readFromParcel(reply);
return interface_cast<ISurface>(reply.readStrongBinder());
}
- virtual status_t destroySurface(SurfaceID sid)
+ virtual status_t destroySurface(const sp<IBinder>& handle)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
- data.writeInt32(sid);
+ data.writeStrongBinder(handle);
remote()->transact(DESTROY_SURFACE, data, &reply);
return reply.readInt32();
}
@@ -89,21 +87,18 @@ status_t BnSurfaceComposerClient::onTransact(
switch(code) {
case CREATE_SURFACE: {
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
- surface_data_t params;
String8 name = data.readString8();
uint32_t w = data.readInt32();
uint32_t h = data.readInt32();
PixelFormat format = data.readInt32();
uint32_t flags = data.readInt32();
- sp<ISurface> s = createSurface(&params, name, w, h,
- format, flags);
- params.writeToParcel(reply);
+ sp<ISurface> s = createSurface(name, w, h, format, flags);
reply->writeStrongBinder(s->asBinder());
return NO_ERROR;
} break;
case DESTROY_SURFACE: {
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
- reply->writeInt32( destroySurface( data.readInt32() ) );
+ reply->writeInt32( destroySurface( data.readStrongBinder() ) );
return NO_ERROR;
} break;
default:
@@ -111,20 +106,4 @@ status_t BnSurfaceComposerClient::onTransact(
}
}
-// ----------------------------------------------------------------------
-
-status_t ISurfaceComposerClient::surface_data_t::readFromParcel(const Parcel& parcel)
-{
- token = parcel.readInt32();
- identity = parcel.readInt32();
- return NO_ERROR;
-}
-
-status_t ISurfaceComposerClient::surface_data_t::writeToParcel(Parcel* parcel) const
-{
- parcel->writeInt32(token);
- parcel->writeInt32(identity);
- return NO_ERROR;
-}
-
}; // namespace android
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 5e5edcd..acdbd77 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -24,29 +24,41 @@ namespace android {
status_t layer_state_t::write(Parcel& output) const
{
- status_t err;
-
- err = output.write(transparentRegion);
- if (err < NO_ERROR) return err;
-
- // NOTE: regions are at the end of the structure
- size_t size = sizeof(layer_state_t);
- size -= sizeof(transparentRegion);
- err = output.write(this, size);
- return err;
+ output.writeStrongBinder(surface);
+ output.writeInt32(what);
+ output.writeFloat(x);
+ output.writeFloat(y);
+ output.writeInt32(z);
+ output.writeInt32(w);
+ output.writeInt32(h);
+ output.writeInt32(layerStack);
+ output.writeFloat(alpha);
+ output.writeInt32(flags);
+ output.writeInt32(mask);
+ *reinterpret_cast<layer_state_t::matrix22_t *>(
+ output.writeInplace(sizeof(layer_state_t::matrix22_t))) = matrix;
+ output.write(crop);
+ output.write(transparentRegion);
+ return NO_ERROR;
}
status_t layer_state_t::read(const Parcel& input)
{
- status_t err;
-
- err = input.read(transparentRegion);
- if (err < NO_ERROR) return err;
-
- // NOTE: regions are at the end of the structure
- size_t size = sizeof(layer_state_t);
- size -= sizeof(transparentRegion);
- input.read(this, size);
+ surface = input.readStrongBinder();
+ what = input.readInt32();
+ x = input.readFloat();
+ y = input.readFloat();
+ z = input.readInt32();
+ w = input.readInt32();
+ h = input.readInt32();
+ layerStack = input.readInt32();
+ alpha = input.readFloat();
+ flags = input.readInt32();
+ mask = input.readInt32();
+ matrix = *reinterpret_cast<layer_state_t::matrix22_t const *>(
+ input.readInplace(sizeof(layer_state_t::matrix22_t)));
+ input.read(crop);
+ input.read(transparentRegion);
return NO_ERROR;
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 51d37b3..81fc019 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -48,11 +48,12 @@ namespace android {
SurfaceControl::SurfaceControl(
const sp<SurfaceComposerClient>& client,
- const sp<ISurface>& surface,
- const ISurfaceComposerClient::surface_data_t& data)
- : mClient(client), mSurface(surface),
- mToken(data.token), mIdentity(data.identity)
+ const sp<ISurface>& surface)
+ : mClient(client)
{
+ if (surface != 0) {
+ mSurface = surface->asBinder();
+ }
}
SurfaceControl::~SurfaceControl()
@@ -63,9 +64,8 @@ SurfaceControl::~SurfaceControl()
void SurfaceControl::destroy()
{
if (isValid()) {
- mClient->destroySurface(mToken);
+ mClient->destroySurface(mSurface);
}
-
// clear all references and trigger an IPC now, to make sure things
// happen without delay, since these resources are quite heavy.
mClient.clear();
@@ -89,81 +89,81 @@ bool SurfaceControl::isSameSurface(
{
if (lhs == 0 || rhs == 0)
return false;
- return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
+ return lhs->mSurface == rhs->mSurface;
}
status_t SurfaceControl::setLayerStack(int32_t layerStack) {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
- return client->setLayerStack(mToken, layerStack);
+ return client->setLayerStack(mSurface, layerStack);
}
status_t SurfaceControl::setLayer(int32_t layer) {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
- return client->setLayer(mToken, layer);
+ return client->setLayer(mSurface, layer);
}
status_t SurfaceControl::setPosition(int32_t x, int32_t y) {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
- return client->setPosition(mToken, x, y);
+ return client->setPosition(mSurface, x, y);
}
status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
- return client->setSize(mToken, w, h);
+ return client->setSize(mSurface, w, h);
}
status_t SurfaceControl::hide() {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
- return client->hide(mToken);
+ return client->hide(mSurface);
}
status_t SurfaceControl::show() {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
- return client->show(mToken);
+ return client->show(mSurface);
}
status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
- return client->setFlags(mToken, flags, mask);
+ return client->setFlags(mSurface, flags, mask);
}
status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
- return client->setTransparentRegionHint(mToken, transparent);
+ return client->setTransparentRegionHint(mSurface, transparent);
}
status_t SurfaceControl::setAlpha(float alpha) {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
- return client->setAlpha(mToken, alpha);
+ return client->setAlpha(mSurface, alpha);
}
status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
- return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
+ return client->setMatrix(mSurface, dsdx, dtdx, dsdy, dtdy);
}
status_t SurfaceControl::setCrop(const Rect& crop) {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
- return client->setCrop(mToken, crop);
+ return client->setCrop(mSurface, crop);
}
status_t SurfaceControl::validate() const
{
- if (mToken<0 || mClient==0) {
- ALOGE("invalid token (%d, identity=%u) or client (%p)",
- mToken, mIdentity, mClient.get());
+ if (mSurface==0 || mClient==0) {
+ ALOGE("invalid ISurface (%p) or client (%p)",
+ mSurface.get(), mClient.get());
return NO_INIT;
}
return NO_ERROR;
@@ -172,15 +172,12 @@ status_t SurfaceControl::validate() const
status_t SurfaceControl::writeSurfaceToParcel(
const sp<SurfaceControl>& control, Parcel* parcel)
{
- sp<ISurface> sur;
- uint32_t identity = 0;
+ sp<IBinder> sur;
if (SurfaceControl::isValid(control)) {
- sur = control->mSurface;
- identity = control->mIdentity;
+ sur = control->mSurface;
}
- parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
+ parcel->writeStrongBinder(sur);
parcel->writeStrongBinder(NULL); // NULL IGraphicBufferProducer in this case.
- parcel->writeInt32(identity);
return NO_ERROR;
}
@@ -198,13 +195,10 @@ sp<Surface> SurfaceControl::getSurface() const
// Surface
// ============================================================================
-// ---------------------------------------------------------------------------
-
Surface::Surface(const sp<SurfaceControl>& surface)
- : SurfaceTextureClient(),
- mSurface(surface->mSurface),
- mIdentity(surface->mIdentity)
+ : SurfaceTextureClient()
{
+ mSurface = interface_cast<ISurface>(surface->mSurface);
sp<IGraphicBufferProducer> st;
if (mSurface != NULL) {
st = mSurface->getSurfaceTexture();
@@ -223,15 +217,12 @@ Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
} else if (mSurface != NULL) {
st = mSurface->getSurfaceTexture();
}
-
- mIdentity = parcel.readInt32();
init(st);
}
Surface::Surface(const sp<IGraphicBufferProducer>& st)
: SurfaceTextureClient(),
- mSurface(NULL),
- mIdentity(0)
+ mSurface(NULL)
{
init(st);
}
@@ -245,19 +236,16 @@ status_t Surface::writeToParcel(
if (Surface::isValid(surface)) {
sur = surface->mSurface;
st = surface->getISurfaceTexture();
- identity = surface->mIdentity;
} else if (surface != 0 &&
(surface->mSurface != NULL ||
surface->getISurfaceTexture() != NULL)) {
ALOGE("Parceling invalid surface with non-NULL ISurface/IGraphicBufferProducer "
- "as NULL: mSurface = %p, bufferProducer = %p, mIdentity = %d, ",
- surface->mSurface.get(), surface->getISurfaceTexture().get(),
- surface->mIdentity);
+ "as NULL: mSurface = %p, bufferProducer = %p ",
+ surface->mSurface.get(), surface->getISurfaceTexture().get());
}
parcel->writeStrongBinder(sur != NULL ? sur->asBinder() : NULL);
parcel->writeStrongBinder(st != NULL ? st->asBinder() : NULL);
- parcel->writeInt32(identity);
return NO_ERROR;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 0c6881a..0bafc92 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -128,7 +128,7 @@ class Composer : public Singleton<Composer>
void setAnimationTransactionImpl();
layer_state_t* getLayerStateLocked(
- const sp<SurfaceComposerClient>& client, SurfaceID id);
+ const sp<SurfaceComposerClient>& client, const sp<IBinder>& id);
DisplayState& getDisplayStateLocked(const sp<IBinder>& token);
@@ -136,26 +136,26 @@ public:
sp<IBinder> createDisplay(const String8& displayName, bool secure);
sp<IBinder> getBuiltInDisplay(int32_t id);
- status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
+ status_t setPosition(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
float x, float y);
- status_t setSize(const sp<SurfaceComposerClient>& client, SurfaceID id,
+ status_t setSize(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
uint32_t w, uint32_t h);
- status_t setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id,
+ status_t setLayer(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
int32_t z);
- status_t setFlags(const sp<SurfaceComposerClient>& client, SurfaceID id,
+ status_t setFlags(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
uint32_t flags, uint32_t mask);
status_t setTransparentRegionHint(
- const sp<SurfaceComposerClient>& client, SurfaceID id,
+ const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
const Region& transparentRegion);
- status_t setAlpha(const sp<SurfaceComposerClient>& client, SurfaceID id,
+ status_t setAlpha(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
float alpha);
- status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id,
+ status_t setMatrix(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
float dsdx, float dtdx, float dsdy, float dtdy);
status_t setOrientation(int orientation);
- status_t setCrop(const sp<SurfaceComposerClient>& client, SurfaceID id,
+ status_t setCrop(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
const Rect& crop);
status_t setLayerStack(const sp<SurfaceComposerClient>& client,
- SurfaceID id, uint32_t layerStack);
+ const sp<IBinder>& id, uint32_t layerStack);
void setDisplaySurface(const sp<IBinder>& token,
const sp<IGraphicBufferProducer>& bufferProducer);
@@ -241,7 +241,7 @@ void Composer::setAnimationTransactionImpl() {
}
layer_state_t* Composer::getLayerStateLocked(
- const sp<SurfaceComposerClient>& client, SurfaceID id) {
+ const sp<SurfaceComposerClient>& client, const sp<IBinder>& id) {
ComposerState s;
s.client = client->mClient;
@@ -258,7 +258,7 @@ layer_state_t* Composer::getLayerStateLocked(
}
status_t Composer::setPosition(const sp<SurfaceComposerClient>& client,
- SurfaceID id, float x, float y) {
+ const sp<IBinder>& id, float x, float y) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
@@ -270,7 +270,7 @@ status_t Composer::setPosition(const sp<SurfaceComposerClient>& client,
}
status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
- SurfaceID id, uint32_t w, uint32_t h) {
+ const sp<IBinder>& id, uint32_t w, uint32_t h) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
@@ -286,7 +286,7 @@ status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
}
status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
- SurfaceID id, int32_t z) {
+ const sp<IBinder>& id, int32_t z) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
@@ -297,7 +297,7 @@ status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
}
status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
- SurfaceID id, uint32_t flags,
+ const sp<IBinder>& id, uint32_t flags,
uint32_t mask) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
@@ -311,7 +311,7 @@ status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
}
status_t Composer::setTransparentRegionHint(
- const sp<SurfaceComposerClient>& client, SurfaceID id,
+ const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
const Region& transparentRegion) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
@@ -323,7 +323,7 @@ status_t Composer::setTransparentRegionHint(
}
status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client,
- SurfaceID id, float alpha) {
+ const sp<IBinder>& id, float alpha) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
@@ -334,7 +334,7 @@ status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client,
}
status_t Composer::setLayerStack(const sp<SurfaceComposerClient>& client,
- SurfaceID id, uint32_t layerStack) {
+ const sp<IBinder>& id, uint32_t layerStack) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
@@ -345,7 +345,7 @@ status_t Composer::setLayerStack(const sp<SurfaceComposerClient>& client,
}
status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
- SurfaceID id, float dsdx, float dtdx,
+ const sp<IBinder>& id, float dsdx, float dtdx,
float dsdy, float dtdy) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
@@ -362,7 +362,7 @@ status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
}
status_t Composer::setCrop(const sp<SurfaceComposerClient>& client,
- SurfaceID id, const Rect& crop) {
+ const sp<IBinder>& id, const Rect& crop) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
@@ -472,11 +472,9 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface(
{
sp<SurfaceControl> result;
if (mStatus == NO_ERROR) {
- ISurfaceComposerClient::surface_data_t data;
- sp<ISurface> surface = mClient->createSurface(&data, name,
- w, h, format, flags);
+ sp<ISurface> surface = mClient->createSurface(name, w, h, format, flags);
if (surface != 0) {
- result = new SurfaceControl(this, surface, data);
+ result = new SurfaceControl(this, surface);
}
}
return result;
@@ -491,7 +489,7 @@ sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) {
return Composer::getInstance().getBuiltInDisplay(id);
}
-status_t SurfaceComposerClient::destroySurface(SurfaceID sid) {
+status_t SurfaceComposerClient::destroySurface(const sp<IBinder>& sid) {
if (mStatus != NO_ERROR)
return mStatus;
status_t err = mClient->destroySurface(sid);
@@ -518,53 +516,53 @@ void SurfaceComposerClient::setAnimationTransaction() {
// ----------------------------------------------------------------------------
-status_t SurfaceComposerClient::setCrop(SurfaceID id, const Rect& crop) {
+status_t SurfaceComposerClient::setCrop(const sp<IBinder>& id, const Rect& crop) {
return getComposer().setCrop(this, id, crop);
}
-status_t SurfaceComposerClient::setPosition(SurfaceID id, float x, float y) {
+status_t SurfaceComposerClient::setPosition(const sp<IBinder>& id, float x, float y) {
return getComposer().setPosition(this, id, x, y);
}
-status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) {
+status_t SurfaceComposerClient::setSize(const sp<IBinder>& id, uint32_t w, uint32_t h) {
return getComposer().setSize(this, id, w, h);
}
-status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) {
+status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) {
return getComposer().setLayer(this, id, z);
}
-status_t SurfaceComposerClient::hide(SurfaceID id) {
+status_t SurfaceComposerClient::hide(const sp<IBinder>& id) {
return getComposer().setFlags(this, id,
layer_state_t::eLayerHidden,
layer_state_t::eLayerHidden);
}
-status_t SurfaceComposerClient::show(SurfaceID id) {
+status_t SurfaceComposerClient::show(const sp<IBinder>& id) {
return getComposer().setFlags(this, id,
0,
layer_state_t::eLayerHidden);
}
-status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags,
+status_t SurfaceComposerClient::setFlags(const sp<IBinder>& id, uint32_t flags,
uint32_t mask) {
return getComposer().setFlags(this, id, flags, mask);
}
-status_t SurfaceComposerClient::setTransparentRegionHint(SurfaceID id,
+status_t SurfaceComposerClient::setTransparentRegionHint(const sp<IBinder>& id,
const Region& transparentRegion) {
return getComposer().setTransparentRegionHint(this, id, transparentRegion);
}
-status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) {
+status_t SurfaceComposerClient::setAlpha(const sp<IBinder>& id, float alpha) {
return getComposer().setAlpha(this, id, alpha);
}
-status_t SurfaceComposerClient::setLayerStack(SurfaceID id, uint32_t layerStack) {
+status_t SurfaceComposerClient::setLayerStack(const sp<IBinder>& id, uint32_t layerStack) {
return getComposer().setLayerStack(this, id, layerStack);
}
-status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx,
+status_t SurfaceComposerClient::setMatrix(const sp<IBinder>& id, float dsdx, float dtdx,
float dsdy, float dtdy) {
return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
}