1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1790ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#ifndef ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H
1890ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#define ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23dd3423c6247965bf67ea30c75e484a6f5d72b1a2Mathias Agopian#include <binder/IBinder.h>
246d9b9dfd555ee2bc1dd8381dde95d45f9500b3caMathias Agopian#include <binder/IMemory.h>
25dd3423c6247965bf67ea30c75e484a6f5d72b1a2Mathias Agopian
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/RefBase.h>
27b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian#include <utils/Singleton.h>
28b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian#include <utils/SortedVector.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/threads.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h>
329cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian
33abe815dd6978b718c04f6e22e1a893d2b51d11a1Mathias Agopian#include <gui/CpuConsumer.h>
34e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/SurfaceControl.h>
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
409cce325fae8adcf7560a28eef394489f09bad74dMathias Agopianclass DisplayInfo;
41698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianclass Composer;
4241f673c9b3aac0d96e41c928845c39186d565212Mathias Agopianclass ISurfaceComposerClient;
432adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenclass IGraphicBufferProducer;
44a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianclass Region;
45b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
46b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
47b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
48d4784a3b90f849e8732968d45886fb0c8f0d8cf3Mathias Agopianclass SurfaceComposerClient : public RefBase
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
50698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    friend class Composer;
516c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallpublic:
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                SurfaceComposerClient();
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    virtual     ~SurfaceComposerClient();
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Always make sure we could initialize
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t    initCheck() const;
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Return the connection of this client
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<IBinder> connection() const;
606c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Forcibly remove connection before all references have gone away.
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    void        dispose();
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
64e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    // callback when the composer is dies
65e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
66e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            void* cookie = NULL, uint32_t flags = 0);
67e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
68e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    // Get information about a display
699d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    static status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info);
70e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
712a09bb321930e1f782599ec902bca1db58b9af77Jeff Brown    /* triggers screen off and waits for it to complete */
722a09bb321930e1f782599ec902bca1db58b9af77Jeff Brown    static void blankDisplay(const sp<IBinder>& display);
732a09bb321930e1f782599ec902bca1db58b9af77Jeff Brown
742a09bb321930e1f782599ec902bca1db58b9af77Jeff Brown    /* triggers screen on and waits for it to complete */
752a09bb321930e1f782599ec902bca1db58b9af77Jeff Brown    static void unblankDisplay(const sp<IBinder>& display);
762a09bb321930e1f782599ec902bca1db58b9af77Jeff Brown
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // ------------------------------------------------------------------------
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // surface creation / destruction
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //! Create a surface
8101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    sp<SurfaceControl> createSurface(
82285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian            const String8& name,// name of the surface
83285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian            uint32_t w,         // width in pixel
84285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian            uint32_t h,         // height in pixel
85285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian            PixelFormat format, // pixel-format desired
86285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian            uint32_t flags = 0  // usage flags
87285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian    );
88285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian
896c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    //! Create a virtual display
90dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    static sp<IBinder> createDisplay(const String8& displayName, bool secure);
91285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian
926c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    //! Destroy a virtual display
936c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    static void destroyDisplay(const sp<IBinder>& display);
946c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
959d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    //! Get the token for the existing default displays.
969d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    //! Possible values for id are eDisplayIdMain and eDisplayIdHdmi.
979d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    static sp<IBinder> getBuiltInDisplay(int32_t id);
989d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // ------------------------------------------------------------------------
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Composer parameters
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // All composer parameters must be changed within a transaction
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // several surfaces can be updated in one transaction, all changes are
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // committed at once when the transaction is closed.
104e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    // closeGlobalTransaction() requires an IPC with the server.
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //! Open a composer transaction on all active SurfaceComposerClients.
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static void openGlobalTransaction();
1082d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //! Close a composer transaction on all active SurfaceComposerClients.
11028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    static void closeGlobalTransaction(bool synchronous = false);
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1122d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    //! Flag the currently open transaction as an animation transaction.
1132d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    static void setAnimationTransaction();
1142d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
115ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    status_t    hide(const sp<IBinder>& id);
116ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    status_t    show(const sp<IBinder>& id);
117ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    status_t    setFlags(const sp<IBinder>& id, uint32_t flags, uint32_t mask);
118ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    status_t    setTransparentRegionHint(const sp<IBinder>& id, const Region& transparent);
119ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    status_t    setLayer(const sp<IBinder>& id, int32_t layer);
120ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    status_t    setAlpha(const sp<IBinder>& id, float alpha=1.0f);
121ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    status_t    setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, float dsdy, float dtdy);
122ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    status_t    setPosition(const sp<IBinder>& id, float x, float y);
123ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    status_t    setSize(const sp<IBinder>& id, uint32_t w, uint32_t h);
124ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    status_t    setCrop(const sp<IBinder>& id, const Rect& crop);
125ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    status_t    setLayerStack(const sp<IBinder>& id, uint32_t layerStack);
126ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    status_t    destroySurface(const sp<IBinder>& id);
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
128e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    static void setDisplaySurface(const sp<IBinder>& token,
1292adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden            const sp<IGraphicBufferProducer>& bufferProducer);
130e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    static void setDisplayLayerStack(const sp<IBinder>& token,
131e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            uint32_t layerStack);
13200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian
13300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian    /* setDisplayProjection() defines the projection of layer stacks
13400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian     * to a given display.
13500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian     *
13600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian     * - orientation defines the display's orientation.
13700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian     * - layerStackRect defines which area of the window manager coordinate
13800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian     * space will be used.
13900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian     * - displayRect defines where on the display will layerStackRect be
14000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian     * mapped to. displayRect is specified post-orientation, that is
14100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian     * it uses the orientation seen by the end-user.
14200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian     */
14300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian    static void setDisplayProjection(const sp<IBinder>& token,
14400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian            uint32_t orientation,
14500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian            const Rect& layerStackRect,
14600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian            const Rect& displayRect);
147e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
148631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopianprivate:
149d4784a3b90f849e8732968d45886fb0c8f0d8cf3Mathias Agopian    virtual void onFirstRef();
150698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Composer& getComposer();
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
152698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    mutable     Mutex                       mLock;
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                status_t                    mStatus;
1547e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian                sp<ISurfaceComposerClient>  mClient;
155698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                Composer&                   mComposer;
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project};
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
158d4784a3b90f849e8732968d45886fb0c8f0d8cf3Mathias Agopian// ---------------------------------------------------------------------------
15974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
16074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianclass ScreenshotClient
16174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
1622a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianpublic:
1632a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    static status_t capture(
1642a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            const sp<IBinder>& display,
1652a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            const sp<IGraphicBufferProducer>& producer,
1662a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            uint32_t reqWidth, uint32_t reqHeight,
1672a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            uint32_t minLayerZ, uint32_t maxLayerZ);
1682a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
1692a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianprivate:
170abe815dd6978b718c04f6e22e1a893d2b51d11a1Mathias Agopian    mutable sp<CpuConsumer> mCpuConsumer;
171db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian    mutable sp<BufferQueue> mBufferQueue;
172abe815dd6978b718c04f6e22e1a893d2b51d11a1Mathias Agopian    CpuConsumer::LockedBuffer mBuffer;
173abe815dd6978b718c04f6e22e1a893d2b51d11a1Mathias Agopian    bool mHaveBuffer;
1742a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
17574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianpublic:
17674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    ScreenshotClient();
1778000d0694bc34bc17d869da546d8ff8790ae7be4Mathias Agopian    ~ScreenshotClient();
17874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
17974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // frees the previous screenshot and capture a new one
1809d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    status_t update(const sp<IBinder>& display);
1819d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    status_t update(const sp<IBinder>& display,
1829d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            uint32_t reqWidth, uint32_t reqHeight);
1839d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown    status_t update(const sp<IBinder>& display,
1849d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            uint32_t reqWidth, uint32_t reqHeight,
185bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            uint32_t minLayerZ, uint32_t maxLayerZ);
18674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
187abe815dd6978b718c04f6e22e1a893d2b51d11a1Mathias Agopian    sp<CpuConsumer> getCpuConsumer() const;
188abe815dd6978b718c04f6e22e1a893d2b51d11a1Mathias Agopian
18974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release memory occupied by the screenshot
19074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    void release();
19174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
19274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // pixels are valid until this object is freed or
19374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release() or update() is called
19474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    void const* getPixels() const;
19574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
19674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    uint32_t getWidth() const;
19774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    uint32_t getHeight() const;
19874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    PixelFormat getFormat() const;
19974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    uint32_t getStride() const;
20074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // size of allocated memory in bytes
20174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    size_t getSize() const;
20274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian};
20374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
20474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian// ---------------------------------------------------------------------------
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20790ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#endif // ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H
208