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 "ams_mgr_proxy.h"
19 #include "datashare_proxy.h"
20 #include "datashare_log.h"
21
22 namespace OHOS {
23 namespace DataShare {
24 using namespace AppExecFwk;
25 constexpr int WAIT_TIME = 1;
26 /**
27 * @brief This method is called back to receive the connection result after an ability calls the
28 * ConnectAbility method to connect it to an extension ability.
29 *
30 * @param element: Indicates information about the connected extension ability.
31 * @param remote: Indicates the remote proxy object of the extension ability.
32 * @param resultCode: Indicates the connection result code. The value 0 indicates a successful connection, and any
33 * other value indicates a connection failure.
34 */
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)35 void DataShareConnection::OnAbilityConnectDone(
36 const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int resultCode)
37 {
38 LOG_INFO("on connect done, uri:%{public}s, ret=%{public}d", uri_.ToString().c_str(), resultCode);
39 if (remoteObject == nullptr) {
40 LOG_ERROR("remote is nullptr");
41 return;
42 }
43 std::unique_lock<std::mutex> lock(condition_.mutex);
44 SetDataShareProxy(new (std::nothrow) DataShareProxy(remoteObject));
45 condition_.condition.notify_all();
46 }
47
48 /**
49 * @brief This method is called back to receive the disconnection result after the connected extension ability crashes
50 * or is killed. If the extension ability exits unexpectedly, all its connections are disconnected, and each ability
51 * previously connected to it will call onAbilityDisconnectDone.
52 *
53 * @param element: Indicates information about the disconnected extension ability.
54 * @param resultCode: Indicates the disconnection result code. The value 0 indicates a successful disconnection, and
55 * any other value indicates a disconnection failure.
56 */
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)57 void DataShareConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
58 {
59 LOG_INFO("on disconnect done, uri:%{public}s, ret:%{public}d", uri_.ToString().c_str(), resultCode);
60 {
61 std::unique_lock<std::mutex> lock(condition_.mutex);
62 SetDataShareProxy(nullptr);
63 condition_.condition.notify_all();
64 }
65 if (!uri_.ToString().empty()) {
66 ConnectDataShareExtAbility(uri_, token_);
67 }
68 }
69
70 /**
71 * @brief connect remote ability of DataShareExtAbility.
72 */
ConnectDataShareExtAbility(const Uri & uri,const sptr<IRemoteObject> & token)73 std::shared_ptr<DataShareProxy> DataShareConnection::ConnectDataShareExtAbility(const Uri &uri,
74 const sptr<IRemoteObject> &token)
75 {
76 if (dataShareProxy_ != nullptr) {
77 return dataShareProxy_;
78 }
79 auto reqUri = uri_.ToString().empty() ? uri.ToString() : uri_.ToString();
80 AmsMgrProxy* instance = AmsMgrProxy::GetInstance();
81 if (instance == nullptr) {
82 LOG_ERROR("Connect: AmsMgrProxy::GetInstance failed");
83 return nullptr;
84 }
85
86 ErrCode ret = instance->Connect(reqUri, this, token);
87 if (ret != ERR_OK) {
88 LOG_ERROR("connect ability failed, ret = %{public}d", ret);
89 return nullptr;
90 }
91 std::unique_lock<std::mutex> lock(condition_.mutex);
92 if (condition_.condition.wait_for(lock, std::chrono::seconds(WAIT_TIME),
93 [this] { return dataShareProxy_ != nullptr; })) {
94 LOG_DEBUG("connect ability ended successfully");
95 }
96 return dataShareProxy_;
97 }
98
99 /**
100 * @brief disconnect remote ability of DataShareExtAbility.
101 */
DisconnectDataShareExtAbility()102 void DataShareConnection::DisconnectDataShareExtAbility()
103 {
104 uri_ = Uri("");
105 if (dataShareProxy_ == nullptr) {
106 return;
107 }
108 AmsMgrProxy* instance = AmsMgrProxy::GetInstance();
109 if (instance == nullptr) {
110 LOG_ERROR("Disconnect: AmsMgrProxy::GetInstance failed");
111 return;
112 }
113
114 ErrCode ret = instance->DisConnect(this);
115 if (ret != ERR_OK) {
116 LOG_ERROR("disconnect ability failed, ret = %{public}d", ret);
117 return;
118 }
119 std::unique_lock<std::mutex> lock(condition_.mutex);
120 if (condition_.condition.wait_for(lock, std::chrono::seconds(WAIT_TIME),
121 [this] { return dataShareProxy_ == nullptr; })) {
122 LOG_DEBUG("disconnect ability successfully");
123 } else {
124 LOG_INFO("disconnect timeout");
125 }
126 }
127
SetDataShareProxy(sptr<DataShareProxy> proxy)128 void DataShareConnection::SetDataShareProxy(sptr<DataShareProxy> proxy)
129 {
130 if (proxy == nullptr) {
131 dataShareProxy_ = nullptr;
132 return;
133 }
134
135 dataShareProxy_ =
136 std::shared_ptr<DataShareProxy>(proxy.GetRefPtr(), [holder = proxy](const auto *) {});
137 }
138
~DataShareConnection()139 DataShareConnection::~DataShareConnection()
140 {
141 }
142
GetDataShareProxy(const Uri & uri,const sptr<IRemoteObject> & token)143 std::shared_ptr<DataShareProxy> DataShareConnection::GetDataShareProxy(const Uri &uri,
144 const sptr<IRemoteObject> &token)
145 {
146 return ConnectDataShareExtAbility(uri, token);
147 }
148 } // namespace DataShare
149 } // namespace OHOS