• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "display_manager.h"
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 const std::string DLP_INDEX = "ohos.dlp.params.index";
30 
31 class EmptyConnection : public IRemoteStub<IAbilityConnection> {
32 public:
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)33     void OnAbilityConnectDone(const AppExecFwk::ElementName &element,
34         const sptr<IRemoteObject> &remoteObject, int resultCode) override
35     {
36         HILOG_DEBUG("OnAbilityConnectDone");
37     }
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)38     void OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) override
39     {
40         HILOG_DEBUG("OnAbilityDisconnectDone");
41     }
42 };
43 }
44 const std::string StartAbilitySandboxSavefile::handlerName_ = "start_ability_snadbox_savefile";
45 
MatchStartRequest(StartAbilityParams & params)46 bool StartAbilitySandboxSavefile::MatchStartRequest(StartAbilityParams &params)
47 {
48     if (params.IsCallerSandboxApp() && params.want.GetAction() == "ohos.want.action.CREATE_FILE" &&
49         params.want.GetStringParam("startMode") == "save") {
50         return true;
51     }
52 
53     auto element = params.want.GetElement();
54     if (element.GetBundleName() == DLP_BUNDLE_NAME && element.GetAbilityName() == DLP_ABILITY_NAME &&
55         !ContainRecord(params.requestCode)) {
56         return true;
57     }
58     return false;
59 }
60 
HandleStartRequest(StartAbilityParams & params)61 int StartAbilitySandboxSavefile::HandleStartRequest(StartAbilityParams &params)
62 {
63     HILOG_DEBUG("called");
64     auto callerRecord = params.GetCallerRecord();
65     if (!callerRecord) {
66         HILOG_ERROR("this shouldn't happen: caller is null");
67         return ERR_INVALID_CALLER;
68     }
69 
70     if (!params.SandboxExternalAuth()) {
71         HILOG_WARN("sandbox external auth failed");
72         return CHECK_PERMISSION_FAILED;
73     }
74 
75     auto reqCode = PushRecord(params.requestCode, callerRecord);
76     auto &want = params.want;
77     want.SetElementName(DLP_BUNDLE_NAME, DLP_ABILITY_NAME);
78     want.SetParam("requestCode", reqCode);
79     want.SetParam("startMode", std::string("save_redirect"));
80 
81     return StartAbility(params, reqCode);
82 }
83 
StartAbility(StartAbilityParams & params,int requestCode)84 int StartAbilitySandboxSavefile::StartAbility(StartAbilityParams &params, int requestCode)
85 {
86     AbilityRequest abilityRequest;
87     abilityRequest.callType = AbilityCallType::CALL_REQUEST_TYPE;
88     abilityRequest.callerUid = IPCSkeleton::GetCallingUid();
89     abilityRequest.callerToken = params.callerToken;
90     abilityRequest.startSetting = nullptr;
91     abilityRequest.want = params.want;
92     abilityRequest.connect = sptr<IAbilityConnection>(new EmptyConnection());
93 
94     auto abilityMs = DelayedSingleton<AbilityManagerService>::GetInstance();
95     auto ret = abilityMs->GenerateAbilityRequest(params.want, requestCode,
96         abilityRequest, params.callerToken, params.GetValidUserId());
97     if (ret != ERR_OK) {
98         HILOG_ERROR("Generate ability request error.");
99         return ret;
100     }
101 
102     if (params.startOptions) {
103         if (params.startOptions->GetDisplayID() == 0) {
104             abilityRequest.want.SetParam(Want::PARAM_RESV_DISPLAY_ID,
105                 static_cast<int32_t>(Rosen::DisplayManager::GetInstance().GetDefaultDisplayId()));
106         } else {
107             abilityRequest.want.SetParam(Want::PARAM_RESV_DISPLAY_ID, params.startOptions->GetDisplayID());
108         }
109         abilityRequest.want.SetParam(Want::PARAM_RESV_WINDOW_MODE, params.startOptions->GetWindowMode());
110     }
111 
112     return abilityMs->StartAbilityJust(abilityRequest, params.GetValidUserId());
113 }
114 
GetHandlerName()115 std::string StartAbilitySandboxSavefile::GetHandlerName()
116 {
117     return StartAbilitySandboxSavefile::handlerName_;
118 }
119 
PushRecord(int reqCode,const std::shared_ptr<AbilityRecord> & caller)120 int StartAbilitySandboxSavefile::PushRecord(int reqCode, const std::shared_ptr<AbilityRecord> &caller)
121 {
122     std::lock_guard guard(recordsMutex_);
123     requestCode_++;
124     if (requestCode_ >= INT_MAX) {
125         requestCode_ = 0;
126     }
127 
128     auto it = fileSavingRecords_.find(requestCode_);
129     if (it != fileSavingRecords_.end()) {
130         HILOG_ERROR("repeated request code");
131         fileSavingRecords_.erase(it);
132     }
133 
134     SaveFileRecord record{reqCode, caller};
135     fileSavingRecords_.emplace(requestCode_, record);
136     return requestCode_;
137 }
138 
ContainRecord(int reqCode)139 bool StartAbilitySandboxSavefile::ContainRecord(int reqCode)
140 {
141     std::lock_guard guard(recordsMutex_);
142     return fileSavingRecords_.count(reqCode) > 0;
143 }
144 
HandleResult(const Want & want,int resultCode,int requestCode)145 void StartAbilitySandboxSavefile::HandleResult(const Want &want, int resultCode, int requestCode)
146 {
147     std::shared_ptr<AbilityRecord> callerRecord;
148     int originReqCode = -1;
149     {
150         std::lock_guard guard(recordsMutex_);
151         auto it = fileSavingRecords_.find(requestCode);
152         if (it != fileSavingRecords_.end()) {
153             callerRecord = it->second.caller.lock();
154             originReqCode = it->second.originReqCode;
155             fileSavingRecords_.erase(it);
156         }
157     }
158     if (!callerRecord) {
159         HILOG_ERROR("request code not found: %{public}d.", requestCode);
160         return;
161     }
162     callerRecord->SendSandboxSavefileResult(want, resultCode, originReqCode);
163 }
164 } // namespace AAFwk
165 } // namespace OHOS