## When to Use<a name="section18502174174019"></a>
## When to Use
IPC/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.
## Available APIs<a name="section1633115419401"></a>
<tdclass="cellrowborder"valign="top"width="33.33333333333333%"headers="mcps1.2.4.1.3 "><pid="p13885724405"><aname="p13885724405"></a><aname="p13885724405"></a>Obtains the holder of a remote proxy object. This method must be implemented by the derived classes of <strongid="b18927631105113"><aname="b18927631105113"></a><aname="b18927631105113"></a>IRemoteBroker</strong>. If you call this method on the stub, the <strongid="b7932163110519"><aname="b7932163110519"></a><aname="b7932163110519"></a>RemoteObject</strong> is returned; if you call this method on the proxy, the proxy object is returned.</p>
<tdclass="cellrowborder"valign="top"width="33.33333333333333%"headers="mcps1.2.4.1.3 "><pid="p1188582414016"><aname="p1188582414016"></a><aname="p1188582414016"></a>Called to process a request from the proxy and return the result. Derived classes need to override this method.</p>
<tdclass="cellrowborder"valign="top"width="33.33333333333333%"headers="mcps1.2.4.1.3 "><pid="p688592413018"><aname="p688592413018"></a><aname="p688592413018"></a>Service proxy classes are derived from the <strongid="b169739356519"><aname="b169739356519"></a><aname="b169739356519"></a>IRemoteProxy</strong> class.</p>
</td>
</tr>
</tbody>
</table>
## How to Develop<a name="section4207112818418"></a>
| IRemoteBroker | sptr\<IRemoteObject> AsObject() | Obtains the holder of a remote proxy object. This method must be implemented by the derived classes of **IRemoteBroker**. If you call this method on the stub, the **RemoteObject** is returned; if you call this method on the proxy, the proxy object is returned. |
| IRemoteStub | virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) | Called to process a request from the proxy and return the result. Derived classes need to override this method. |
| IRemoteProxy | | Service proxy classes are derived from the **IRemoteProxy** class. |
## How to Develop
**Using Native APIs**
1. Define the IPC interface **ITestAbility**.
**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.
```
class ITestAbility : public IRemoteBroker {
public:
// DECLARE_INTERFACE_DESCRIPTOR is mandatory, and the input parameter is std::u16string.
int TRANS_ID_PING_ABILITY = 1; // Define the message code.
virtual int TestPingAbility(const std::u16string &dummy) = 0; // Define functions.
};
```
2. Define and implement service provider **TestAbilityStub**.
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.
```
class TestAbilityStub : public IRemoteStub<ITestAbility> {
3. Define the **TestAbility** class that implements functions for the stub.
```
class TestAbility : public TestAbilityStub {
public:
int TestPingAbility(const std::u16string &dummy);
}
int TestAbility::TestPingAbility(const std::u16string &dummy) {
return 0;
}
```
4. Define and implement **TestAbilityProxy**.
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.
```
class TestAbilityProxy : public IRemoteProxy<ITestAbility> {
int TestAbilityProxy::TestPingService(const std::u16string &dummy) {
MessageOption option;
MessageParcel dataParcel, replyParcel;
dataParcel.WriteString16(dummy);
int error = Remote()->SendRequest(TRANS_ID_PING_ABILITY, dataParcel, replyParcel, option);
int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1;
return result;
}
```
5. Register and start an SA.
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.
```
// Register the TestAbilityStub instance with the SystemAbilityManager on the same device as the SA.
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
samgr->AddSystemAbility(said, new TestAbility());
// Register the TestAbilityStub instance with the SystemAbilityManager on a different device.
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ISystemAbilityManager::SAExtraProp saExtra;
saExtra.isDistributed = true; // Set a distributed SA.
int result = samgr->AddSystemAbility(said, new TestAbility(), saExtra);
```
6. Obtain the SA.
Call the **GetSystemAbility** function of the **SystemAbilityManager** class to obtain the **IRemoteObject** for the SA, and create a **TestAbilityProxy** instance.
```
// Obtain the proxy of the SA registered on the local device.
sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(sdid, deviceId); // deviceId identifies a device.
sptr<TestAbilityProxy> proxy(new TestAbilityProxy(remoteObject)); // Construct a proxy.
```
1. Define the IPC interface **ITestAbility**.
**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.
```
class ITestAbility : public IRemoteBroker {
public:
// DECLARE_INTERFACE_DESCRIPTOR is mandatory, and the input parameter is std::u16string.
int TRANS_ID_PING_ABILITY = 1; // Define the message code.
virtual int TestPingAbility(const std::u16string &dummy) = 0; // Define functions.
};
```
2. Define and implement service provider **TestAbilityStub**.
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.
```
class TestAbilityStub : public IRemoteStub<ITestAbility> {
3. Define the **TestAbility** class that implements functions for the stub.
```
class TestAbility : public TestAbilityStub {
public:
int TestPingAbility(const std::u16string &dummy);
}
int TestAbility::TestPingAbility(const std::u16string &dummy) {
return 0;
}
```
4. Define and implement **TestAbilityProxy**.
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.
```
class TestAbilityProxy : public IRemoteProxy<ITestAbility> {
int TestAbilityProxy::TestPingService(const std::u16string &dummy) {
MessageOption option;
MessageParcel dataParcel, replyParcel;
dataParcel.WriteString16(dummy);
int error = Remote()->SendRequest(TRANS_ID_PING_ABILITY, dataParcel, replyParcel, option);
int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1;
return result;
}
```
5. Register and start an SA.
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.
```
// Register the TestAbilityStub instance with the SystemAbilityManager on the same device as the SA.
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
samgr->AddSystemAbility(said, new TestAbility());
// Register the TestAbilityStub instance with the SystemAbilityManager on a different device.
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ISystemAbilityManager::SAExtraProp saExtra;
saExtra.isDistributed = true; // Set a distributed SA.
int result = samgr->AddSystemAbility(said, new TestAbility(), saExtra);
```
6. Obtain the SA.
Call the **GetSystemAbility** function of the **SystemAbilityManager** class to obtain the **IRemoteObject** for the SA, and create a **TestAbilityProxy** instance.
```
// Obtain the proxy of the SA registered on the local device.