1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "datashare_connection.h"
17
18 #include "ability_manager_client.h"
19 #include "datashare_proxy.h"
20 #include "datashare_log.h"
21
22 namespace OHOS {
23 namespace DataShare {
24 using namespace AppExecFwk;
25 sptr<DataShareConnection> DataShareConnection::instance_ = nullptr;
26 constexpr int WAIT_TIME = 1;
27
28 /**
29 * @brief This method is called back to receive the connection result after an ability calls the
30 * ConnectAbility method to connect it to an extension ability.
31 *
32 * @param element: Indicates information about the connected extension ability.
33 * @param remote: Indicates the remote proxy object of the extension ability.
34 * @param resultCode: Indicates the connection result code. The value 0 indicates a successful connection, and any
35 * other value indicates a connection failure.
36 */
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)37 void DataShareConnection::OnAbilityConnectDone(
38 const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int resultCode)
39 {
40 LOG_INFO("on connect done, uri:%{public}s, ret=%{public}d", uri_.ToString().c_str(), resultCode);
41 if (remoteObject == nullptr) {
42 LOG_ERROR("remote is nullptr");
43 return;
44 }
45 std::unique_lock<std::mutex> lock(condition_.mutex);
46 SetDataShareProxy(iface_cast<DataShareProxy>(remoteObject));
47 condition_.condition.notify_all();
48 }
49
50 /**
51 * @brief This method is called back to receive the disconnection result after the connected extension ability crashes
52 * or is killed. If the extension ability exits unexpectedly, all its connections are disconnected, and each ability
53 * previously connected to it will call onAbilityDisconnectDone.
54 *
55 * @param element: Indicates information about the disconnected extension ability.
56 * @param resultCode: Indicates the disconnection result code. The value 0 indicates a successful disconnection, and
57 * any other value indicates a disconnection failure.
58 */
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)59 void DataShareConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
60 {
61 LOG_INFO("on disconnect done, uri:%{public}s, ret:%{public}d", uri_.ToString().c_str(), resultCode);
62 auto proxy = dataShareProxy_;
63 {
64 std::unique_lock<std::mutex> lock(condition_.mutex);
65 SetDataShareProxy(nullptr);
66 condition_.condition.notify_all();
67 }
68 if (proxy != nullptr && !uri_.ToString().empty()) {
69 LOG_INFO("uri : %{public}s disconnect,start reconnect", uri_.ToString().c_str());
70 ConnectDataShareExtAbility(uri_, proxy->AsObject());
71 }
72 }
73
74 /**
75 * @brief connect remote ability of DataShareExtAbility.
76 */
ConnectDataShareExtAbility(const Uri & uri,const sptr<IRemoteObject> & token)77 bool DataShareConnection::ConnectDataShareExtAbility(const Uri &uri, const sptr<IRemoteObject> &token)
78 {
79 if (dataShareProxy_ != nullptr) {
80 return true;
81 }
82
83 AAFwk::Want want;
84 if (uri_.ToString().empty()) {
85 want.SetUri(uri);
86 } else {
87 want.SetUri(uri_);
88 }
89 ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, this, token);
90 if (ret != ERR_OK) {
91 LOG_ERROR("connect ability failed, ret = %{public}d", ret);
92 return false;
93 }
94 std::unique_lock<std::mutex> lock(condition_.mutex);
95 if (condition_.condition.wait_for(lock, std::chrono::seconds(WAIT_TIME),
96 [this] { return dataShareProxy_ != nullptr; })) {
97 LOG_INFO("connect ability ended successfully");
98 }
99 return dataShareProxy_ != nullptr;
100 }
101
102 /**
103 * @brief disconnect remote ability of DataShareExtAbility.
104 */
DisconnectDataShareExtAbility()105 void DataShareConnection::DisconnectDataShareExtAbility()
106 {
107 uri_ = Uri("");
108 if (dataShareProxy_ == nullptr) {
109 return;
110 }
111 ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(this);
112 if (ret != ERR_OK) {
113 LOG_ERROR("disconnect ability failed, ret = %{public}d", ret);
114 return;
115 }
116 std::unique_lock<std::mutex> lock(condition_.mutex);
117 if (condition_.condition.wait_for(lock, std::chrono::seconds(WAIT_TIME),
118 [this] { return dataShareProxy_ == nullptr; })) {
119 LOG_INFO("disconnect ability ended successfully");
120 }
121 LOG_INFO("called end, ret=%{public}d", ret);
122 }
123
124 /**
125 * @brief check whether connected to remote extension ability.
126 *
127 * @return bool true if connected, otherwise false.
128 */
IsExtAbilityConnected()129 bool DataShareConnection::IsExtAbilityConnected()
130 {
131 return dataShareProxy_ != nullptr;
132 }
133
GetDataShareProxy()134 sptr<IDataShare> DataShareConnection::GetDataShareProxy()
135 {
136 return dataShareProxy_;
137 }
138
SetDataShareProxy(sptr<IDataShare> proxy)139 void DataShareConnection::SetDataShareProxy(sptr<IDataShare> proxy)
140 {
141 dataShareProxy_ = proxy;
142 }
143
~DataShareConnection()144 DataShareConnection::~DataShareConnection()
145 {
146 }
147 } // namespace DataShare
148 } // namespace OHOS