Binder.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Palmsource, Inc.
00003  * 
00004  * This software is licensed as described in the file LICENSE, which
00005  * you should have received as part of this distribution. The terms
00006  * are also available at http://www.openbinder.org/license.html.
00007  * 
00008  * This software consists of voluntary contributions made by many
00009  * individuals. For the exact contribution history, see the revision
00010  * history and logs, available at http://www.openbinder.org
00011  */
00012 
00013 #ifndef _SUPPORT_BINDER_H_
00014 #define _SUPPORT_BINDER_H_
00015 
00021 #include <support/Value.h>
00022 #include <support/StaticValue.h>
00023 #include <support/SupportDefs.h>
00024 #include <support/Value.h>
00025 #include <support/Context.h>
00026 
00027 #if _SUPPORTS_NAMESPACE
00028 namespace palmos {
00029 namespace support {
00030 #endif
00031 
00036 // ------------------------------------------------------------------------
00041 
00042 struct BAutobinderDef;
00043 
00044 struct effect_action_def {
00045     typedef status_t    (*put_func)     (const sptr<IInterface>& target,
00046                                          const SValue& value);
00047     typedef SValue      (*get_func)     (const sptr<IInterface>& target);
00048     typedef SValue      (*invoke_func)  (const sptr<IInterface>& target,
00049                                          const SValue& value);
00050     
00051     size_t              struct_size;    
00052 
00053     const void*         raw_key;        
00054     const SValue&       key() const;    
00055     BAutobinderDef*     parameters;     
00056     
00057     put_func            put;            
00058     get_func            get;            
00059     invoke_func         invoke;         
00060 };
00061 
00063 enum {
00064     B_ACTIONS_SORTED_BY_KEY     = 0x00000001
00065 };
00066 
00067 enum {
00068     B_NO_ACTION                 = 0x00000000,
00069     B_INVOKE_ACTION             = 0x00000001,
00070     B_GET_ACTION,
00071     B_PUT_ACTION
00072 };
00073 
00074 status_t _IMPEXP_SUPPORT
00075 execute_effect( const sptr<IInterface>& target,
00076                 const SValue &in, const SValue &inBindings,
00077                 const SValue &outBindings, SValue *out,
00078                 const effect_action_def* actions, size_t num_actions,
00079                 uint32_t flags = 0);
00081 
00082 // ------------------------------------------------------------------------
00083 
00085 class BBinder : public IBinder
00086 {
00087     public:
00088         inline  const SContext&         Context() const;
00089         
00090         virtual SValue                  Inspect(const sptr<IBinder>& caller,
00091                                                 const SValue &which,
00092                                                 uint32_t flags = 0);
00093         virtual sptr<IInterface>        InterfaceFor(   const SValue &descriptor,
00094                                                         uint32_t flags = 0);
00095         virtual status_t                Link(   const sptr<IBinder>& target,
00096                                                 const SValue &bindings,
00097                                                 uint32_t flags = 0);
00098         virtual status_t                Unlink( const wptr<IBinder>& target,
00099                                                 const SValue &bindings,
00100                                                 uint32_t flags = 0);
00101         virtual status_t                Effect( const SValue &in,
00102                                                 const SValue &inBindings,
00103                                                 const SValue &outBindings,
00104                                                 SValue *out);
00105         
00106         virtual status_t                Transact(   uint32_t code,
00107                                                     SParcel& data,
00108                                                     SParcel* reply = NULL,
00109                                                     uint32_t flags = 0);
00110 
00111         virtual status_t                AutobinderPut(  const BAutobinderDef* def,
00112                                                         const void* value);
00113         virtual status_t                AutobinderGet(  const BAutobinderDef* def,
00114                                                         void* result);
00115         virtual status_t                AutobinderInvoke(   const BAutobinderDef* def,
00116                                                             void** params,
00117                                                             void* result);
00118         
00119         virtual status_t                LinkToDeath(    const sptr<BBinder>& target,
00120                                                         const SValue &method,
00121                                                         uint32_t flags = 0);
00122         virtual status_t                UnlinkToDeath(  const wptr<BBinder>& target,
00123                                                         const SValue &method,
00124                                                         uint32_t flags = 0);
00125         virtual bool                    IsBinderAlive() const;
00126         virtual status_t                PingBinder();
00127         
00128         virtual BBinder*                LocalBinder();
00129 #if _SUPPORTS_NAMESPACE
00130         virtual palmos::osp::BpBinder*  RemoteBinder();
00131 #else
00132         virtual BpBinder*               RemoteBinder();
00133 #endif
00134 
00135         // Local data flow implementation.  Call Push() to transfer data to
00136         // anything linked to you.
00137                 bool                    IsLinked() const;
00138                 status_t                Push(const SValue &out);
00139 
00140     protected:
00141                                         BBinder();
00142                                         BBinder(const SContext& context);
00143                                         BBinder(const BBinder& other);
00144         virtual                         ~BBinder();
00145 
00146         virtual status_t                HandleEffect(   const SValue &in,
00147                                                         const SValue &inBindings,
00148                                                         const SValue &outBindings,
00149                                                         SValue *out);
00150         
00151         // These functions are called by the default implementation of
00152         // HandleEffect(), interpreting an Effect() calls as Put(), Get(),
00153         // and Invoke(), respectively.  These are for use by scripting
00154         // languages.  Static languages should use execute_effect() and/or
00155         // the autobinder.
00156         virtual status_t                Told(const SValue& what, const SValue& in);
00157         virtual status_t                Asked(const SValue& what, SValue* out);
00158         virtual status_t                Called( const SValue& func,
00159                                                 const SValue& args,
00160                                                 SValue* out);
00161 
00162         virtual status_t                Pull(SValue *inMaskAndDefaultsOutData);
00163 
00165 
00175         virtual bool                    HoldRefForLink(const SValue& binding, uint32_t flags);
00176 
00177     private:
00178                 void                    BeginEffectContext(const struct EffectCache &cache);
00179                 void                    EndEffectContext();
00180 
00181                 
00182                 BBinder&                operator=(const BBinder& o);    // No implementation
00183 
00184         static  int32_t                 gBinderTLS;
00185         
00186         struct extensions;
00187         
00188         const SContext                  m_context;
00189         extensions *                    m_extensions;
00190 };
00191 
00192 /*-------------------------------------------------------------*/
00193 /*------- BnInterface Implementation ---------------------------*/
00194 
00196 
00198 template<class INTERFACE>
00199 class BnInterface : public INTERFACE, public BBinder
00200 {
00201 public:
00202         virtual SValue                  Inspect(const sptr<IBinder>&, const SValue &which, uint32_t flags = 0)
00203     { (void)flags; return which * SValue(INTERFACE::Descriptor(),SValue::Binder(this)); };
00204         virtual sptr<IInterface>    InterfaceFor(const SValue &desc, uint32_t flags = 0)
00205                 { return (desc == INTERFACE::Descriptor()) ? sptr<IInterface>(this) : BBinder::InterfaceFor(desc, flags); }
00206     
00207 protected:
00208 
00209 #if defined(_MSC_VER) && _MSC_VER
00210         inline                          BnInterface() { };
00211         inline                          BnInterface(const SContext& context) : BBinder(context) { };
00212         inline                          BnInterface(const BnInterface<INTERFACE>& other) : INTERFACE(), BBinder(other) { };
00213         inline virtual                  ~BnInterface() { };
00214 #else
00215                                         BnInterface();
00216                                         BnInterface(const SContext& context);
00217                                         BnInterface(const BnInterface<INTERFACE>& other);
00218         virtual                         ~BnInterface();
00219 #endif
00220 
00221         
00222         
00223         virtual sptr<IBinder>           AsBinderImpl()          { return this; }
00224         virtual sptr<const IBinder>     AsBinderImpl() const    { return this; }
00225 };
00226 
00227 /*-------------------------------------------------------------*/
00228 /*------- BpAtom Implementation --------------------------------*/
00229 
00231 
00234 class BpAtom : public virtual SAtom
00235 {
00236     protected:
00237                                         BpAtom(const sptr<IBinder>& o);
00238         virtual                         ~BpAtom();
00239         virtual void                    InitAtom();
00240         virtual status_t                FinishAtom(const void* id);
00241         virtual status_t                IncStrongAttempted(uint32_t flags, const void* id);
00242         virtual status_t                DeleteAtom(const void* id);
00243         
00244         inline  IBinder*                Remote()                { return m_remote; }
00245         // NOTE: This removes constness from the remote binder.
00246         inline  IBinder*                Remote() const          { return m_remote; }
00247                 
00248     private:
00249                                         BpAtom(const BpAtom& o);    // no implementation
00250         BpAtom&                         operator=(const BpAtom& o); // no implementation
00251 
00252         IBinder* const                  m_remote;
00253         int32_t                         m_state;
00254         size_t                          _reserved;
00255 };
00256 
00257 /*-------------------------------------------------------------*/
00258 /*------- BpInterface Implementation ---------------------------*/
00259 
00261 
00263 template<class INTERFACE>
00264 class BpInterface : public INTERFACE, public BpAtom
00265 {
00266     protected:
00267         inline                          BpInterface(const sptr<IBinder>& o) : BpAtom(o) { }
00268         inline virtual                  ~BpInterface() { }
00269         
00270         virtual sptr<IBinder>           AsBinderImpl()
00271                                             { return sptr<IBinder>(Remote()); }
00272         virtual sptr<const IBinder>     AsBinderImpl() const
00273                                             { return sptr<const IBinder>(Remote()); }
00274 
00275         virtual void                    InitAtom()
00276                                             { BpAtom::InitAtom(); }
00277         virtual status_t                FinishAtom(const void* id)
00278                                             { return BpAtom::FinishAtom(id); }
00279         virtual status_t                IncStrongAttempted(uint32_t flags, const void* id)
00280                                             { return BpAtom::IncStrongAttempted(flags, id); }
00281         virtual status_t                DeleteAtom(const void* id)
00282                                             { return BpAtom::DeleteAtom(id); }
00283 };
00284 
00285 /*-------------------------------------------------------------*/
00286 /*------- B_IMPLEMENT_META_INTERFACE --------------------------*/
00287 
00289 
00306 #define B_IMPLEMENT_META_INTERFACE_NO_INSTANTIATE(iname, descriptor, leftmostbase)          \
00307         B_STATIC_STRING_VALUE_LARGE(descriptor_ ## iname, descriptor,)                      \
00308         const BNS(::palmos::support::) SValue& I ## iname :: Descriptor()                   \
00309         {                                                                                   \
00310             return descriptor_ ## iname;                                                    \
00311         }                                                                                   \
00312         BNS(::palmos::support::) sptr<I ## iname> I ## iname :: AsInterface(                \
00313             const BNS(::palmos::support::) sptr< BNS(::palmos::support::) IBinder> &o,      \
00314             status_t* out_error)                                                            \
00315         {                                                                                   \
00316             return static_cast<I ## iname*>(                                                \
00317                 static_cast<leftmostbase*>(                                                 \
00318                 IInterface::ExecAsInterface(                                                \
00319                         o,                                                                  \
00320                         descriptor_ ## iname,                                               \
00321                         instantiate_proxy_ ## iname,                                        \
00322                         out_error)                                                          \
00323                     .ptr() ));                                                              \
00324         }                                                                                   \
00325         BNS(::palmos::support::) sptr<I ## iname> I ## iname :: AsInterface(                \
00326             const BNS(::palmos::support::) SValue &v,                                       \
00327             status_t* out_error)                                                            \
00328         {                                                                                   \
00329             sptr<IBinder> obj = v.AsBinder(out_error);                                      \
00330             if (out_error && *out_error != B_OK) return NULL;                               \
00331             return static_cast<I ## iname*>(                                                \
00332                 static_cast<leftmostbase*>(                                                 \
00333                     IInterface::ExecAsInterface(                                            \
00334                         obj,                                                                \
00335                         descriptor_ ## iname,                                               \
00336                         instantiate_proxy_ ## iname,                                        \
00337                         out_error)                                                          \
00338                     .ptr() ));                                                              \
00339         }                                                                                   \
00340         BNS(::palmos::support::) sptr<I ## iname> I ## iname :: AsInterfaceNoInspect(       \
00341             const BNS(::palmos::support::) sptr< BNS(::palmos::support::) IBinder> &o,      \
00342             status_t* out_error)                                                            \
00343         {                                                                                   \
00344             return static_cast<I ## iname*>(                                                \
00345                 static_cast<leftmostbase*>(                                                 \
00346                     IInterface::ExecAsInterfaceNoInspect(                                   \
00347                         o,                                                                  \
00348                         descriptor_ ## iname,                                               \
00349                         instantiate_proxy_ ## iname,                                        \
00350                         out_error)                                                          \
00351                     .ptr() ));                                                              \
00352         }                                                                                   \
00353         BNS(::palmos::support::) sptr<I ## iname> I ## iname :: AsInterfaceNoInspect(       \
00354             const BNS(::palmos::support::) SValue &v,                                       \
00355             status_t* out_error)                                                            \
00356         {                                                                                   \
00357             sptr<IBinder> obj = v.AsBinder(out_error);                                      \
00358             if (out_error && *out_error != B_OK) return NULL;                               \
00359             return static_cast<I ## iname*>(                                                \
00360                 static_cast<leftmostbase*>(                                                 \
00361                 IInterface::ExecAsInterfaceNoInspect(                                       \
00362                     obj,                                                                    \
00363                     descriptor_ ## iname,                                                   \
00364                     instantiate_proxy_ ## iname,                                            \
00365                     out_error)                                                              \
00366                 .ptr() ));                                                                  \
00367         }                                                                                   \
00368 
00369 
00370 #define B_IMPLEMENT_META_INTERFACE(iname, descriptor, leftmostbase)                         \
00371         static BNS(::palmos::support::) sptr<BNS(::palmos::support::) IInterface>           \
00372         instantiate_proxy_ ## iname (const BNS(::palmos::support::)sptr<BNS(::palmos::support::) IBinder>& b) {     \
00373             return static_cast<leftmostbase*>(new Bp ## iname(b));                          \
00374         }                                                                                   \
00375         B_IMPLEMENT_META_INTERFACE_NO_INSTANTIATE(iname, descriptor, leftmostbase)          \
00376 
00377 
00378 
00379 #define B_IMPLEMENT_META_INTERFACE_LOCAL(iname, descriptor, leftmostbase)                   \
00380         static BNS(::palmos::support::) sptr<BNS(::palmos::support::) IInterface>           \
00381         instantiate_proxy_ ## iname (const BNS(::palmos::support::)sptr<BNS(::palmos::support::) IBinder>& b) {     \
00382             return NULL;                                                                    \
00383         }                                                                                   \
00384         B_IMPLEMENT_META_INTERFACE_NO_INSTANTIATE(iname, descriptor, leftmostbase)          \
00385 
00386 
00388 /*-------------------------------------------------------------*/
00389 /*---- No user serviceable parts after this -------------------*/
00390 
00391 // The first field of a BBinder is its containing context.
00392 inline const SContext& BBinder::Context() const
00393 {
00394     return m_context;
00395 }
00396 
00397 #if !defined(_MSC_VER) || !_MSC_VER
00398 template<class INTERFACE>
00399 inline BnInterface<INTERFACE>::BnInterface()
00400 {
00401 }
00402 
00403 template<class INTERFACE>
00404 inline BnInterface<INTERFACE>::BnInterface(const SContext& context) : BBinder(context)
00405 {
00406 }
00407 
00408 template<class INTERFACE>
00409 inline BnInterface<INTERFACE>::BnInterface(const BnInterface<INTERFACE>& other) : INTERFACE(), BBinder(other)
00410 {
00411 }
00412 
00413 template<class INTERFACE>
00414 inline BnInterface<INTERFACE>::~BnInterface()
00415 {
00416 }
00417 #endif
00418 
00419 inline const SValue& effect_action_def::key() const
00420 {
00421     return *reinterpret_cast<const SValue*>(raw_key);
00422 }
00423 
00424 #if _SUPPORTS_NAMESPACE
00425 } } // namespace palmos::support
00426 #endif
00427 
00428 #endif  /* _SUPPORT_BINDER_H_ */