1*d57664e9SAndroid Build Coastguard Worker /* 2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project 3*d57664e9SAndroid Build Coastguard Worker * 4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*d57664e9SAndroid Build Coastguard Worker * 8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*d57664e9SAndroid Build Coastguard Worker * 10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*d57664e9SAndroid Build Coastguard Worker * limitations under the License. 15*d57664e9SAndroid Build Coastguard Worker */ 16*d57664e9SAndroid Build Coastguard Worker 17*d57664e9SAndroid Build Coastguard Worker #ifndef _UI_SPRITES_H 18*d57664e9SAndroid Build Coastguard Worker #define _UI_SPRITES_H 19*d57664e9SAndroid Build Coastguard Worker 20*d57664e9SAndroid Build Coastguard Worker #include <utils/RefBase.h> 21*d57664e9SAndroid Build Coastguard Worker #include <utils/Looper.h> 22*d57664e9SAndroid Build Coastguard Worker 23*d57664e9SAndroid Build Coastguard Worker #include <gui/SurfaceComposerClient.h> 24*d57664e9SAndroid Build Coastguard Worker 25*d57664e9SAndroid Build Coastguard Worker #include "SpriteIcon.h" 26*d57664e9SAndroid Build Coastguard Worker 27*d57664e9SAndroid Build Coastguard Worker namespace android { 28*d57664e9SAndroid Build Coastguard Worker 29*d57664e9SAndroid Build Coastguard Worker /* 30*d57664e9SAndroid Build Coastguard Worker * Transformation matrix for a sprite. 31*d57664e9SAndroid Build Coastguard Worker */ 32*d57664e9SAndroid Build Coastguard Worker struct SpriteTransformationMatrix { SpriteTransformationMatrixSpriteTransformationMatrix33*d57664e9SAndroid Build Coastguard Worker inline SpriteTransformationMatrix() : dsdx(1.0f), dtdx(0.0f), dsdy(0.0f), dtdy(1.0f) { } SpriteTransformationMatrixSpriteTransformationMatrix34*d57664e9SAndroid Build Coastguard Worker inline SpriteTransformationMatrix(float dsdx, float dtdx, float dsdy, float dtdy) : 35*d57664e9SAndroid Build Coastguard Worker dsdx(dsdx), dtdx(dtdx), dsdy(dsdy), dtdy(dtdy) { } 36*d57664e9SAndroid Build Coastguard Worker 37*d57664e9SAndroid Build Coastguard Worker float dsdx; 38*d57664e9SAndroid Build Coastguard Worker float dtdx; 39*d57664e9SAndroid Build Coastguard Worker float dsdy; 40*d57664e9SAndroid Build Coastguard Worker float dtdy; 41*d57664e9SAndroid Build Coastguard Worker 42*d57664e9SAndroid Build Coastguard Worker inline bool operator== (const SpriteTransformationMatrix& other) { 43*d57664e9SAndroid Build Coastguard Worker return dsdx == other.dsdx 44*d57664e9SAndroid Build Coastguard Worker && dtdx == other.dtdx 45*d57664e9SAndroid Build Coastguard Worker && dsdy == other.dsdy 46*d57664e9SAndroid Build Coastguard Worker && dtdy == other.dtdy; 47*d57664e9SAndroid Build Coastguard Worker } 48*d57664e9SAndroid Build Coastguard Worker 49*d57664e9SAndroid Build Coastguard Worker inline bool operator!= (const SpriteTransformationMatrix& other) { 50*d57664e9SAndroid Build Coastguard Worker return !(*this == other); 51*d57664e9SAndroid Build Coastguard Worker } 52*d57664e9SAndroid Build Coastguard Worker }; 53*d57664e9SAndroid Build Coastguard Worker 54*d57664e9SAndroid Build Coastguard Worker /* 55*d57664e9SAndroid Build Coastguard Worker * A sprite is a simple graphical object that is displayed on-screen above other layers. 56*d57664e9SAndroid Build Coastguard Worker * The basic sprite class is an interface. 57*d57664e9SAndroid Build Coastguard Worker * The implementation is provided by the sprite controller. 58*d57664e9SAndroid Build Coastguard Worker */ 59*d57664e9SAndroid Build Coastguard Worker class Sprite : public RefBase { 60*d57664e9SAndroid Build Coastguard Worker protected: Sprite()61*d57664e9SAndroid Build Coastguard Worker Sprite() { } ~Sprite()62*d57664e9SAndroid Build Coastguard Worker virtual ~Sprite() { } 63*d57664e9SAndroid Build Coastguard Worker 64*d57664e9SAndroid Build Coastguard Worker public: 65*d57664e9SAndroid Build Coastguard Worker enum { 66*d57664e9SAndroid Build Coastguard Worker // The base layer for pointer sprites. 67*d57664e9SAndroid Build Coastguard Worker BASE_LAYER_POINTER = 0, // reserve space for 1 pointer 68*d57664e9SAndroid Build Coastguard Worker 69*d57664e9SAndroid Build Coastguard Worker // The base layer for spot sprites. 70*d57664e9SAndroid Build Coastguard Worker BASE_LAYER_SPOT = 1, // reserve space for MAX_POINTER_ID spots 71*d57664e9SAndroid Build Coastguard Worker }; 72*d57664e9SAndroid Build Coastguard Worker 73*d57664e9SAndroid Build Coastguard Worker /* Sets the bitmap that is drawn by the sprite. 74*d57664e9SAndroid Build Coastguard Worker * The sprite retains a copy of the bitmap for subsequent rendering. */ 75*d57664e9SAndroid Build Coastguard Worker virtual void setIcon(const SpriteIcon& icon) = 0; 76*d57664e9SAndroid Build Coastguard Worker clearIcon()77*d57664e9SAndroid Build Coastguard Worker inline void clearIcon() { 78*d57664e9SAndroid Build Coastguard Worker setIcon(SpriteIcon()); 79*d57664e9SAndroid Build Coastguard Worker } 80*d57664e9SAndroid Build Coastguard Worker 81*d57664e9SAndroid Build Coastguard Worker /* Sets whether the sprite is visible. */ 82*d57664e9SAndroid Build Coastguard Worker virtual void setVisible(bool visible) = 0; 83*d57664e9SAndroid Build Coastguard Worker 84*d57664e9SAndroid Build Coastguard Worker /* Sets the sprite position on screen, relative to the sprite's hot spot. */ 85*d57664e9SAndroid Build Coastguard Worker virtual void setPosition(float x, float y) = 0; 86*d57664e9SAndroid Build Coastguard Worker 87*d57664e9SAndroid Build Coastguard Worker /* Sets the layer of the sprite, relative to the system sprite overlay layer. 88*d57664e9SAndroid Build Coastguard Worker * Layer 0 is the overlay layer, > 0 appear above this layer. */ 89*d57664e9SAndroid Build Coastguard Worker virtual void setLayer(int32_t layer) = 0; 90*d57664e9SAndroid Build Coastguard Worker 91*d57664e9SAndroid Build Coastguard Worker /* Sets the sprite alpha blend ratio between 0.0 and 1.0. */ 92*d57664e9SAndroid Build Coastguard Worker virtual void setAlpha(float alpha) = 0; 93*d57664e9SAndroid Build Coastguard Worker 94*d57664e9SAndroid Build Coastguard Worker /* Sets the sprite transformation matrix. */ 95*d57664e9SAndroid Build Coastguard Worker virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 0; 96*d57664e9SAndroid Build Coastguard Worker 97*d57664e9SAndroid Build Coastguard Worker /* Sets the id of the display where the sprite should be shown. */ 98*d57664e9SAndroid Build Coastguard Worker virtual void setDisplayId(ui::LogicalDisplayId displayId) = 0; 99*d57664e9SAndroid Build Coastguard Worker 100*d57664e9SAndroid Build Coastguard Worker /* Sets the flag to hide sprite on mirrored displays. 101*d57664e9SAndroid Build Coastguard Worker * This will add ISurfaceComposerClient::eSkipScreenshot flag to the sprite. */ 102*d57664e9SAndroid Build Coastguard Worker virtual void setSkipScreenshot(bool skip) = 0; 103*d57664e9SAndroid Build Coastguard Worker }; 104*d57664e9SAndroid Build Coastguard Worker 105*d57664e9SAndroid Build Coastguard Worker /* 106*d57664e9SAndroid Build Coastguard Worker * Displays sprites on the screen. 107*d57664e9SAndroid Build Coastguard Worker * 108*d57664e9SAndroid Build Coastguard Worker * This interface is used by PointerController and SpotController to draw pointers or 109*d57664e9SAndroid Build Coastguard Worker * spot representations of fingers. It is not intended for general purpose use 110*d57664e9SAndroid Build Coastguard Worker * by other components. 111*d57664e9SAndroid Build Coastguard Worker * 112*d57664e9SAndroid Build Coastguard Worker * All sprite position updates and rendering is performed asynchronously. 113*d57664e9SAndroid Build Coastguard Worker * 114*d57664e9SAndroid Build Coastguard Worker * Clients are responsible for animating sprites by periodically updating their properties. 115*d57664e9SAndroid Build Coastguard Worker */ 116*d57664e9SAndroid Build Coastguard Worker class SpriteController { 117*d57664e9SAndroid Build Coastguard Worker public: 118*d57664e9SAndroid Build Coastguard Worker using ParentSurfaceProvider = std::function<sp<SurfaceControl>(ui::LogicalDisplayId)>; 119*d57664e9SAndroid Build Coastguard Worker SpriteController(const sp<Looper>& looper, int32_t overlayLayer, ParentSurfaceProvider parent); 120*d57664e9SAndroid Build Coastguard Worker SpriteController(const SpriteController&) = delete; 121*d57664e9SAndroid Build Coastguard Worker SpriteController& operator=(const SpriteController&) = delete; 122*d57664e9SAndroid Build Coastguard Worker virtual ~SpriteController(); 123*d57664e9SAndroid Build Coastguard Worker 124*d57664e9SAndroid Build Coastguard Worker /* Initialize the callback for the message handler. */ 125*d57664e9SAndroid Build Coastguard Worker void setHandlerController(const std::shared_ptr<SpriteController>& controller); 126*d57664e9SAndroid Build Coastguard Worker 127*d57664e9SAndroid Build Coastguard Worker /* Creates a new sprite, initially invisible. The lifecycle of the sprite must not extend beyond 128*d57664e9SAndroid Build Coastguard Worker * the lifecycle of this SpriteController. */ 129*d57664e9SAndroid Build Coastguard Worker virtual sp<Sprite> createSprite(); 130*d57664e9SAndroid Build Coastguard Worker 131*d57664e9SAndroid Build Coastguard Worker /* Opens or closes a transaction to perform a batch of sprite updates as part of 132*d57664e9SAndroid Build Coastguard Worker * a single operation such as setPosition and setAlpha. It is not necessary to 133*d57664e9SAndroid Build Coastguard Worker * open a transaction when updating a single property. 134*d57664e9SAndroid Build Coastguard Worker * Calls to openTransaction() nest and must be matched by an equal number 135*d57664e9SAndroid Build Coastguard Worker * of calls to closeTransaction(). */ 136*d57664e9SAndroid Build Coastguard Worker virtual void openTransaction(); 137*d57664e9SAndroid Build Coastguard Worker virtual void closeTransaction(); 138*d57664e9SAndroid Build Coastguard Worker 139*d57664e9SAndroid Build Coastguard Worker private: 140*d57664e9SAndroid Build Coastguard Worker class Handler : public virtual android::MessageHandler { 141*d57664e9SAndroid Build Coastguard Worker public: 142*d57664e9SAndroid Build Coastguard Worker enum { MSG_UPDATE_SPRITES, MSG_DISPOSE_SURFACES }; 143*d57664e9SAndroid Build Coastguard Worker 144*d57664e9SAndroid Build Coastguard Worker void handleMessage(const Message& message) override; 145*d57664e9SAndroid Build Coastguard Worker std::weak_ptr<SpriteController> spriteController; 146*d57664e9SAndroid Build Coastguard Worker }; 147*d57664e9SAndroid Build Coastguard Worker 148*d57664e9SAndroid Build Coastguard Worker enum { 149*d57664e9SAndroid Build Coastguard Worker DIRTY_BITMAP = 1 << 0, 150*d57664e9SAndroid Build Coastguard Worker DIRTY_ALPHA = 1 << 1, 151*d57664e9SAndroid Build Coastguard Worker DIRTY_POSITION = 1 << 2, 152*d57664e9SAndroid Build Coastguard Worker DIRTY_TRANSFORMATION_MATRIX = 1 << 3, 153*d57664e9SAndroid Build Coastguard Worker DIRTY_LAYER = 1 << 4, 154*d57664e9SAndroid Build Coastguard Worker DIRTY_VISIBILITY = 1 << 5, 155*d57664e9SAndroid Build Coastguard Worker DIRTY_HOTSPOT = 1 << 6, 156*d57664e9SAndroid Build Coastguard Worker DIRTY_DISPLAY_ID = 1 << 7, 157*d57664e9SAndroid Build Coastguard Worker DIRTY_ICON_STYLE = 1 << 8, 158*d57664e9SAndroid Build Coastguard Worker DIRTY_DRAW_DROP_SHADOW = 1 << 9, 159*d57664e9SAndroid Build Coastguard Worker DIRTY_SKIP_SCREENSHOT = 1 << 10, 160*d57664e9SAndroid Build Coastguard Worker }; 161*d57664e9SAndroid Build Coastguard Worker 162*d57664e9SAndroid Build Coastguard Worker /* Describes the state of a sprite. 163*d57664e9SAndroid Build Coastguard Worker * This structure is designed so that it can be copied during updates so that 164*d57664e9SAndroid Build Coastguard Worker * surfaces can be resized and redrawn without blocking the client by holding a lock 165*d57664e9SAndroid Build Coastguard Worker * on the sprites for a long time. 166*d57664e9SAndroid Build Coastguard Worker * Note that the SpriteIcon holds a reference to a shared (and immutable) bitmap. */ 167*d57664e9SAndroid Build Coastguard Worker struct SpriteState { 168*d57664e9SAndroid Build Coastguard Worker uint32_t dirty{0}; 169*d57664e9SAndroid Build Coastguard Worker 170*d57664e9SAndroid Build Coastguard Worker SpriteIcon icon; 171*d57664e9SAndroid Build Coastguard Worker bool visible{false}; 172*d57664e9SAndroid Build Coastguard Worker float positionX{0}; 173*d57664e9SAndroid Build Coastguard Worker float positionY{0}; 174*d57664e9SAndroid Build Coastguard Worker int32_t layer{0}; 175*d57664e9SAndroid Build Coastguard Worker float alpha{1.0f}; 176*d57664e9SAndroid Build Coastguard Worker SpriteTransformationMatrix transformationMatrix; 177*d57664e9SAndroid Build Coastguard Worker ui::LogicalDisplayId displayId{ui::LogicalDisplayId::DEFAULT}; 178*d57664e9SAndroid Build Coastguard Worker 179*d57664e9SAndroid Build Coastguard Worker sp<SurfaceControl> surfaceControl; 180*d57664e9SAndroid Build Coastguard Worker int32_t surfaceWidth{0}; 181*d57664e9SAndroid Build Coastguard Worker int32_t surfaceHeight{0}; 182*d57664e9SAndroid Build Coastguard Worker bool surfaceDrawn{false}; 183*d57664e9SAndroid Build Coastguard Worker bool surfaceVisible{false}; 184*d57664e9SAndroid Build Coastguard Worker bool skipScreenshot{false}; 185*d57664e9SAndroid Build Coastguard Worker wantSurfaceVisibleSpriteState186*d57664e9SAndroid Build Coastguard Worker inline bool wantSurfaceVisible() const { 187*d57664e9SAndroid Build Coastguard Worker return visible && alpha > 0.0f && icon.isValid(); 188*d57664e9SAndroid Build Coastguard Worker } 189*d57664e9SAndroid Build Coastguard Worker }; 190*d57664e9SAndroid Build Coastguard Worker 191*d57664e9SAndroid Build Coastguard Worker /* Client interface for a sprite. 192*d57664e9SAndroid Build Coastguard Worker * Requests acquire a lock on the controller, update local state and request the 193*d57664e9SAndroid Build Coastguard Worker * controller to invalidate the sprite. 194*d57664e9SAndroid Build Coastguard Worker * The real heavy lifting of creating, resizing and redrawing surfaces happens 195*d57664e9SAndroid Build Coastguard Worker * asynchronously with no locks held except in short critical section to copy 196*d57664e9SAndroid Build Coastguard Worker * the sprite state before the work and update the sprite surface control afterwards. 197*d57664e9SAndroid Build Coastguard Worker */ 198*d57664e9SAndroid Build Coastguard Worker class SpriteImpl : public Sprite { 199*d57664e9SAndroid Build Coastguard Worker protected: 200*d57664e9SAndroid Build Coastguard Worker virtual ~SpriteImpl(); 201*d57664e9SAndroid Build Coastguard Worker 202*d57664e9SAndroid Build Coastguard Worker public: 203*d57664e9SAndroid Build Coastguard Worker explicit SpriteImpl(SpriteController& controller); 204*d57664e9SAndroid Build Coastguard Worker 205*d57664e9SAndroid Build Coastguard Worker virtual void setIcon(const SpriteIcon& icon); 206*d57664e9SAndroid Build Coastguard Worker virtual void setVisible(bool visible); 207*d57664e9SAndroid Build Coastguard Worker virtual void setPosition(float x, float y); 208*d57664e9SAndroid Build Coastguard Worker virtual void setLayer(int32_t layer); 209*d57664e9SAndroid Build Coastguard Worker virtual void setAlpha(float alpha); 210*d57664e9SAndroid Build Coastguard Worker virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix); 211*d57664e9SAndroid Build Coastguard Worker virtual void setDisplayId(ui::LogicalDisplayId displayId); 212*d57664e9SAndroid Build Coastguard Worker virtual void setSkipScreenshot(bool skip); 213*d57664e9SAndroid Build Coastguard Worker getStateLocked()214*d57664e9SAndroid Build Coastguard Worker inline const SpriteState& getStateLocked() const { 215*d57664e9SAndroid Build Coastguard Worker return mLocked.state; 216*d57664e9SAndroid Build Coastguard Worker } 217*d57664e9SAndroid Build Coastguard Worker resetDirtyLocked()218*d57664e9SAndroid Build Coastguard Worker inline void resetDirtyLocked() { 219*d57664e9SAndroid Build Coastguard Worker mLocked.state.dirty = 0; 220*d57664e9SAndroid Build Coastguard Worker } 221*d57664e9SAndroid Build Coastguard Worker setSurfaceLocked(const sp<SurfaceControl> & surfaceControl,int32_t width,int32_t height,bool drawn,bool visible)222*d57664e9SAndroid Build Coastguard Worker inline void setSurfaceLocked(const sp<SurfaceControl>& surfaceControl, 223*d57664e9SAndroid Build Coastguard Worker int32_t width, int32_t height, bool drawn, bool visible) { 224*d57664e9SAndroid Build Coastguard Worker mLocked.state.surfaceControl = surfaceControl; 225*d57664e9SAndroid Build Coastguard Worker mLocked.state.surfaceWidth = width; 226*d57664e9SAndroid Build Coastguard Worker mLocked.state.surfaceHeight = height; 227*d57664e9SAndroid Build Coastguard Worker mLocked.state.surfaceDrawn = drawn; 228*d57664e9SAndroid Build Coastguard Worker mLocked.state.surfaceVisible = visible; 229*d57664e9SAndroid Build Coastguard Worker } 230*d57664e9SAndroid Build Coastguard Worker 231*d57664e9SAndroid Build Coastguard Worker private: 232*d57664e9SAndroid Build Coastguard Worker SpriteController& mController; 233*d57664e9SAndroid Build Coastguard Worker 234*d57664e9SAndroid Build Coastguard Worker struct Locked { 235*d57664e9SAndroid Build Coastguard Worker SpriteState state; 236*d57664e9SAndroid Build Coastguard Worker } mLocked; // guarded by mController->mLock 237*d57664e9SAndroid Build Coastguard Worker 238*d57664e9SAndroid Build Coastguard Worker void invalidateLocked(uint32_t dirty); 239*d57664e9SAndroid Build Coastguard Worker }; 240*d57664e9SAndroid Build Coastguard Worker 241*d57664e9SAndroid Build Coastguard Worker /* Stores temporary information collected during the sprite update cycle. */ 242*d57664e9SAndroid Build Coastguard Worker struct SpriteUpdate { SpriteUpdateSpriteUpdate243*d57664e9SAndroid Build Coastguard Worker inline SpriteUpdate() : surfaceChanged(false) { } SpriteUpdateSpriteUpdate244*d57664e9SAndroid Build Coastguard Worker inline SpriteUpdate(const sp<SpriteImpl> sprite, const SpriteState& state) : 245*d57664e9SAndroid Build Coastguard Worker sprite(sprite), state(state), surfaceChanged(false) { 246*d57664e9SAndroid Build Coastguard Worker } 247*d57664e9SAndroid Build Coastguard Worker 248*d57664e9SAndroid Build Coastguard Worker sp<SpriteImpl> sprite; 249*d57664e9SAndroid Build Coastguard Worker SpriteState state; 250*d57664e9SAndroid Build Coastguard Worker bool surfaceChanged; 251*d57664e9SAndroid Build Coastguard Worker }; 252*d57664e9SAndroid Build Coastguard Worker 253*d57664e9SAndroid Build Coastguard Worker mutable Mutex mLock; 254*d57664e9SAndroid Build Coastguard Worker 255*d57664e9SAndroid Build Coastguard Worker sp<Looper> mLooper; 256*d57664e9SAndroid Build Coastguard Worker const int32_t mOverlayLayer; 257*d57664e9SAndroid Build Coastguard Worker sp<Handler> mHandler; 258*d57664e9SAndroid Build Coastguard Worker ParentSurfaceProvider mParentSurfaceProvider; 259*d57664e9SAndroid Build Coastguard Worker 260*d57664e9SAndroid Build Coastguard Worker sp<SurfaceComposerClient> mSurfaceComposerClient; 261*d57664e9SAndroid Build Coastguard Worker 262*d57664e9SAndroid Build Coastguard Worker struct Locked { 263*d57664e9SAndroid Build Coastguard Worker std::vector<sp<SpriteImpl>> invalidatedSprites; 264*d57664e9SAndroid Build Coastguard Worker std::vector<sp<SurfaceControl>> disposedSurfaces; 265*d57664e9SAndroid Build Coastguard Worker uint32_t transactionNestingCount; 266*d57664e9SAndroid Build Coastguard Worker bool deferredSpriteUpdate; 267*d57664e9SAndroid Build Coastguard Worker } mLocked; // guarded by mLock 268*d57664e9SAndroid Build Coastguard Worker 269*d57664e9SAndroid Build Coastguard Worker void invalidateSpriteLocked(const sp<SpriteImpl>& sprite); 270*d57664e9SAndroid Build Coastguard Worker void disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl); 271*d57664e9SAndroid Build Coastguard Worker 272*d57664e9SAndroid Build Coastguard Worker void doUpdateSprites(); 273*d57664e9SAndroid Build Coastguard Worker void doDisposeSurfaces(); 274*d57664e9SAndroid Build Coastguard Worker 275*d57664e9SAndroid Build Coastguard Worker void ensureSurfaceComposerClient(); 276*d57664e9SAndroid Build Coastguard Worker sp<SurfaceControl> obtainSurface(int32_t width, int32_t height, ui::LogicalDisplayId displayId, 277*d57664e9SAndroid Build Coastguard Worker bool hideOnMirrored); 278*d57664e9SAndroid Build Coastguard Worker }; 279*d57664e9SAndroid Build Coastguard Worker 280*d57664e9SAndroid Build Coastguard Worker } // namespace android 281*d57664e9SAndroid Build Coastguard Worker 282*d57664e9SAndroid Build Coastguard Worker #endif // _UI_SPRITES_H 283