IssueNo:#I65N2Z:新增组件拦截器

Description:component interception
Sig:ability_ability_runtime
Feature or Bugfix:Bugfix
Binary Source:No

Signed-off-by: wangdengjia <wangdengjia@huawei.com>
This commit is contained in:
wangdengjia
2022-12-11 11:20:50 +08:00
parent 4b490e49e9
commit 0bdac65a8a
14 changed files with 468 additions and 6 deletions
@@ -27,6 +27,7 @@
#include "ability_start_setting.h"
#include "extension_running_info.h"
#include "iability_controller.h"
#include "icomponent_interception.h"
#include "mission_listener_interface.h"
#include "mission_info.h"
#include "mission_snapshot.h"
@@ -551,6 +552,14 @@ public:
virtual int SetAbilityController(const sptr<AppExecFwk::IAbilityController> &abilityController,
bool imAStabilityTest) = 0;
/**
* Set component interception.
*
* @param componentInterception, component interception.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int SetComponentInterception(const sptr<AppExecFwk::IComponentInterception> &componentInterception) {};
/**
* Is user a stability test.
*
@@ -860,6 +869,8 @@ public:
// stop extension ability (61)
STOP_EXTENSION_ABILITY,
SET_COMPONENT_INTERCEPTION,
// ipc id 1001-2000 for DMS
// ipc id for starting ability (1001)
START_ABILITY = 1001,
@@ -69,6 +69,8 @@ ohos_shared_library("app_manager") {
"src/appmgr/app_task_info.cpp",
"src/appmgr/application_state_observer_proxy.cpp",
"src/appmgr/application_state_observer_stub.cpp",
"src/appmgr/component_interception_proxy.cpp",
"src/appmgr/component_interception_stub.cpp",
"src/appmgr/configuration_observer_proxy.cpp",
"src/appmgr/configuration_observer_stub.cpp",
"src/appmgr/priority_object.cpp",
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_ABILITY_RUNTIME_COMPONENT_INTERCEPTION_PROXY_H
#define OHOS_ABILITY_RUNTIME_COMPONENT_INTERCEPTION_PROXY_H
#include "iremote_proxy.h"
#include "icomponent_interception.h"
namespace OHOS {
namespace AppExecFwk {
/**
* @brief Interface to monitor what is happening in component manager.
*/
class ComponentInterceptionProxy : public IRemoteProxy<IComponentInterception> {
public:
explicit ComponentInterceptionProxy(const sptr<IRemoteObject> &impl);
virtual ~ComponentInterceptionProxy() = default;
/**
* The system is trying to start an component.
*
* @param want The want of component to start.
* @param callerToken Caller component token.
* @param requestCode the requestCode of the component to start.
* @param componentStatus the status of component.
* @param extraParam The extra param of component to start.
* @return Return true to allow component to start, or false to reject.
*/
virtual bool AllowComponentStart(const Want &want, const sptr<IRemoteObject> &callerToken,
int requestCode, int componentStatus, sptr<Want> &extraParam) override;
private:
bool WriteInterfaceToken(MessageParcel &data);
void SetExtraParam(const sptr<Want> &want, sptr<Want> &extraParam);
static inline BrokerDelegator<ComponentInterceptionProxy> delegator_;
};
} // namespace AppExecFwk
} // namespace OHOS
#endif
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_ABILITY_RUNTIME_COMPONENT_INTERCEPTION_STUB_H
#define OHOS_ABILITY_RUNTIME_COMPONENT_INTERCEPTION_STUB_H
#include "iremote_stub.h"
#include "icomponent_interception.h"
namespace OHOS {
namespace AppExecFwk {
/**
* @brief Interface to monitor what is happening in component manager.
*/
class ComponentInterceptionStub : public IRemoteStub<IComponentInterception> {
public:
ComponentInterceptionStub();
virtual ~ComponentInterceptionStub();
virtual int OnRemoteRequest(
uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
/**
* The system is trying to start an component.
*
* @param want The want of component to start.
* @param callerToken Caller component token.
* @param requestCode the requestCode of the component to start.
* @param componentStatus the status of component.
* @param extraParam The extra param of component to start.
* @return Return true to allow component to start, or false to reject.
*/
virtual bool AllowComponentStart(const Want &want, const sptr<IRemoteObject> &callerToken,
int requestCode, int componentStatus, sptr<Want> &extraParam) override;
private:
using ComponentInterceptionFunc = int32_t (ComponentInterceptionStub::*)
(MessageParcel &data, MessageParcel &reply);
std::map<uint32_t, ComponentInterceptionFunc> requestFuncMap_;
int32_t HandleAllowComponentStart(MessageParcel &data, MessageParcel &reply);
DISALLOW_COPY_AND_MOVE(ComponentInterceptionStub);
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_COMPONENT_INTERCEPTION_STUB_H
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_ABILITY_RUNTIME_COMPONENT_INTERCEPTION_H
#define OHOS_ABILITY_RUNTIME_COMPONENT_INTERCEPTION_H
#include "iremote_broker.h"
#include "iremote_object.h"
#include "want.h"
namespace OHOS {
namespace AppExecFwk {
using OHOS::AAFwk::Want;
/**
* @brief Interface to monitor what is happening in component manager.
*/
class IComponentInterception : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.appexecfwk.IComponentInterception");
/**
* The system is trying to start an component.
*
* @param want The want of component to start.
* @param callerToken Caller component token.
* @param requestCode the requestCode of the component to start.
* @param componentStatus the status of component.
* @param extraParam The extra param of component to start.
* @return Return true to allow component to start, or false to reject.
*/
virtual bool AllowComponentStart(const Want &want, const sptr<IRemoteObject> &callerToken,
int requestCode, int componentStatus, sptr<Want> &extraParam) = 0;
enum class Message {
TRANSACT_ON_ALLOW_COMPONENT_START = 1,
};
};
} // namespace AppExecFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_COMPONENT_INTERCEPTION_H
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "component_interception_proxy.h"
#include "hilog_wrapper.h"
#include "ipc_types.h"
namespace OHOS {
namespace AppExecFwk {
ComponentInterceptionProxy::ComponentInterceptionProxy(
const sptr<IRemoteObject> &impl) : IRemoteProxy<IComponentInterception>(impl)
{}
bool ComponentInterceptionProxy::WriteInterfaceToken(MessageParcel &data)
{
if (!data.WriteInterfaceToken(ComponentInterceptionProxy::GetDescriptor())) {
HILOG_ERROR("write interface token failed");
return false;
}
return true;
}
bool ComponentInterceptionProxy::AllowComponentStart(const Want &want, const sptr<IRemoteObject> &callerToken,
int requestCode, int componentStatus, sptr<Want> &extraParam)
{
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
if (!WriteInterfaceToken(data)) {
return true;
}
data.WriteParcelable(&want);
data.WriteRemoteObject(callerToken);
data.WriteInt32(requestCode);
data.WriteInt32(componentStatus);
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
HILOG_ERROR("Remote() is NULL");
return true;
}
int32_t ret = remote->SendRequest(
static_cast<uint32_t>(IComponentInterception::Message::TRANSACT_ON_ALLOW_COMPONENT_START),
data, reply, option);
if (ret != NO_ERROR) {
HILOG_WARN("SendRequest is failed, error code: %{public}d", ret);
return true;
}
bool hasExtraParam = reply.ReadBool();
if (hasExtraParam) {
sptr<Want> tempWant = reply.ReadParcelable<Want>();
if (tempWant != nullptr) {
SetExtraParam(tempWant, extraParam);
}
}
return reply.ReadBool();
}
void ComponentInterceptionProxy::SetExtraParam(const sptr<Want> &want, sptr<Want> &extraParam)
{
sptr<IRemoteObject> tempCallBack = want->GetRemoteObject(Want::PARAM_RESV_ABILITY_INFO_CALLBACK);
if (tempCallBack == nullptr) {
return;
}
extraParam->SetParam(Want::PARAM_RESV_REQUEST_PROC_CODE,
want->GetIntParam(Want::PARAM_RESV_REQUEST_PROC_CODE, 0));
extraParam->SetParam(Want::PARAM_RESV_REQUEST_TOKEN_CODE,
want->GetIntParam(Want::PARAM_RESV_REQUEST_TOKEN_CODE, 0));
extraParam->SetParam(Want::PARAM_RESV_ABILITY_INFO_CALLBACK, tempCallBack);
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "component_interception_stub.h"
#include "appexecfwk_errors.h"
#include "hilog_wrapper.h"
#include "ipc_types.h"
#include "iremote_object.h"
namespace OHOS {
namespace AppExecFwk {
ComponentInterceptionStub::ComponentInterceptionStub()
{
requestFuncMap_[static_cast<uint32_t>(
IComponentInterception::Message::TRANSACT_ON_ALLOW_COMPONENT_START)] =
&ComponentInterceptionStub::HandleAllowComponentStart;
}
ComponentInterceptionStub::~ComponentInterceptionStub()
{
requestFuncMap_.clear();
}
int ComponentInterceptionStub::OnRemoteRequest(
uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
HILOG_INFO("ComponentInterceptionStub::OnReceived, code = %{public}u, flags= %{public}d.", code, option.GetFlags());
std::u16string descriptor = ComponentInterceptionStub::GetDescriptor();
std::u16string remoteDescriptor = data.ReadInterfaceToken();
if (descriptor != remoteDescriptor) {
HILOG_ERROR("local descriptor is not equal to remote");
return ERR_INVALID_STATE;
}
auto itFunc = requestFuncMap_.find(code);
if (itFunc != requestFuncMap_.end()) {
auto requestFunc = itFunc->second;
if (requestFunc != nullptr) {
return (this->*requestFunc)(data, reply);
}
}
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
bool ComponentInterceptionStub::AllowComponentStart(const Want &want, const sptr<IRemoteObject> &callerToken,
int requestCode, int componentStatus, sptr<Want> &extraParam)
{
return true;
}
int32_t ComponentInterceptionStub::HandleAllowComponentStart(MessageParcel &data, MessageParcel &reply)
{
HILOG_INFO("HandleAllowComponentStart");
std::unique_ptr<Want> want(data.ReadParcelable<Want>());
if (!want) {
HILOG_ERROR("ReadParcelable<Want> failed");
return ERR_APPEXECFWK_PARCEL_ERROR;
}
sptr<IRemoteObject> token = data.ReadRemoteObject();
int requestCode = data.ReadInt32();
int componentStatus = data.ReadInt32();
sptr<Want> extraParam = new (std::nothrow) Want();
bool result = AllowComponentStart(*want, token, requestCode, componentStatus, extraParam);
if (want->GetRemoteObject(Want::PARAM_RESV_ABILITY_INFO_CALLBACK)) {
reply.WriteBool(true);
reply.WriteParcelable(extraParam);
} else {
reply.WriteBool(false);
}
reply.WriteBool(result);
return NO_ERROR;
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -475,6 +475,9 @@ public:
virtual int SetAbilityController(const sptr<AppExecFwk::IAbilityController> &abilityController,
bool imAStabilityTest) override;
virtual int SetComponentInterception(
const sptr<AppExecFwk::IComponentInterception> &componentInterception) override;
/**
* Is user a stability test.
*
@@ -713,6 +713,14 @@ public:
*/
virtual int DoAbilityBackground(const sptr<IRemoteObject> &token, uint32_t flag) override;
/**
* Set component interception.
*
* @param componentInterception, component interception.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int SetComponentInterception(const sptr<AppExecFwk::IComponentInterception> &componentInterception) override;
bool IsAbilityControllerStart(const Want &want, const std::string &bundleName);
bool IsAbilityControllerForeground(const std::string &bundleName);
@@ -721,6 +729,9 @@ public:
void GrantUriPermission(const Want &want, int32_t validUserId, uint32_t targetTokenId);
bool IsComponentInterceptionStart(const Want &want, const sptr<IRemoteObject> &callerToken,
int requestCode, int componentStatus, AbilityRequest &request);
/**
* Send not response process ID to ability manager service.
* @param pid The not response process ID.
@@ -1164,6 +1175,8 @@ private:
void InitStartupFlag();
void UpdateAbilityRequestInfo(const sptr<Want> &want, AbilityRequest &request);
constexpr static int REPOLL_TIME_MICRO_SECONDS = 1000000;
constexpr static int WAITING_BOOT_ANIMATION_TIMER = 5;
@@ -1193,6 +1206,7 @@ private:
bool controllerIsAStabilityTest_ = false;
std::recursive_mutex globalLock_;
std::shared_mutex managersMutex_;
sptr<AppExecFwk::IComponentInterception> componentInterception_ = nullptr;
std::multimap<std::string, std::string> timeoutMap_;
@@ -150,6 +150,7 @@ private:
int SendANRProcessIDInner(MessageParcel &data, MessageParcel &reply);
int SetAbilityControllerInner(MessageParcel &data, MessageParcel &reply);
int SetComponentInterceptionInner(MessageParcel &data, MessageParcel &reply);
int StartUserTestInner(MessageParcel &data, MessageParcel &reply);
int FinishUserTestInner(MessageParcel &data, MessageParcel &reply);
@@ -2294,6 +2294,30 @@ int AbilityManagerProxy::SetAbilityController(const sptr<AppExecFwk::IAbilityCon
return reply.ReadInt32();
}
int AbilityManagerProxy::SetComponentInterception(const sptr<AppExecFwk::IComponentInterception> &componentInterception)
{
if (!componentInterception) {
HILOG_ERROR("componentInterception nullptr");
return ERR_INVALID_VALUE;
}
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!WriteInterfaceToken(data)) {
return INNER_ERR;
}
if (!data.WriteRemoteObject(componentInterception->AsObject())) {
HILOG_ERROR("componentInterception write failed.");
return ERR_INVALID_VALUE;
}
auto error = Remote()->SendRequest(IAbilityManager::SET_COMPONENT_INTERCEPTION, data, reply, option);
if (error != NO_ERROR) {
HILOG_ERROR("Send request error: %{public}d", error);
return error;
}
return reply.ReadInt32();
}
bool AbilityManagerProxy::IsRunningInStabilityTest()
{
MessageParcel data;
@@ -579,6 +579,10 @@ int AbilityManagerService::StartAbilityInner(const Want &want, const sptr<IRemot
}
#endif
result = GenerateAbilityRequest(want, requestCode, abilityRequest, callerToken, validUserId);
if (!IsComponentInterceptionStart(want, callerToken, requestCode, result, abilityRequest)) {
return ERR_OK;
}
if (result != ERR_OK) {
HILOG_ERROR("Generate ability request local error.");
return result;
@@ -3140,10 +3144,10 @@ int AbilityManagerService::GenerateAbilityRequest(
request.callerToken = callerToken;
request.startSetting = nullptr;
auto isPerm = AAFwk::PermissionVerification::GetInstance()->VerifyMissionPermission();
if (isPerm) {
sptr<IRemoteObject> abilityInfoCallback = want.GetRemoteObject("abilityInfoCallback");
if (abilityInfoCallback != nullptr) {
sptr<IRemoteObject> abilityInfoCallback = want.GetRemoteObject(Want::PARAM_RESV_ABILITY_INFO_CALLBACK);
if (abilityInfoCallback != nullptr) {
auto isPerm = AAFwk::PermissionVerification::GetInstance()->IsGatewayCall();
if (isPerm) {
request.abilityInfoCallback = abilityInfoCallback;
}
}
@@ -5706,5 +5710,54 @@ bool AbilityManagerService::JudgeSelfCalled(const std::shared_ptr<AbilityRecord>
return true;
}
int AbilityManagerService::SetComponentInterception(
const sptr<AppExecFwk::IComponentInterception> &componentInterception)
{
HILOG_DEBUG("%{public}s", __func__);
auto isPerm = AAFwk::PermissionVerification::GetInstance()->IsGatewayCall();
if (!isPerm) {
HILOG_ERROR("%{public}s: Permission verification failed", __func__);
return CHECK_PERMISSION_FAILED;
}
std::lock_guard<std::recursive_mutex> guard(globalLock_);
componentInterception_ = componentInterception;
HILOG_DEBUG("%{public}s, end", __func__);
return ERR_OK;
}
bool AbilityManagerService::IsComponentInterceptionStart(const Want &want, const sptr<IRemoteObject> &callerToken,
int requestCode, int componentStatus, AbilityRequest &request)
{
if (componentInterception_ != nullptr) {
HILOG_DEBUG("%{public}s", __func__);
sptr<Want> extraParam = new (std::nothrow) Want();
bool isStart = componentInterception_->AllowComponentStart(want, callerToken,
requestCode, componentStatus, extraParam);
UpdateAbilityRequestInfo(extraParam, request);
if (!isStart) {
HILOG_INFO("not finishing start component because interception");
return false;
}
}
return true;
}
void AbilityManagerService::UpdateAbilityRequestInfo(const sptr<Want> &want, AbilityRequest &request)
{
if (want == nullptr) {
return;
}
sptr<IRemoteObject> tempCallBack = want->GetRemoteObject(Want::PARAM_RESV_ABILITY_INFO_CALLBACK);
if (tempCallBack == nullptr) {
return;
}
request.want.SetParam(Want::PARAM_RESV_REQUEST_PROC_CODE,
want->GetIntParam(Want::PARAM_RESV_REQUEST_PROC_CODE, 0));
request.want.SetParam(Want::PARAM_RESV_REQUEST_TOKEN_CODE,
want->GetIntParam(Want::PARAM_RESV_REQUEST_TOKEN_CODE, 0));
request.abilityInfoCallback = tempCallBack;
}
} // namespace AAFwk
} // namespace OHOS
@@ -151,6 +151,7 @@ void AbilityManagerStub::ThirdStepInit()
requestFuncMap_[REGISTER_WMS_HANDLER] = &AbilityManagerStub::RegisterWindowManagerServiceHandlerInner;
requestFuncMap_[COMPLETEFIRSTFRAMEDRAWING] = &AbilityManagerStub::CompleteFirstFrameDrawingInner;
#endif
requestFuncMap_[SET_COMPONENT_INTERCEPTION] = &AbilityManagerStub::SetComponentInterceptionInner;
}
int AbilityManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
@@ -1255,6 +1256,23 @@ int AbilityManagerStub::SetAbilityControllerInner(MessageParcel &data, MessagePa
return NO_ERROR;
}
int AbilityManagerStub::SetComponentInterceptionInner(MessageParcel &data, MessageParcel &reply)
{
sptr<AppExecFwk::IComponentInterception> componentInterception =
iface_cast<AppExecFwk::IComponentInterception>(data.ReadRemoteObject());
if (componentInterception == nullptr) {
HILOG_ERROR("AbilityManagerStub: SetComponentInterceptionInner readParcelable failed!");
return ERR_NULL_OBJECT;
}
int32_t result = SetComponentInterception(componentInterception);
HILOG_INFO("AbilityManagerStub: SetComponentInterceptionInner result = %{public}d", result);
if (!reply.WriteInt32(result)) {
HILOG_ERROR("SetComponentInterceptionInner failed.");
return ERR_INVALID_VALUE;
}
return NO_ERROR;
}
int AbilityManagerStub::IsRunningInStabilityTestInner(MessageParcel &data, MessageParcel &reply)
{
bool result = IsRunningInStabilityTest();
@@ -171,7 +171,7 @@ void AppMgrServiceInner::LoadAbility(const sptr<IRemoteObject> &token, const spt
StartProcess(abilityInfo->applicationName, processName, startFlags, appRecord,
appInfo->uid, appInfo->bundleName, bundleIndex);
} else {
appRecord->SetRequestProcCode((want == nullptr) ? 0 : want->GetIntParam("requestProcCode", 0));
appRecord->SetRequestProcCode((want == nullptr) ? 0 : want->GetIntParam(Want::PARAM_RESV_REQUEST_PROC_CODE, 0));
StartAbility(token, preToken, abilityInfo, appRecord, hapModuleInfo, want);
}
PerfProfile::GetInstance().SetAbilityLoadEndTime(GetTickCount());
@@ -880,7 +880,7 @@ std::shared_ptr<AppRunningRecord> AppMgrServiceInner::CreateAppRunningRecord(con
}
appRecord->SetAppIndex(want->GetIntParam(DLP_PARAMS_INDEX, 0));
appRecord->SetSecurityFlag(want->GetBoolParam(DLP_PARAMS_SECURITY_FLAG, false));
appRecord->SetRequestProcCode(want->GetIntParam("requestProcCode", 0));
appRecord->SetRequestProcCode(want->GetIntParam(Want::PARAM_RESV_REQUEST_PROC_CODE, 0));
}
if (preToken) {