1# IPC & RPC Development Guidelines<a name="EN-US_TOPIC_0000001103710988"></a> 2 3- [When to Use](#section18502174174019) 4- [Available APIs](#section1633115419401) 5- [How to Develop](#section4207112818418) 6 7## When to Use<a name="section18502174174019"></a> 8 9IPC/RPC enables a proxy and a stub that run on different processes to communicate with each other, regardless of whether they run on the same or different devices. 10 11## Available APIs<a name="section1633115419401"></a> 12 13**Table 1** Native IPC APIs 14 15<a name="table178849240013"></a> 16<table><thead align="left"><tr id="row6884924608"><th class="cellrowborder" valign="top" width="14.12141214121412%" id="mcps1.2.4.1.1"><p id="p98846241706"><a name="p98846241706"></a><a name="p98846241706"></a>Class/Interface</p> 17</th> 18<th class="cellrowborder" valign="top" width="52.54525452545254%" id="mcps1.2.4.1.2"><p id="p1488482414020"><a name="p1488482414020"></a><a name="p1488482414020"></a>Function</p> 19</th> 20<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p388516244016"><a name="p388516244016"></a><a name="p388516244016"></a>Description</p> 21</th> 22</tr> 23</thead> 24<tbody><tr id="row15885824402"><td class="cellrowborder" valign="top" width="14.12141214121412%" headers="mcps1.2.4.1.1 "><p id="p08859241008"><a name="p08859241008"></a><a name="p08859241008"></a>IRemoteBroker</p> 25</td> 26<td class="cellrowborder" valign="top" width="52.54525452545254%" headers="mcps1.2.4.1.2 "><p id="p388572412010"><a name="p388572412010"></a><a name="p388572412010"></a>sptr<IRemoteObject> AsObject()</p> 27</td> 28<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p13885724405"><a name="p13885724405"></a><a name="p13885724405"></a>Obtains the holder of a remote proxy object. This method must be implemented by the derived classes of <strong id="b18927631105113"><a name="b18927631105113"></a><a name="b18927631105113"></a>IRemoteBroker</strong>. If you call this method on the stub, the <strong id="b7932163110519"><a name="b7932163110519"></a><a name="b7932163110519"></a>RemoteObject</strong> is returned; if you call this method on the proxy, the proxy object is returned.</p> 29</td> 30</tr> 31<tr id="row138859241808"><td class="cellrowborder" valign="top" width="14.12141214121412%" headers="mcps1.2.4.1.1 "><p id="p1888515245012"><a name="p1888515245012"></a><a name="p1888515245012"></a>IRemoteStub</p> 32</td> 33<td class="cellrowborder" valign="top" width="52.54525452545254%" headers="mcps1.2.4.1.2 "><p id="p1388516240011"><a name="p1388516240011"></a><a name="p1388516240011"></a>virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)</p> 34</td> 35<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p1188582414016"><a name="p1188582414016"></a><a name="p1188582414016"></a>Called to process a request from the proxy and return the result. Derived classes need to override this method.</p> 36</td> 37</tr> 38<tr id="row108856241904"><td class="cellrowborder" valign="top" width="14.12141214121412%" headers="mcps1.2.4.1.1 "><p id="p6885924609"><a name="p6885924609"></a><a name="p6885924609"></a>IRemoteProxy</p> 39</td> 40<td class="cellrowborder" valign="top" width="52.54525452545254%" headers="mcps1.2.4.1.2 "> </td> 41<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p688592413018"><a name="p688592413018"></a><a name="p688592413018"></a>Service proxy classes are derived from the <strong id="b169739356519"><a name="b169739356519"></a><a name="b169739356519"></a>IRemoteProxy</strong> class.</p> 42</td> 43</tr> 44</tbody> 45</table> 46 47## How to Develop<a name="section4207112818418"></a> 48 49**Using Native APIs** 50 511. Define the IPC interface **ITestAbility**. 52 53 **ITestAbility** inherits the IPC base class **IRemoteBroker** and defines descriptors, functions, and message code. The functions need to be implemented on both the proxy and stub. 54 55 ``` 56 class ITestAbility : public IRemoteBroker { 57 public: 58 // DECLARE_INTERFACE_DESCRIPTOR is mandatory, and the input parameter is std::u16string. 59 DECLARE_INTERFACE_DESCRIPTOR(u"test.ITestAbility"); 60 int TRANS_ID_PING_ABILITY = 1; // Define the message code. 61 virtual int TestPingAbility(const std::u16string &dummy) = 0; // Define functions. 62 }; 63 ``` 64 652. Define and implement service provider **TestAbilityStub**. 66 67 This class is related to the IPC framework and needs to inherit **IRemoteStub<ITestAbility\>**. You need to override **OnRemoteRequest** on the stub to receive requests from the proxy. 68 69 ``` 70 class TestAbilityStub : public IRemoteStub<ITestAbility> { 71 public: 72 virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; 73 int TestPingAbility(const std::u16string &dummy) override; 74 }; 75 76 int TestServiceStub::OnRemoteRequest(uint32_t code, 77 MessageParcel &data, MessageParcel &reply, MessageOption &option) 78 { 79 switch (code) { 80 case TRANS_ID_PING_ABILITY: { 81 std::u16string dummy = data.ReadString16(); 82 int result = TestPingAbility(dummy); 83 reply.WriteInt32(result); 84 return 0; 85 } 86 default: 87 return IPCObjectStub::OnRemoteRequest(code, data, reply, option); 88 } 89 } 90 ``` 91 923. Define the **TestAbility** class that implements functions for the stub. 93 94 ``` 95 class TestAbility : public TestAbilityStub { 96 public: 97 int TestPingAbility(const std::u16string &dummy); 98 } 99 100 int TestAbility::TestPingAbility(const std::u16string &dummy) { 101 return 0; 102 } 103 ``` 104 1054. Define and implement **TestAbilityProxy**. 106 107 This class is implemented on the proxy and inherits **IRemoteProxy<ITestAbility\>**. You can call **SendRequest** to send a request to the stub and expose the capabilities provided by the stub. 108 109 ``` 110 class TestAbilityProxy : public IRemoteProxy<ITestAbility> { 111 public: 112 explicit TestAbilityProxy(const sptr<IRemoteObject> &impl); 113 int TestPingService(const std::u16string &dummy) override; 114 private: 115 static inline BrokerDelegator<TestAbilityProxy> delegator_; // Use the iface_cast macro. 116 } 117 118 TestAbilityProxy::TestAbilityProxy(const sptr<IRemoteObject> &impl) 119 : IRemoteProxy<ITestAbility>(impl) 120 { 121 } 122 123 int TestAbilityProxy::TestPingService(const std::u16string &dummy) { 124 MessageOption option; 125 MessageParcel dataParcel, replyParcel; 126 dataParcel.WriteString16(dummy); 127 int error = Remote()->SendRequest(TRANS_ID_PING_ABILITY, dataParcel, replyParcel, option); 128 int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1; 129 return result; 130 } 131 ``` 132 1335. Register and start an SA. 134 135 Call **AddSystemAbility** to register the **TestAbilityStub** instance of the SA with **SystemAbilityManager**. The registration parameters vary depending on whether the **SystemAbilityManager** resides on the same device as the SA. 136 137 ``` 138 // Register the TestAbilityStub instance with the SystemAbilityManager on the same device as the SA. 139 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 140 samgr->AddSystemAbility(said, new TestAbility()); 141 142 // Register the TestAbilityStub instance with the SystemAbilityManager on a different device. 143 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 144 ISystemAbilityManager::SAExtraProp saExtra; 145 saExtra.isDistributed = true; // Set a distributed SA. 146 int result = samgr->AddSystemAbility(said, new TestAbility(), saExtra); 147 ``` 148 1496. Obtain the SA. 150 151 Call the **GetSystemAbility** function of the **SystemAbilityManager** class to obtain the **IRemoteObject** for the SA, and create a **TestAbilityProxy** instance. 152 153 ``` 154 // Obtain the proxy of the SA registered on the local device. 155 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 156 sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(said); 157 sptr<ITestAbility> testAbility = iface_cast<ITestAbility>(remoteObject); // Use the iface_cast macro to convert the proxy to a specific type. 158 159 // Obtain the proxies of the SAs registered with other devices. 160 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 161 sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(sdid, deviceId); // deviceId identifies a device. 162 sptr<TestAbilityProxy> proxy(new TestAbilityProxy(remoteObject)); // Construct a proxy. 163 ``` 164 165 166