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 #ifndef CAMERA_PICKER_NAPI_H 17 #define CAMERA_PICKER_NAPI_H 18 19 #include <atomic> 20 #include <memory> 21 #include <cstdint> 22 23 #include "ability_context.h" 24 #include "camera_device.h" 25 #include "camera_napi_utils.h" 26 #include "context.h" 27 #include "ui_content.h" 28 #include "ui_extension_base/ui_extension_context.h" 29 #include "napi_ref_manager.h" 30 31 namespace OHOS { 32 namespace CameraStandard { 33 34 typedef struct { 35 std::string saveUri; 36 CameraPosition cameraPosition; 37 int videoDuration; 38 } PickerProfile; 39 40 enum class PickerContextType : uint32_t { UNKNOWN, UI_EXTENSION, ABILITY }; 41 struct PickerContextProxy { PickerContextProxyPickerContextProxy42 PickerContextProxy(std::shared_ptr<AbilityRuntime::Context> context) : mContext_(context) 43 { 44 if (AbilityRuntime::Context::ConvertTo<AbilityRuntime::UIExtensionContext>(context) != nullptr) { 45 type_ = PickerContextType::UI_EXTENSION; 46 } else if (AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context) != nullptr) { 47 type_ = PickerContextType::ABILITY; 48 } else { 49 type_ = PickerContextType::UNKNOWN; 50 } 51 } 52 GetTypePickerContextProxy53 PickerContextType GetType() 54 { 55 return type_; 56 } 57 GetBundleNamePickerContextProxy58 std::string GetBundleName() 59 { 60 auto context = mContext_.lock(); 61 if (context != nullptr) { 62 return context->GetBundleName(); 63 } 64 return ""; 65 } 66 GetUIContentPickerContextProxy67 Ace::UIContent* GetUIContent() 68 { 69 auto uiContext = mContext_.lock(); 70 if (uiContext == nullptr) { 71 return nullptr; 72 } 73 switch (type_) { 74 case PickerContextType::UI_EXTENSION: { 75 auto ctx = AbilityRuntime::Context::ConvertTo<AbilityRuntime::UIExtensionContext>(uiContext); 76 if (ctx != nullptr) { 77 return ctx->GetUIContent(); 78 } 79 break; 80 } 81 case PickerContextType::ABILITY: { 82 auto ctx = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(uiContext); 83 if (ctx != nullptr) { 84 return ctx->GetUIContent(); 85 } 86 break; 87 } 88 default: 89 // Do nothing 90 break; 91 } 92 return nullptr; 93 } 94 95 private: 96 std::weak_ptr<AbilityRuntime::Context> mContext_; 97 PickerContextType type_ = PickerContextType::UNKNOWN; 98 }; 99 100 enum class PickerMediaType : uint32_t { PHOTO, VIDEO }; 101 102 class UIExtensionCallback { 103 public: 104 explicit UIExtensionCallback(std::shared_ptr<PickerContextProxy> contextProxy); 105 void OnRelease(int32_t releaseCode); 106 void OnResult(int32_t resultCode, const OHOS::AAFwk::Want& result); 107 void OnReceive(const OHOS::AAFwk::WantParams& request); 108 void OnError(int32_t code, const std::string& name, const std::string& message); 109 void OnRemoteReady(const std::shared_ptr<OHOS::Ace::ModalUIExtensionProxy>& uiProxy); 110 void CloseWindow(); 111 void OnDestroy(); 112 WaitResultLock()113 inline void WaitResultLock() 114 { 115 std::unique_lock<std::mutex> lock(cbMutex_); 116 while (!isCallbackReturned_) { 117 cbFinishCondition_.wait(lock); 118 } 119 } 120 SetSessionId(int32_t sessionId)121 inline void SetSessionId(int32_t sessionId) 122 { 123 sessionId_ = sessionId; 124 } 125 NotifyResultLock()126 inline void NotifyResultLock() 127 { 128 std::unique_lock<std::mutex> lock(cbMutex_); 129 cbFinishCondition_.notify_one(); 130 } 131 GetResultMediaType()132 inline std::string GetResultMediaType() 133 { 134 if (resultMode_ == "VIDEO") { 135 return "video"; 136 } 137 return "photo"; 138 } 139 GetResultCode()140 inline int32_t GetResultCode() 141 { 142 return resultCode_; 143 } 144 GetResultUri()145 inline std::string GetResultUri() 146 { 147 return resultUri_; 148 } 149 150 private: 151 bool FinishPicker(int32_t code); 152 int32_t sessionId_ = 0; 153 int32_t resultCode_ = 0; 154 std::string resultMode_ = ""; 155 std::string resultUri_ = ""; 156 std::shared_ptr<PickerContextProxy> contextProxy_; 157 std::condition_variable cbFinishCondition_; 158 std::mutex cbMutex_; 159 bool isCallbackReturned_ = false; 160 }; 161 162 class CameraPickerNapi { 163 public: 164 static napi_value Init(napi_env env, napi_value exports); 165 static napi_value CreatePickerMediaType(napi_env env); 166 static napi_value CreatePickerProfile(napi_env env); 167 static napi_value CreatePickerResult(napi_env env); 168 169 static napi_value Pick(napi_env env, napi_callback_info info); 170 171 static napi_value CameraPickerNapiConstructor(napi_env env, napi_callback_info info); 172 static void CameraPickerNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint); 173 174 private: 175 static thread_local uint32_t cameraPickerTaskId; 176 static thread_local napi_ref sConstructor_; 177 static thread_local napi_ref mediaTypeRef_; 178 }; 179 180 struct CameraPickerAsyncContext : public AsyncContext { 181 std::string resultUri; 182 std::string errorMsg; 183 PickerProfile pickerProfile; 184 AAFwk::Want want; 185 std::shared_ptr<PickerContextProxy> contextProxy; 186 std::shared_ptr<UIExtensionCallback> uiExtCallback; 187 int32_t resultCode; 188 bool bRetBool; 189 }; 190 } // namespace CameraStandard 191 } // namespace OHOS 192 193 #endif /* CAMERA_PICKER_NAPI_H */ 194