1# IPC & RPC Development 2 3## When to Use 4 5IPC/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. 6 7## Available APIs 8 9**Table 1** Native IPC APIs 10 11| Class/Interface | Function | Description | 12| --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | 13| 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. | 14| 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. | 15| IRemoteProxy | | Service proxy classes are derived from the **IRemoteProxy** class. | 16 17## How to Develop 18 19**Using Native APIs** 20 211. Define the IPC interface **ITestAbility**. 22 23 **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. 24 25 ``` 26 class ITestAbility : public IRemoteBroker { 27 public: 28 // DECLARE_INTERFACE_DESCRIPTOR is mandatory, and the input parameter is std::u16string. 29 DECLARE_INTERFACE_DESCRIPTOR(u"test.ITestAbility"); 30 int TRANS_ID_PING_ABILITY = 1; // Define the message code. 31 virtual int TestPingAbility(const std::u16string &dummy) = 0; // Define functions. 32 }; 33 ``` 34 352. Define and implement service provider **TestAbilityStub**. 36 37 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. 38 39 ``` 40 class TestAbilityStub : public IRemoteStub<ITestAbility> { 41 public: 42 virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; 43 int TestPingAbility(const std::u16string &dummy) override; 44 }; 45 46 int TestServiceStub::OnRemoteRequest(uint32_t code, 47 MessageParcel &data, MessageParcel &reply, MessageOption &option) 48 { 49 switch (code) { 50 case TRANS_ID_PING_ABILITY: { 51 std::u16string dummy = data.ReadString16(); 52 int result = TestPingAbility(dummy); 53 reply.WriteInt32(result); 54 return 0; 55 } 56 default: 57 return IPCObjectStub::OnRemoteRequest(code, data, reply, option); 58 } 59 } 60 ``` 61 623. Define the **TestAbility** class that implements functions for the stub. 63 64 ``` 65 class TestAbility : public TestAbilityStub { 66 public: 67 int TestPingAbility(const std::u16string &dummy); 68 } 69 70 int TestAbility::TestPingAbility(const std::u16string &dummy) { 71 return 0; 72 } 73 ``` 74 754. Define and implement **TestAbilityProxy**. 76 77 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. 78 79 ``` 80 class TestAbilityProxy : public IRemoteProxy<ITestAbility> { 81 public: 82 explicit TestAbilityProxy(const sptr<IRemoteObject> &impl); 83 int TestPingService(const std::u16string &dummy) override; 84 private: 85 static inline BrokerDelegator<TestAbilityProxy> delegator_; // Use the iface_cast macro. 86 } 87 88 TestAbilityProxy::TestAbilityProxy(const sptr<IRemoteObject> &impl) 89 : IRemoteProxy<ITestAbility>(impl) 90 { 91 } 92 93 int TestAbilityProxy::TestPingService(const std::u16string &dummy) { 94 MessageOption option; 95 MessageParcel dataParcel, replyParcel; 96 dataParcel.WriteString16(dummy); 97 int error = Remote()->SendRequest(TRANS_ID_PING_ABILITY, dataParcel, replyParcel, option); 98 int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1; 99 return result; 100 } 101 ``` 102 1035. Register and start an SA. 104 105 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. 106 107 ``` 108 // Register the TestAbilityStub instance with the SystemAbilityManager on the same device as the SA. 109 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 110 samgr->AddSystemAbility(said, new TestAbility()); 111 112 // Register the TestAbilityStub instance with the SystemAbilityManager on a different device. 113 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 114 ISystemAbilityManager::SAExtraProp saExtra; 115 saExtra.isDistributed = true; // Set a distributed SA. 116 int result = samgr->AddSystemAbility(said, new TestAbility(), saExtra); 117 ``` 118 1196. Obtain the SA. 120 121 Call the **GetSystemAbility** function of the **SystemAbilityManager** class to obtain the **IRemoteObject** for the SA, and create a **TestAbilityProxy** instance. 122 123 ``` 124 // Obtain the proxy of the SA registered on the local device. 125 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 126 sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(said); 127 sptr<ITestAbility> testAbility = iface_cast<ITestAbility>(remoteObject); // Use the iface_cast macro to convert the proxy to a specific type. 128 129 // Obtain the proxies of the SAs registered with other devices. 130 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 131 sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(sdid, deviceId); // deviceId identifies a device. 132 sptr<TestAbilityProxy> proxy(new TestAbilityProxy(remoteObject)); // Construct a proxy. 133 ```