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 "connection/screen_snapshot_picker_connection.h"
17 
18 #include "window_manager_hilog.h"
19 
20 namespace OHOS::Rosen {
21 constexpr int32_t TRANS_CMD_SEND_SNAPSHOT_RECT = 2;
22 constexpr int32_t RES_FAILURE = -1;
23 constexpr int32_t RES_SUCCESS = 0;
24 constexpr int32_t RES_FAILURE_FOR_PRIVACY_WINDOW = -2;
25 constexpr uint32_t ERRCODE_RECV_PRIVACY_WINDOW = 1;
26 
GetInstance()27 ScreenSnapshotPickerConnection &ScreenSnapshotPickerConnection::GetInstance()
28 {
29     static ScreenSnapshotPickerConnection screenSnapshotPickerConnection;
30     return screenSnapshotPickerConnection;
31 }
32 
SnapshotPickerConnectExtension()33 bool ScreenSnapshotPickerConnection::SnapshotPickerConnectExtension()
34 {
35     if (bundleName_.empty() || abilityName_.empty()) {
36         TLOGE(WmsLogTag::DMS, "screen snapshot bundleName or abilityName is empty");
37         return false;
38     }
39     TLOGI(WmsLogTag::DMS, "bundleName:%{public}s, abilityName:%{public}s",
40         bundleName_.c_str(), abilityName_.c_str());
41     if (abilityConnection_ != nullptr) {
42         TLOGI(WmsLogTag::DMS, "screen snapshot already connected");
43         return true;
44     }
45     abilityConnection_ = std::make_unique<ScreenSessionAbilityConnection>();
46     if (abilityConnection_ == nullptr) {
47         TLOGE(WmsLogTag::DMS, "connection is nullptr");
48         return false;
49     }
50     bool ret = abilityConnection_->ScreenSessionConnectExtension(bundleName_, abilityName_);
51     if (!ret) {
52         TLOGE(WmsLogTag::DMS, "ScreenSessionConnectExtension failed");
53         return false;
54     }
55     TLOGI(WmsLogTag::DMS, "SnapshotPickerConnectExtension succeed");
56     return true;
57 }
58 
GetScreenSnapshotInfo(Media::Rect & rect,ScreenId & screenId)59 int32_t ScreenSnapshotPickerConnection::GetScreenSnapshotInfo(Media::Rect &rect, ScreenId &screenId)
60 {
61     MessageParcel data;
62     MessageParcel reply;
63 
64     if (abilityConnection_ == nullptr) {
65         TLOGE(WmsLogTag::DMS, "ability connection is nullptr");
66         return RES_FAILURE;
67     }
68 
69     if (abilityConnection_->GetScreenSessionAbilityConnectionStub() == nullptr) {
70         TLOGE(WmsLogTag::DMS, "ScreenSessionAbilityConnectionStud is nullptr");
71         return RES_FAILURE;
72     }
73 
74     if (!data.WriteInterfaceToken(GetScreenSessionAbilityConnectionStub()->GetDescriptor())) {
75         TLOGE(WmsLogTag::DMS, "WriteInterfaceToken failed");
76         return RES_FAILURE;
77     }
78 
79     if (!data.WriteRemoteObject(abilityConnection_->GetScreenSessionAbilityConnectionStub()->AsObject())) {
80         TLOGE(WmsLogTag::DMS, "WriteRemoteObject failed");
81         return RES_FAILURE;
82     }
83     int32_t ret = abilityConnection_->SendMessageBlock(TRANS_CMD_SEND_SNAPSHOT_RECT, data, reply);
84     if (ret != ERR_OK) {
85         TLOGE(WmsLogTag::DMS, "send message failed");
86         return RES_FAILURE;
87     }
88 
89     //Screenshot privacy window returns error
90     if (GetScreenSessionAbilityConnectionStub()->GetErrCode() == ERRCODE_RECV_PRIVACY_WINDOW) {
91         GetScreenSessionAbilityConnectionStub()->EraseErrCode();
92         return RES_FAILURE_FOR_PRIVACY_WINDOW;
93     }
94 
95     screenId = static_cast<ScreenId>(GetScreenSessionAbilityConnectionStub()->GetScreenId());
96     rect.left = GetScreenSessionAbilityConnectionStub()->GetLeft();
97     rect.top = GetScreenSessionAbilityConnectionStub()->GetTop();
98     rect.width = GetScreenSessionAbilityConnectionStub()->GetWidth();
99     rect.height = GetScreenSessionAbilityConnectionStub()->GetHeight();
100 
101     TLOGI(WmsLogTag::DMS, "snapshot area info screenId:%{public}" PRIu64", \
102         left:%{public}d, top:%{public}d, width:%{public}d, height:%{public}d",
103         screenId, rect.left, rect.top, rect.width, rect.height);
104 
105     return RES_SUCCESS;
106 }
107 
SnapshotPickerDisconnectExtension()108 void ScreenSnapshotPickerConnection::SnapshotPickerDisconnectExtension()
109 {
110     if (abilityConnection_ == nullptr) {
111         TLOGE(WmsLogTag::DMS, "ability connect failed");
112         return;
113     }
114 
115     abilityConnection_->ScreenSessionDisconnectExtension();
116     abilityConnection_ = nullptr;
117     TLOGI(WmsLogTag::DMS, "SnapshotPickerDisconnectExtension exit");
118 }
119 
GetScreenSessionAbilityConnectionStub()120 sptr<ScreenSessionAbilityConnectionStub> ScreenSnapshotPickerConnection::GetScreenSessionAbilityConnectionStub()
121 {
122     return abilityConnection_->GetScreenSessionAbilityConnectionStub();
123 }
124 
SetBundleName(const std::string & bundleName)125 void ScreenSnapshotPickerConnection::SetBundleName(const std::string &bundleName)
126 {
127     bundleName_ = bundleName;
128 }
129 
SetAbilityName(const std::string & abilityName)130 void ScreenSnapshotPickerConnection::SetAbilityName(const std::string &abilityName)
131 {
132     abilityName_ = abilityName;
133 }
134 } // namespace OHOS::Rosen