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 <condition_variable>
17 #include <cstdint>
18 #include <mutex>
19 #include "camera_app_manager_utils.h"
20 #include "camera_privacy.h"
21 #include "camera_log.h"
22 #include "hcamera_device.h"
23 #include "hcapture_session.h"
24 #include "ipc_skeleton.h"
25 #include "types.h"
26
27 namespace OHOS {
28 namespace CameraStandard {
29 using OHOS::Security::AccessToken::PrivacyKit;
30 using OHOS::Security::AccessToken::AccessTokenKit;
31
CastToSession(sptr<IStreamOperatorCallback> streamOpCb)32 sptr<HCaptureSession> CastToSession(sptr<IStreamOperatorCallback> streamOpCb)
33 {
34 if (streamOpCb == nullptr) {
35 return nullptr;
36 }
37 return static_cast<HCaptureSession*>(streamOpCb.GetRefPtr());
38 }
39
PermStateChangeCallback(Security::AccessToken::PermStateChangeInfo & result)40 void PermissionStatusChangeCb::PermStateChangeCallback(Security::AccessToken::PermStateChangeInfo& result)
41 {
42 MEDIA_INFO_LOG("enter PermissionStatusChangeNotify permStateChangeType:%{public}d"
43 " permissionName:%{public}s", result.permStateChangeType, result.permissionName.c_str());
44 auto device = cameraDevice_.promote();
45 if ((result.permStateChangeType == 0) && (device != nullptr)) {
46 auto session = CastToSession(device->GetStreamOperatorCallback());
47 if (session) {
48 session->ReleaseStreams();
49 session->StopMovingPhoto();
50 }
51 device->CloseDevice();
52 device->OnError(DEVICE_PREEMPT, 0);
53 }
54 }
55
StateChangeNotify(Security::AccessToken::AccessTokenID tokenId,bool isShowing)56 void CameraUseStateChangeCb::StateChangeNotify(Security::AccessToken::AccessTokenID tokenId, bool isShowing)
57 {
58 MEDIA_INFO_LOG("enter CameraUseStateChangeNotify");
59 auto device = cameraDevice_.promote();
60 CHECK_ERROR_RETURN_LOG((isShowing == true) || (device == nullptr), "abnormal callback from privacy.");
61 auto cameraPrivacy = device->GetCameraPrivacy();
62 CHECK_ERROR_RETURN_LOG(cameraPrivacy == nullptr, "cameraPrivacy is nullptr.");
63 if (cameraPrivacy->WaitFor() == std::cv_status::timeout) {
64 MEDIA_INFO_LOG("CameraUseStateChangeCb::StateChangeNotify wait timeout");
65 device = cameraDevice_.promote();
66 bool isForeground = CameraAppManagerUtils::IsForegroundApplication(tokenId);
67 if ((isShowing == false) && (device != nullptr) && !isForeground) {
68 auto session = CastToSession(device->GetStreamOperatorCallback());
69 if (session) {
70 session->ReleaseStreams();
71 session->StopMovingPhoto();
72 }
73 device->CloseDevice();
74 }
75 }
76 }
77
~CameraPrivacy()78 CameraPrivacy::~CameraPrivacy()
79 {
80 cameraUseCallbackPtr_ = nullptr;
81 permissionCallbackPtr_ = nullptr;
82 }
83
IsAllowUsingCamera()84 bool CameraPrivacy::IsAllowUsingCamera()
85 {
86 return PrivacyKit::IsAllowedUsingPermission(callerToken_, OHOS_PERMISSION_CAMERA);
87 }
88
RegisterPermissionCallback()89 bool CameraPrivacy::RegisterPermissionCallback()
90 {
91 Security::AccessToken::PermStateChangeScope scopeInfo;
92 scopeInfo.permList = {OHOS_PERMISSION_CAMERA};
93 scopeInfo.tokenIDs = {callerToken_};
94 int32_t res;
95 {
96 std::lock_guard<std::mutex> lock(permissionCbMutex_);
97 permissionCallbackPtr_ = std::make_shared<PermissionStatusChangeCb>(cameraDevice_, scopeInfo);
98 res = AccessTokenKit::RegisterPermStateChangeCallback(permissionCallbackPtr_);
99 }
100 MEDIA_INFO_LOG("CameraPrivacy::RegisterPermissionCallback res:%{public}d", res);
101 CHECK_ERROR_PRINT_LOG(res != CAMERA_OK, "RegisterPermissionCallback failed.");
102 return res == CAMERA_OK;
103 }
104
UnregisterPermissionCallback()105 void CameraPrivacy::UnregisterPermissionCallback()
106 {
107 std::lock_guard<std::mutex> lock(permissionCbMutex_);
108 CHECK_ERROR_RETURN_LOG(permissionCallbackPtr_ == nullptr, "permissionCallbackPtr_ is null.");
109 MEDIA_DEBUG_LOG("UnregisterPermissionCallback unregister");
110 int32_t res = AccessTokenKit::UnRegisterPermStateChangeCallback(permissionCallbackPtr_);
111 MEDIA_INFO_LOG("CameraPrivacy::UnregisterPermissionCallback res:%{public}d", res);
112 CHECK_ERROR_PRINT_LOG(res != CAMERA_OK, "UnregisterPermissionCallback failed.");
113 permissionCallbackPtr_ = nullptr;
114 }
115
AddCameraPermissionUsedRecord()116 bool CameraPrivacy::AddCameraPermissionUsedRecord()
117 {
118 int32_t successCout = 1;
119 int32_t failCount = 0;
120 int32_t res = PrivacyKit::AddPermissionUsedRecord(callerToken_, OHOS_PERMISSION_CAMERA, successCout, failCount);
121 MEDIA_INFO_LOG("CameraPrivacy::AddCameraPermissionUsedRecord res:%{public}d", res);
122 CHECK_ERROR_PRINT_LOG(res != CAMERA_OK, "AddCameraPermissionUsedRecord failed.");
123 return res == CAMERA_OK;
124 }
125
StartUsingPermissionCallback()126 bool CameraPrivacy::StartUsingPermissionCallback()
127 {
128 int32_t res;
129 {
130 std::lock_guard<std::mutex> lock(cameraUseCbMutex_);
131 CHECK_ERROR_RETURN_RET_LOG(cameraUseCallbackPtr_, true, "has StartUsingPermissionCallback!");
132 cameraUseCallbackPtr_ = std::make_shared<CameraUseStateChangeCb>(cameraDevice_);
133 res = PrivacyKit::StartUsingPermission(callerToken_, OHOS_PERMISSION_CAMERA, cameraUseCallbackPtr_, pid_);
134 }
135 MEDIA_INFO_LOG("CameraPrivacy::StartUsingPermissionCallback res:%{public}d", res);
136 bool ret = (res == CAMERA_OK || res == Security::AccessToken::ERR_EDM_POLICY_CHECK_FAILED ||
137 res == Security::AccessToken::ERR_PRIVACY_POLICY_CHECK_FAILED);
138 CHECK_ERROR_PRINT_LOG(!ret, "StartUsingPermissionCallback failed.");
139 return ret;
140 }
141
StopUsingPermissionCallback()142 void CameraPrivacy::StopUsingPermissionCallback()
143 {
144 {
145 std::lock_guard<std::mutex> lock(cameraUseCbMutex_);
146 int32_t res = PrivacyKit::StopUsingPermission(callerToken_, OHOS_PERMISSION_CAMERA, pid_);
147 MEDIA_INFO_LOG("CameraPrivacy::StopUsingPermissionCallback res:%{public}d", res);
148 CHECK_ERROR_PRINT_LOG(res != CAMERA_OK, "StopUsingPermissionCallback failed.");
149 cameraUseCallbackPtr_ = nullptr;
150 }
151 Notify();
152 }
153 } // namespace CameraStandard
154 } // namespace OHOS