1 /*
2 * Copyright (c) 2023 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 "start_ability_sandbox_savefile.h"
17 #include <climits>
18 #include "hilog_wrapper.h"
19 #include "ability_manager_errors.h"
20 #include "ability_util.h"
21 #include "ability_manager_service.h"
22
23
24 namespace OHOS {
25 namespace AAFwk {
26 namespace {
27 const std::string DLP_BUNDLE_NAME = "com.ohos.dlpmanager";
28 const std::string DLP_ABILITY_NAME = "SaveAsAbility";
29 }
30 const std::string StartAbilitySandboxSavefile::handlerName_ = "start_ability_snadbox_savefile";
31
MatchStartRequest(StartAbilityParams & params)32 bool StartAbilitySandboxSavefile::MatchStartRequest(StartAbilityParams ¶ms)
33 {
34 if (params.IsCallerSandboxApp() && params.want.GetAction() == "ohos.want.action.CREATE_FILE" &&
35 params.want.GetStringParam("startMode") == "save") {
36 return true;
37 }
38
39 auto element = params.want.GetElement();
40 if (element.GetBundleName() == DLP_BUNDLE_NAME && element.GetAbilityName() == DLP_ABILITY_NAME &&
41 !ContainRecord(params.requestCode)) {
42 return true;
43 }
44 return false;
45 }
46
HandleStartRequest(StartAbilityParams & params)47 int StartAbilitySandboxSavefile::HandleStartRequest(StartAbilityParams ¶ms)
48 {
49 HILOG_DEBUG("called");
50 auto callerRecord = params.GetCallerRecord();
51 if (!callerRecord) {
52 HILOG_ERROR("this shouldn't happen: caller is null");
53 return ERR_INVALID_CALLER;
54 }
55
56 if (!params.SandboxExternalAuth()) {
57 HILOG_WARN("sandbox external auth failed");
58 return CHECK_PERMISSION_FAILED;
59 }
60
61 auto reqCode = PushRecord(params.requestCode, callerRecord);
62 auto &want = params.want;
63 want.SetElementName(DLP_BUNDLE_NAME, DLP_ABILITY_NAME);
64 want.SetParam("requestCode", reqCode);
65 want.SetParam("startMode", std::string("save_redirect"));
66
67 auto abilityMs = DelayedSingleton<AbilityManagerService>::GetInstance();
68 if (params.startOptions) {
69 return abilityMs->StartAbilityForOptionInner(want, *params.startOptions, params.callerToken, params.userId,
70 reqCode, params.isStartAsCaller);
71 }
72 return abilityMs->StartAbilityInner(want, params.callerToken, reqCode, params.userId,
73 params.isStartAsCaller);
74 }
75
GetHandlerName()76 std::string StartAbilitySandboxSavefile::GetHandlerName()
77 {
78 return StartAbilitySandboxSavefile::handlerName_;
79 }
80
PushRecord(int reqCode,const std::shared_ptr<AbilityRecord> & caller)81 int StartAbilitySandboxSavefile::PushRecord(int reqCode, const std::shared_ptr<AbilityRecord> &caller)
82 {
83 std::lock_guard guard(recordsMutex_);
84 requestCode_++;
85 if (requestCode_ >= INT_MAX) {
86 requestCode_ = 0;
87 }
88
89 auto it = fileSavingRecords_.find(requestCode_);
90 if (it != fileSavingRecords_.end()) {
91 HILOG_ERROR("repeated request code");
92 fileSavingRecords_.erase(it);
93 }
94
95 SaveFileRecord record{reqCode, caller};
96 fileSavingRecords_.emplace(requestCode_, record);
97 return requestCode_;
98 }
99
ContainRecord(int reqCode)100 bool StartAbilitySandboxSavefile::ContainRecord(int reqCode)
101 {
102 std::lock_guard guard(recordsMutex_);
103 return fileSavingRecords_.count(reqCode) > 0;
104 }
105
HandleResult(const Want & want,int resultCode,int requestCode)106 void StartAbilitySandboxSavefile::HandleResult(const Want &want, int resultCode, int requestCode)
107 {
108 std::shared_ptr<AbilityRecord> callerRecord;
109 int originReqCode = -1;
110 {
111 std::lock_guard guard(recordsMutex_);
112 auto it = fileSavingRecords_.find(requestCode);
113 if (it != fileSavingRecords_.end()) {
114 callerRecord = it->second.caller.lock();
115 originReqCode = it->second.originReqCode;
116 fileSavingRecords_.erase(it);
117 }
118 }
119 if (!callerRecord) {
120 HILOG_ERROR("request code not found: %{public}d.", requestCode);
121 return;
122 }
123 callerRecord->SendSandboxSavefileResult(want, resultCode, originReqCode);
124 }
125 } // namespace AAFwk
126 } // namespace OHOS