/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef AML_MP_MESSAGE_H_ #define AML_MP_MESSAGE_H_ #include "AmlMpData.h" #include "AmlMpEventLooper.h" #include "AmlMpRefBase.h" #include namespace aml_mp { struct AmlMpBuffer; struct AmlMpEventHandler; struct AReplyToken : public AmlMpRefBase { explicit AReplyToken(const sptr &looper) : mLooper(looper), mReplied(false) { } private: friend struct AmlMpMessage; friend struct AmlMpEventLooper; wptr mLooper; sptr mReply; bool mReplied; sptr getLooper() const { return mLooper.promote(); } // if reply is not set, returns false; otherwise, it retrieves the reply and returns true bool retrieveReply(sptr *reply) { if (mReplied) { *reply = mReply; mReply.clear(); } return mReplied; } // sets the reply for this token. returns OK or error int setReply(const sptr &reply); }; struct AmlMpMessage : public AmlMpRefBase { AmlMpMessage(); AmlMpMessage(uint32_t what, const sptr &handler); // Construct an AMessage from a parcel. // nestingAllowed determines how many levels AMessage can be nested inside // AMessage. The default value here is arbitrarily set to 255. // FromParcel() returns NULL on error, which occurs when the input parcel // contains // - an AMessage nested deeper than maxNestingLevel; or // - an item whose type is not recognized by this function. // Types currently recognized by this function are: // Item types set/find function suffixes // ========================================== // int32_t Int32 // int64_t Int64 // size_t Size // float Float // double Double // AString String // AMessage Message //static sptr FromParcel(const Parcel &parcel, //size_t maxNestingLevel = 255); // Write this AMessage to a parcel. // All items in the AMessage must have types that are recognized by // FromParcel(); otherwise, TRESPASS error will occur. //void writeToParcel(Parcel *parcel) const; void setWhat(uint32_t what); uint32_t what() const; void setTarget(const sptr &handler); void clear(); void setInt32(const char *name, int32_t value); void setInt64(const char *name, int64_t value); void setSize(const char *name, size_t value); void setFloat(const char *name, float value); void setDouble(const char *name, double value); void setPointer(const char *name, void *value); void setString(const char *name, const char *s, ssize_t len = -1); void setString(const char *name, const std::string &s); void setObject(const char *name, const sptr &obj); void setBuffer(const char *name, const sptr &buffer); void setMessage(const char *name, const sptr &obj); void setRect( const char *name, int32_t left, int32_t top, int32_t right, int32_t bottom); bool contains(const char *name) const; bool findInt32(const char *name, int32_t *value) const; bool findInt64(const char *name, int64_t *value) const; bool findSize(const char *name, size_t *value) const; bool findFloat(const char *name, float *value) const; bool findDouble(const char *name, double *value) const; bool findPointer(const char *name, void **value) const; bool findString(const char *name, std::string *value) const; bool findObject(const char *name, sptr *obj) const; bool findBuffer(const char *name, sptr *buffer) const; bool findMessage(const char *name, sptr *obj) const; // finds signed integer types cast to int64_t bool findAsInt64(const char *name, int64_t *value) const; // finds any numeric type cast to a float bool findAsFloat(const char *name, float *value) const; bool findRect( const char *name, int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) const; int post(int64_t delayUs = 0); // Posts the message to its target and waits for a response (or error) // before returning. int postAndAwaitResponse(sptr *response); // If this returns true, the sender of this message is synchronously // awaiting a response and the reply token is consumed from the message // and stored into replyID. The reply token must be used to send the response // using "postReply" below. bool senderAwaitsResponse(sptr *replyID); // Posts the message as a response to a reply token. A reply token can // only be used once. Returns OK if the response could be posted; otherwise, // an error. int postReply(const sptr &replyID); // Performs a deep-copy of "this", contained messages are in turn "dup'ed". // Warning: RefBase items, i.e. "objects" are _not_ copied but only have // their refcount incremented. sptr dup() const; // Adds all items from other into this. void extend(const sptr &other); // Performs a shallow or deep comparison of |this| and |other| and returns // an AMessage with the differences. // Warning: RefBase items, i.e. "objects" are _not_ copied but only have // their refcount incremented. // This is true for AMessages that have no corresponding AMessage equivalent in |other|. // (E.g. there is no such key or the type is different.) On the other hand, changes in // the AMessage (or AMessages if deep is |false|) are returned in new objects. sptr changesFrom(const sptr &other, bool deep = false) const; std::string debugString(int32_t indent = 0) const; enum Type { kTypeInt32, kTypeInt64, kTypeSize, kTypeFloat, kTypeDouble, kTypePointer, kTypeString, kTypeObject, kTypeMessage, kTypeRect, kTypeBuffer, }; struct Rect { int32_t mLeft, mTop, mRight, mBottom; }; size_t countEntries() const; const char *getEntryNameAt(size_t index, Type *type) const; /** * Retrieves the item at a specific index. */ typedef AData< int32_t, int64_t, size_t, float, double, Rect, std::string, void *, sptr, sptr, sptr>::Basic ItemData; /** * Finds an item by name. This can be used if the type is unknown. * * \param name name of the item * Returns an empty item if no item is present with that name. */ ItemData findItem(const char *name) const; /** * Sets an item of arbitrary type. Does nothing if the item value is empty. * * \param name name of the item * \param item value of the item */ void setItem(const char *name, const ItemData &item); ItemData getEntryAt(size_t index) const; /** * Finds an entry by name and returns its index. * * \retval countEntries() if the entry is not found. */ size_t findEntryByName(const char *name) const; /** * Sets the name of an entry based on index. * * \param index index of the entry * \param name (new) name of the entry * * \retval OK the name was set successfully * \retval BAD_INDEX invalid index * \retval BAD_VALUE name is invalid (null) * \retval ALREADY_EXISTS name is already used by another entry */ int setEntryNameAt(size_t index, const char *name); /** * Sets the item of an entry based on index. * * \param index index of the entry * \param item new item of the entry * * \retval OK the item was set successfully * \retval BAD_INDEX invalid index * \retval BAD_VALUE item is invalid (null) * \retval BAD_TYPE type is unsupported (should not happen) */ int setEntryAt(size_t index, const ItemData &item); /** * Removes an entry based on index. * * \param index index of the entry * * \retval OK the entry was removed successfully * \retval BAD_INDEX invalid index */ int removeEntryAt(size_t index); protected: virtual ~AmlMpMessage(); private: friend struct AmlMpEventLooper; // deliver() uint32_t mWhat; // used only for debugging AmlMpEventLooper::handler_id mTarget; wptr mHandler; wptr mLooper; struct Item { union { int32_t int32Value; int64_t int64Value; size_t sizeValue; float floatValue; double doubleValue; void *ptrValue; AmlMpRefBase *refValue; std::string *stringValue; Rect rectValue; } u; const char *mName; size_t mNameLength; Type mType; void setName(const char *name, size_t len); }; enum { kMaxNumItems = 64 }; Item mItems[kMaxNumItems]; size_t mNumItems; Item *allocateItem(const char *name); void freeItemValue(Item *item); const Item *findItem(const char *name, Type type) const; void setObjectInternal( const char *name, const sptr &obj, Type type); size_t findItemIndex(const char *name, size_t len) const; void deliver(); AmlMpMessage(const AmlMpMessage&) = delete; AmlMpMessage& operator= (const AmlMpMessage&) = delete; }; } // namespace android #endif // A_MESSAGE_H_