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 #ifndef OHOS_ABILITY_RUNTIME_DATA_ABILITY_HELPER_IMPL_H
17 #define OHOS_ABILITY_RUNTIME_DATA_ABILITY_HELPER_IMPL_H
18 
19 #include <mutex>
20 #include <map>
21 #include <string>
22 
23 #include "context.h"
24 #include "fa_context.h"
25 #include "uri.h"
26 
27 using Uri = OHOS::Uri;
28 
29 namespace OHOS {
30 namespace NativeRdb {
31 class AbsSharedResultSet;
32 class DataAbilityPredicates;
33 class ValuesBucket;
34 }  // namespace NativeRdb
35 namespace AppExecFwk {
36 using string = std::string;
37 class DataAbilityResult;
38 class DataAbilityOperation;
39 class PacMap;
40 class IDataAbilityObserver;
41 class DataAbilityHelperImpl final : public std::enable_shared_from_this<DataAbilityHelperImpl> {
42 public:
43     ~DataAbilityHelperImpl() = default;
44 
45     /**
46      * @brief Creates a DataAbilityHelperImpl instance without specifying the Uri based on the given Context.
47      *
48      * @param context Indicates the Context object on OHOS.
49      *
50      * @return Returns the created DataAbilityHelperImpl instance where Uri is not specified.
51      */
52     static std::shared_ptr<DataAbilityHelperImpl> Creator(const std::shared_ptr<Context> &context);
53 
54     /**
55      * @brief You can use this method to specify the Uri of the data to operate and set the binding relationship
56      * between the ability using the Data template (Data ability for short) and the associated client process in
57      * a DataAbilityHelperImpl instance.
58      *
59      * @param context Indicates the Context object on OHOS.
60      * @param uri Indicates the database table or disk file to operate.
61      * @param tryBind Specifies whether the exit of the corresponding Data ability process causes the exit of the
62      * client process.
63      *
64      * @return Returns the created DataAbilityHelperImpl instance.
65      */
66     static std::shared_ptr<DataAbilityHelperImpl> Creator(
67         const std::shared_ptr<Context> &context, const std::shared_ptr<Uri> &uri, const bool tryBind);
68 
69     /**
70      * @brief You can use this method to specify the Uri of the data to operate and set the binding relationship
71      * between the ability using the Data template (Data ability for short) and the associated client process in
72      * a DataAbilityHelperImpl instance.
73      *
74      * @param context Indicates the Context object on OHOS.
75      * @param uri Indicates the database table or disk file to operate.
76      * @param tryBind Specifies whether the exit of the corresponding Data ability process causes the exit of the
77      * client process.
78      *
79      * @return Returns the created DataAbilityHelperImpl instance.
80      */
81     static std::shared_ptr<DataAbilityHelperImpl> Creator(
82         const std::shared_ptr<OHOS::AbilityRuntime::Context> &context,
83         const std::shared_ptr<Uri> &uri, const bool tryBind);
84 
85     /**
86      * @brief Creates a DataAbilityHelperImpl instance without specifying the Uri based.
87      *
88      * @param token Indicates the System token.
89      *
90      * @return Returns the created DataAbilityHelperImpl instance where Uri is not specified.
91      */
92     static std::shared_ptr<DataAbilityHelperImpl> Creator(const sptr<IRemoteObject> &token);
93 
94     /**
95      * @brief You can use this method to specify the Uri of the data to operate and set the binding relationship
96      * between the ability using the Data template (Data ability for short) and the associated client process in
97      * a DataAbilityHelperImpl instance.
98      *
99      * @param token Indicates the System token.
100      * @param uri Indicates the database table or disk file to operate.
101      *
102      * @return Returns the created DataAbilityHelperImpl instance.
103      */
104     static std::shared_ptr<DataAbilityHelperImpl> Creator(
105         const sptr<IRemoteObject> &token, const std::shared_ptr<Uri> &uri);
106 
107     /**
108      * @brief Releases the client resource of the Data ability.
109      * You should call this method to releases client resource after the data operations are complete.
110      *
111      * @return Returns true if the resource is successfully released; returns false otherwise.
112      */
113     bool Release();
114     /**
115      * @brief Obtains the MIME types of files supported.
116      *
117      * @param uri Indicates the path of the files to obtain.
118      * @param mimeTypeFilter Indicates the MIME types of the files to obtain. This parameter cannot be null.
119      *
120      * @return Returns the matched MIME types. If there is no match, null is returned.
121      */
122     std::vector<std::string> GetFileTypes(Uri &uri, const std::string &mimeTypeFilter);
123 
124     /**
125      * @brief Opens a file in a specified remote path.
126      *
127      * @param uri Indicates the path of the file to open.
128      * @param mode Indicates the file open mode, which can be "r" for read-only access, "w" for write-only access
129      * (erasing whatever data is currently in the file), "wt" for write access that truncates any existing file,
130      * "wa" for write-only access to append to any existing data, "rw" for read and write access on any existing data,
131      *  or "rwt" for read and write access that truncates any existing file.
132      *
133      * @return Returns the file descriptor.
134      */
135     int OpenFile(Uri &uri, const std::string &mode);
136 
137     /**
138      * @brief This is like openFile, open a file that need to be able to return sub-sections of files,often assets
139      * inside of their .hap.
140      *
141      * @param uri Indicates the path of the file to open.
142      * @param mode Indicates the file open mode, which can be "r" for read-only access, "w" for write-only access
143      * (erasing whatever data is currently in the file), "wt" for write access that truncates any existing file,
144      * "wa" for write-only access to append to any existing data, "rw" for read and write access on any existing
145      * data, or "rwt" for read and write access that truncates any existing file.
146      *
147      * @return Returns the RawFileDescriptor object containing file descriptor.
148      */
149     int OpenRawFile(Uri &uri, const std::string &mode);
150 
151     /**
152      * @brief Inserts a single data record into the database.
153      *
154      * @param uri Indicates the path of the data to operate.
155      * @param value  Indicates the data record to insert. If this parameter is null, a blank row will be inserted.
156      *
157      * @return Returns the index of the inserted data record.
158      */
159     int Insert(Uri &uri, const NativeRdb::ValuesBucket &value);
160 
161     /**
162      * @brief Updates data records in the database.
163      *
164      * @param uri Indicates the path of data to update.
165      * @param value Indicates the data to update. This parameter can be null.
166      * @param predicates Indicates filter criteria. You should define the processing logic when this parameter is null.
167      *
168      * @return Returns the number of data records updated.
169      */
170     int Update(Uri &uri, const NativeRdb::ValuesBucket &value, const NativeRdb::DataAbilityPredicates &predicates);
171 
172     /**
173      * @brief Deletes one or more data records from the database.
174      *
175      * @param uri Indicates the path of the data to operate.
176      * @param predicates Indicates filter criteria. You should define the processing logic when this parameter is null.
177      *
178      * @return Returns the number of data records deleted.
179      */
180     int Delete(Uri &uri, const NativeRdb::DataAbilityPredicates &predicates);
181 
182     std::shared_ptr<AppExecFwk::PacMap> Call(
183         const Uri &uri, const std::string &method, const std::string &arg, const AppExecFwk::PacMap &pacMap);
184 
185     /**
186      * @brief Deletes one or more data records from the database.
187      *
188      * @param uri Indicates the path of data to query.
189      * @param columns Indicates the columns to query. If this parameter is null, all columns are queried.
190      * @param predicates Indicates filter criteria. You should define the processing logic when this parameter is null.
191      *
192      * @return Returns the query result.
193      */
194     std::shared_ptr<NativeRdb::AbsSharedResultSet> Query(
195         Uri &uri, std::vector<std::string> &columns, const NativeRdb::DataAbilityPredicates &predicates);
196 
197     /**
198      * @brief Obtains the MIME type matching the data specified by the URI of the Data ability. This method should be
199      * implemented by a Data ability. Data abilities supports general data types, including text, HTML, and JPEG.
200      *
201      * @param uri Indicates the URI of the data.
202      *
203      * @return Returns the MIME type that matches the data specified by uri.
204      */
205     std::string GetType(Uri &uri);
206 
207     /**
208      * @brief Reloads data in the database.
209      *
210      * @param uri Indicates the position where the data is to reload. This parameter is mandatory.
211      * @param extras Indicates the PacMap object containing the additional parameters to be passed in this call. This
212      * parameter can be null. If a custom Sequenceable object is put in the PacMap object and will be transferred across
213      * processes, you must call BasePacMap.setClassLoader(ClassLoader) to set a class loader for the custom object.
214      *
215      * @return Returns true if the data is successfully reloaded; returns false otherwise.
216      */
217     bool Reload(Uri &uri, const PacMap &extras);
218 
219     /**
220      * @brief Inserts multiple data records into the database.
221      *
222      * @param uri Indicates the path of the data to operate.
223      * @param values Indicates the data records to insert.
224      *
225      * @return Returns the number of data records inserted.
226      */
227     int BatchInsert(Uri &uri, const std::vector<NativeRdb::ValuesBucket> &values);
228 
229     /**
230      * @brief Registers an observer to DataObsMgr specified by the given Uri.
231      *
232      * @param uri, Indicates the path of the data to operate.
233      * @param dataObserver, Indicates the IDataAbilityObserver object.
234      */
235     void RegisterObserver(const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver);
236 
237     /**
238      * @brief Deregisters an observer used for DataObsMgr specified by the given Uri.
239      *
240      * @param uri, Indicates the path of the data to operate.
241      * @param dataObserver, Indicates the IDataAbilityObserver object.
242      */
243     void UnregisterObserver(const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver);
244 
245     /**
246      * @brief Notifies the registered observers of a change to the data resource specified by Uri.
247      *
248      * @param uri, Indicates the path of the data to operate.
249      */
250     void NotifyChange(const Uri &uri);
251 
252     /**
253      * @brief Converts the given uri that refer to the Data ability into a normalized URI. A normalized URI can be used
254      * across devices, persisted, backed up, and restored. It can refer to the same item in the Data ability even if the
255      * context has changed. If you implement URI normalization for a Data ability, you must also implement
256      * denormalizeUri(ohos.utils.net.Uri) to enable URI denormalization. After this feature is enabled, URIs passed to
257      * any method that is called on the Data ability must require normalization verification and denormalization. The
258      * default implementation of this method returns null, indicating that this Data ability does not support URI
259      * normalization.
260      *
261      * @param uri Indicates the Uri object to normalize.
262      *
263      * @return Returns the normalized Uri object if the Data ability supports URI normalization; returns null otherwise.
264      */
265     Uri NormalizeUri(Uri &uri);
266 
267     /**
268      * @brief Converts the given normalized uri generated by normalizeUri(ohos.utils.net.Uri) into a denormalized one.
269      * The default implementation of this method returns the original URI passed to it.
270      *
271      * @param uri uri Indicates the Uri object to denormalize.
272      *
273      * @return Returns the denormalized Uri object if the denormalization is successful; returns the original Uri passed
274      * to this method if there is nothing to do; returns null if the data identified by the original Uri cannot be found
275      * in the current environment.
276      */
277     Uri DenormalizeUri(Uri &uri);
278 
279     /**
280      * @brief Performs batch operations on the database.
281      *
282      * @param uri Indicates the path of data to operate.
283      * @param operations Indicates a list of database operations on the database.
284      * @return Returns the result of each operation, in array.
285      */
286     std::vector<std::shared_ptr<DataAbilityResult>> ExecuteBatch(
287         const Uri &uri, const std::vector<std::shared_ptr<DataAbilityOperation>> &operations);
288 
289 private:
290     DataAbilityHelperImpl(const std::shared_ptr<Context> &context, const std::shared_ptr<Uri> &uri,
291         const sptr<AAFwk::IAbilityScheduler> &dataAbilityProxy, bool tryBind = false);
292     DataAbilityHelperImpl(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context,
293         const std::shared_ptr<Uri> &uri, const sptr<AAFwk::IAbilityScheduler> &dataAbilityProxy, bool tryBind = false);
294     explicit DataAbilityHelperImpl(const std::shared_ptr<Context> &context);
295     DataAbilityHelperImpl(const sptr<IRemoteObject> &token, const std::shared_ptr<Uri> &uri,
296         const sptr<AAFwk::IAbilityScheduler> &dataAbilityProxy);
297     explicit DataAbilityHelperImpl(const sptr<IRemoteObject> &token);
298 
299     static bool CheckUri(const std::shared_ptr<Uri> &uri);
300 
301     void AddDataAbilityDeathRecipient(const sptr<IRemoteObject> &token);
302     void OnSchedulerDied(const wptr<IRemoteObject> &remote);
303 
304     bool CheckUriParam(const Uri &uri);
305     bool CheckOhosUri(const Uri &checkUri);
306 
307     sptr<AAFwk::IAbilityScheduler> GetDataAbilityProxy(const Uri &uri, bool addDeathRecipient = true);
308 
309     void ReleaseDataAbility(sptr<AAFwk::IAbilityScheduler> dataAbilityProxy);
310 
311     bool CheckUriAndDataObserver(const Uri &uri,
312         const sptr<AAFwk::IDataAbilityObserver> &dataObserver);
313 
314     sptr<IRemoteObject> token_;
315     std::weak_ptr<Context> context_;
316     std::shared_ptr<Uri> uri_ = nullptr;
317     bool tryBind_ = false;
318     bool isSystemCaller_ = false;
319     sptr<AAFwk::IAbilityScheduler> dataAbilityProxy_ = nullptr;
320     std::mutex lock_;
321     std::mutex oplock_;
322 
323     sptr<IRemoteObject::DeathRecipient> callerDeathRecipient_ = nullptr;  // caller binderDied Recipient
324     std::map<sptr<AAFwk::IDataAbilityObserver>, sptr<AAFwk::IAbilityScheduler>> registerMap_;
325     std::map<sptr<AAFwk::IDataAbilityObserver>, std::string> uriMap_;
326 };
327 
328 class DataAbilityDeathRecipient : public IRemoteObject::DeathRecipient {
329 public:
330     using RemoteDiedHandler = std::function<void(const wptr<IRemoteObject> &)>;
331 
332     explicit DataAbilityDeathRecipient(RemoteDiedHandler handler);
333 
334     virtual ~DataAbilityDeathRecipient();
335 
336     virtual void OnRemoteDied(const wptr<IRemoteObject> &remote);
337 
338 private:
339     RemoteDiedHandler handler_;
340 };
341 }  // namespace AppExecFwk
342 }  // namespace OHOS
343 #endif  // OHOS_ABILITY_RUNTIME_DATA_ABILITY_HELPER_IMPL_H
344