已合并
fix bug #20216
xhz-sz创建于 19 天前
fix bug #20216
已合并
共 15 个文件变更+679-96
| @@ -90,6 +90,10 @@ void JsPreloadUIExtensionCallbackClient::ProcessOnDestroyDone(int32_t extensionA | |||
| 90 | 90 | ||
| 91 | void JsPreloadUIExtensionCallbackClient::CallJsPreloadedUIExtensionAbility(int32_t preloadId) | 91 | void JsPreloadUIExtensionCallbackClient::CallJsPreloadedUIExtensionAbility(int32_t preloadId) |
| 92 | { | 92 | { |
| 93 | + if (env_ == nullptr) { | ||
| 94 | + TAG_LOGE(AAFwkTag::ABILITYMGR, "null env_"); | ||
| 95 | + return; | ||
| 96 | + } | ||
| 93 | HandleScope handleScope(env_); | 97 | HandleScope handleScope(env_); |
| 94 | if (callbackRef_ == nullptr) { | 98 | if (callbackRef_ == nullptr) { |
| 95 | TAG_LOGE(AAFwkTag::ABILITYMGR, "null callbackRef_"); | 99 | TAG_LOGE(AAFwkTag::ABILITYMGR, "null callbackRef_"); |
| @@ -1133,6 +1133,26 @@ bool JsUIExtensionContext::CheckConnectAlreadyExist(napi_env env, AAFwk::Want& w | |||
| 1133 | return true; | 1133 | return true; |
| 1134 | } | 1134 | } |
| 1135 | 1135 | ||
| 1136 | +static sptr<JSUIServiceUIExtConnection> CreateUIServiceExtConnection(napi_env env, AAFwk::Want& want) | ||
| 1137 | +{ | ||
| 1138 | + sptr<JSUIServiceUIExtConnection> connection = sptr<JSUIServiceUIExtConnection>::MakeSptr(env); | ||
| 1139 | + if (connection == nullptr) { | ||
| 1140 | + TAG_LOGE(AAFwkTag::UISERVC_EXT, "null connection"); | ||
| 1141 | + ThrowError(env, static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER), | ||
| 1142 | + GetInnerErrorMsg(AbilityInnerErrorMsg::MEMORY_ALLOC_FAILED)); | ||
| 1143 | + return nullptr; | ||
| 1144 | + } | ||
| 1145 | + sptr<UIExtensionServiceHostStubImpl> stub = connection->GetServiceHostStub(); | ||
| 1146 | + if (stub == nullptr) { | ||
| 1147 | + TAG_LOGE(AAFwkTag::UISERVC_EXT, "null service host stub"); | ||
| 1148 | + ThrowError(env, static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER), | ||
| 1149 | + GetInnerErrorMsg(AbilityInnerErrorMsg::MEMORY_ALLOC_FAILED)); | ||
| 1150 | + return nullptr; | ||
| 1151 | + } | ||
| 1152 | + want.SetParam(UISERVICEHOSTPROXY_KEY, stub->AsObject()); | ||
| 1153 | + return connection; | ||
| 1154 | +} | ||
| 1155 | + | ||
| 1136 | napi_value JsUIExtensionContext::OnConnectUIServiceExtension(napi_env env, NapiCallbackInfo& info) | 1156 | napi_value JsUIExtensionContext::OnConnectUIServiceExtension(napi_env env, NapiCallbackInfo& info) |
| 1137 | { | 1157 | { |
| 1138 | TAG_LOGI(AAFwkTag::UISERVC_EXT, "called"); | 1158 | TAG_LOGI(AAFwkTag::UISERVC_EXT, "called"); |
| @@ -1153,9 +1173,10 @@ napi_value JsUIExtensionContext::OnConnectUIServiceExtension(napi_env env, NapiC | |||
| 1153 | return result; | 1173 | return result; |
| 1154 | } | 1174 | } |
| 1155 | 1175 | ||
| 1156 | - sptr<JSUIServiceUIExtConnection> connection = sptr<JSUIServiceUIExtConnection>::MakeSptr(env); | 1176 | + sptr<JSUIServiceUIExtConnection> connection = CreateUIServiceExtConnection(env, want); |
| 1157 | - sptr<UIExtensionServiceHostStubImpl> stub = connection->GetServiceHostStub(); | 1177 | + if (connection == nullptr) { |
| 1158 | - want.SetParam(UISERVICEHOSTPROXY_KEY, stub->AsObject()); | 1178 | + return CreateJsUndefined(env); |
| 1179 | + } | ||
| 1159 | 1180 | ||
| 1160 | result = nullptr; | 1181 | result = nullptr; |
| 1161 | std::unique_ptr<NapiAsyncTask> uasyncTask = CreateAsyncTaskWithLastParam(env, nullptr, nullptr, nullptr, &result); | 1182 | std::unique_ptr<NapiAsyncTask> uasyncTask = CreateAsyncTaskWithLastParam(env, nullptr, nullptr, nullptr, &result); |
| @@ -1203,6 +1224,21 @@ void JsUIExtensionContext::DoConnectUIServiceExtension(napi_env env, | |||
| 1203 | } | 1224 | } |
| 1204 | } | 1225 | } |
| 1205 | 1226 | ||
| 1227 | +static void DoDisconnectUIServiceExtensionComplete(napi_env env, NapiAsyncTask& task, | ||
| 1228 | + int64_t connectId, std::shared_ptr<ErrCode> innerErrCode) | ||
| 1229 | +{ | ||
| 1230 | + if (*innerErrCode == static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT)) { | ||
| 1231 | + task.Reject(env, CreateJsError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT)); | ||
| 1232 | + UIServiceConnection::RemoveUIServiceExtensionConnection(connectId); | ||
| 1233 | + } else if (*innerErrCode == static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER)) { | ||
| 1234 | + task.Reject(env, CreateJsError(env, static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER), | ||
| 1235 | + GetInnerErrorMsg(AbilityInnerErrorMsg::CONNECTION_NOT_FOUND))); | ||
| 1236 | + UIServiceConnection::RemoveUIServiceExtensionConnection(connectId); | ||
| 1237 | + } else { | ||
| 1238 | + task.ResolveWithNoError(env, CreateJsUndefined(env)); | ||
| 1239 | + } | ||
| 1240 | +} | ||
| 1241 | + | ||
| 1206 | napi_value JsUIExtensionContext::OnDisconnectUIServiceExtension(napi_env env, NapiCallbackInfo& info) | 1242 | napi_value JsUIExtensionContext::OnDisconnectUIServiceExtension(napi_env env, NapiCallbackInfo& info) |
| 1207 | { | 1243 | { |
| 1208 | if (info.argc < ARGC_ONE) { | 1244 | if (info.argc < ARGC_ONE) { |
| @@ -1235,21 +1271,13 @@ napi_value JsUIExtensionContext::OnDisconnectUIServiceExtension(napi_env env, Na | |||
| 1235 | if (!connection) { | 1271 | if (!connection) { |
| 1236 | TAG_LOGW(AAFwkTag::UISERVC_EXT, "null connection"); | 1272 | TAG_LOGW(AAFwkTag::UISERVC_EXT, "null connection"); |
| 1237 | *innerErrCode = static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER); | 1273 | *innerErrCode = static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER); |
| 1274 | + return; | ||
| 1238 | } | 1275 | } |
| 1239 | context->DisconnectAbility(want, connection); | 1276 | context->DisconnectAbility(want, connection); |
| 1240 | }; | 1277 | }; |
| 1241 | NapiAsyncTask::CompleteCallback complete = | 1278 | NapiAsyncTask::CompleteCallback complete = |
| 1242 | [connectId, innerErrCode](napi_env env, NapiAsyncTask& task, int32_t status) { | 1279 | [connectId, innerErrCode](napi_env env, NapiAsyncTask& task, int32_t status) { |
| 1243 | - if (*innerErrCode == static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT)) { | 1280 | + DoDisconnectUIServiceExtensionComplete(env, task, connectId, innerErrCode); |
| 1244 | - task.Reject(env, CreateJsError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT)); | ||
| 1245 | - UIServiceConnection::RemoveUIServiceExtensionConnection(connectId); | ||
| 1246 | - } else if (*innerErrCode == static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER)) { | ||
| 1247 | - task.Reject(env, CreateJsError(env, static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER), | ||
| 1248 | - GetInnerErrorMsg(AbilityInnerErrorMsg::CONNECTION_NOT_FOUND))); | ||
| 1249 | - UIServiceConnection::RemoveUIServiceExtensionConnection(connectId); | ||
| 1250 | - } else { | ||
| 1251 | - task.ResolveWithNoError(env, CreateJsUndefined(env)); | ||
| 1252 | - } | ||
| 1253 | }; | 1281 | }; |
| 1254 | napi_value result = nullptr; | 1282 | napi_value result = nullptr; |
| 1255 | NapiAsyncTask::Schedule("JsUIExtensionContext::OnDisconnectUIServiceExtension", | 1283 | NapiAsyncTask::Schedule("JsUIExtensionContext::OnDisconnectUIServiceExtension", |
| @@ -1259,6 +1287,11 @@ napi_value JsUIExtensionContext::OnDisconnectUIServiceExtension(napi_env env, Na | |||
| 1259 | 1287 | ||
| 1260 | napi_value JsUIExtensionContext::OnReportDrawnCompleted(napi_env env, NapiCallbackInfo& info) | 1288 | napi_value JsUIExtensionContext::OnReportDrawnCompleted(napi_env env, NapiCallbackInfo& info) |
| 1261 | { | 1289 | { |
| 1290 | + if (info.argc < ARGC_ONE) { | ||
| 1291 | + TAG_LOGE(AAFwkTag::UI_EXT, "invalid argc"); | ||
| 1292 | + ThrowTooFewParametersError(env); | ||
| 1293 | + return CreateJsUndefined(env); | ||
| 1294 | + } | ||
| 1262 | TAG_LOGD(AAFwkTag::UI_EXT, "called"); | 1295 | TAG_LOGD(AAFwkTag::UI_EXT, "called"); |
| 1263 | auto innerErrorCode = std::make_shared<int32_t>(ERR_OK); | 1296 | auto innerErrorCode = std::make_shared<int32_t>(ERR_OK); |
| 1264 | NapiAsyncTask::ExecuteCallback execute = [weak = context_, innerErrorCode]() { | 1297 | NapiAsyncTask::ExecuteCallback execute = [weak = context_, innerErrorCode]() { |
Mframeworks/native/ability/native/ui_service_extension_ability/js_ui_service_extension_context.cpp+3-0
| @@ -667,6 +667,9 @@ void JSUIServiceExtensionConnection::HandleOnAbilityDisconnectDone(const AppExec | |||
| 667 | }); | 667 | }); |
| 668 | if (item != g_connects.end()) { | 668 | if (item != g_connects.end()) { |
| 669 | // match bundlename && abilityname | 669 | // match bundlename && abilityname |
| 670 | + if (item->second) { | ||
| 671 | + item->second->RemoveConnectionObject(); | ||
| 672 | + } | ||
| 670 | g_connects.erase(item); | 673 | g_connects.erase(item); |
| 671 | TAG_LOGD( | 674 | TAG_LOGD( |
| 672 | AAFwkTag::UISERVC_EXT, "OnAbilityDisconnectDone erase g_connects.size:%{public}zu", g_connects.size()); | 675 | AAFwkTag::UISERVC_EXT, "OnAbilityDisconnectDone erase g_connects.size:%{public}zu", g_connects.size()); |
| @@ -580,15 +580,28 @@ int32_t UIExtensionAbilityManager::RegisterPreloadUIExtensionHostClient(const sp | |||
| 580 | 580 | ||
| 581 | { | 581 | { |
| 582 | std::lock_guard lock(preloadUIExtRecipientMapMutex_); | 582 | std::lock_guard lock(preloadUIExtRecipientMapMutex_); |
| 583 | + auto it = preloadUIExtensionHostClientDeathRecipients_.find(callerPid); | ||
| 584 | + if (it != preloadUIExtensionHostClientDeathRecipients_.end()) { | ||
| 585 | + TAG_LOGW(AAFwkTag::UI_EXT, "recipient added before, callerPid: %{public}d", callerPid); | ||
| 586 | + return ERR_OK; | ||
| 587 | + } | ||
| 588 | + if (!callerToken->AddDeathRecipient(deathRecipient)) { | ||
| 589 | + TAG_LOGE(AAFwkTag::UI_EXT, "AddDeathRecipient fail"); | ||
| 590 | + return INNER_ERR; | ||
| 591 | + } | ||
| 583 | preloadUIExtensionHostClientDeathRecipients_[callerPid] = deathRecipient; | 592 | preloadUIExtensionHostClientDeathRecipients_[callerPid] = deathRecipient; |
| 584 | } | 593 | } |
| 585 | 594 | ||
| 586 | - callerToken->AddDeathRecipient(deathRecipient); | ||
| 587 | try { | 595 | try { |
| 588 | uiExtensionAbilityRecordMgr_->RegisterPreloadUIExtensionHostClient(callerToken); | 596 | uiExtensionAbilityRecordMgr_->RegisterPreloadUIExtensionHostClient(callerToken); |
| 589 | } catch (std::exception &e) { | 597 | } catch (std::exception &e) { |
| 590 | TAG_LOGE(AAFwkTag::UI_EXT, "RegisterPreloadUIExtensionHostClient failed, exception = %{public}s", e.what()); | 598 | TAG_LOGE(AAFwkTag::UI_EXT, "RegisterPreloadUIExtensionHostClient failed, exception = %{public}s", e.what()); |
| 591 | callerToken->RemoveDeathRecipient(deathRecipient); | 599 | callerToken->RemoveDeathRecipient(deathRecipient); |
| 600 | + { | ||
| 601 | + std::lock_guard lock(preloadUIExtRecipientMapMutex_); | ||
| 602 | + preloadUIExtensionHostClientDeathRecipients_.erase(callerPid); | ||
| 603 | + } | ||
| 604 | + return INNER_ERR; | ||
| 592 | } | 605 | } |
| 593 | return ERR_OK; | 606 | return ERR_OK; |
| 594 | } | 607 | } |
| @@ -1550,7 +1563,6 @@ void UIExtensionAbilityManager::CompleteBackground(const std::shared_ptr<BaseExt | |||
| 1550 | return; | 1563 | return; |
| 1551 | } | 1564 | } |
| 1552 | abilityRecord->SetAbilityState(AbilityState::BACKGROUND); | 1565 | abilityRecord->SetAbilityState(AbilityState::BACKGROUND); |
| 1553 | - CHECK_POINTER(abilityRecord); | ||
| 1554 | auto sessionInfo = abilityRecord->GetSessionInfo(); | 1566 | auto sessionInfo = abilityRecord->GetSessionInfo(); |
| 1555 | CHECK_POINTER(sessionInfo); | 1567 | CHECK_POINTER(sessionInfo); |
| 1556 | TAG_LOGI(AAFwkTag::UI_EXT, | 1568 | TAG_LOGI(AAFwkTag::UI_EXT, |
| @@ -52,7 +52,7 @@ int WantReceiverStub::SendInner(MessageParcel &data, MessageParcel &reply) | |||
| 52 | 52 | ||
| 53 | int WantReceiverStub::PerformReceiveInner(MessageParcel &data, MessageParcel &reply) | 53 | int WantReceiverStub::PerformReceiveInner(MessageParcel &data, MessageParcel &reply) |
| 54 | { | 54 | { |
| 55 | - Want *want = data.ReadParcelable<Want>(); | 55 | + std::unique_ptr<Want> want(data.ReadParcelable<Want>()); |
| 56 | if (want == nullptr) { | 56 | if (want == nullptr) { |
| 57 | TAG_LOGE(AAFwkTag::WANTAGENT, "null want"); | 57 | TAG_LOGE(AAFwkTag::WANTAGENT, "null want"); |
| 58 | return ERR_INVALID_VALUE; | 58 | return ERR_INVALID_VALUE; |
| @@ -61,10 +61,9 @@ int WantReceiverStub::PerformReceiveInner(MessageParcel &data, MessageParcel &re | |||
| 61 | int resultCode = data.ReadInt32(); | 61 | int resultCode = data.ReadInt32(); |
| 62 | std::string bundleName = Str16ToStr8(data.ReadString16()); | 62 | std::string bundleName = Str16ToStr8(data.ReadString16()); |
| 63 | 63 | ||
| 64 | - WantParams *wantParams = data.ReadParcelable<WantParams>(); | 64 | + std::unique_ptr<WantParams> wantParams(data.ReadParcelable<WantParams>()); |
| 65 | if (wantParams == nullptr) { | 65 | if (wantParams == nullptr) { |
| 66 | TAG_LOGE(AAFwkTag::WANTAGENT, "null wantParams"); | 66 | TAG_LOGE(AAFwkTag::WANTAGENT, "null wantParams"); |
| 67 | - delete want; | ||
| 68 | return ERR_INVALID_VALUE; | 67 | return ERR_INVALID_VALUE; |
| 69 | } | 68 | } |
| 70 | 69 | ||
| @@ -72,8 +71,6 @@ int WantReceiverStub::PerformReceiveInner(MessageParcel &data, MessageParcel &re | |||
| 72 | bool sticky = data.ReadBool(); | 71 | bool sticky = data.ReadBool(); |
| 73 | int sendingUser = data.ReadInt32(); | 72 | int sendingUser = data.ReadInt32(); |
| 74 | PerformReceive(*want, resultCode, bundleName, *wantParams, serialized, sticky, sendingUser); | 73 | PerformReceive(*want, resultCode, bundleName, *wantParams, serialized, sticky, sendingUser); |
| 75 | - delete want; | ||
| 76 | - delete wantParams; | ||
| 77 | return NO_ERROR; | 74 | return NO_ERROR; |
| 78 | } | 75 | } |
| 79 | } // namespace AAFwk | 76 | } // namespace AAFwk |
| @@ -15,6 +15,8 @@ | |||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | + | ||
| 19 | + | ||
| 18 | namespace OHOS { | 20 | namespace OHOS { |
| 19 | namespace AAFwk { | 21 | namespace AAFwk { |
| 20 | bool WantsInfo::ReadFromParcel(Parcel &parcel) | 22 | bool WantsInfo::ReadFromParcel(Parcel &parcel) |
| @@ -45,8 +47,14 @@ WantsInfo *WantsInfo::Unmarshalling(Parcel &parcel) | |||
| 45 | 47 | ||
| 46 | bool WantsInfo::Marshalling(Parcel &parcel) const | 48 | bool WantsInfo::Marshalling(Parcel &parcel) const |
| 47 | { | 49 | { |
| 48 | - parcel.WriteParcelable(&want); | 50 | + if (!parcel.WriteParcelable(&want)) { |
| 49 | - parcel.WriteString16(Str8ToStr16(resolvedTypes)); | 51 | + TAG_LOGE(AAFwkTag::ABILITYMGR, "write want failed"); |
| 52 | + return false; | ||
| 53 | + } | ||
| 54 | + if (!parcel.WriteString16(Str8ToStr16(resolvedTypes))) { | ||
| 55 | + TAG_LOGE(AAFwkTag::ABILITYMGR, "write resolvedTypes failed"); | ||
| 56 | + return false; | ||
| 57 | + } | ||
| 50 | return true; | 58 | return true; |
| 51 | } | 59 | } |
| 52 | } // namespace AAFwk | 60 | } // namespace AAFwk |
| @@ -555,6 +555,7 @@ group("unittest") { | |||
| 555 | "ui_extension_utils_test:unittest", | 555 | "ui_extension_utils_test:unittest", |
| 556 | "ui_extension_ability_manager_test:unittest", | 556 | "ui_extension_ability_manager_test:unittest", |
| 557 | "ui_extension_ability_manager_second_test:unittest", | 557 | "ui_extension_ability_manager_second_test:unittest", |
| 558 | + "ui_extension_ability_manager_third_test:unittest", | ||
| 558 | "update_caller_info_util_test:unittest", | 559 | "update_caller_info_util_test:unittest", |
| 559 | "uri_utils_second_test", | 560 | "uri_utils_second_test", |
| 560 | "uri_utils_test:unittest", | 561 | "uri_utils_test:unittest", |
| @@ -28,13 +28,18 @@ ohos_unittest("js_ui_extension_context_test") { | |||
| 28 | debug = false | 28 | debug = false |
| 29 | } | 29 | } |
| 30 | include_dirs = [ | 30 | include_dirs = [ |
| 31 | + "${ability_runtime_napi_path}/ability_manager", | ||
| 31 | "${ability_runtime_path}/interfaces/kits/native/ability/native", | 32 | "${ability_runtime_path}/interfaces/kits/native/ability/native", |
| 32 | "${ability_runtime_path}/interfaces/kits/native/ability/native/ability_runtime", | 33 | "${ability_runtime_path}/interfaces/kits/native/ability/native/ability_runtime", |
| 33 | "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_extension_ability", | 34 | "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_extension_ability", |
| 34 | "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_extension_base", | 35 | "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_extension_base", |
| 36 | + "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_service_extension_ability/connection", | ||
| 35 | ] | 37 | ] |
| 36 | 38 | ||
| 37 | - sources = [ "js_ui_extension_context_test.cpp" ] | 39 | + sources = [ |
| 40 | + "${ability_runtime_napi_path}/ability_manager/js_preload_ui_extension_callback_client.cpp", | ||
| 41 | + "js_ui_extension_context_test.cpp", | ||
| 42 | + ] | ||
| 38 | 43 | ||
| 39 | configs = [] | 44 | configs = [] |
| 40 | 45 | ||
| @@ -46,6 +51,7 @@ ohos_unittest("js_ui_extension_context_test") { | |||
| 46 | "${ability_runtime_native_path}/ability/native:abilitykit_native", | 51 | "${ability_runtime_native_path}/ability/native:abilitykit_native", |
| 47 | "${ability_runtime_native_path}/ability/native:extensionkit_native", | 52 | "${ability_runtime_native_path}/ability/native:extensionkit_native", |
| 48 | "${ability_runtime_native_path}/ability/native:ui_extension", | 53 | "${ability_runtime_native_path}/ability/native:ui_extension", |
| 54 | + "${ability_runtime_native_path}/ability/native:ui_service_extension_connection", | ||
| 49 | "${ability_runtime_native_path}/ability:ability_context_native", | 55 | "${ability_runtime_native_path}/ability:ability_context_native", |
| 50 | "${ability_runtime_native_path}/appkit:app_context", | 56 | "${ability_runtime_native_path}/appkit:app_context", |
| 51 | "${ability_runtime_path}/js_environment/frameworks/js_environment:js_environment", | 57 | "${ability_runtime_path}/js_environment/frameworks/js_environment:js_environment", |
| @@ -13,7 +13,9 @@ | |||
| 13 | * limitations under the License. | 13 | * limitations under the License. |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | + | ||
| 16 | 17 | ||
| 18 | + | ||
| 17 | 19 | ||
| 18 | 20 | ||
| 19 | 21 | ||
| @@ -33,6 +35,10 @@ | |||
| 33 | 35 | ||
| 34 | 36 | ||
| 35 | 37 | ||
| 38 | + | ||
| 39 | + | ||
| 40 | + | ||
| 41 | + | ||
| 36 | 42 | ||
| 37 | using namespace testing; | 43 | using namespace testing; |
| 38 | using namespace testing::ext; | 44 | using namespace testing::ext; |
| @@ -66,6 +72,7 @@ class MockDeferred : public NativeDeferred { | |||
| 66 | public: | 72 | public: |
| 67 | void Resolve(napi_value data) override | 73 | void Resolve(napi_value data) override |
| 68 | { | 74 | { |
| 75 | + settled_ = true; | ||
| 69 | resolved_ = true; | 76 | resolved_ = true; |
| 70 | if (nref_ != nullptr) { | 77 | if (nref_ != nullptr) { |
| 71 | napi_delete_reference(env_, nref_); | 78 | napi_delete_reference(env_, nref_); |
| @@ -78,10 +85,12 @@ public: | |||
| 78 | 85 | ||
| 79 | void Reject(napi_value reason) override | 86 | void Reject(napi_value reason) override |
| 80 | { | 87 | { |
| 88 | + settled_ = true; | ||
| 81 | resolved_ = false; | 89 | resolved_ = false; |
| 82 | } | 90 | } |
| 83 | 91 | ||
| 84 | public: | 92 | public: |
| 93 | + static bool IsSettled() { return settled_; } | ||
| 85 | static bool GetLastResolveStatus() { return resolved_; } | 94 | static bool GetLastResolveStatus() { return resolved_; } |
| 86 | static napi_ref GetLastResolveValue() { return nref_; } | 95 | static napi_ref GetLastResolveValue() { return nref_; } |
| 87 | static void Clear() | 96 | static void Clear() |
| @@ -90,10 +99,14 @@ public: | |||
| 90 | delete (reinterpret_cast<NativeReference*>(nref_)); | 99 | delete (reinterpret_cast<NativeReference*>(nref_)); |
| 91 | nref_ = nullptr; | 100 | nref_ = nullptr; |
| 92 | } | 101 | } |
| 102 | + settled_ = false; | ||
| 103 | + resolved_ = false; | ||
| 93 | } | 104 | } |
| 105 | + static bool settled_; | ||
| 94 | static bool resolved_; | 106 | static bool resolved_; |
| 95 | static napi_ref nref_; | 107 | static napi_ref nref_; |
| 96 | }; | 108 | }; |
| 109 | +bool MockDeferred::settled_ = false; | ||
| 97 | bool MockDeferred::resolved_ = false; | 110 | bool MockDeferred::resolved_ = false; |
| 98 | napi_ref MockDeferred::nref_ = nullptr; | 111 | napi_ref MockDeferred::nref_ = nullptr; |
| 99 | 112 | ||
| @@ -122,8 +135,15 @@ public: | |||
| 122 | virtual ErrCode DisconnectAbility(const AAFwk::Want &want, | 135 | virtual ErrCode DisconnectAbility(const AAFwk::Want &want, |
| 123 | const sptr<AbilityConnectCallback> &connectCallback) const override | 136 | const sptr<AbilityConnectCallback> &connectCallback) const override |
| 124 | { | 137 | { |
| 138 | + disconnectAbilityCount_++; | ||
| 125 | return ERR_OK; | 139 | return ERR_OK; |
| 126 | } | 140 | } |
| 141 | + | ||
| 142 | + ErrCode ReportDrawnCompleted() override | ||
| 143 | + { | ||
| 144 | + reportDrawnCompletedCount_++; | ||
| 145 | + return reportDrawnCompletedResult_; | ||
| 146 | + } | ||
| 127 | public: | 147 | public: |
| 128 | static void DoneConnect(int status) | 148 | static void DoneConnect(int status) |
| 129 | { | 149 | { |
| @@ -139,9 +159,14 @@ public: | |||
| 139 | callback_->OnAbilityDisconnectDone(element, 0); | 159 | callback_->OnAbilityDisconnectDone(element, 0); |
| 140 | } | 160 | } |
| 141 | void SetConnectResult(ErrCode code) { connectRet_ = code; } | 161 | void SetConnectResult(ErrCode code) { connectRet_ = code; } |
| 162 | + int32_t GetDisconnectAbilityCount() const { return disconnectAbilityCount_.load(); } | ||
| 163 | + int32_t GetReportDrawnCompletedCount() const { return reportDrawnCompletedCount_.load(); } | ||
| 142 | protected: | 164 | protected: |
| 143 | static sptr<AbilityConnectCallback> callback_; | 165 | static sptr<AbilityConnectCallback> callback_; |
| 144 | ErrCode connectRet_ = ERR_OK; | 166 | ErrCode connectRet_ = ERR_OK; |
| 167 | + ErrCode reportDrawnCompletedResult_ = ERR_OK; | ||
| 168 | + mutable std::atomic<int32_t> disconnectAbilityCount_ = 0; | ||
| 169 | + std::atomic<int32_t> reportDrawnCompletedCount_ = 0; | ||
| 145 | }; | 170 | }; |
| 146 | 171 | ||
| 147 | sptr<AbilityConnectCallback> MockAbilityContextImpl::callback_; | 172 | sptr<AbilityConnectCallback> MockAbilityContextImpl::callback_; |
| @@ -160,6 +185,7 @@ public: | |||
| 160 | } | 185 | } |
| 161 | void Connect(napi_value* argv, int32_t argc); | 186 | void Connect(napi_value* argv, int32_t argc); |
| 162 | void Disconnect(napi_value* argv, int32_t argc); | 187 | void Disconnect(napi_value* argv, int32_t argc); |
| 188 | + void ReportDrawnCompleted(napi_value* argv, int32_t argc); | ||
| 163 | public: | 189 | public: |
| 164 | std::shared_ptr<JsUIExtensionContext> jsUIExtensionContext_; | 190 | std::shared_ptr<JsUIExtensionContext> jsUIExtensionContext_; |
| 165 | std::shared_ptr<MockAbilityContextImpl> abilityContextImpl_; | 191 | std::shared_ptr<MockAbilityContextImpl> abilityContextImpl_; |
| @@ -264,6 +290,27 @@ void UIExtensionContextTest::Disconnect(napi_value* argv, int32_t argc) | |||
| 264 | } | 290 | } |
| 265 | } | 291 | } |
| 266 | 292 | ||
| 293 | +void UIExtensionContextTest::ReportDrawnCompleted(napi_value* argv, int32_t argc) | ||
| 294 | +{ | ||
| 295 | + napi_callback func = [](napi_env env, napi_callback_info info) -> napi_value { | ||
| 296 | + return JsUIExtensionContext::ReportDrawnCompleted(env, info); | ||
| 297 | + }; | ||
| 298 | + HandleScope handleScope(env_); | ||
| 299 | + napi_value recv = nullptr; | ||
| 300 | + napi_create_object(env_, &recv); | ||
| 301 | + napi_status wrapret = napi_wrap(env_, recv, jsUIExtensionContext_.get(), | ||
| 302 | + [](napi_env env, void* data, void* hint) {}, nullptr, nullptr); | ||
| 303 | + EXPECT_EQ(wrapret, napi_ok); | ||
| 304 | + | ||
| 305 | + napi_value funcValue = nullptr; | ||
| 306 | + napi_create_function(env_, "reportDrawnCompleted", NAPI_AUTO_LENGTH, func, nullptr, &funcValue); | ||
| 307 | + napi_value funcResultValue = nullptr; | ||
| 308 | + napi_status status = napi_call_function(env_, recv, funcValue, argc, argv, &funcResultValue); | ||
| 309 | + if (status != napi_ok) { | ||
| 310 | + TAG_LOGE(AAFwkTag::UI_EXT, "call reportDrawnCompleted failed %{public}d", status); | ||
| 311 | + } | ||
| 312 | +} | ||
| 313 | + | ||
| 267 | HWTEST_F(UIExtensionContextTest, AbilityRuntime_UIExtensionContext_0100, TestSize.Level1) | 314 | HWTEST_F(UIExtensionContextTest, AbilityRuntime_UIExtensionContext_0100, TestSize.Level1) |
| 268 | { | 315 | { |
| 269 | GTEST_LOG_(INFO) << "AbilityRuntime_UIExtensionContext_0100 start"; | 316 | GTEST_LOG_(INFO) << "AbilityRuntime_UIExtensionContext_0100 start"; |
| @@ -391,6 +438,95 @@ HWTEST_F(UIExtensionContextTest, AbilityRuntime_UIExtensionContext_0105, TestSiz | |||
| 391 | GTEST_LOG_(INFO) << "AbilityRuntime_UIExtensionContext_0105 end"; | 438 | GTEST_LOG_(INFO) << "AbilityRuntime_UIExtensionContext_0105 end"; |
| 392 | } | 439 | } |
| 393 | 440 | ||
| 441 | +/** | ||
| 442 | + * @tc.name: AbilityRuntime_UIExtensionContext_DisconnectMissingConnection_0100 | ||
| 443 | + * @tc.desc: A missing connection is rejected without calling the native disconnect API. | ||
| 444 | + * @tc.type: FUNC | ||
| 445 | + */ | ||
| 446 | +HWTEST_F(UIExtensionContextTest, AbilityRuntime_UIExtensionContext_DisconnectMissingConnection_0100, TestSize.Level1) | ||
| 447 | +{ | ||
| 448 | + HandleScope handleScope(env_); | ||
| 449 | + TryCatch tryCatch(env_); | ||
| 450 | + constexpr int64_t missingConnectionId = std::numeric_limits<int64_t>::max(); | ||
| 451 | + UIServiceConnection::RemoveUIServiceExtensionConnection(missingConnectionId); | ||
| 452 | + sptr<IRemoteObject> remoteObject = nullptr; | ||
| 453 | + napi_value proxy = AAFwk::JsUIServiceProxy::CreateJsUIServiceProxy( | ||
| 454 | + env_, remoteObject, missingConnectionId, remoteObject); | ||
| 455 | + ASSERT_NE(proxy, nullptr); | ||
| 456 | + napi_value argv[] = { proxy }; | ||
| 457 | + | ||
| 458 | + Disconnect(argv, ARGC_ONE); | ||
| 459 | + ArkNativeEngine* engine = reinterpret_cast<ArkNativeEngine*>(env_); | ||
| 460 | + uv_loop_t* loop = engine->GetUVLoop(); | ||
| 461 | + RunNowait(loop); | ||
| 462 | + RunNowait(loop); | ||
| 463 | + | ||
| 464 | + EXPECT_FALSE(tryCatch.HasCaught()); | ||
| 465 | + EXPECT_EQ(abilityContextImpl_->GetDisconnectAbilityCount(), 0); | ||
| 466 | + EXPECT_TRUE(MockDeferred::IsSettled()); | ||
| 467 | + EXPECT_FALSE(MockDeferred::GetLastResolveStatus()); | ||
| 468 | +} | ||
| 469 | + | ||
| 470 | +/** | ||
| 471 | + * @tc.name: AbilityRuntime_UIExtensionContext_ReportDrawnCompleted_0100 | ||
| 472 | + * @tc.desc: Calling reportDrawnCompleted without a callback reports too few parameters. | ||
| 473 | + * @tc.type: FUNC | ||
| 474 | + */ | ||
| 475 | +HWTEST_F(UIExtensionContextTest, AbilityRuntime_UIExtensionContext_ReportDrawnCompleted_0100, TestSize.Level1) | ||
| 476 | +{ | ||
| 477 | + HandleScope handleScope(env_); | ||
| 478 | + TryCatch tryCatch(env_); | ||
| 479 | + | ||
| 480 | + ReportDrawnCompleted(nullptr, ARGC_ZERO); | ||
| 481 | + | ||
| 482 | + EXPECT_TRUE(tryCatch.HasCaught()); | ||
| 483 | + EXPECT_EQ(abilityContextImpl_->GetReportDrawnCompletedCount(), 0); | ||
| 484 | + tryCatch.ClearException(); | ||
| 485 | + ArkNativeEngine* engine = reinterpret_cast<ArkNativeEngine*>(env_); | ||
| 486 | + if (!engine->lastException_.IsEmpty()) { | ||
| 487 | + engine->lastException_.Empty(); | ||
| 488 | + } | ||
| 489 | +} | ||
| 490 | + | ||
| 491 | +/** | ||
| 492 | + * @tc.name: AbilityRuntime_UIExtensionContext_ReportDrawnCompleted_0200 | ||
| 493 | + * @tc.desc: A valid callback invokes the native reportDrawnCompleted API and completes asynchronously. | ||
| 494 | + * @tc.type: FUNC | ||
| 495 | + */ | ||
| 496 | +HWTEST_F(UIExtensionContextTest, AbilityRuntime_UIExtensionContext_ReportDrawnCompleted_0200, TestSize.Level1) | ||
| 497 | +{ | ||
| 498 | + HandleScope handleScope(env_); | ||
| 499 | + bool callbackInvoked = false; | ||
| 500 | + napi_value callback = nullptr; | ||
| 501 | + ASSERT_EQ(napi_create_function(env_, "reportDrawnCallback", NAPI_AUTO_LENGTH, | ||
| 502 | + MarkCallbackInvoked, &callbackInvoked, &callback), napi_ok); | ||
| 503 | + napi_value argv[] = { callback }; | ||
| 504 | + | ||
| 505 | + ReportDrawnCompleted(argv, ARGC_ONE); | ||
| 506 | + ArkNativeEngine* engine = reinterpret_cast<ArkNativeEngine*>(env_); | ||
| 507 | + uv_loop_t* loop = engine->GetUVLoop(); | ||
| 508 | + RunNowait(loop); | ||
| 509 | + RunNowait(loop); | ||
| 510 | + | ||
| 511 | + EXPECT_EQ(abilityContextImpl_->GetReportDrawnCompletedCount(), 1); | ||
| 512 | + EXPECT_TRUE(callbackInvoked); | ||
| 513 | +} | ||
| 514 | + | ||
| 515 | +/** | ||
| 516 | + * @tc.name: AbilityRuntime_PreloadUIExtensionCallback_NullEnv_0100 | ||
| 517 | + * @tc.desc: Calling the preload callback client with a null NAPI environment does not crash. | ||
| 518 | + * @tc.type: FUNC | ||
| 519 | + */ | ||
| 520 | +HWTEST_F(UIExtensionContextTest, AbilityRuntime_PreloadUIExtensionCallback_NullEnv_0100, TestSize.Level1) | ||
| 521 | +{ | ||
| 522 | + auto callbackClient = std::make_shared<JsPreloadUIExtensionCallbackClient>(nullptr, nullptr); | ||
| 523 | + ASSERT_NE(callbackClient, nullptr); | ||
| 524 | + | ||
| 525 | + callbackClient->CallJsPreloadedUIExtensionAbility(1); | ||
| 526 | + | ||
| 527 | + SUCCEED(); | ||
| 528 | +} | ||
| 529 | + | ||
| 394 | HWTEST_F(UIExtensionContextTest, AbilityRuntime_UIExtensionContext_0106, TestSize.Level1) | 530 | HWTEST_F(UIExtensionContextTest, AbilityRuntime_UIExtensionContext_0106, TestSize.Level1) |
| 395 | { | 531 | { |
| 396 | GTEST_LOG_(INFO) << "AbilityRuntime_UIExtensionContext_0106 start"; | 532 | GTEST_LOG_(INFO) << "AbilityRuntime_UIExtensionContext_0106 start"; |
| @@ -1513,4 +1649,4 @@ HWTEST_F(UIExtensionContextTest, TerminateSelfWithResultEmbeddable_0400, TestSiz | |||
| 1513 | GTEST_LOG_(INFO) << "TerminateSelfWithResultEmbeddable_0400 end"; | 1649 | GTEST_LOG_(INFO) << "TerminateSelfWithResultEmbeddable_0400 end"; |
| 1514 | } | 1650 | } |
| 1515 | } // namespace AAFwk | 1651 | } // namespace AAFwk |
| 1516 | -} // namespace OHOS | 1652 | +} // namespace OHOS |
| @@ -37,6 +37,17 @@ namespace OHOS { | |||
| 37 | namespace AbilityRuntime { | 37 | namespace AbilityRuntime { |
| 38 | namespace { | 38 | namespace { |
| 39 | const int64_t COMMECTION_ID = 100; | 39 | const int64_t COMMECTION_ID = 100; |
| 40 | + | ||
| 41 | +napi_value MarkDisconnectCallbackInvoked(napi_env env, napi_callback_info info) | ||
| 42 | +{ | ||
| 43 | + size_t argc = 0; | ||
| 44 | + void* data = nullptr; | ||
| 45 | + napi_get_cb_info(env, info, &argc, nullptr, nullptr, &data); | ||
| 46 | + if (data != nullptr) { | ||
| 47 | + *static_cast<bool*>(data) = true; | ||
| 48 | + } | ||
| 49 | + return CreateJsUndefined(env); | ||
| 50 | +} | ||
| 40 | } // namespace | 51 | } // namespace |
| 41 | 52 | ||
| 42 | class JsUiServiceExtensionContextSecondTest : public testing::Test { | 53 | class JsUiServiceExtensionContextSecondTest : public testing::Test { |
| @@ -71,6 +82,16 @@ void JsUiServiceExtensionContextSecondTest::SetUp() | |||
| 71 | 82 | ||
| 72 | void JsUiServiceExtensionContextSecondTest::TearDown() | 83 | void JsUiServiceExtensionContextSecondTest::TearDown() |
| 73 | { | 84 | { |
| 85 | + { | ||
| 86 | + std::lock_guard guard(g_connectsMutex); | ||
| 87 | + for (auto &item : g_connects) { | ||
| 88 | + if (item.second != nullptr) { | ||
| 89 | + item.second->RemoveConnectionObject(); | ||
| 90 | + } | ||
| 91 | + } | ||
| 92 | + g_connects.clear(); | ||
| 93 | + g_serialNumber = 0; | ||
| 94 | + } | ||
| 74 | if (env_ != nullptr) { | 95 | if (env_ != nullptr) { |
| 75 | delete reinterpret_cast<NativeEngine*>(env_); | 96 | delete reinterpret_cast<NativeEngine*>(env_); |
| 76 | env_ = nullptr; | 97 | env_ = nullptr; |
| @@ -167,6 +188,44 @@ HWTEST_F(JsUiServiceExtensionContextSecondTest, FindConnection_0100, TestSize.Le | |||
| 167 | TAG_LOGI(AAFwkTag::TEST, "FindConnection_0100 end"); | 188 | TAG_LOGI(AAFwkTag::TEST, "FindConnection_0100 end"); |
| 168 | } | 189 | } |
| 169 | 190 | ||
| 191 | +/** | ||
| 192 | + * @tc.name: HandleOnAbilityDisconnectDone_0400 | ||
| 193 | + * @tc.desc: A matched connection releases its JS reference and is removed after disconnect. | ||
| 194 | + * @tc.type: FUNC | ||
| 195 | + */ | ||
| 196 | +HWTEST_F(JsUiServiceExtensionContextSecondTest, HandleOnAbilityDisconnectDone_0400, TestSize.Level1) | ||
| 197 | +{ | ||
| 198 | + bool callbackInvoked = false; | ||
| 199 | + napi_value connectionObject = nullptr; | ||
| 200 | + ASSERT_EQ(napi_create_object(env_, &connectionObject), napi_ok); | ||
| 201 | + napi_value onDisconnect = nullptr; | ||
| 202 | + ASSERT_EQ(napi_create_function(env_, "onDisconnect", NAPI_AUTO_LENGTH, | ||
| 203 | + MarkDisconnectCallbackInvoked, &callbackInvoked, &onDisconnect), napi_ok); | ||
| 204 | + ASSERT_EQ(napi_set_named_property(env_, connectionObject, "onDisconnect", onDisconnect), napi_ok); | ||
| 205 | + | ||
| 206 | + sptr<JSUIServiceExtensionConnection> connection = new JSUIServiceExtensionConnection(env_); | ||
| 207 | + connection->SetJsConnectionObject(connectionObject); | ||
| 208 | + connection->SetConnectionId(COMMECTION_ID); | ||
| 209 | + AppExecFwk::ElementName element("device", "com.example.uiservice", "UIServiceExtensionAbility"); | ||
| 210 | + Want want; | ||
| 211 | + want.SetElement(element); | ||
| 212 | + ConnectionKey key; | ||
| 213 | + key.want = want; | ||
| 214 | + key.id = COMMECTION_ID; | ||
| 215 | + key.accountId = -1; | ||
| 216 | + { | ||
| 217 | + std::lock_guard guard(g_connectsMutex); | ||
| 218 | + g_connects.emplace(key, connection); | ||
| 219 | + } | ||
| 220 | + | ||
| 221 | + connection->HandleOnAbilityDisconnectDone(element, ERR_OK); | ||
| 222 | + | ||
| 223 | + EXPECT_TRUE(callbackInvoked); | ||
| 224 | + EXPECT_EQ(connection->jsConnectionObject_, nullptr); | ||
| 225 | + std::lock_guard guard(g_connectsMutex); | ||
| 226 | + EXPECT_TRUE(g_connects.empty()); | ||
| 227 | +} | ||
| 228 | + | ||
| 170 | /** | 229 | /** |
| 171 | * @tc.name: OnConnectServiceExtensionAbility_0100 | 230 | * @tc.name: OnConnectServiceExtensionAbility_0100 |
| 172 | * @tc.desc: basic function test. | 231 | * @tc.desc: basic function test. |
| @@ -247,4 +306,4 @@ HWTEST_F(JsUiServiceExtensionContextSecondTest, OnDisConnectServiceExtensionAbil | |||
| 247 | TAG_LOGI(AAFwkTag::TEST, "OnDisConnectServiceExtensionAbility_0200 end"); | 306 | TAG_LOGI(AAFwkTag::TEST, "OnDisConnectServiceExtensionAbility_0200 end"); |
| 248 | } | 307 | } |
| 249 | } // namespace AbilityRuntime | 308 | } // namespace AbilityRuntime |
| 250 | -} // namespace OHOS | 309 | +} // namespace OHOS |
| @@ -1018,21 +1018,16 @@ HWTEST_F(UIExtensionAbilityManagerTest, AAFwk_AbilityMS_RegisterPreloadUIExtensi | |||
| 1018 | /* | 1018 | /* |
| 1019 | * Feature: UIExtensionAbilityManager | 1019 | * Feature: UIExtensionAbilityManager |
| 1020 | * Function: RegisterPreloadUIExtensionHostClient | 1020 | * Function: RegisterPreloadUIExtensionHostClient |
| 1021 | - * SubFunction: NA | 1021 | + * CaseDescription: Verify registration fails when a local token cannot register a death recipient |
| 1022 | - * FunctionPoints: NA | ||
| 1023 | - * EnvConditions: NA | ||
| 1024 | - * CaseDescription: Verify RegisterPreloadUIExtensionHostClient with valid parameters | ||
| 1025 | */ | 1022 | */ |
| 1026 | HWTEST_F(UIExtensionAbilityManagerTest, AAFwk_AbilityMS_RegisterPreloadUIExtensionHostClient_003, TestSize.Level1) | 1023 | HWTEST_F(UIExtensionAbilityManagerTest, AAFwk_AbilityMS_RegisterPreloadUIExtensionHostClient_003, TestSize.Level1) |
| 1027 | { | 1024 | { |
| 1028 | std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); | 1025 | std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); |
| 1029 | - std::shared_ptr<AbilityRecord> abilityRecord = serviceRecord_; | 1026 | + sptr<IRemoteObject> callerToken = serviceRecord_->GetToken(); |
| 1030 | - ASSERT_NE(abilityRecord, nullptr); | 1027 | + |
| 1031 | - sptr<IRemoteObject> callerToken = abilityRecord->GetToken(); | 1028 | + EXPECT_EQ(connectManager->RegisterPreloadUIExtensionHostClient(callerToken), INNER_ERR); |
| 1032 | - ASSERT_NE(callerToken, nullptr); | 1029 | + EXPECT_TRUE(connectManager->preloadUIExtensionHostClientDeathRecipients_.empty()); |
| 1033 | - | 1030 | + EXPECT_TRUE(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.empty()); |
| 1034 | - int32_t res = connectManager->RegisterPreloadUIExtensionHostClient(callerToken); | ||
| 1035 | - EXPECT_EQ(res, ERR_OK); | ||
| 1036 | } | 1031 | } |
| 1037 | 1032 | ||
| 1038 | /* | 1033 | /* |
| @@ -1073,43 +1068,30 @@ HWTEST_F(UIExtensionAbilityManagerTest, AAFwk_AbilityMS_UnRegisterPreloadUIExten | |||
| 1073 | /* | 1068 | /* |
| 1074 | * Feature: UIExtensionAbilityManager | 1069 | * Feature: UIExtensionAbilityManager |
| 1075 | * Function: UnRegisterPreloadUIExtensionHostClient | 1070 | * Function: UnRegisterPreloadUIExtensionHostClient |
| 1076 | - * SubFunction: NA | 1071 | + * CaseDescription: Verify unregistering an unknown process is idempotent |
| 1077 | - * FunctionPoints: NA | ||
| 1078 | - * EnvConditions: NA | ||
| 1079 | - * CaseDescription: Verify UnRegisterPreloadUIExtensionHostClient with valid callerPid | ||
| 1080 | */ | 1072 | */ |
| 1081 | HWTEST_F(UIExtensionAbilityManagerTest, AAFwk_AbilityMS_UnRegisterPreloadUIExtensionHostClient_003, TestSize.Level1) | 1073 | HWTEST_F(UIExtensionAbilityManagerTest, AAFwk_AbilityMS_UnRegisterPreloadUIExtensionHostClient_003, TestSize.Level1) |
| 1082 | { | 1074 | { |
| 1083 | std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); | 1075 | std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); |
| 1084 | - int32_t callerPid = 5678; | 1076 | + |
| 1085 | - | 1077 | + EXPECT_EQ(connectManager->UnRegisterPreloadUIExtensionHostClient(5678), ERR_OK); |
| 1086 | - int32_t res = connectManager->UnRegisterPreloadUIExtensionHostClient(callerPid); | 1078 | + EXPECT_TRUE(connectManager->preloadUIExtensionHostClientDeathRecipients_.empty()); |
| 1087 | - EXPECT_EQ(res, ERR_OK); | ||
| 1088 | } | 1079 | } |
| 1089 | 1080 | ||
| 1090 | /* | 1081 | /* |
| 1091 | * Feature: UIExtensionAbilityManager | 1082 | * Feature: UIExtensionAbilityManager |
| 1092 | * Function: UnRegisterPreloadUIExtensionHostClient | 1083 | * Function: UnRegisterPreloadUIExtensionHostClient |
| 1093 | - * SubFunction: NA | 1084 | + * CaseDescription: Verify failed registration leaves no state for unregistering |
| 1094 | - * FunctionPoints: NA | ||
| 1095 | - * EnvConditions: NA | ||
| 1096 | - * CaseDescription: Verify UnRegisterPreloadUIExtensionHostClient | ||
| 1097 | */ | 1085 | */ |
| 1098 | HWTEST_F(UIExtensionAbilityManagerTest, AAFwk_AbilityMS_UnRegisterPreloadUIExtensionHostClient_004, TestSize.Level1) | 1086 | HWTEST_F(UIExtensionAbilityManagerTest, AAFwk_AbilityMS_UnRegisterPreloadUIExtensionHostClient_004, TestSize.Level1) |
| 1099 | { | 1087 | { |
| 1100 | std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); | 1088 | std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); |
| 1101 | - std::shared_ptr<AbilityRecord> abilityRecord = serviceRecord_; | 1089 | + sptr<IRemoteObject> callerToken = serviceRecord_->GetToken(); |
| 1102 | - ASSERT_NE(abilityRecord, nullptr); | ||
| 1103 | - sptr<IRemoteObject> callerToken = abilityRecord->GetToken(); | ||
| 1104 | - int32_t callerPid = IPCSkeleton::GetCallingPid(); | ||
| 1105 | - connectManager->RegisterPreloadUIExtensionHostClient(callerToken); | ||
| 1106 | - EXPECT_EQ(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.size(), 1); | ||
| 1107 | - | ||
| 1108 | - connectManager->UnRegisterPreloadUIExtensionHostClient(1); | ||
| 1109 | - EXPECT_EQ(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.size(), 1); | ||
| 1110 | 1090 | ||
| 1111 | - connectManager->UnRegisterPreloadUIExtensionHostClient(callerPid); | 1091 | + EXPECT_EQ(connectManager->RegisterPreloadUIExtensionHostClient(callerToken), INNER_ERR); |
| 1112 | - EXPECT_EQ(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.size(), 0); | 1092 | + EXPECT_EQ(connectManager->UnRegisterPreloadUIExtensionHostClient(IPCSkeleton::GetCallingPid()), ERR_OK); |
| 1093 | + EXPECT_TRUE(connectManager->preloadUIExtensionHostClientDeathRecipients_.empty()); | ||
| 1094 | + EXPECT_TRUE(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.empty()); | ||
| 1113 | } | 1095 | } |
| 1114 | 1096 | ||
| 1115 | /* | 1097 | /* |
| @@ -1340,21 +1322,16 @@ HWTEST_F(UIExtensionAbilityManagerTest, RegisterPreloadUIExtensionHostClient_002 | |||
| 1340 | /* | 1322 | /* |
| 1341 | * Feature: UIExtensionAbilityManager | 1323 | * Feature: UIExtensionAbilityManager |
| 1342 | * Function: RegisterPreloadUIExtensionHostClient | 1324 | * Function: RegisterPreloadUIExtensionHostClient |
| 1343 | - * SubFunction: NA | 1325 | + * CaseDescription: Verify registration fails when a local token cannot register a death recipient |
| 1344 | - * FunctionPoints: NA | ||
| 1345 | - * EnvConditions: NA | ||
| 1346 | - * CaseDescription: Verify RegisterPreloadUIExtensionHostClient with valid parameters | ||
| 1347 | */ | 1326 | */ |
| 1348 | HWTEST_F(UIExtensionAbilityManagerTest, RegisterPreloadUIExtensionHostClient_003, TestSize.Level1) | 1327 | HWTEST_F(UIExtensionAbilityManagerTest, RegisterPreloadUIExtensionHostClient_003, TestSize.Level1) |
| 1349 | { | 1328 | { |
| 1350 | std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); | 1329 | std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); |
| 1351 | - std::shared_ptr<AbilityRecord> abilityRecord = serviceRecord_; | 1330 | + sptr<IRemoteObject> callerToken = serviceRecord_->GetToken(); |
| 1352 | - ASSERT_NE(abilityRecord, nullptr); | 1331 | + |
| 1353 | - sptr<IRemoteObject> callerToken = abilityRecord->GetToken(); | 1332 | + EXPECT_EQ(connectManager->RegisterPreloadUIExtensionHostClient(callerToken), INNER_ERR); |
| 1354 | - ASSERT_NE(callerToken, nullptr); | 1333 | + EXPECT_TRUE(connectManager->preloadUIExtensionHostClientDeathRecipients_.empty()); |
| 1355 | - | 1334 | + EXPECT_TRUE(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.empty()); |
| 1356 | - int32_t res = connectManager->RegisterPreloadUIExtensionHostClient(callerToken); | ||
| 1357 | - EXPECT_EQ(res, ERR_OK); | ||
| 1358 | } | 1335 | } |
| 1359 | 1336 | ||
| 1360 | /* | 1337 | /* |
| @@ -1395,43 +1372,30 @@ HWTEST_F(UIExtensionAbilityManagerTest, UnRegisterPreloadUIExtensionHostClient_0 | |||
| 1395 | /* | 1372 | /* |
| 1396 | * Feature: UIExtensionAbilityManager | 1373 | * Feature: UIExtensionAbilityManager |
| 1397 | * Function: UnRegisterPreloadUIExtensionHostClient | 1374 | * Function: UnRegisterPreloadUIExtensionHostClient |
| 1398 | - * SubFunction: NA | 1375 | + * CaseDescription: Verify unregistering an unknown process is idempotent |
| 1399 | - * FunctionPoints: NA | ||
| 1400 | - * EnvConditions: NA | ||
| 1401 | - * CaseDescription: Verify UnRegisterPreloadUIExtensionHostClient with valid callerPid | ||
| 1402 | */ | 1376 | */ |
| 1403 | HWTEST_F(UIExtensionAbilityManagerTest, UnRegisterPreloadUIExtensionHostClient_003, TestSize.Level1) | 1377 | HWTEST_F(UIExtensionAbilityManagerTest, UnRegisterPreloadUIExtensionHostClient_003, TestSize.Level1) |
| 1404 | { | 1378 | { |
| 1405 | std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); | 1379 | std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); |
| 1406 | - int32_t callerPid = 5678; | 1380 | + |
| 1407 | - | 1381 | + EXPECT_EQ(connectManager->UnRegisterPreloadUIExtensionHostClient(5678), ERR_OK); |
| 1408 | - int32_t res = connectManager->UnRegisterPreloadUIExtensionHostClient(callerPid); | 1382 | + EXPECT_TRUE(connectManager->preloadUIExtensionHostClientDeathRecipients_.empty()); |
| 1409 | - EXPECT_EQ(res, ERR_OK); | ||
| 1410 | } | 1383 | } |
| 1411 | 1384 | ||
| 1412 | /* | 1385 | /* |
| 1413 | * Feature: UIExtensionAbilityManager | 1386 | * Feature: UIExtensionAbilityManager |
| 1414 | * Function: UnRegisterPreloadUIExtensionHostClient | 1387 | * Function: UnRegisterPreloadUIExtensionHostClient |
| 1415 | - * SubFunction: NA | 1388 | + * CaseDescription: Verify failed registration leaves no state for unregistering |
| 1416 | - * FunctionPoints: NA | ||
| 1417 | - * EnvConditions: NA | ||
| 1418 | - * CaseDescription: Verify UnRegisterPreloadUIExtensionHostClient | ||
| 1419 | */ | 1389 | */ |
| 1420 | HWTEST_F(UIExtensionAbilityManagerTest, UnRegisterPreloadUIExtensionHostClient_004, TestSize.Level1) | 1390 | HWTEST_F(UIExtensionAbilityManagerTest, UnRegisterPreloadUIExtensionHostClient_004, TestSize.Level1) |
| 1421 | { | 1391 | { |
| 1422 | std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); | 1392 | std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); |
| 1423 | - std::shared_ptr<AbilityRecord> abilityRecord = serviceRecord_; | 1393 | + sptr<IRemoteObject> callerToken = serviceRecord_->GetToken(); |
| 1424 | - ASSERT_NE(abilityRecord, nullptr); | ||
| 1425 | - sptr<IRemoteObject> callerToken = abilityRecord->GetToken(); | ||
| 1426 | - int32_t callerPid = IPCSkeleton::GetCallingPid(); | ||
| 1427 | - connectManager->RegisterPreloadUIExtensionHostClient(callerToken); | ||
| 1428 | - EXPECT_EQ(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.size(), 1); | ||
| 1429 | - | ||
| 1430 | - connectManager->UnRegisterPreloadUIExtensionHostClient(1); | ||
| 1431 | - EXPECT_EQ(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.size(), 1); | ||
| 1432 | 1394 | ||
| 1433 | - connectManager->UnRegisterPreloadUIExtensionHostClient(callerPid); | 1395 | + EXPECT_EQ(connectManager->RegisterPreloadUIExtensionHostClient(callerToken), INNER_ERR); |
| 1434 | - EXPECT_EQ(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.size(), 0); | 1396 | + EXPECT_EQ(connectManager->UnRegisterPreloadUIExtensionHostClient(IPCSkeleton::GetCallingPid()), ERR_OK); |
| 1397 | + EXPECT_TRUE(connectManager->preloadUIExtensionHostClientDeathRecipients_.empty()); | ||
| 1398 | + EXPECT_TRUE(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.empty()); | ||
| 1435 | } | 1399 | } |
| 1436 | 1400 | ||
| 1437 | /* | 1401 | /* |
| @@ -0,0 +1,101 @@ | |||
| 1 | +# Copyright (c) 2026 Huawei Device Co., Ltd. | ||
| 2 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 3 | +# you may not use this file except in compliance with the License. | ||
| 4 | +# You may obtain a copy of the License at | ||
| 5 | +# | ||
| 6 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 7 | +# | ||
| 8 | +# Unless required by applicable law or agreed to in writing, software | ||
| 9 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 10 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 11 | +# See the License for the specific language governing permissions and | ||
| 12 | +# limitations under the License. | ||
| 13 | + | ||
| 14 | +import("//build/test.gni") | ||
| 15 | +import("//foundation/ability/ability_runtime/ability_runtime.gni") | ||
| 16 | + | ||
| 17 | +module_output_path = "ability_runtime/ability_runtime/ui_extension_ability_manager_third" | ||
| 18 | + | ||
| 19 | +ohos_unittest("ui_extension_ability_manager_third_test") { | ||
| 20 | + module_out_path = module_output_path | ||
| 21 | + sanitize = { | ||
| 22 | + cfi = true | ||
| 23 | + cfi_cross_dso = true | ||
| 24 | + debug = false | ||
| 25 | + blocklist = "../../cfi_blocklist.txt" | ||
| 26 | + } | ||
| 27 | + branch_protector_ret = "pac_ret" | ||
| 28 | + | ||
| 29 | + include_dirs = [ | ||
| 30 | + "${ability_runtime_test_path}/mock/services_abilitymgr_test/libs/system_ability_mock", | ||
| 31 | + "${ability_runtime_test_path}/mock/frameworks_kits_ability_native_test/include", | ||
| 32 | + "${ability_runtime_test_path}/mock/mock_sa_call", | ||
| 33 | + "${ability_runtime_test_path}/mock/task_handler_wrap_mock/include", | ||
| 34 | + ] | ||
| 35 | + | ||
| 36 | + sources = [ | ||
| 37 | + # add mock file | ||
| 38 | + "${ability_runtime_test_path}/mock/services_abilitymgr_test/libs/appexecfwk_core/src/appmgr/mock_app_scheduler.cpp", | ||
| 39 | + "${ability_runtime_test_path}/mock/task_handler_wrap_mock/src/mock_task_handler_wrap.cpp", | ||
| 40 | + "ui_extension_ability_manager_third_test.cpp", | ||
| 41 | + ] | ||
| 42 | + | ||
| 43 | + configs = [ | ||
| 44 | + "${ability_runtime_services_path}/abilitymgr:abilityms_config", | ||
| 45 | + "${ability_runtime_test_path}/mock/services_abilitymgr_test:aafwk_mock_config", | ||
| 46 | + ] | ||
| 47 | + cflags = [] | ||
| 48 | + if (target_cpu == "arm") { | ||
| 49 | + cflags += [ "-DBINDER_IPC_32BIT" ] | ||
| 50 | + } | ||
| 51 | + deps = [ | ||
| 52 | + "${ability_runtime_innerkits_path}/ability_manager:ability_connect_callback_stub", | ||
| 53 | + "${ability_runtime_innerkits_path}/ability_manager:ability_manager", | ||
| 54 | + "${ability_runtime_innerkits_path}/deps_wrapper:ability_deps_wrapper", | ||
| 55 | + "${ability_runtime_native_path}/ability/native:abilitykit_native", | ||
| 56 | + "${ability_runtime_services_path}/abilitymgr:abilityms", | ||
| 57 | + "${ability_runtime_services_path}/common:perm_verification", | ||
| 58 | + "${ability_runtime_services_path}/common:task_handler_wrap", | ||
| 59 | + "${ability_runtime_test_path}/mock/services_abilitymgr_test/libs/aakit:aakit_mock", | ||
| 60 | + "${ability_runtime_test_path}/mock/services_abilitymgr_test/libs/appexecfwk_core:appexecfwk_bundlemgr_mock", | ||
| 61 | + ] | ||
| 62 | + | ||
| 63 | + external_deps = [ | ||
| 64 | + "ability_base:want", | ||
| 65 | + "ability_base:zuri", | ||
| 66 | + "access_token:libaccesstoken_sdk", | ||
| 67 | + "access_token:libnativetoken", | ||
| 68 | + "access_token:libtoken_setproc", | ||
| 69 | + "c_utils:utils", | ||
| 70 | + "common_event_service:cesfwk_innerkits", | ||
| 71 | + "eventhandler:libeventhandler", | ||
| 72 | + "ffrt:libffrt", | ||
| 73 | + "googletest:gmock_main", | ||
| 74 | + "googletest:gtest_main", | ||
| 75 | + "hilog:libhilog", | ||
| 76 | + "hisysevent:libhisysevent", | ||
| 77 | + "init:libbeget_proxy", | ||
| 78 | + "ipc:ipc_core", | ||
| 79 | + "napi:ace_napi", | ||
| 80 | + "safwk:system_ability_fwk", | ||
| 81 | + "samgr:samgr_proxy", | ||
| 82 | + "selinux_adapter:librestorecon", | ||
| 83 | + ] | ||
| 84 | + | ||
| 85 | + if (ability_runtime_graphics) { | ||
| 86 | + external_deps += [ | ||
| 87 | + "image_framework:image_native", | ||
| 88 | + "window_manager:libwsutils", | ||
| 89 | + "window_manager:scene_session", | ||
| 90 | + ] | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + if (background_task_mgr_continuous_task_enable) { | ||
| 94 | + external_deps += [ "background_task_mgr:bgtaskmgr_innerkits" ] | ||
| 95 | + } | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | +group("unittest") { | ||
| 99 | + testonly = true | ||
| 100 | + deps = [ ":ui_extension_ability_manager_third_test" ] | ||
| 101 | +} | ||
Atest/unittest/ui_extension_ability_manager_third_test/ui_extension_ability_manager_third_test.cpp+189-0
| @@ -0,0 +1,189 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + | ||
| 34 | +using namespace testing::ext; | ||
| 35 | + | ||
| 36 | +namespace OHOS { | ||
| 37 | +namespace AAFwk { | ||
| 38 | +class MockPreloadHostClient final : public IRemoteObject { | ||
| 39 | +public: | ||
| 40 | + explicit MockPreloadHostClient(bool addDeathRecipientResult) | ||
| 41 | + : IRemoteObject(u"mock_preload_host_client"), addDeathRecipientResult_(addDeathRecipientResult) | ||
| 42 | + {} | ||
| 43 | + | ||
| 44 | + ~MockPreloadHostClient() override = default; | ||
| 45 | + | ||
| 46 | + int32_t GetObjectRefCount() override | ||
| 47 | + { | ||
| 48 | + return 0; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + int SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override | ||
| 52 | + { | ||
| 53 | + (void)code; | ||
| 54 | + (void)data; | ||
| 55 | + (void)reply; | ||
| 56 | + (void)option; | ||
| 57 | + return ERR_OK; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + bool IsProxyObject() const override | ||
| 61 | + { | ||
| 62 | + return true; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + bool CheckObjectLegality() const override | ||
| 66 | + { | ||
| 67 | + return true; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + bool AddDeathRecipient(const sptr<DeathRecipient> &recipient) override | ||
| 71 | + { | ||
| 72 | + addDeathRecipientCount_++; | ||
| 73 | + deathRecipient_ = recipient; | ||
| 74 | + return addDeathRecipientResult_; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + bool RemoveDeathRecipient(const sptr<DeathRecipient> &recipient) override | ||
| 78 | + { | ||
| 79 | + removeDeathRecipientCount_++; | ||
| 80 | + return recipient == deathRecipient_; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + bool Marshalling(Parcel &parcel) const override | ||
| 84 | + { | ||
| 85 | + (void)parcel; | ||
| 86 | + return true; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + sptr<IRemoteBroker> AsInterface() override | ||
| 90 | + { | ||
| 91 | + return nullptr; | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + int Dump(int fd, const std::vector<std::u16string> &args) override | ||
| 95 | + { | ||
| 96 | + (void)fd; | ||
| 97 | + (void)args; | ||
| 98 | + return ERR_OK; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + bool addDeathRecipientResult_ = true; | ||
| 102 | + int32_t addDeathRecipientCount_ = 0; | ||
| 103 | + int32_t removeDeathRecipientCount_ = 0; | ||
| 104 | + sptr<DeathRecipient> deathRecipient_ = nullptr; | ||
| 105 | +}; | ||
| 106 | + | ||
| 107 | +class UIExtensionAbilityManagerThirdTest : public testing::Test {}; | ||
| 108 | + | ||
| 109 | +/* | ||
| 110 | + * Feature: UIExtensionAbilityManager | ||
| 111 | + * Function: RegisterPreloadUIExtensionHostClient | ||
| 112 | + * CaseDescription: Verify successful registration and unregister cleanup | ||
| 113 | + */ | ||
| 114 | +HWTEST_F(UIExtensionAbilityManagerThirdTest, RegisterPreloadUIExtensionHostClient_006, TestSize.Level1) | ||
| 115 | +{ | ||
| 116 | + std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); | ||
| 117 | + sptr<MockPreloadHostClient> callerToken = new MockPreloadHostClient(true); | ||
| 118 | + const int32_t callerPid = IPCSkeleton::GetCallingPid(); | ||
| 119 | + | ||
| 120 | + int32_t res = connectManager->RegisterPreloadUIExtensionHostClient(callerToken); | ||
| 121 | + | ||
| 122 | + EXPECT_EQ(res, ERR_OK); | ||
| 123 | + EXPECT_EQ(callerToken->addDeathRecipientCount_, 1); | ||
| 124 | + EXPECT_EQ(connectManager->preloadUIExtensionHostClientDeathRecipients_.count(callerPid), 1); | ||
| 125 | + EXPECT_EQ(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.count( | ||
| 126 | + callerPid), 1); | ||
| 127 | + | ||
| 128 | + res = connectManager->UnRegisterPreloadUIExtensionHostClient(callerPid + 1); | ||
| 129 | + EXPECT_EQ(res, ERR_OK); | ||
| 130 | + EXPECT_EQ(callerToken->removeDeathRecipientCount_, 0); | ||
| 131 | + EXPECT_EQ(connectManager->preloadUIExtensionHostClientDeathRecipients_.count(callerPid), 1); | ||
| 132 | + EXPECT_EQ(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.count( | ||
| 133 | + callerPid), 1); | ||
| 134 | + | ||
| 135 | + res = connectManager->UnRegisterPreloadUIExtensionHostClient(callerPid); | ||
| 136 | + EXPECT_EQ(res, ERR_OK); | ||
| 137 | + EXPECT_EQ(callerToken->removeDeathRecipientCount_, 1); | ||
| 138 | + EXPECT_TRUE(connectManager->preloadUIExtensionHostClientDeathRecipients_.empty()); | ||
| 139 | + EXPECT_TRUE(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.empty()); | ||
| 140 | +} | ||
| 141 | + | ||
| 142 | +/* | ||
| 143 | + * Feature: UIExtensionAbilityManager | ||
| 144 | + * Function: RegisterPreloadUIExtensionHostClient | ||
| 145 | + * CaseDescription: Verify registration rollback when adding a death recipient fails | ||
| 146 | + */ | ||
| 147 | +HWTEST_F(UIExtensionAbilityManagerThirdTest, RegisterPreloadUIExtensionHostClient_007, TestSize.Level1) | ||
| 148 | +{ | ||
| 149 | + std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); | ||
| 150 | + sptr<MockPreloadHostClient> callerToken = new MockPreloadHostClient(false); | ||
| 151 | + | ||
| 152 | + int32_t res = connectManager->RegisterPreloadUIExtensionHostClient(callerToken); | ||
| 153 | + | ||
| 154 | + EXPECT_EQ(res, INNER_ERR); | ||
| 155 | + EXPECT_EQ(callerToken->addDeathRecipientCount_, 1); | ||
| 156 | + EXPECT_EQ(callerToken->removeDeathRecipientCount_, 0); | ||
| 157 | + EXPECT_TRUE(connectManager->preloadUIExtensionHostClientDeathRecipients_.empty()); | ||
| 158 | + EXPECT_TRUE(connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.empty()); | ||
| 159 | +} | ||
| 160 | + | ||
| 161 | +/* | ||
| 162 | + * Feature: UIExtensionAbilityManager | ||
| 163 | + * Function: RegisterPreloadUIExtensionHostClient | ||
| 164 | + * CaseDescription: Verify duplicate registration for the same process is idempotent | ||
| 165 | + */ | ||
| 166 | +HWTEST_F(UIExtensionAbilityManagerThirdTest, RegisterPreloadUIExtensionHostClient_008, TestSize.Level1) | ||
| 167 | +{ | ||
| 168 | + std::shared_ptr<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(0); | ||
| 169 | + sptr<MockPreloadHostClient> firstCallerToken = new MockPreloadHostClient(true); | ||
| 170 | + sptr<MockPreloadHostClient> secondCallerToken = new MockPreloadHostClient(true); | ||
| 171 | + const int32_t callerPid = IPCSkeleton::GetCallingPid(); | ||
| 172 | + | ||
| 173 | + EXPECT_EQ(connectManager->RegisterPreloadUIExtensionHostClient(firstCallerToken), ERR_OK); | ||
| 174 | + EXPECT_EQ(connectManager->RegisterPreloadUIExtensionHostClient(secondCallerToken), ERR_OK); | ||
| 175 | + | ||
| 176 | + EXPECT_EQ(firstCallerToken->addDeathRecipientCount_, 1); | ||
| 177 | + EXPECT_EQ(secondCallerToken->addDeathRecipientCount_, 0); | ||
| 178 | + EXPECT_EQ(connectManager->preloadUIExtensionHostClientDeathRecipients_.size(), 1); | ||
| 179 | + auto tokenIter = connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.find( | ||
| 180 | + callerPid); | ||
| 181 | + ASSERT_NE(tokenIter, | ||
| 182 | + connectManager->uiExtensionAbilityRecordMgr_->preloadUIExtensionHostClientCallerTokens_.end()); | ||
| 183 | + sptr<IRemoteObject> expectedCallerToken = firstCallerToken; | ||
| 184 | + EXPECT_EQ(tokenIter->second, expectedCallerToken); | ||
| 185 | + | ||
| 186 | + EXPECT_EQ(connectManager->UnRegisterPreloadUIExtensionHostClient(callerPid), ERR_OK); | ||
| 187 | +} | ||
| 188 | +} // namespace AAFwk | ||
| 189 | +} // namespace OHOS | ||
| @@ -33,6 +33,7 @@ ohos_unittest("wants_info_test") { | |||
| 33 | external_deps = [ | 33 | external_deps = [ |
| 34 | "ability_base:want", | 34 | "ability_base:want", |
| 35 | "c_utils:utils", | 35 | "c_utils:utils", |
| 36 | + "hilog:libhilog", | ||
| 36 | "ipc:ipc_core", | 37 | "ipc:ipc_core", |
| 37 | ] | 38 | ] |
| 38 | } | 39 | } |
| @@ -13,7 +13,9 @@ | |||
| 13 | * limitations under the License. | 13 | * limitations under the License. |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | + | ||
| 16 | 17 | ||
| 18 | + | ||
| 17 | 19 | ||
| 18 | 20 | ||
| 19 | 21 | ||
| @@ -28,8 +30,38 @@ using OHOS::AppExecFwk::ElementName; | |||
| 28 | 30 | ||
| 29 | namespace OHOS { | 31 | namespace OHOS { |
| 30 | namespace AAFwk { | 32 | namespace AAFwk { |
| 31 | -#define SLEEP(milli) std::this_thread::sleep_for(std::chrono::seconds(milli)) | 33 | +namespace { |
| 32 | -namespace {} // namespace | 34 | +class LimitedAllocator final : public Allocator { |
| 35 | +public: | ||
| 36 | + explicit LimitedAllocator(size_t maxAllocationSize) : maxAllocationSize_(maxAllocationSize) {} | ||
| 37 | + | ||
| 38 | + ~LimitedAllocator() override = default; | ||
| 39 | + | ||
| 40 | + void *Realloc(void *data, size_t newSize) override | ||
| 41 | + { | ||
| 42 | + if (newSize > maxAllocationSize_) { | ||
| 43 | + return nullptr; | ||
| 44 | + } | ||
| 45 | + return std::realloc(data, newSize); | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + void *Alloc(size_t size) override | ||
| 49 | + { | ||
| 50 | + if (size > maxAllocationSize_) { | ||
| 51 | + return nullptr; | ||
| 52 | + } | ||
| 53 | + return std::malloc(size); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + void Dealloc(void *data) override | ||
| 57 | + { | ||
| 58 | + std::free(data); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | +private: | ||
| 62 | + size_t maxAllocationSize_; | ||
| 63 | +}; | ||
| 64 | +} // namespace | ||
| 33 | class WantsInfoTest : public testing::Test { | 65 | class WantsInfoTest : public testing::Test { |
| 34 | public: | 66 | public: |
| 35 | static void SetUpTestCase(); | 67 | static void SetUpTestCase(); |
| @@ -66,12 +98,49 @@ HWTEST_F(WantsInfoTest, WantsInfoTest_0100, TestSize.Level1) | |||
| 66 | info.want = want; | 98 | info.want = want; |
| 67 | info.resolvedTypes = "nihao"; | 99 | info.resolvedTypes = "nihao"; |
| 68 | Parcel parcel; | 100 | Parcel parcel; |
| 69 | - info.Marshalling(parcel); | 101 | + ASSERT_TRUE(info.Marshalling(parcel)); |
| 70 | auto unInfo = WantsInfo::Unmarshalling(parcel); | 102 | auto unInfo = WantsInfo::Unmarshalling(parcel); |
| 103 | + ASSERT_NE(unInfo, nullptr); | ||
| 71 | EXPECT_EQ(unInfo->want.GetElement().GetBundleName(), "com.ix.hiMusic"); | 104 | EXPECT_EQ(unInfo->want.GetElement().GetBundleName(), "com.ix.hiMusic"); |
| 72 | EXPECT_EQ(unInfo->want.GetElement().GetAbilityName(), "MusicSAbility"); | 105 | EXPECT_EQ(unInfo->want.GetElement().GetAbilityName(), "MusicSAbility"); |
| 73 | EXPECT_EQ(unInfo->resolvedTypes, "nihao"); | 106 | EXPECT_EQ(unInfo->resolvedTypes, "nihao"); |
| 74 | delete unInfo; | 107 | delete unInfo; |
| 75 | } | 108 | } |
| 109 | + | ||
| 110 | +/* | ||
| 111 | + * @tc.number : WantsInfoTest_0200 | ||
| 112 | + * @tc.name : Marshalling want failure | ||
| 113 | + * @tc.desc : Marshalling returns false when the Want cannot be written. | ||
| 114 | + */ | ||
| 115 | +HWTEST_F(WantsInfoTest, WantsInfoTest_0200, TestSize.Level1) | ||
| 116 | +{ | ||
| 117 | + WantsInfo info; | ||
| 118 | + Parcel parcel(new LimitedAllocator(0)); | ||
| 119 | + | ||
| 120 | + EXPECT_FALSE(info.Marshalling(parcel)); | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | +/* | ||
| 124 | + * @tc.number : WantsInfoTest_0300 | ||
| 125 | + * @tc.name : Marshalling resolvedTypes failure | ||
| 126 | + * @tc.desc : Marshalling returns false when resolvedTypes cannot be written after the Want. | ||
| 127 | + */ | ||
| 128 | +HWTEST_F(WantsInfoTest, WantsInfoTest_0300, TestSize.Level1) | ||
| 129 | +{ | ||
| 130 | + WantsInfo info; | ||
| 131 | + Want want; | ||
| 132 | + ElementName element("device", "com.ix.hiMusic", "MusicSAbility"); | ||
| 133 | + want.SetElement(element); | ||
| 134 | + info.want = want; | ||
| 135 | + | ||
| 136 | + Parcel wantParcel; | ||
| 137 | + ASSERT_TRUE(wantParcel.WriteParcelable(&info.want)); | ||
| 138 | + const size_t wantParcelCapacity = wantParcel.GetDataCapacity(); | ||
| 139 | + ASSERT_GT(wantParcelCapacity, 0); | ||
| 140 | + info.resolvedTypes.assign(wantParcelCapacity, 'a'); | ||
| 141 | + Parcel parcel(new LimitedAllocator(wantParcelCapacity)); | ||
| 142 | + | ||
| 143 | + EXPECT_FALSE(info.Marshalling(parcel)); | ||
| 144 | +} | ||
| 76 | } // namespace AAFwk | 145 | } // namespace AAFwk |
| 77 | } // namespace OHOS | 146 | } // namespace OHOS |
补充判空