1/*
2 * Copyright (c) 2021-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 "operation.h"
17#include "operation_builder.h"
18#include "parcel_macro_base.h"
19using namespace OHOS::AppExecFwk;
20namespace OHOS {
21namespace AAFwk {
22Operation::Operation() : flags_(0), uri_("")
23{
24}
25
26Operation::Operation(const Operation &other) : flags_(0), uri_(other.uri_.ToString())
27{
28    flags_ = other.flags_;
29    action_ = other.action_;
30    deviceId_ = other.deviceId_;
31    entities_ = other.entities_;
32    bundleName_ = other.bundleName_;
33    abilityName_ = other.abilityName_;
34    moduleName_ = other.moduleName_;
35}
36
37Operation::~Operation()
38{}
39
40/**
41 * @description: Obtains the value of the abilityName attribute included in this Operation.
42 * @return Returns the ability name included in this Operation.
43 */
44std::string Operation::GetAbilityName() const
45{
46    return abilityName_;
47}
48
49/**
50 * @description: Obtains the value of the action attribute included in this Operation.
51 * @return Returns the action included in this Operation.
52 */
53std::string Operation::GetAction() const
54{
55    return action_;
56}
57/**
58 * @description: Sets a bundle name in this Want.
59 * If a bundle name is specified in a Want, the Want will match only
60 * the abilities in the specified bundle. You cannot use this method and
61 * setPicker(ohos.aafwk.content.Want) on the same Want.
62 * @param bundleName Indicates the bundle name to set.
63 * @return Returns a Want object containing the specified bundle name.
64 */
65void Operation::SetBundleName(const std::string &bundleName)
66{
67    bundleName_ = bundleName;
68}
69/**
70 * @description: Obtains the value of the bundleName attribute included in this Operation.
71 * @return Returns the bundle name included in this Operation.
72 */
73std::string Operation::GetBundleName() const
74{
75    return bundleName_;
76}
77
78/**
79 * @description: Obtains the value of the deviceId attribute included in this Operation.
80 * @return Returns the device ID included in this Operation.
81 */
82std::string Operation::GetDeviceId() const
83{
84    return deviceId_;
85}
86
87/**
88 * @description: Obtains the value of the entities attribute included in this Operation.
89 * @return Returns the entities included in this Operation.
90 */
91const std::vector<std::string> &Operation::GetEntities() const
92{
93    return entities_;
94}
95
96std::string Operation::GetModuleName() const
97{
98    return moduleName_;
99}
100
101/**
102 * @description: Adds the description of an entity to a Want
103 * @param entity Indicates the entity description to add
104 * @return Returns this Want object containing the entity.
105 */
106void Operation::AddEntity(const std::string &entity)
107{
108    if (!HasEntity(entity)) {
109        entities_.emplace_back(entity);
110    }
111}
112
113/**
114 * @description: Removes the description of an entity from a Want
115 * @param entity Indicates the entity description to remove.
116 * @return void
117 */
118void Operation::RemoveEntity(const std::string &entity)
119{
120    if (!entities_.empty()) {
121        auto it = std::find(entities_.begin(), entities_.end(), entity);
122        if (it != entities_.end()) {
123            entities_.erase(it);
124        }
125    }
126}
127
128/**
129 * @description: Checks whether a Want contains the given entity
130 * @param entity Indicates the entity to check
131 * @return Returns true if the given entity is contained; returns false otherwise
132 */
133bool Operation::HasEntity(const std::string &entity) const
134{
135    return std::find(entities_.begin(), entities_.end(), entity) != entities_.end();
136}
137
138/**
139 * @description: Obtains the number of entities in a Want
140 * @return Returns the entity quantity
141 */
142int Operation::CountEntities() const
143{
144    return entities_.size();
145}
146/**
147 * @description: Obtains the value of the flags attribute included in this Operation.
148 * @return Returns the flags included in this Operation.
149 */
150unsigned int Operation::GetFlags() const
151{
152    return flags_;
153}
154
155/**
156 * @description: Sets a flag in a Want.
157 * @param flags Indicates the flag to set.
158 * @return Returns this Want object containing the flag.
159 */
160void Operation::SetFlags(unsigned int flags)
161{
162    flags_ = flags;
163}
164/**
165 * @description: Adds a flag to a Want.
166 * @param flags Indicates the flag to add.
167 * @return Returns the Want object with the added flag.
168 */
169void Operation::AddFlags(unsigned int flags)
170{
171    flags_ |= flags;
172}
173
174/**
175 * @description: Removes the description of a flag from a Want.
176 * @param flags Indicates the flag to remove.
177 * @return Removes the description of a flag from a Want.
178 */
179void Operation::RemoveFlags(unsigned int flags)
180{
181    flags_ &= ~flags;
182}
183
184/**
185 * @description: Obtains the value of the uri attribute included in this Operation.
186 * @return Returns the URI included in this Operation.
187 */
188Uri Operation::GetUri() const
189{
190    return uri_;
191}
192
193bool Operation::operator==(const Operation &other) const
194{
195    if (abilityName_ != other.abilityName_) {
196        return false;
197    }
198    if (action_ != other.action_) {
199        return false;
200    }
201    if (bundleName_ != other.bundleName_) {
202        return false;
203    }
204    if (deviceId_ != other.deviceId_) {
205        return false;
206    }
207    if (moduleName_ != other.moduleName_) {
208        return false;
209    }
210
211    size_t entitiesCount = entities_.size();
212    size_t otherEntitiesCount = other.entities_.size();
213    if (entitiesCount != otherEntitiesCount) {
214        return false;
215    } else {
216        for (size_t i = 0; i < entitiesCount; i++) {
217            if (entities_[i] != other.entities_[i]) {
218                return false;
219            }
220        }
221    }
222    if (flags_ != other.flags_) {
223        return false;
224    }
225    if (uri_.ToString() != other.uri_.ToString()) {
226        return false;
227    }
228    return true;
229}
230
231Operation &Operation::operator=(const Operation &other)
232{
233    if (this != &other) {
234        uri_ = other.uri_;
235        flags_ = other.flags_;
236        action_ = other.action_;
237        deviceId_ = other.deviceId_;
238        entities_ = other.entities_;
239        bundleName_ = other.bundleName_;
240        abilityName_ = other.abilityName_;
241        moduleName_ = other.moduleName_;
242    }
243    return *this;
244}
245
246bool Operation::Marshalling(Parcel &parcel) const
247{
248    WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(abilityName_));
249    WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(action_));
250    WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(bundleName_));
251    WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(deviceId_));
252    WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(StringVector, parcel, entities_);
253    WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, flags_);
254
255    Uri uri("");
256    if (uri_ == uri) {
257        WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, VALUE_NULL);
258    } else {
259        if (!parcel.WriteInt32(VALUE_OBJECT)) {
260            return false;
261        }
262        if (!parcel.WriteParcelable(&uri_)) {
263            return false;
264        }
265    }
266    return true;
267}
268
269Operation *Operation::Unmarshalling(Parcel &parcel)
270{
271    Operation *operation = new (std::nothrow) Operation();
272    if (operation != nullptr && !operation->ReadFromParcel(parcel)) {
273        delete operation;
274        operation = nullptr;
275    }
276
277    return operation;
278}
279
280bool Operation::ReadFromParcel(Parcel &parcel)
281{
282    std::u16string readString16;
283    READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, readString16);
284    abilityName_ = Str16ToStr8(readString16);
285    readString16.clear();
286
287    READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, readString16);
288    action_ = Str16ToStr8(readString16);
289    readString16.clear();
290
291    READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, readString16);
292    bundleName_ = Str16ToStr8(readString16);
293    readString16.clear();
294
295    READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, readString16);
296    deviceId_ = Str16ToStr8(readString16);
297    readString16.clear();
298
299    READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(StringVector, parcel, &entities_);
300    READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, flags_);
301
302    // uri_
303    int32_t empty = VALUE_NULL;
304    if (!parcel.ReadInt32(empty)) {
305        return false;
306    }
307
308    if (empty == VALUE_OBJECT) {
309        auto uri = parcel.ReadParcelable<Uri>();
310        if (uri != nullptr) {
311            uri_ = *uri;
312            delete uri;
313            uri = nullptr;
314        } else {
315            return false;
316        }
317    }
318    return true;
319}
320
321/**
322 * @description: Sets a uri in this operation.
323 * @param uri Indicates uri object to set.
324 * @return -
325 */
326void Operation::SetUri(const Uri &uri)
327{
328    uri_ = uri;
329}
330
331/**
332 * @description: Returns a uri in this operation.
333 * @param uri Indicates uri object to set.
334 * @return Returns a uri in this operation.
335 */
336Uri &Operation::GetUri(const Uri &uri)
337{
338    return uri_;
339}
340
341/**
342 * @description: Sets the value of the abilityName attribute included in this Operation.
343 * @param abilityname
344 * @return -
345 */
346void Operation::SetAbilityName(const std::string &abilityname)
347{
348    abilityName_ = abilityname;
349}
350/**
351 * @description: Sets the value of the deviceId attribute included in this Operation.
352 * @param  deviceid
353 * @return -
354 */
355void Operation::SetDeviceId(const std::string &deviceid)
356{
357    deviceId_ = deviceid;
358}
359
360/**
361 * @description: Sets the value of the action attribute included in this Operation.
362 * @param deviceid Indicates deviceid object to set.
363 * @return -
364 */
365void Operation::SetAction(const std::string &action)
366{
367    action_ = action;
368}
369
370/**
371 * @description: Sets the entities of this Operation.
372 * @param entities Indicates entities to set.
373 * @return -
374 */
375void Operation::SetEntities(const std::vector<std::string> &entities)
376{
377    entities_.clear();
378    entities_ = entities;
379}
380
381void Operation::SetModuleName(const std::string &moduleName)
382{
383    moduleName_ = moduleName;
384}
385
386void Operation::DumpInfo(int level) const
387{
388    ABILITYBASE_LOGI("===Operation::abilityName_ %{public}s =============", abilityName_.c_str());
389    ABILITYBASE_LOGI("===Operation::action_ %{public}s =============", action_.c_str());
390    ABILITYBASE_LOGI("===Operation::bundleName_ %{public}s =============", bundleName_.c_str());
391    ABILITYBASE_LOGI("===Operation::moduleName_ %{public}s =============", moduleName_.c_str());
392    size_t entities_count = entities_.size();
393    ABILITYBASE_LOGI("===Operation::entities_: count %{public}u =============", (uint32_t)entities_count);
394    for (size_t i = 0; i < entities_count; i++) {
395        ABILITYBASE_LOGI("=Operation::entities_[%{public}u]: %{public}s =============", (uint32_t)i,
396            entities_[i].c_str());
397    }
398    ABILITYBASE_LOGI("===Operation::flags_ %{public}ud =============", flags_);
399    ABILITYBASE_LOGI("===Operation::uri_ %{public}s =============", uri_.ToString().c_str());
400}
401}  // namespace AAFwk
402}  // namespace OHOS